A robust, enterprise-ready task management system featuring Clean Architecture, REST API, and a companion CLI tool.
Explore the docs »
Report Bug
·
Request Feature
This project is a comprehensive task management system built with Go 1.24. It serves as a personal learning laboratory where I've implemented various modern software engineering patterns and technologies, even when not strictly required, to master their practical application.
The core focus of this project is to demonstrate:
- Clean Architecture: Strict separation of concerns between Domain, Application, and Infrastructure layers.
- REST API: Full-featured RESTful JSON API with JWT authentication.
- Test-Driven Development (TDD): High test coverage with unit, integration, and behavioral tests.
- Developer Experience: A fully-featured interactive CLI for seamless interaction.
- REST API: Clean RESTful JSON API with JWT authentication for web clients.
- Interactive CLI: A powerful terminal client with built-in authentication, task processing, and command suggestions.
- JWT Authentication: Secure access control for all task-related operations with bcrypt password hashing.
- Persistent Storage: SQLite backend using a CGO-free driver (
modernc.org/sqlite) for maximum portability. - Advanced Logging: Structured JSON/Text logging with automatic log rotation and compression via Lumberjack.
- Containerized: Ready-to-deploy Docker and Docker Compose configurations (including Loki for log aggregation).
- Observability: Prepared for integration with Loki and Grafana.
- Configuration: Flexible configuration via environment variables, YAML/JSON files, or command-line flags.
- Go 1.24+
- Docker (optional, for containerized deployment)
- Clone the repository:
git clone https://github.com/bryack/Go.git cd Go - Install dependencies:
go mod tidy
- Configure environment:
export TASKMANAGER_JWT_SECRET="your-32-character-secret-key"
Start the REST API server:
TASKMANAGER_JWT_SECRET="your-32-char-min-secret" go run ./cmd/serverAlternative methods:
# With configuration file
go run ./cmd/server --config=config.yaml
# Show current configuration
go run ./cmd/server --show-config
# With custom port
TASKMANAGER_SERVER_PORT=3000 go run ./cmd/serverThe CLI provides an interactive experience. Run it and follow the prompts:
go run ./cmd/cliCLI Commands:
| Command | Description |
|---|---|
login |
Authenticate with email and password |
register |
Create a new account |
logout |
Logout and clear stored token |
add |
Create a new task |
list |
Show all tasks |
update |
Update task description or status |
delete |
Delete a task |
status |
Toggle task completion status |
process |
Process all tasks in parallel |
clear |
Clear task description |
help |
Show available commands |
exit |
Save and exit the application |
CLI Configuration:
# Set custom server URL
export TASK_SERVER_URL="http://localhost:3000"Health Check:
curl http://localhost:8080/healthRegister a User:
curl -X POST http://localhost:8080/register \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"password123"}'Login:
curl -X POST http://localhost:8080/login \
-H "Content-Type: application/json" \
-d '{"email":"user@example.com","password":"password123"}'Create a Task:
curl -X POST http://localhost:8080/tasks \
-H "Authorization: Bearer <your_token>" \
-H "Content-Type: application/json" \
-d '{"description":"My first task"}'Get All Tasks:
curl -H "Authorization: Bearer <your_token>" http://localhost:8080/tasksGet Single Task:
curl -H "Authorization: Bearer <your_token>" http://localhost:8080/tasks/1Update a Task:
curl -X PUT http://localhost:8080/tasks/1 \
-H "Authorization: Bearer <your_token>" \
-H "Content-Type: application/json" \
-d '{"description":"Updated task","done":true}'Delete a Task:
curl -X DELETE http://localhost:8080/tasks/1 \
-H "Authorization: Bearer <your_token>"| Variable | Required | Default | Description |
|---|---|---|---|
TASKMANAGER_JWT_SECRET |
Yes | — | Secret key for JWT signing (min 32 chars) |
TASKMANAGER_DATABASE_PATH |
No | ./data/tasks.db |
Path to SQLite database file |
TASKMANAGER_SERVER_PORT |
No | 8080 |
HTTP server listening port |
TASKMANAGER_SERVER_HOST |
No | 0.0.0.0 |
HTTP server host address |
TASKMANAGER_JWT_EXPIRATION |
No | 24h |
JWT token expiration duration |
| Variable | Required | Default | Description |
|---|---|---|---|
TASKMANAGER_LOG_LEVEL |
No | info |
Log level: debug, info, warn, error |
TASKMANAGER_LOG_FORMAT |
No | json |
Log format: json or text |
TASKMANAGER_LOG_OUTPUT |
No | stderr |
Log output: stdout, stderr, or file path |
| Variable | Required | Default | Description |
|---|---|---|---|
TASK_SERVER_URL |
No | http://localhost:8080 |
Server URL for CLI client |
The server supports configuration via YAML or JSON files:
# config.yaml
server:
host: "0.0.0.0"
port: 8080
shutdown_timeout: "30s"
database:
path: "./data/tasks.db"
jwt:
secret: "CHANGE_ME_IN_PRODUCTION_MIN_32_CHARS"
expiration: "24h"
logging:
level: "info"
format: "json"
output: "stderr"
service_name: "task-manager-api"
environment: "production"Configuration precedence:
- Command-line flags (highest priority)
- Environment variables (
TASKMANAGER_*) - Configuration file (
config.yamlorconfig.json) - Default values (lowest priority)
The project follows the principles of Clean Architecture:
| Layer | Package | Responsibility |
|---|---|---|
| Domain | internal/domain |
Pure business models and interfaces (no external dependencies) |
| Application | application |
Use cases and business logic orchestration |
| Adapters | adapters/* |
External implementations (HTTP server, SQLite storage) |
| Infrastructure | infrastructure, logger, auth, validation |
Cross-cutting concerns |
Key directories:
cmd/server— HTTP server entry pointcmd/cli— Interactive CLI clientinternal/handlers— HTTP request handlersadapters/storage— SQLite persistence layerauth— JWT authentication and password hashing
I prioritize reliability through comprehensive testing:
# Run all tests
go test ./...
# Run specific test
go test -run TestFunctionName ./...
# Verbose output
go test -v ./...
# Coverage report
go test -cover ./...
# Race detector
go test -race ./...
# Integration tests (requires Docker)
export TESTCONTAINERS_RYUK_DISABLED=true
go test ./adapters/storage/... -tags=integrationNote for Fedora 43+: Disable testcontainers Ryuk:
export TESTCONTAINERS_RYUK_DISABLED=true# Build and run
docker-compose up -d --build
# View logs
docker-compose logs -f
# Stop
docker-compose down# Run with Loki for centralized logging
docker-compose -f docker-compose.yml -f docker-compose.loki.yml up -ddocker run -d \
-p 8080:8080 \
-e TASKMANAGER_JWT_SECRET="your-secure-secret-key" \
-e TASKMANAGER_DATABASE_PATH="/data/tasks.db" \
-v ./data:/data \
--name task-manager \
task-manager:latest- JWT Authentication
- REST API Implementation
- SQLite Storage (CGO-free)
- Interactive CLI Tool
- Structured Logging with Rotation
- Docker & Docker Compose Support
- Full gRPC Implementation
- Integration with Prometheus/Grafana
- Frontend Web Dashboard
Distributed under the MIT License
Anna Nurgaleeva
- LinkedIn: Anna Nurgaleeva
- Telegram: @bryacka