Problem
We have duplicate Prisma select definitions for roadmap tasks scattered across multiple files. When adding a new field like stakworkProjectId, it required updates in 7+ places:
src/types/roadmap.tsx - RoadmapTaskListItemBase
src/types/roadmap.tsx - FeatureDetail.phases.tasks
src/types/roadmap.tsx - PhaseWithTasks.tasks
src/services/roadmap/phases.ts - getPhase()
src/services/roadmap/tickets.ts - createTicket()
src/services/roadmap/tickets.ts - updateTicket()
src/services/roadmap/tickets.ts - reorderTasks()
src/app/api/features/[featureId]/route.ts - GET handler (2 places)
This is error-prone and violates DRY.
Proposed Solution
Create a shared constant for the task select shape:
// src/lib/prisma-selects.ts
export const ROADMAP_TASK_SELECT = {
id: true,
title: true,
description: true,
status: true,
priority: true,
order: true,
featureId: true,
phaseId: true,
bountyCode: true,
stakworkProjectId: true,
dependsOnTaskIds: true,
createdAt: true,
updatedAt: true,
assignee: {
select: {
id: true,
name: true,
email: true,
image: true,
},
},
phase: {
select: {
id: true,
name: true,
},
},
} as const;
Then derive the TypeScript type from it and reuse everywhere.
Benefits
- Single source of truth for task shape
- Adding new fields requires only 1 change
- Type safety maintained via
Prisma.TaskGetPayload<{ select: typeof ROADMAP_TASK_SELECT }>
Files to Update
- Create
src/lib/prisma-selects.ts
- Update
src/types/roadmap.tsx to derive types from constants
- Update all service files to use shared selects
- Update API routes to use shared selects
Problem
We have duplicate Prisma select definitions for roadmap tasks scattered across multiple files. When adding a new field like
stakworkProjectId, it required updates in 7+ places:src/types/roadmap.tsx-RoadmapTaskListItemBasesrc/types/roadmap.tsx-FeatureDetail.phases.taskssrc/types/roadmap.tsx-PhaseWithTasks.taskssrc/services/roadmap/phases.ts-getPhase()src/services/roadmap/tickets.ts-createTicket()src/services/roadmap/tickets.ts-updateTicket()src/services/roadmap/tickets.ts-reorderTasks()src/app/api/features/[featureId]/route.ts- GET handler (2 places)This is error-prone and violates DRY.
Proposed Solution
Create a shared constant for the task select shape:
Then derive the TypeScript type from it and reuse everywhere.
Benefits
Prisma.TaskGetPayload<{ select: typeof ROADMAP_TASK_SELECT }>Files to Update
src/lib/prisma-selects.tssrc/types/roadmap.tsxto derive types from constants