diff --git a/TODO.md b/TODO.md deleted file mode 100644 index 586b05d..0000000 --- a/TODO.md +++ /dev/null @@ -1,312 +0,0 @@ -# UPAAS Implementation Plan - -## Feature Roadmap - -### Core Infrastructure -- [x] Uber fx dependency injection -- [x] Chi router integration -- [x] Structured logging (slog) with TTY detection -- [x] Configuration via Viper (env vars, config files) -- [x] SQLite database with embedded migrations -- [x] Embedded templates (html/template) -- [x] Embedded static assets (Tailwind CSS, JS) -- [x] Server startup (`Server.Run()`) -- [x] Graceful shutdown (`Server.Shutdown()`) -- [x] Route wiring (`SetupRoutes()`) - -### Authentication & Authorization -- [x] Single admin user model -- [x] Argon2id password hashing -- [x] Initial setup flow (create admin on first run) -- [x] Cookie-based session management (gorilla/sessions) -- [x] Session middleware for protected routes -- [x] Login/logout handlers -- [ ] API token authentication (for JSON API) - -### App Management -- [x] Create apps with name, repo URL, branch, Dockerfile path -- [x] Edit app configuration -- [x] Delete apps (cascades to related entities) -- [x] List all apps on dashboard -- [x] View app details -- [x] Per-app SSH keypair generation (Ed25519) -- [x] Per-app webhook secret (UUID) - -### Container Configuration -- [x] Environment variables (add, delete per app) -- [x] Docker labels (add, delete per app) -- [x] Volume mounts (add, delete per app, with read-only option) -- [x] Docker network configuration per app -- [ ] Edit existing environment variables -- [ ] Edit existing labels -- [ ] Edit existing volume mounts -- [ ] CPU/memory resource limits - -### Deployment Pipeline -- [x] Manual deploy trigger from UI -- [x] Repository cloning via Docker git container -- [x] SSH key authentication for private repos -- [x] Docker image building with configurable Dockerfile -- [x] Container creation with env vars, labels, volumes -- [x] Old container removal before new deployment -- [x] Deployment status tracking (building, deploying, success, failed) -- [x] Deployment logs storage -- [x] View deployment history per app -- [x] Container logs viewing -- [ ] Deployment rollback to previous image -- [x] Deployment cancellation - -### Manual Container Controls -- [x] Restart container -- [x] Stop container -- [x] Start stopped container - -### Webhook Integration -- [x] Gitea webhook endpoint (`/webhook/:secret`) -- [x] Push event parsing -- [x] Branch extraction from refs -- [x] Branch matching (only deploy configured branch) -- [x] Webhook event audit log -- [x] Automatic deployment on matching webhook -- [ ] Webhook event history UI -- [ ] GitHub webhook support -- [ ] GitLab webhook support - -### Health Monitoring -- [x] Health check endpoint (`/health`) -- [x] Application uptime tracking -- [x] Docker container health status checking -- [x] Post-deployment health verification (60s delay) -- [ ] Custom health check commands per app - -### Notifications -- [x] ntfy integration (HTTP POST) -- [x] Slack-compatible webhook integration -- [x] Build start/success/failure notifications -- [x] Deploy success/failure notifications -- [x] Priority mapping for notification urgency - -### Observability -- [x] Request logging middleware -- [x] Request ID generation -- [x] Sentry error reporting (optional) -- [x] Prometheus metrics endpoint (optional, with basic auth) -- [ ] Structured logging for all operations -- [ ] Deployment count/duration metrics -- [ ] Container health status metrics -- [ ] Webhook event metrics -- [ ] Audit log table for user actions - -### API -- [ ] JSON API (`/api/v1/*`) -- [ ] List apps endpoint -- [ ] Get app details endpoint -- [ ] Create app endpoint -- [ ] Delete app endpoint -- [ ] Trigger deploy endpoint -- [ ] List deployments endpoint -- [ ] API documentation - -### UI Features -- [x] Server-rendered HTML templates -- [x] Dashboard with app list -- [x] App creation form -- [x] App detail view with all configurations -- [x] App edit form -- [x] Deployment history page -- [x] Login page -- [x] Setup page -- [ ] Container logs page -- [ ] Webhook event history page -- [ ] Settings page (webhook secret, SSH public key) -- [ ] Real-time deployment log streaming (WebSocket/SSE) - -### Future Considerations -- [ ] Multi-user support with roles -- [ ] Private Docker registry authentication -- [ ] Scheduled deployments -- [ ] Backup/restore of app configurations - ---- - -## Phase 1: Critical (Application Cannot Start) - -### 1.1 Server Startup Infrastructure -- [x] Implement `Server.Run()` in `internal/server/server.go` - - Start HTTP server with configured address/port - - Handle TLS if configured - - Block until shutdown signal received -- [x] Implement `Server.Shutdown()` in `internal/server/server.go` - - Graceful shutdown with context timeout - - Close database connections - - Stop running containers gracefully (optional) -- [x] Implement `SetupRoutes()` in `internal/server/routes.go` - - Wire up chi router with all handlers - - Apply middleware (logging, auth, CORS, metrics) - - Define public vs protected route groups - - Serve static assets and templates - -### 1.2 Route Configuration -``` -Public Routes: - GET /health - GET /setup, POST /setup - GET /login, POST /login - POST /webhook/:secret - -Protected Routes (require auth): - GET /logout - GET /dashboard - GET /apps/new, POST /apps - GET /apps/:id, POST /apps/:id, DELETE /apps/:id - GET /apps/:id/edit, POST /apps/:id/edit - GET /apps/:id/deployments - GET /apps/:id/logs - POST /apps/:id/env-vars, DELETE /apps/:id/env-vars/:id - POST /apps/:id/labels, DELETE /apps/:id/labels/:id - POST /apps/:id/volumes, DELETE /apps/:id/volumes/:id - POST /apps/:id/deploy -``` - -## Phase 2: High Priority (Core Functionality Gaps) - -### 2.1 Container Logs -- [x] Implement `HandleAppLogs()` in `internal/handlers/app.go` - - Fetch logs via Docker API (`ContainerLogs`) - - Support tail parameter (last N lines) - - Stream logs with SSE or chunked response -- [x] Add Docker client method `GetContainerLogs(containerID, tail int) (io.Reader, error)` - -### 2.2 Manual Container Controls -- [x] Add `POST /apps/:id/restart` endpoint - - Stop and start container - - Record restart in deployment log -- [x] Add `POST /apps/:id/stop` endpoint - - Stop container without deleting - - Update app status -- [x] Add `POST /apps/:id/start` endpoint - - Start stopped container - - Run health check - -## Phase 3: Medium Priority (UX Improvements) - -### 3.1 Edit Operations for Related Entities -- [ ] Add `PUT /apps/:id/env-vars/:id` endpoint - - Update existing environment variable value - - Trigger container restart with new env -- [ ] Add `PUT /apps/:id/labels/:id` endpoint - - Update existing Docker label -- [ ] Add `PUT /apps/:id/volumes/:id` endpoint - - Update volume mount paths - - Validate paths before saving - -### 3.2 Deployment Rollback -- [ ] Add `previous_image_id` column to apps table - - Store last successful image ID before new deploy -- [ ] Add `POST /apps/:id/rollback` endpoint - - Stop current container - - Start container with previous image - - Create deployment record for rollback -- [ ] Update deploy service to save previous image before building new one - -### 3.3 Deployment Cancellation -- [x] Add cancellation context to deploy service -- [x] Add `POST /apps/:id/deployments/:id/cancel` endpoint -- [x] Handle cleanup of partial builds/containers - -## Phase 4: Lower Priority (Nice to Have) - -### 4.1 JSON API -- [ ] Add `/api/v1` route group with JSON responses -- [ ] Implement API endpoints mirroring web routes: - - `GET /api/v1/apps` - list apps - - `POST /api/v1/apps` - create app - - `GET /api/v1/apps/:id` - get app details - - `DELETE /api/v1/apps/:id` - delete app - - `POST /api/v1/apps/:id/deploy` - trigger deploy - - `GET /api/v1/apps/:id/deployments` - list deployments -- [ ] Add API token authentication (separate from session auth) -- [ ] Document API in README - -### 4.2 Resource Limits -- [ ] Add `cpu_limit` and `memory_limit` columns to apps table -- [ ] Add fields to app edit form -- [ ] Pass limits to Docker container create - -### 4.3 UI Improvements -- [ ] Add webhook event history page - - Show received webhooks per app - - Display match/no-match status -- [ ] Add settings page - - View/regenerate webhook secret - - View SSH public key -- [ ] Add real-time deployment log streaming - - WebSocket or SSE for live build output - -### 4.4 Observability -- [ ] Add structured logging for all operations -- [ ] Add Prometheus metrics for: - - Deployment count/duration - - Container health status - - Webhook events received -- [ ] Add audit log table for user actions - -## Phase 5: Future Considerations - -- [ ] Multi-user support with roles -- [ ] Private Docker registry authentication -- [ ] Custom health check commands per app -- [ ] Scheduled deployments -- [ ] Backup/restore of app configurations -- [ ] GitHub/GitLab webhook support (in addition to Gitea) - ---- - -## Implementation Notes - -### Server.Run() Example -```go -func (s *Server) Run() error { - s.SetupRoutes() - - srv := &http.Server{ - Addr: s.config.ListenAddr, - Handler: s.router, - } - - go func() { - <-s.shutdownCh - ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) - defer cancel() - srv.Shutdown(ctx) - }() - - return srv.ListenAndServe() -} -``` - -### SetupRoutes() Structure -```go -func (s *Server) SetupRoutes() { - r := chi.NewRouter() - - // Global middleware - r.Use(s.middleware.RequestID) - r.Use(s.middleware.Logger) - r.Use(s.middleware.Recoverer) - - // Public routes - r.Get("/health", s.handlers.HandleHealthCheck()) - r.Get("/login", s.handlers.HandleLoginPage()) - // ... - - // Protected routes - r.Group(func(r chi.Router) { - r.Use(s.middleware.SessionAuth) - r.Get("/dashboard", s.handlers.HandleDashboard()) - // ... - }) - - s.router = r -} -```