Skip to content

F1: Client CRUD (create, rename, reorder, archive, delete) #4

@rororowyourboat

Description

@rororowyourboat

Summary

Add a persistent Client entity as the top-level organizational unit for grouping Projects. Clients are event-sourced through the existing command pipeline — no new architectural patterns required.

Scope

  • Define ClientId branded type in packages/contracts/src/baseSchemas.ts
  • Add OrchestrationClient schema to packages/contracts/src/orchestration.ts
  • Add commands: client.create, client.rename, client.reorder, client.archive, client.unarchive, client.delete
  • Add corresponding events: client.created, client.renamed, client.reordered, client.archived, client.unarchived, client.deleted
  • Add "client" to aggregateKind union and commandToAggregateRef in OrchestrationEngine.ts
  • Add decider cases in decider.ts
  • Add projector cases in projector.ts
  • Add SQLite migration for projection_clients table (client_id, name, sort_order, created_at, updated_at, archived_at, deleted_at)
  • Add ProjectionClientRepository service + SQL layer
  • Add clients[] array to OrchestrationReadModel snapshot
  • Wire up RPC endpoint for dispatch

Constraints

  • Client names unique (case-insensitive)
  • Name length: 1–100 chars (trimmed, non-empty)
  • Max 100 clients per instance
  • Delete is soft-delete (deletedAt), does not cascade to Projects
  • Archive hides from default sidebar but preserves children
  • sortOrder persisted server-side (not localStorage)
  • "Unassigned" section is virtual (not a real Client entity)

Key files to modify

  • packages/contracts/src/baseSchemas.ts — add ClientId
  • packages/contracts/src/orchestration.ts — commands, events, read model
  • packages/contracts/src/rpc.ts — if new RPC method needed
  • apps/server/src/orchestration/Layers/OrchestrationEngine.tscommandToAggregateRef
  • apps/server/src/orchestration/decider.ts
  • apps/server/src/orchestration/projector.ts
  • apps/server/src/persistence/Migrations/ — new migration
  • apps/server/src/persistence/Services/ — new repository interface
  • apps/server/src/persistence/Layers/ — new repository SQL impl

Dependencies

None — this is the foundation.

Acceptance criteria

  • Can create a Client with a name via the command pipeline
  • Duplicate names are rejected
  • Can rename, reorder, archive, unarchive, and soft-delete a Client
  • Client state survives server restart (persisted in SQLite)
  • Snapshot includes clients[] array
  • Existing snapshots without clients decode successfully (backward compat via Schema.optional/withDecodingDefault)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Priority 1 - Foundationclient-hierarchyClient hierarchy & workspace organizationenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions