tracks/README_GOLANG.md
Claude 4e9e0b4efa
Add default admin user and admin-only user creation
Features added:
- Automatic creation of default admin user on first startup (login: admin, password: admin)
- Admin-only endpoint POST /api/admin/users for creating new users
- Admin users can set is_admin flag when creating users
- Non-admin users are blocked from accessing admin endpoints

Implementation:
- Added CreateDefaultAdmin() function in internal/database/database.go
  - Checks if any users exist, creates admin only if database is empty
  - Admin user: login "admin", password "admin", is_admin true
- Added CreateUser() method to auth service for admin user creation
- Added CreateUser() handler to auth handler
- Added /api/admin/users endpoint with AuthMiddleware + AdminMiddleware
- Updated README_GOLANG.md with:
  - Default admin credentials
  - Instructions for creating additional users
  - Admin API documentation

Security:
- Default admin password should be changed after first login
- AdminMiddleware ensures only users with is_admin=true can access admin routes
- Non-admin users receive 403 Forbidden when accessing admin endpoints

Tested:
- Default admin creation on startup ✓
- Admin login with default credentials ✓
- Admin can create new users ✓
- New users can login ✓
- Non-admin users blocked from admin endpoints ✓
2025-11-05 11:35:36 +00:00

11 KiB

Tracks - Golang Rewrite

This is a complete rewrite of the Tracks GTD (Getting Things Done) application in Golang. Tracks is a web-based todo list application designed to help you organize and manage your tasks using the GTD methodology.

Features

Core GTD Functionality

  • Todos/Actions: Create, manage, and track individual tasks
  • Contexts: Organize actions by context (@home, @work, @phone, etc.)
  • Projects: Group related actions into projects
  • Dependencies: Create dependencies between todos (blocking relationships)
  • Tags: Flexible tagging system for categorization
  • State Management: Active, Completed, Deferred (tickler), and Pending (blocked) states

Advanced Features

  • Due Dates: Set and track due dates for todos
  • Deferred Actions: Schedule todos to appear at a future date (show_from)
  • Starred Todos: Flag high-priority items
  • Project Tracking: Track project status and health
  • Statistics: Built-in stats for todos, projects, and contexts
  • SQLite Database: Simple, file-based database with no external dependencies

Technical Features

  • RESTful API: Complete REST API for all operations
  • JWT Authentication: Secure token-based authentication
  • Docker Support: Ready-to-deploy Docker configuration
  • Database Migrations: Automatic database schema management
  • Clean Architecture: Well-organized, maintainable codebase

Architecture

Technology Stack

  • Language: Go 1.21+
  • Web Framework: Gin
  • ORM: GORM
  • Database: SQLite
  • Authentication: JWT (golang-jwt)
  • Password Hashing: bcrypt

Project Structure

tracks-golang/
├── cmd/
│   └── tracks/           # Main application entry point
├── internal/
│   ├── config/           # Configuration management
│   ├── database/         # Database connection and migrations
│   ├── handlers/         # HTTP request handlers
│   ├── middleware/       # HTTP middleware (auth, etc.)
│   ├── models/          # Database models
│   └── services/        # Business logic
├── .env.example         # Environment configuration template
├── Dockerfile           # Docker build configuration
├── docker-compose.yml   # Docker Compose setup
└── go.mod              # Go module dependencies

Getting Started

Prerequisites

  • Go 1.21 or higher
  • Docker and Docker Compose (optional)

Installation

  1. Clone the repository:
git clone https://github.com/TracksApp/tracks.git
cd tracks
  1. Start the application:
docker-compose up -d

The application will be available at http://localhost:3000

Option 2: Run Locally

  1. Clone the repository:
git clone https://github.com/TracksApp/tracks.git
cd tracks
  1. Copy the environment file:
cp .env.example .env
  1. Edit .env and configure your settings (database, JWT secret, etc.)

  2. Install dependencies:

go mod download
  1. Run the application:
go run cmd/tracks/main.go

The application will be available at http://localhost:3000

Default Admin User

On first startup, the application automatically creates a default admin user:

  • Username: admin
  • Password: admin

Important: Change the default password immediately after first login!

To login, make a POST request to /api/auth/login:

curl -X POST http://localhost:3000/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"login":"admin","password":"admin"}'

The response will include a JWT token that you can use for authenticated requests.

Creating Additional Users

As an admin, you can create new users via the admin API:

curl -X POST http://localhost:3000/api/admin/users \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
  -d '{
    "login": "newuser",
    "password": "password123",
    "first_name": "John",
    "last_name": "Doe",
    "is_admin": false
  }'

Set "is_admin": true to grant admin privileges to the new user.

Configuration

The application can be configured using environment variables. See .env.example for all available options.

Key Configuration Options

Server Configuration:

  • SERVER_HOST: Host to bind to (default: 0.0.0.0)
  • SERVER_PORT: Port to listen on (default: 3000)
  • GIN_MODE: Gin mode (debug, release, test)

Database Configuration:

  • DB_NAME: SQLite database file path (default: tracks.db)

Authentication:

  • JWT_SECRET: Secret key for JWT tokens (change in production!)
  • TOKEN_EXPIRY_HOURS: Token expiration time in hours (default: 168 = 7 days)
  • SECURE_COOKIES: Use secure cookies (set to true in production with HTTPS)

Application:

  • OPEN_SIGNUPS: Allow user registration (default: false)
  • ADMIN_EMAIL: Admin contact email

API Documentation

Authentication

Register (if OPEN_SIGNUPS=true)

