This commit introduces a complete rewrite of the Tracks GTD application in Go (Golang), providing a modern, performant alternative to the Ruby on Rails implementation. ## Architecture & Technology Stack - Language: Go 1.21+ - Web Framework: Gin - ORM: GORM with SQLite/MySQL/PostgreSQL support - Authentication: JWT with bcrypt password hashing - Clean Architecture: Separated models, services, handlers, and middleware ## Implemented Features ### Core Models - User: Authentication and user management - Context: GTD contexts (@home, @work, etc.) - Project: Project grouping and tracking - Todo: Task management with state machine (active, completed, deferred, pending) - Tag: Flexible tagging system with polymorphic associations - Dependency: Todo dependencies with circular dependency detection - Preference: User preferences and settings - Note: Project notes - Attachment: File attachment support (model only) - RecurringTodo: Recurring task template (model only) ### API Endpoints **Authentication:** - POST /api/auth/login - User login - POST /api/auth/register - User registration - POST /api/auth/logout - User logout - GET /api/me - Get current user **Todos:** - GET /api/todos - List todos with filtering - POST /api/todos - Create todo - GET /api/todos/:id - Get todo details - PUT /api/todos/:id - Update todo - DELETE /api/todos/:id - Delete todo - POST /api/todos/:id/complete - Mark as completed - POST /api/todos/:id/activate - Mark as active - POST /api/todos/:id/defer - Defer to future date - POST /api/todos/:id/dependencies - Add dependency - DELETE /api/todos/:id/dependencies/:successor_id - Remove dependency **Projects:** - GET /api/projects - List projects - POST /api/projects - Create project - GET /api/projects/:id - Get project details - PUT /api/projects/:id - Update project - DELETE /api/projects/:id - Delete project - POST /api/projects/:id/complete - Complete project - POST /api/projects/:id/activate - Activate project - POST /api/projects/:id/hide - Hide project - POST /api/projects/:id/review - Mark as reviewed - GET /api/projects/:id/stats - Get project statistics **Contexts:** - GET /api/contexts - List contexts - POST /api/contexts - Create context - GET /api/contexts/:id - Get context details - PUT /api/contexts/:id - Update context - DELETE /api/contexts/:id - Delete context - POST /api/contexts/:id/hide - Hide context - POST /api/contexts/:id/activate - Activate context - POST /api/contexts/:id/close - Close context - GET /api/contexts/:id/stats - Get context statistics ### Business Logic **Todo State Management:** - Active: Ready to work on - Completed: Finished tasks - Deferred: Future actions (show_from date) - Pending: Blocked by dependencies **Dependency Management:** - Create blocking relationships between todos - Automatic state transitions when blocking todos complete - Circular dependency detection - Automatic unblocking when prerequisites complete **Tag System:** - Polymorphic tagging for todos and recurring todos - Automatic tag creation on first use - Tag cloud support **Project & Context Tracking:** - State management (active, hidden, closed/completed) - Statistics and health indicators - Review tracking for projects ### Infrastructure **Configuration:** - Environment-based configuration - Support for SQLite, MySQL, and PostgreSQL - Configurable JWT secrets and token expiry - Flexible server settings **Database:** - GORM for ORM - Automatic migrations - Connection pooling - Multi-database support **Authentication & Security:** - JWT-based authentication - Bcrypt password hashing - Secure cookie support - Token refresh mechanism **Docker Support:** - Multi-stage Dockerfile for optimized builds - Docker Compose with PostgreSQL - Volume mounting for data persistence - Production-ready configuration ## Project Structure ``` cmd/tracks/ # Application entry point internal/ config/ # Configuration management database/ # Database setup and migrations handlers/ # HTTP request handlers middleware/ # Authentication middleware models/ # Database models services/ # Business logic layer ``` ## Documentation - README_GOLANG.md: Comprehensive documentation - .env.example: Configuration template - API documentation included in README - Code comments for complex logic ## Future Work The following features from the original Rails app are not yet implemented: - Recurring todo instantiation logic - Email integration (Mailgun/CloudMailin) - Advanced statistics and analytics - Import/Export functionality (CSV, YAML, XML) - File upload handling for attachments - Mobile views - RSS/Atom feeds - iCalendar export ## Benefits Over Rails Version - Performance: Compiled binary, lower resource usage - Deployment: Single binary, no runtime dependencies - Type Safety: Compile-time type checking - Concurrency: Better handling of concurrent requests - Memory: Lower memory footprint - Portability: Easy cross-platform compilation ## Testing The code structure supports testing, though tests are not yet implemented. Future work includes adding unit and integration tests.
9.9 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
- Multi-database Support: SQLite, MySQL, and PostgreSQL
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, MySQL, or PostgreSQL
- 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
- PostgreSQL, MySQL, or SQLite (default)
- Docker and Docker Compose (optional)
Installation
Option 1: Run with Docker Compose (Recommended)
- Clone the repository:
git clone https://github.com/TracksApp/tracks.git
cd tracks
- Start the application:
docker-compose up -d
The application will be available at http://localhost:3000
Option 2: Run Locally
- Clone the repository:
git clone https://github.com/TracksApp/tracks.git
cd tracks
- Copy the environment file:
cp .env.example .env
-
Edit
.envand configure your settings (database, JWT secret, etc.) -
Install dependencies:
go mod download
- Run the application:
go run cmd/tracks/main.go
The application will be available at http://localhost:3000
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_DRIVER: Database driver (sqlite, mysql, postgres)DB_HOST: Database hostDB_PORT: Database portDB_NAME: Database name (or file path for SQLite)DB_USER: Database userDB_PASSWORD: Database password
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>
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 IDproject_id: Filter by project IDtag: Filter by tag namestarred: 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
- Define models in
internal/models/ - Create service in
internal/services/ - Create handler in
internal/handlers/ - Register routes in
cmd/tracks/main.go
Deployment
Docker Production Deployment
- Update
docker-compose.ymlwith production settings - Set strong passwords and secrets
- Configure SSL/TLS termination (nginx, traefik, etc.)
- Run:
docker-compose up -d
Binary Deployment
- Build for your platform:
CGO_ENABLED=1 go build -o tracks ./cmd/tracks
- Create
.envfile with configuration - 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:
- Export data from Rails app using YAML export
- Create equivalent users in Go version
- Import data using the import API (to be implemented)
Or run both versions side-by-side during transition.
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
License
Same as the original Tracks project.
Support
For issues and questions:
- GitHub Issues: https://github.com/TracksApp/tracks/issues
- Original Tracks: https://github.com/TracksApp/tracks
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.