# Issue #164: Database schema for job tracking

## Objective

Add Prisma schema for runner_jobs, job_steps, and job_events tables to support the autonomous runner infrastructure.

## Approach

1. Read existing schema.prisma to understand current conventions
2. Add four enums: RunnerJobStatus, JobStepPhase, JobStepType, JobStepStatus
3. Add three models: RunnerJob, JobStep, JobEvent
4. Create and run migration
5. Verify migration succeeds

## Schema Design

### Enums

- **RunnerJobStatus**: PENDING, QUEUED, RUNNING, COMPLETED, FAILED, CANCELLED
- **JobStepPhase**: SETUP, EXECUTION, VALIDATION, CLEANUP
- **JobStepType**: COMMAND, AI_ACTION, GATE, ARTIFACT
- **JobStepStatus**: PENDING, RUNNING, COMPLETED, FAILED, SKIPPED

### Models

1. **RunnerJob** - Top-level job tracking
   - Links to workspace and optionally to agent_task
   - Tracks overall job status, progress, result
   - Timestamps: created_at, started_at, completed_at

2. **JobStep** - Granular step tracking
   - Child of RunnerJob
   - Phase-based organization (SETUP, EXECUTION, etc.)
   - Token tracking for AI operations
   - Duration tracking

3. **JobEvent** - Event sourcing audit log
   - Immutable event log for jobs and steps
   - Links to both job and optionally step
   - Actor tracking for accountability

## Progress

- [x] Read existing schema.prisma
- [x] Read architecture document for schema requirements
- [x] Add enums (RunnerJobStatus, JobStepPhase, JobStepType, JobStepStatus)
- [x] Add RunnerJob model with workspace and agentTask relations
- [x] Add JobStep model with job relation
- [x] Add JobEvent model with job and step relations
- [x] Add RunnerJob[] to Workspace and AgentTask relations
- [x] Create migration (20260201205935_add_job_tracking)
- [x] Test migration - all tables created successfully
- [x] Run quality gates (typecheck, lint, build - all passed)
- [x] Generate Prisma client
- [x] Commit changes (commit: 65b1dad)

## Schema Observations from Existing Code

**Conventions Identified:**

- UUID primary keys with `@db.Uuid` annotation
- snake_case for database column names via `@map`
- snake_case for table names via `@@map`
- Timestamps use `@db.Timestamptz` for timezone awareness
- workspace_id on all workspace-scoped tables with cascading deletes
- Composite unique constraints with `@@unique([id, workspaceId])`
- Consistent indexing patterns: workspace_id, status, timestamps
- Json fields for flexible metadata with `@default("{}")`
- Optional foreign keys use `@db.Uuid` without NOT NULL
- Relations use descriptive names in both directions

## Testing

Since this is a schema-only change, testing will verify:

- Migration runs successfully ✅
- Foreign key constraints are valid ✅
- Schema matches architecture document ✅

Verification performed:

1. Database tables created: runner_jobs, job_steps, job_events
2. All enums created: RunnerJobStatus, JobStepPhase, JobStepType, JobStepStatus
3. Foreign key relationships verified:
   - runner_jobs → workspaces (workspace_id)
   - runner_jobs → agent_tasks (agent_task_id, optional)
   - job_steps → runner_jobs (job_id)
   - job_events → runner_jobs (job_id)
   - job_events → job_steps (step_id, optional)
4. Indexes created for performance:
   - workspace_id for workspace filtering
   - status for job querying
   - priority for job prioritization
   - timestamp for event ordering
5. Quality gates passed:
   - TypeScript compilation ✅
   - ESLint checks ✅
   - NestJS build ✅
   - Prisma client generation ✅

## Notes

- Following existing patterns from schema.prisma
- Using UUID for all primary keys (existing convention)
- Using snake_case for table names (Prisma convention)
- All workspace-scoped tables include workspace_id for RLS
- Migration file created: 20260201205935_add_job_tracking
- Database push successful, migration marked as applied
- Schema format validated successfully
