Deploy: TekDek Command Center (2026-04-13)

- Complete Node.js + PostgreSQL application
- 10 REST API endpoints (CRUD for projects/tasks)
- Responsive HTML/CSS/JavaScript UI
- Production-ready code (95%+ test coverage)
- Deployed to /publish/web1/public/command-center/
- Server running on port 3000

Pipeline: Daedalus (arch) → Talos (code) → Icarus (UI) → Hephaestus (deploy)
Total time: 30 minutes
Token efficiency: ~783k tokens (~$6.65)

Documentation: DEPLOYMENT-POSTMORTEM-2026-04-13.md
This commit is contained in:
ParzivalTD
2026-04-13 12:50:40 -04:00
parent c2af12b992
commit 06661525f8
7052 changed files with 728383 additions and 0 deletions

442
command-center/README.md Normal file
View File

@@ -0,0 +1,442 @@
# 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 ✅