nexus/.planning/phases/40-job-infrastructure/40-01-SUMMARY.md

5.8 KiB

phase plan subsystem tags dependency_graph tech_stack key_files decisions metrics
40-job-infrastructure 01 content-jobs
db-schema
services
async-jobs
live-events
requires provides affects
content_jobs DB table with queued/running/done/failed lifecycle
contentJobStore CRUD service
contentJobRunner async dispatcher with live events
MAX_GENERATED_ASSET_BYTES constant (500MB)
assets.sourceTaskId column
LIVE_EVENT_TYPES extended with content_job.* events
packages/db/src/schema/
packages/shared/src/constants.ts
server/src/services/
server/src/attachment-types.ts
added patterns
Drizzle ORM pgTable schema with $type<> for typed status fields
Fire-and-forget async job dispatch with void pattern
DB write before live event publish (ordered consistency)
renderContent stub for future renderer plug-in by jobType
created modified
packages/db/src/schema/content_jobs.ts
server/src/services/content-job-store.ts
server/src/services/content-job-runner.ts
packages/db/src/migrations/0046_tense_randall.sql
packages/db/src/schema/assets.ts
packages/db/src/schema/index.ts
packages/shared/src/constants.ts
server/src/attachment-types.ts
server/src/services/index.ts
content_jobs.resultAssetId has no FK to assets — populated post-creation, circular FK avoided
assets.sourceTaskId is nullable text with no FK — task IDs are string identifiers, not UUIDs
renderContent is a stub returning placeholder.txt — phases 41-45 add real renderers keyed by jobType
Migration applied via drizzle-kit generate from worktree dist/ (main repo has pre-existing duplicate migration files)
duration completed tasks_completed tasks_total files_created files_modified
~10 minutes 2026-04-04 2 2 4 5

Phase 40 Plan 01: Schema, constants, and services for content jobs Summary

One-liner: content_jobs table + async job runner with store/runner services using fire-and-forget dispatch and ordered DB-before-event lifecycle.

What Was Built

The foundational data model and async execution engine for v1.7 content generation. Phase 40 Plan 01 establishes:

  1. DB schema (content_jobs table) with full lifecycle columns and two composite indexes for efficient querying by company+status and company+createdAt.
  2. assets.sourceTaskId — nullable text column allowing generated assets to be traced back to their originating conversation task.
  3. LIVE_EVENT_TYPES — extended with content_job.queued, content_job.running, content_job.done, content_job.failed for real-time job progress.
  4. MAX_GENERATED_ASSET_BYTES — 500MB constant (vs 10MB upload limit) for generated/namespace storage, configurable via PAPERCLIP_GENERATED_ASSET_MAX_BYTES.
  5. contentJobStore — CRUD service with create/getById/listByCompany/transition operations against the content_jobs table.
  6. contentJobRunner — async fire-and-forget dispatcher that transitions jobs through running→done/failed, stores generated assets with sourceTaskId, and publishes live events after each DB write.

Tasks Completed

Task Name Commit Files
1 Schema, constants, and migrations 8bf4bd91 content_jobs.ts, assets.ts, index.ts, constants.ts, attachment-types.ts, migration 0046
2 contentJobStore and contentJobRunner b359fec9 content-job-store.ts, content-job-runner.ts, services/index.ts

Verification

  • pnpm tsc --noEmit --project packages/db/tsconfig.json — PASS
  • pnpm tsc --noEmit --project packages/shared/tsconfig.json — PASS
  • pnpm tsc --noEmit --project server/tsconfig.json — PASS
  • Migration file 0046_tense_randall.sql generated with correct DDL

Deviations from Plan

Migration apply limitation (pre-existing blocker, out of scope)

Found during: Task 1

Issue: The main repo (/opt/nexus) has pre-existing duplicate migration files (0047_nebulous_klaw.sql and 0047_overjoyed_groot.sql, 0048_add_chat_messages_updated_at.sql and 0048_flashy_marrow.sql) from parallel agent work. The check:migrations script prevents both db:generate and db:migrate in the main repo.

Impact: Migration 0046_tense_randall.sql was generated successfully from the worktree's clean migration state but could not be applied via pnpm db:migrate.

Resolution: Migration will be applied when the worktree is merged and the duplicate migration numbering conflict is resolved. The SQL is correct and ready for execution. This is a pre-existing issue deferred to .planning/deferred-items.md.

Migration file content verified: Creates content_jobs table, adds source_task_id to assets, creates both compound indexes, adds FK to companies.

Known Stubs

renderContent stub in server/src/services/content-job-runner.ts:

  • Returns { filename: "placeholder.txt", contentType: "text/plain", buffer: Buffer.from("placeholder output") } for all jobTypes
  • This is intentional — the plan specifies this as a stub for phases 41-45 to fill in real renderers keyed by jobType
  • Does NOT prevent the plan's goal (job infrastructure) from being achieved

Self-Check: PASSED

Files verified to exist:

  • /opt/nexus/.claude/worktrees/agent-ac2e6085/packages/db/src/schema/content_jobs.ts — FOUND
  • /opt/nexus/.claude/worktrees/agent-ac2e6085/server/src/services/content-job-store.ts — FOUND
  • /opt/nexus/.claude/worktrees/agent-ac2e6085/server/src/services/content-job-runner.ts — FOUND
  • /opt/nexus/.claude/worktrees/agent-ac2e6085/packages/db/src/migrations/0046_tense_randall.sql — FOUND

Commits verified:

  • 8bf4bd91 — FOUND (feat(40-01): schema, constants, and migrations for content jobs)
  • b359fec9 — FOUND (feat(40-01): contentJobStore and contentJobRunner services)