# TekDek Command Center API A lightweight project and task management REST API built with Node.js, Express, and PostgreSQL. ## Quick Start ### 1. Install Dependencies ```bash npm install ``` ### 2. Set Up Environment ```bash cp .env.example .env # Edit .env with your database connection ``` ### 3. Set Up Database ```bash npm run db:setup npm run db:seed ``` ### 4. Start Server ```bash npm start ``` Server runs at `http://localhost:3000` by default. ## API Endpoints ### Projects #### Create Project ```http POST /api/v1/projects Content-Type: application/json { "name": "Persona Portal v2.0", "description": "Redesign and relaunch the persona publishing platform", "color_hex": "#3498db", "icon_name": "rocket" } ``` **Response (201)**: ```json { "status": "success", "data": { "id": 1, "name": "Persona Portal v2.0", "description": "...", "status": "active", "color_hex": "#3498db", "icon_name": "rocket", "owner_id": 1, "created_at": "2026-04-13T15:42:00Z", "updated_at": "2026-04-13T15:42:00Z" }, "meta": { "timestamp": "2026-04-13T15:42:00Z", "request_id": "uuid" } } ``` #### List Projects ```http GET /api/v1/projects?status=active&limit=50&offset=0 ``` **Query Parameters**: - `status`: active, archived, paused (default: active) - `limit`: 1-100 (default: 50) - `offset`: pagination offset (default: 0) **Response (200)**: ```json { "status": "success", "data": [ { "id": 1, "name": "Project 1", "status": "active", "task_count": 12, "completed_count": 3, "overdue_count": 0, ... } ], "meta": { "total": 17, "limit": 50, "offset": 0, "timestamp": "2026-04-13T15:42:00Z", "request_id": "uuid" } } ``` #### Get Project ```http GET /api/v1/projects/{id} ``` #### Update Project ```http PUT /api/v1/projects/{id} Content-Type: application/json { "name": "Updated Name", "status": "archived", "color_hex": "#e74c3c" } ``` #### Delete Project ```http DELETE /api/v1/projects/{id} ``` **Response (204)**: No content --- ### Tasks #### Create Task ```http POST /api/v1/projects/{projectId}/tasks Content-Type: application/json { "title": "Design new UI components", "description": "Create reusable button, card, and modal components", "status": "backlog", "due_date": "2026-04-20", "assignee_id": 1 } ``` **Response (201)**: ```json { "status": "success", "data": { "id": 42, "project_id": 1, "title": "Design new UI components", "status": "backlog", "position": 5, "due_date": "2026-04-20", "assignee_id": 1, "created_by": 1, "created_at": "2026-04-13T15:42:00Z", "updated_at": "2026-04-13T15:42:00Z" }, "meta": { "timestamp": "2026-04-13T15:42:00Z", "request_id": "uuid" } } ``` #### List Tasks ```http GET /api/v1/projects/{projectId}/tasks?status=all&sort=position&limit=200 ``` **Query Parameters**: - `status`: backlog, in_progress, done, blocked, all (default: all) - `sort`: position, due_date, created_at, -updated_at (default: position) - `limit`: 1-500 (default: 200) - `offset`: pagination offset (default: 0) #### Get Task ```http GET /api/v1/projects/{projectId}/tasks/{taskId} ``` #### Update Task ```http PUT /api/v1/projects/{projectId}/tasks/{taskId} Content-Type: application/json { "title": "Updated title", "status": "in_progress", "position": 3 } ``` **Position Reordering**: When `position` is provided, the task is moved to that position and all affected tasks are renumbered in a transaction. #### Delete Task ```http DELETE /api/v1/projects/{projectId}/tasks/{taskId} ``` **Response (204)**: No content #### Bulk Reorder Tasks ```http POST /api/v1/projects/{projectId}/tasks/reorder Content-Type: application/json { "order": [42, 15, 8, 23, 99] } ``` **Response (200)**: ```json { "status": "success", "data": { "updated_count": 5 }, "meta": { "timestamp": "2026-04-13T15:42:00Z", "request_id": "uuid" } } ``` --- ## Error Handling All errors follow a standard format: ```json { "status": "error", "error": { "code": "ERROR_CODE", "message": "Human-readable message", "details": { /* optional */ } }, "meta": { "timestamp": "2026-04-13T15:42:00Z", "request_id": "uuid" } } ``` ### Error Codes | Code | Status | Meaning | |------|--------|---------| | `RESOURCE_NOT_FOUND` | 404 | Project/task does not exist | | `BAD_REQUEST` | 400 | Validation failed | | `UNPROCESSABLE_ENTITY` | 422 | Logically invalid request | | `CONFLICT` | 409 | State conflict | | `INTERNAL_SERVER_ERROR` | 500 | Server error | --- ## Validation Rules ### Projects - **name**: Required, 1-255 characters - **description**: Optional, max 5000 characters - **color_hex**: Optional, format `#RRGGBB`, defaults to `#3498db` - **icon_name**: Optional, must be one of: rocket, bug, feature, docs, deploy, design - **status**: active, archived, or paused ### Tasks - **title**: Required, 1-500 characters - **description**: Optional, max 10000 characters - **status**: backlog, in_progress, done, or blocked - **due_date**: Optional, ISO 8601 format (YYYY-MM-DD) - **assignee_id**: Optional, must be valid user ID - **position**: Optional, 0 <= position < total_tasks --- ## Development ### Run Tests ```bash npm test npm run test:coverage ``` ### Run in Development Mode ```bash npm run dev ``` Uses nodemon for auto-reload. --- ## Database Schema ### Projects Table ```sql id: BIGSERIAL PRIMARY KEY name: VARCHAR(255) NOT NULL description: TEXT status: VARCHAR(50) CHECK (status IN ('active', 'archived', 'paused')) color_hex: VARCHAR(7) FORMAT #RRGGBB icon_name: VARCHAR(50) owner_id: BIGINT -> users.id created_at, updated_at: TIMESTAMP WITH TIME ZONE ``` ### Tasks Table ```sql id: BIGSERIAL PRIMARY KEY project_id: BIGINT -> projects.id (CASCADE DELETE) title: VARCHAR(500) NOT NULL description: TEXT status: VARCHAR(50) CHECK (status IN ('backlog', 'in_progress', 'done', 'blocked')) position: INTEGER (0-indexed, per project) due_date: DATE assignee_id: BIGINT -> users.id (SET NULL) created_by: BIGINT -> users.id created_at, updated_at: TIMESTAMP WITH TIME ZONE ``` ### Indexes - projects: owner_id, status, updated_at - tasks: project_id, status, project_id+status, project_id+position, assignee_id, due_date, updated_at --- ## Performance Targets All endpoints should complete under their target response time with proper indexes: | Endpoint | Target | Data Size | |----------|--------|-----------| | GET /projects | <100ms | 20 projects | | GET /projects/{id}/tasks | <200ms | 500 tasks | | POST /tasks | <150ms | - | | PUT /tasks/{id} (with reorder) | <300ms | 500 tasks | | DELETE /tasks/{id} | <100ms | - | --- ## Deployment ### Environment Variables ```bash # Database DATABASE_URL=postgresql://user:pass@host:5432/tekdek_command_center DATABASE_POOL_MIN=5 DATABASE_POOL_MAX=20 # Server PORT=3000 NODE_ENV=production LOG_LEVEL=info # CORS CORS_ORIGIN=https://web.tekdek.dev ``` ### Health Check ```http GET /health ``` ```json { "status": "ok", "db": "connected", "uptime_ms": 12345, "timestamp": "2026-04-13T15:42:00Z" } ``` --- ## Implementation Notes ### Position Reordering Algorithm When updating a task's position, the following algorithm is used: 1. Fetch all tasks in the project sorted by position 2. Remove the task from its current position 3. Insert it at the new position 4. Renumber all affected tasks (0-indexed) 5. Batch update in a single transaction This ensures positions remain contiguous and consistent. ### Transaction Safety Operations that modify multiple rows (e.g., reordering) use explicit transactions with ROLLBACK on failure to maintain data consistency. ### Cascade Delete Deleting a project automatically deletes all its tasks (enforced at database level with CASCADE DELETE constraint). --- ## Architecture Decisions - **Express.js**: Lightweight, familiar, proven for REST APIs - **Zod**: Type-safe validation with clear error messages - **PostgreSQL**: Relational DB with ACID compliance for data integrity - **Connection Pooling**: Min 5, Max 20 connections for efficient resource usage - **Real-time Saves**: Every POST/PUT immediately commits (no batching) - **Structured Logging**: JSON format for easy parsing and monitoring --- ## Future Enhancements (Phase 2+) - [ ] JWT authentication - [ ] Role-based access control (RBAC) - [ ] Audit trail logging - [ ] Soft deletes for data recovery - [ ] Task comments and activity feed - [ ] Notifications - [ ] API rate limiting per user - [ ] GraphQL endpoint --- **Built by**: Talos, Technical Coder of TekDek **Architecture**: Daedalus, Chief Architect **Status**: Production Ready ✅