Skip to content

web: review types are hand-mirrored instead of imported from @codesema/contract, and have already diverged #90

Description

@naashw

Intent

packages/contract exists to be the shared review contract, and its description says so: "Shared review contract (types + sanitizers) between the codesema CLI and codesema.com." The CLI consumes it (packages/cli/src/contract.ts is a one-line re-export).

The web UI does not. packages/web/package.json declares no dependency on @codesema/contract at all; instead packages/web/src/types.ts:43 redeclares ReviewRecord by hand, with the mirroring stated as a comment at :74:

// Mirrors packages/cli/src/serve.ts and partial.ts.

That mirror has already drifted. files_reviewed?: ReviewedFile[] exists in the contract (packages/contract/src/index.ts:98), is produced by the CLI (packages/cli/src/dual.ts:404) and is recomputed by the contract's own remapping logic (:731-744), but no such field exists in the web type. The typechecker cannot see the divergence, because there is no dependency edge for it to check.

The result is a contract that constrains the external consumer (codesema.com) while leaving the in-repo consumer free to drift — which is the reverse of what a shared contract is for, since the web UI is the one shipped inside the CLI tarball.

Scope

In scope:

  • Review-shaped types in packages/web/src/types.ts that mirror contract types.
  • The missing dependency edge from packages/web to @codesema/contract.

Out of scope:

  • Web-only view types with no contract counterpart (component props, board state).
  • The SSE frame types, unless they turn out to mirror contract types too.
  • Any change to the contract's own shape.

Approach

Add @codesema/contract as a workspace dependency of packages/web, then delete the hand-mirrored declarations in favour of imports, one type at a time. Where the web genuinely needs a narrower view, derive it from the contract type (Pick/Omit) so the typechecker still fails when the source moves.

MODIFIED Requirements

Requirement: Review types MUST have a single source

The system SHALL define review-shaped types once, in @codesema/contract, and both the CLI and the web UI SHALL derive their types from it rather than restate them.

Scenario: a contract field is added

  • GIVEN a new optional field added to the review type in @codesema/contract
  • WHEN the web package is typechecked
  • THEN the web sees the new field without any manual edit to packages/web/src/types.ts

Scenario: a contract field is renamed

  • GIVEN a field renamed in @codesema/contract
  • WHEN the web package is typechecked
  • THEN the build fails at every web site that referenced the old name

Tasks

1. Wire the edge

  • 1.1 Add @codesema/contract as a workspace:* dependency of packages/web
  • 1.2 Confirm the Vite build resolves it and the published tarball is unaffected

2. Remove the mirror

  • 2.1 Inventory the types in packages/web/src/types.ts that mirror contract types
  • 2.2 Replace each with an import, or a Pick/Omit derived from it
  • 2.3 Delete the // Mirrors ... comment once nothing mirrors

3. Close the known drift

  • 3.1 Decide whether the web should render files_reviewed, or explicitly omit it via a derived type

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingseverity:minorMinor severity review finding

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions