Files
Codewalkers/apps/server/db/repositories/initiative-repository.ts
Lukas May 865e8bffa0 feat: Add initiative review gate before push
When all phases complete, the initiative now transitions to
pending_review status instead of silently stopping. The user
reviews the full initiative diff and chooses:
- Push Branch: push cw/<name> to remote for PR workflows
- Merge & Push: merge into default branch and push

Changes:
- Schema: Add pending_review to initiative status enum
- BranchManager: Add pushBranch port + SimpleGit adapter
- Events: initiative:pending_review, initiative:review_approved
- Orchestrator: checkInitiativeCompletion + approveInitiative
- tRPC: getInitiativeReviewDiff, getInitiativeReviewCommits,
  getInitiativeCommitDiff, approveInitiativeReview
- Frontend: InitiativeReview component in ReviewTab
- Subscriptions: Add initiative events + missing preview/conversation
  event types and subscription procedures
2026-03-05 17:02:17 +01:00

73 lines
1.9 KiB
TypeScript

/**
* Initiative Repository Port Interface
*
* Port for Initiative aggregate operations.
* Implementations (Drizzle, etc.) are adapters.
*/
import type { Initiative, NewInitiative } from '../schema.js';
/**
* Data for creating a new initiative.
* Omits system-managed fields (id, createdAt, updatedAt).
*/
export type CreateInitiativeData = Omit<NewInitiative, 'id' | 'createdAt' | 'updatedAt'>;
/**
* Data for updating an initiative.
* Partial of creation data - all fields optional.
*/
export type UpdateInitiativeData = Partial<CreateInitiativeData>;
/**
* Initiative Repository Port
*
* Defines operations for the Initiative aggregate.
* Only knows about initiatives - no knowledge of child entities.
*/
export interface InitiativeRepository {
/**
* Create a new initiative.
* Generates id and sets timestamps automatically.
*/
create(data: CreateInitiativeData): Promise<Initiative>;
/**
* Find an initiative by its ID.
* Returns null if not found.
*/
findById(id: string): Promise<Initiative | null>;
/**
* Find all initiatives.
* Returns empty array if none exist.
*/
findAll(): Promise<Initiative[]>;
/**
* Find all initiatives with a specific status.
* Returns empty array if none exist.
*/
findByStatus(status: 'active' | 'completed' | 'archived' | 'pending_review'): Promise<Initiative[]>;
/**
* Update an initiative.
* Throws if initiative not found.
* Updates updatedAt timestamp automatically.
*/
update(id: string, data: UpdateInitiativeData): Promise<Initiative>;
/**
* Find all initiatives linked to a specific project.
* Returns empty array if none exist.
*/
findByProjectId(projectId: string): Promise<Initiative[]>;
/**
* Delete an initiative.
* Throws if initiative not found.
* Cascades to child phases, plans, tasks via FK constraints.
*/
delete(id: string): Promise<void>;
}