mirror of
https://github.com/TracksApp/tracks.git
synced 2026-02-08 16:44:20 +01:00
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 ✓
500 lines
11 KiB
Markdown
500 lines
11 KiB
Markdown
# 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
|
|
|
|
#### Option 1: Run with Docker Compose (Recommended)
|
|
|
|
1. Clone the repository:
|
|
```bash
|
|
git clone https://github.com/TracksApp/tracks.git
|
|
cd tracks
|
|
```
|
|
|
|
2. Start the application:
|
|
```bash
|
|
docker-compose up -d
|
|
```
|
|
|
|
The application will be available at `http://localhost:3000`
|
|
|
|
#### Option 2: Run Locally
|
|
|
|
1. Clone the repository:
|
|
```bash
|
|
git clone https://github.com/TracksApp/tracks.git
|
|
cd tracks
|
|
```
|
|
|
|
2. Copy the environment file:
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
3. Edit `.env` and configure your settings (database, JWT secret, etc.)
|
|
|
|
4. Install dependencies:
|
|
```bash
|
|
go mod download
|
|
```
|
|
|
|
5. Run the application:
|
|
```bash
|
|
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`:
|
|
```bash
|
|
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:
|
|
|
|
```bash
|
|
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)
|
|
```bash
|
|
POST /api/auth/register
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"login": "username",
|
|
"password": "password",
|
|
"first_name": "John",
|
|
"last_name": "Doe"
|
|
}
|
|
```
|
|
|
|
#### Login
|
|
```bash
|
|
POST /api/auth/login
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"login": "username",
|
|
"password": "password"
|
|
}
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
|
"user": {
|
|
"id": 1,
|
|
"login": "username",
|
|
"first_name": "John",
|
|
"last_name": "Doe"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Get Current User
|
|
```bash
|
|
GET /api/me
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### Admin Endpoints (Requires Admin Role)
|
|
|
|
#### Create User
|
|
```bash
|
|
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:
|
|
```json
|
|
{
|
|
"id": 2,
|
|
"login": "newuser",
|
|
"first_name": "John",
|
|
"last_name": "Doe",
|
|
"is_admin": false,
|
|
"created_at": "2024-01-01T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
### Todos
|
|
|
|
#### List Todos
|
|
```bash
|
|
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
|
|
```bash
|
|
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
|
|
```bash
|
|
PUT /api/todos/:id
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"description": "Buy groceries and snacks",
|
|
"starred": true
|
|
}
|
|
```
|
|
|
|
#### Complete Todo
|
|
```bash
|
|
POST /api/todos/:id/complete
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
#### Defer Todo
|
|
```bash
|
|
POST /api/todos/:id/defer
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"show_from": "2024-12-25T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
#### Add Dependency
|
|
```bash
|
|
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
|
|
```bash
|
|
GET /api/projects?state=active
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
#### Create Project
|
|
```bash
|
|
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
|
|
```bash
|
|
POST /api/projects/:id/complete
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
#### Get Project Stats
|
|
```bash
|
|
GET /api/projects/:id/stats
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
### Contexts
|
|
|
|
#### List Contexts
|
|
```bash
|
|
GET /api/contexts?state=active
|
|
Authorization: Bearer <token>
|
|
```
|
|
|
|
#### Create Context
|
|
```bash
|
|
POST /api/contexts
|
|
Authorization: Bearer <token>
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"name": "@home"
|
|
}
|
|
```
|
|
|
|
#### Hide Context
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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:
|
|
|
|
```bash
|
|
docker-compose up -d
|
|
```
|
|
|
|
### Binary Deployment
|
|
|
|
1. Build for your platform:
|
|
```bash
|
|
CGO_ENABLED=1 go build -o tracks ./cmd/tracks
|
|
```
|
|
|
|
2. Create `.env` file with configuration
|
|
3. Run:
|
|
```bash
|
|
./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:
|
|
- 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.
|