# Counter - Habit Tracking Application

A full-stack web application for tracking habits and activities with counters. Users can create counters, increment/decrement them, and view statistics. The app supports both authenticated users (with database persistence) and anonymous users (with local storage).

## Features

- **User Authentication**: Register and login with JWT tokens
- **Anonymous Usage**: Work without registration using browser local storage
- **Counter Management**: Create, edit, delete, and manage counters
- **Increment/Decrement**: Track positive and negative changes
- **Date-based Tracking**: Counters store entries grouped by dates
- **Statistics**: View today, week, month, and total values
- **Search & Filter**: Find counters by name or description
- **Responsive Design**: Modern UI that works on all devices

## Tech Stack

- **Backend**: Go with Gin framework
- **Frontend**: React with TypeScript
- **Database**: PostgreSQL
- **Authentication**: JWT tokens
- **Deployment**: Docker with multi-stage builds

## Quick Start

### Prerequisites

- Docker and Docker Compose
- Go 1.21+ (for local development)
- Node.js 18+ (for local development)

### Using Docker Compose (Recommended)

1. Clone the repository:
```bash
git clone <repository-url>
cd counter
```

2. Start the application:
```bash
docker-compose up --build
```

3. Open your browser and navigate to `http://localhost:8080`

The application will automatically:
- Start PostgreSQL database
- Build and run the Go backend
- Build and serve the React frontend
- Create necessary database tables

### Local Development

#### Backend Setup

1. Install dependencies:
```bash
go mod download
```

2. Start PostgreSQL (using Docker):
```bash
docker run --name counter-postgres -e POSTGRES_DB=counter_db -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=password -p 5432:5432 -d postgres:15-alpine
```

3. Set environment variables:
```bash
export DATABASE_URL="postgres://postgres:password@localhost:5432/counter_db?sslmode=disable"
export JWT_SECRET="your-secret-key"
```

4. Run the backend:
```bash
go run .
```

#### Frontend Setup

1. Navigate to frontend directory:
```bash
cd frontend
```

2. Install dependencies:
```bash
npm install
```

3. Start the development server:
```bash
npm start
```

4. Open `http://localhost:3000` in your browser

## API Endpoints

### Authentication
- `POST /api/v1/auth/register` - Register a new user
- `POST /api/v1/auth/login` - Login user
- `GET /api/v1/auth/me` - Get current user (protected)

### Counters (Protected)
- `GET /api/v1/counters` - Get all counters
- `POST /api/v1/counters` - Create a new counter
- `GET /api/v1/counters/:id` - Get specific counter
- `PUT /api/v1/counters/:id` - Update counter
- `DELETE /api/v1/counters/:id` - Delete counter
- `POST /api/v1/counters/:id/increment` - Increment/decrement counter
- `GET /api/v1/counters/:id/entries` - Get counter entries
- `GET /api/v1/counters/:id/stats` - Get counter statistics

## Database Schema

### Users Table
- `id` (SERIAL PRIMARY KEY)
- `username` (VARCHAR(50) UNIQUE)
- `email` (VARCHAR(255) UNIQUE)
- `password` (VARCHAR(255))
- `created_at` (TIMESTAMP)
- `updated_at` (TIMESTAMP)

### Counters Table
- `id` (SERIAL PRIMARY KEY)
- `user_id` (INTEGER REFERENCES users(id))
- `name` (VARCHAR(100))
- `description` (TEXT)
- `created_at` (TIMESTAMP)
- `updated_at` (TIMESTAMP)

### Counter Entries Table
- `id` (SERIAL PRIMARY KEY)
- `counter_id` (INTEGER REFERENCES counters(id))
- `value` (INTEGER)
- `date` (DATE)
- `created_at` (TIMESTAMP)

## Anonymous User Support

Anonymous users can use the application without registration:
- Counters are stored in browser's localStorage
- Data persists across browser sessions
- No server-side storage for anonymous users
- Seamless transition to authenticated user (data remains in localStorage)

## Environment Variables

Create a `.env` file based on `env.example`:

```bash
# Database Configuration
DATABASE_URL=postgres://postgres:password@localhost:5432/counter_db?sslmode=disable

# JWT Configuration
JWT_SECRET=your-super-secret-jwt-key-change-in-production

# Server Configuration
PORT=8080
GIN_MODE=release
```

## Deployment

### Production Deployment

1. Set environment variables for production
2. Use a production PostgreSQL database
3. Set a strong JWT secret
4. Build and deploy using Docker:

```bash
docker build -t counter-app .
docker run -p 8080:8080 \
  -e DATABASE_URL="your-production-db-url" \
  -e JWT_SECRET="your-production-secret" \
  counter-app
```

### Docker Compose Production

Update `docker-compose.yml` with production settings:
- Use external PostgreSQL database
- Set production environment variables
- Configure proper networking and volumes

## Development

### Project Structure

```
counter/
├── main.go                 # Main application entry point
├── models.go              # Data models and DTOs
├── database.go            # Database connection and setup
├── auth.go                # Authentication handlers and middleware
├── counters.go            # Counter management handlers
├── docker-compose.yml     # Local development setup
├── Dockerfile            # Multi-stage build for production
├── go.mod                # Go dependencies
├── go.sum                # Go dependencies checksum
└── frontend/             # React frontend
    ├── src/
    │   ├── components/   # React components
    │   ├── hooks/        # Custom React hooks
    │   ├── services/     # API and localStorage services
    │   ├── types/        # TypeScript type definitions
    │   └── App.tsx       # Main React component
    ├── package.json      # Node.js dependencies
    └── public/           # Static assets
```

### Adding New Features

1. **Backend**: Add new handlers in appropriate files
2. **Frontend**: Create components in `src/components/`
3. **API Integration**: Update services in `src/services/`
4. **Types**: Add TypeScript interfaces in `src/types/`

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Submit a pull request

## License

This project is licensed under the MIT License.
