---
phase: 11-architect-agent
plan: 04
type: execute
wave: 2
depends_on: ["11-02"]
files_modified:
  - src/trpc/router.ts
  - src/trpc/context.ts
autonomous: true
---

<objective>
Add Initiative and Phase tRPC procedures for CRUD operations.

Purpose: Enable CLI and future UI to create, read, update, and delete initiatives and phases through type-safe RPC.

Output: tRPC procedures for initiative and phase management.
</objective>

<execution_context>
@~/.claude/get-shit-done/workflows/execute-plan.md
@~/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md

# Depends on Plan 02 for repositories
@.planning/phases/11-architect-agent/11-02-SUMMARY.md

# Source files
@src/trpc/router.ts
@src/trpc/context.ts
</context>

<tasks>

<task type="auto">
  <name>Task 1: Add repositories to tRPC context</name>
  <files>src/trpc/context.ts</files>
  <action>
1. Import InitiativeRepository and PhaseRepository types:
   ```typescript
   import type { InitiativeRepository } from '../db/repositories/initiative-repository.js';
   import type { PhaseRepository } from '../db/repositories/phase-repository.js';
   ```

2. Add to TRPCContext interface:
   ```typescript
   initiativeRepository?: InitiativeRepository;
   phaseRepository?: PhaseRepository;
   ```

3. Add to CreateContextOptions if needed for wiring.
  </action>
  <verify>npm run build passes</verify>
  <done>Context includes optional initiative and phase repositories</done>
</task>

<task type="auto">
  <name>Task 2: Add Initiative tRPC procedures</name>
  <files>src/trpc/router.ts</files>
  <action>
1. Add helper function:
   ```typescript
   function requireInitiativeRepository(ctx: TRPCContext): InitiativeRepository {
     if (!ctx.initiativeRepository) {
       throw new TRPCError({
         code: 'INTERNAL_SERVER_ERROR',
         message: 'Initiative repository not available',
       });
     }
     return ctx.initiativeRepository;
   }
   ```

2. Add Initiative procedures to appRouter:
   ```typescript
   // Create initiative
   createInitiative: publicProcedure
     .input(z.object({
       name: z.string().min(1),
       description: z.string().optional(),
     }))
     .mutation(async ({ ctx, input }) => {
       const repo = requireInitiativeRepository(ctx);
       return repo.create({
         name: input.name,
         description: input.description ?? null,
         status: 'active',
       });
     }),

   // List all initiatives
   listInitiatives: publicProcedure
     .input(z.object({
       status: z.enum(['active', 'completed', 'archived']).optional(),
     }).optional())
     .query(async ({ ctx, input }) => {
       const repo = requireInitiativeRepository(ctx);
       if (input?.status) {
         return repo.findByStatus(input.status);
       }
       return repo.findAll();
     }),

   // Get initiative by ID
   getInitiative: publicProcedure
     .input(z.object({ id: z.string().min(1) }))
     .query(async ({ ctx, input }) => {
       const repo = requireInitiativeRepository(ctx);
       const initiative = await repo.findById(input.id);
       if (!initiative) {
         throw new TRPCError({
           code: 'NOT_FOUND',
           message: `Initiative '${input.id}' not found`,
         });
       }
       return initiative;
     }),

   // Update initiative
   updateInitiative: publicProcedure
     .input(z.object({
       id: z.string().min(1),
       name: z.string().min(1).optional(),
       description: z.string().optional(),
       status: z.enum(['active', 'completed', 'archived']).optional(),
     }))
     .mutation(async ({ ctx, input }) => {
       const repo = requireInitiativeRepository(ctx);
       const { id, ...data } = input;
       return repo.update(id, data);
     }),
   ```
  </action>
  <verify>npm run build passes</verify>
  <done>Initiative CRUD procedures added to router</done>
</task>

<task type="auto">
  <name>Task 3: Add Phase tRPC procedures</name>
  <files>src/trpc/router.ts</files>
  <action>
1. Add helper function:
   ```typescript
   function requirePhaseRepository(ctx: TRPCContext): PhaseRepository {
     if (!ctx.phaseRepository) {
       throw new TRPCError({
         code: 'INTERNAL_SERVER_ERROR',
         message: 'Phase repository not available',
       });
     }
     return ctx.phaseRepository;
   }
   ```

2. Add Phase procedures to appRouter:
   ```typescript
   // Create phase (auto-assigns next number)
   createPhase: publicProcedure
     .input(z.object({
       initiativeId: z.string().min(1),
       name: z.string().min(1),
       description: z.string().optional(),
     }))
     .mutation(async ({ ctx, input }) => {
       const repo = requirePhaseRepository(ctx);
       const nextNumber = await repo.getNextNumber(input.initiativeId);
       return repo.create({
         initiativeId: input.initiativeId,
         number: nextNumber,
         name: input.name,
         description: input.description ?? null,
         status: 'pending',
       });
     }),

   // List phases for initiative
   listPhases: publicProcedure
     .input(z.object({ initiativeId: z.string().min(1) }))
     .query(async ({ ctx, input }) => {
       const repo = requirePhaseRepository(ctx);
       return repo.findByInitiativeId(input.initiativeId);
     }),

   // Get phase by ID
   getPhase: publicProcedure
     .input(z.object({ id: z.string().min(1) }))
     .query(async ({ ctx, input }) => {
       const repo = requirePhaseRepository(ctx);
       const phase = await repo.findById(input.id);
       if (!phase) {
         throw new TRPCError({
           code: 'NOT_FOUND',
           message: `Phase '${input.id}' not found`,
         });
       }
       return phase;
     }),

   // Update phase
   updatePhase: publicProcedure
     .input(z.object({
       id: z.string().min(1),
       name: z.string().min(1).optional(),
       description: z.string().optional(),
       status: z.enum(['pending', 'in_progress', 'completed']).optional(),
     }))
     .mutation(async ({ ctx, input }) => {
       const repo = requirePhaseRepository(ctx);
       const { id, ...data } = input;
       return repo.update(id, data);
     }),

   // Create multiple phases at once (from breakdown)
   createPhasesFromBreakdown: publicProcedure
     .input(z.object({
       initiativeId: z.string().min(1),
       phases: z.array(z.object({
         number: z.number(),
         name: z.string().min(1),
         description: z.string(),
       })),
     }))
     .mutation(async ({ ctx, input }) => {
       const repo = requirePhaseRepository(ctx);
       const created: Phase[] = [];
       for (const p of input.phases) {
         const phase = await repo.create({
           initiativeId: input.initiativeId,
           number: p.number,
           name: p.name,
           description: p.description,
           status: 'pending',
         });
         created.push(phase);
       }
       return created;
     }),
   ```
  </action>
  <verify>npm run build passes</verify>
  <done>Phase CRUD procedures added to router including bulk create</done>
</task>

</tasks>

<verification>
Before declaring plan complete:
- [ ] npm run build succeeds without errors
- [ ] npm test passes
- [ ] Initiative procedures: createInitiative, listInitiatives, getInitiative, updateInitiative
- [ ] Phase procedures: createPhase, listPhases, getPhase, updatePhase, createPhasesFromBreakdown
- [ ] All procedures follow existing patterns (error handling, optional repos)
</verification>

<success_criteria>

- All tasks completed
- Initiative and Phase CRUD available via tRPC
- Bulk phase creation supports Architect breakdown output
- Type-safe input/output validation
</success_criteria>

<output>
After completion, create `.planning/phases/11-architect-agent/11-04-SUMMARY.md`
</output>