POST /api/auth/register
Content-Type: application/json

{
  "login": "username",
  "password": "password",
  "first_name": "John",
  "last_name": "Doe"
}

Login

POST /api/auth/login
Content-Type: application/json

{
  "login": "username",
  "password": "password"
}

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": 1,
    "login": "username",
    "first_name": "John",
    "last_name": "Doe"
  }
}

Get Current User

GET /api/me
Authorization: Bearer <token>

Admin Endpoints (Requires Admin Role)

Create User

POST /api/admin/users
Authorization: Bearer <admin_token>
Content-Type: application/json

{
  "login": "newuser",
  "password": "password123",
  "first_name": "John",
  "last_name": "Doe",
  "is_admin": false
}

Response:

{
  "id": 2,
  "login": "newuser",
  "first_name": "John",
  "last_name": "Doe",
  "is_admin": false,
  "created_at": "2024-01-01T00:00:00Z"
}

Todos

List Todos

GET /api/todos?state=active&context_id=1&include_tags=true
Authorization: Bearer <token>

Query Parameters:

  • state: Filter by state (active, completed, deferred, pending)
  • context_id: Filter by context ID
  • project_id: Filter by project ID
  • tag: Filter by tag name
  • starred: Filter starred todos (true/false)
  • overdue: Show overdue todos (true/false)
  • include_tags: Include tags in response (true/false)

Create Todo

POST /api/todos
Authorization: Bearer <token>
Content-Type: application/json

{
  "description": "Buy groceries",
  "notes": "Don't forget milk",
  "context_id": 1,
  "project_id": 2,
  "due_date": "2024-12-31T00:00:00Z",
  "starred": false,
  "tags": ["shopping", "urgent"]
}

Update Todo

PUT /api/todos/:id
Authorization: Bearer <token>
Content-Type: application/json

{
  "description": "Buy groceries and snacks",
  "starred": true
}

Complete Todo

POST /api/todos/:id/complete
Authorization: Bearer <token>

Defer Todo

POST /api/todos/:id/defer
Authorization: Bearer <token>
Content-Type: application/json

{
  "show_from": "2024-12-25T00:00:00Z"
}

Add Dependency

POST /api/todos/:id/dependencies
Authorization: Bearer <token>
Content-Type: application/json

{
  "successor_id": 5
}

This creates a dependency where todo :id blocks todo 5.

Projects

List Projects

GET /api/projects?state=active
Authorization: Bearer <token>

Create Project

POST /api/projects
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "Home Renovation",
  "description": "Renovate the kitchen and bathroom",
  "default_context_id": 1
}

Complete Project

POST /api/projects/:id/complete
Authorization: Bearer <token>

Get Project Stats

GET /api/projects/:id/stats
Authorization: Bearer <token>

Contexts

List Contexts

GET /api/contexts?state=active
Authorization: Bearer <token>

Create Context

POST /api/contexts
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "@home"
}

Hide Context

POST /api/contexts/:id/hide
Authorization: Bearer <token>

Database Schema

Main Tables

  • users: User accounts and authentication
  • preferences: User preferences and settings
  • contexts: GTD contexts (@home, @work, etc.)
  • projects: Project groupings
  • todos: Individual tasks/actions
  • recurring_todos: Templates for recurring tasks
  • tags: Tag labels
  • taggings: Polymorphic tag assignments
  • dependencies: Todo dependencies
  • notes: Project notes
  • attachments: File attachments for todos

Development

Building

# Build the application
go build -o tracks ./cmd/tracks

# Run tests
go test ./...

# Run with hot reload (install air first: go install github.com/cosmtrek/air@latest)
air

Code Structure

The application follows clean architecture principles:

  • Models: Define database schema and basic methods
  • Services: Contain business logic
  • Handlers: Handle HTTP requests and responses
  • Middleware: Authentication, logging, etc.

Adding New Features

  1. Define models in internal/models/
  2. Create service in internal/services/
  3. Create handler in internal/handlers/
  4. Register routes in cmd/tracks/main.go

Deployment

Docker Production Deployment

  1. Update docker-compose.yml with production settings
  2. Set strong passwords and secrets
  3. Configure SSL/TLS termination (nginx, traefik, etc.)
  4. Run:
docker-compose up -d

Binary Deployment

  1. Build for your platform:
CGO_ENABLED=1 go build -o tracks ./cmd/tracks
  1. Create .env file with configuration
  2. Run:
./tracks

Differences from Original Ruby/Rails Version

Improvements

  • Performance: Significantly faster due to Go's compiled nature
  • Memory Usage: Lower memory footprint
  • Deployment: Single binary, no Ruby runtime needed
  • Type Safety: Compile-time type checking
  • Concurrency: Better handling of concurrent requests

Current Limitations

  • Recurring Todos: Not yet fully implemented
  • Email Integration: Not yet implemented
  • Statistics: Basic stats only (advanced analytics pending)
  • Import/Export: Not yet implemented
  • Mobile Views: Not yet implemented
  • Attachments: Model defined but upload handling pending

Migration Path

To migrate from the Ruby/Rails version:

  1. Export data from Rails app using YAML export
  2. Create equivalent users in Go version
  3. Import data using the import API (to be implemented)

Or run both versions side-by-side during transition.

Contributing

Contributions are welcome! Please:

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

License

Same as the original Tracks project.

Support

For issues and questions:

Acknowledgments

This is a rewrite of the original Tracks application (https://github.com/TracksApp/tracks) created by the Tracks team. The original application is written in Ruby on Rails.