Summary
Response types and query param interfaces are duplicated between the frontend (apps/web/src/api/) and backend (apps/api/src/modules/), despite a shared package (@repo/shared) already existing and being wired up as a dependency of both apps.
Duplicated Types
| Type | Frontend | Backend | Overlap |
|---|
| Organization | Organization | OrganizationResponse | Identical |
| Repository | Repository | RepositoryResponse | Identical |
| PullRequest | PullRequest | PullRequestResponse | ~90% (cycleTime shape differs slightly) |
| MergeFrequency | MergeFrequencyResponse | MergeFrequencyResponse | Identical |
| Query Params | Plain interfaces (e.g. PullRequestsQueryParams) | class-validator DTO classes (e.g. PullRequestListQueryDto) | Same shape, different runtime needs |
Proposed Approach
- Response types — Move shared response interfaces (
Organization, Repository, PullRequest, MergeFrequencyResponse, etc.) into @repo/shared and have both apps import from there. - Query param interfaces — Define base interfaces in
@repo/shared. The backend DTO classes should implements the shared interface while keeping their class-validator decorators for runtime validation. The frontend imports the plain interface directly. - PullRequest alignment — Unify the
CycleTime shape so both sides use the same definition. The backend's richer CycleTimeResponse (with breakdown fields) can extend a base CycleTime type in shared.
Current State of @repo/shared
The package infrastructure is ready (package.json, TypeScript build, exports configured, included in both app dependencies). It currently only exports:
HealthResponsePaginatedResponse<T>CursorPaginationParams
Acceptance Criteria
Summary
Response types and query param interfaces are duplicated between the frontend (
apps/web/src/api/) and backend (apps/api/src/modules/), despite a shared package (@repo/shared) already existing and being wired up as a dependency of both apps.Duplicated Types
OrganizationOrganizationResponseRepositoryRepositoryResponsePullRequestPullRequestResponseMergeFrequencyResponseMergeFrequencyResponsePullRequestsQueryParams)PullRequestListQueryDto)Proposed Approach
Organization,Repository,PullRequest,MergeFrequencyResponse, etc.) into@repo/sharedand have both apps import from there.@repo/shared. The backend DTO classes shouldimplementsthe shared interface while keeping theirclass-validatordecorators for runtime validation. The frontend imports the plain interface directly.CycleTimeshape so both sides use the same definition. The backend's richerCycleTimeResponse(with breakdown fields) can extend a baseCycleTimetype in shared.Current State of
@repo/sharedThe package infrastructure is ready (
package.json, TypeScript build, exports configured, included in both app dependencies). It currently only exports:HealthResponsePaginatedResponse<T>CursorPaginationParamsAcceptance Criteria
@repo/shared(single source of truth)apps/apiandapps/webimport these types from@repo/shared