-
Notifications
You must be signed in to change notification settings - Fork 1
Eliminate type duplications and use single source of truth #321
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR replaces a centralized exported Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Code ReviewSummaryThis is an excellent refactoring that eliminates type duplication and establishes single sources of truth. The approach is clean, well-documented, and follows TypeScript best practices. ✅ Strengths
🔍 Code QualityType Safety: ✅ No compilation errors, proper type inference maintained Import Organization: ✅ Clean imports with inline type imports where used Documentation: ✅ Clear explanatory comments added Backwards Compatibility: ✅ No breaking changes - all type references work identically 🎯 VerificationI verified that:
📋 Observations
🚀 RecommendationLGTM - Approve and merge This refactoring delivers exactly what it promises: eliminates duplication, establishes single sources of truth, and improves maintainability. The code is production-ready. 💡 Minor Suggestion (Optional)Consider documenting this pattern in CLAUDE.md for future reference: ## Type System Patterns
- **Prisma Enums**: Always import from @prisma/client, never redefine
- **tRPC Types**: Use inline RouterOutputs type aliases instead of centralized files
- **Server Utils**: Manual type definitions are OK when needed to avoid circular deps (document why)Great work! 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (3)
src/app/metric/_components/base/MetricDialogBase.tsx (1)
19-20: Type alias duplication noted.This type alias is duplicated across multiple files. See the refactoring suggestion in dashboard-metric-drawer.tsx (lines 22-23).
src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx (1)
21-22: Type alias duplication noted.This type alias is duplicated across multiple files. See the refactoring suggestion in dashboard-metric-drawer.tsx (lines 22-23).
src/app/metric/_components/manual/ManualMetricContent.tsx (1)
15-16: Type alias duplication noted.This type alias is duplicated across multiple files. See the refactoring suggestion in dashboard-metric-drawer.tsx (lines 22-23).
🧹 Nitpick comments (1)
src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx (1)
22-23: Consider extracting the duplicated type alias to a shared location.This type alias
RouterOutputs["dashboard"]["getDashboardCharts"][number]is now defined identically in at least 4 files (dashboard-metric-drawer.tsx, dashboard-metric-card.tsx, MetricDialogBase.tsx, ManualMetricContent.tsx). While deriving from RouterOutputs achieves the PR's goal of a single source of truth, the duplication of the alias definition itself creates maintenance overhead.Consider creating a shared types file (e.g.,
src/app/dashboard/[teamId]/_components/types.ts) that exports this alias once, then import it where needed. This would maintain the benefits of RouterOutputs derivation while following DRY principles.💡 Example shared types file
// src/app/dashboard/[teamId]/_components/types.ts import type { RouterOutputs } from "@/trpc/react"; export type DashboardChartWithRelations = RouterOutputs["dashboard"]["getDashboardCharts"][number];Then in each component:
-import { type RouterOutputs, api } from "@/trpc/react"; +import { api } from "@/trpc/react"; +import type { DashboardChartWithRelations } from "./types"; -type DashboardChartWithRelations = - RouterOutputs["dashboard"]["getDashboardCharts"][number];
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.tssrc/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/lib/goals/types.tssrc/lib/metrics/transformer-types.tssrc/server/api/utils/enrich-charts-with-goal-progress.tssrc/types/dashboard.ts
💤 Files with no reviewable changes (1)
- src/types/dashboard.ts
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Use TypeScript 5.9 with strict type checking for all frontend and backend code
Files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/lib/metrics/transformer-types.tssrc/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.tssrc/lib/goals/types.ts
src/**/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Prefer Server Components for initial data fetching; use Client Components ('use client') only for interactivity
Files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
src/**/*/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Client Components must use
import { api } from '@/trpc/react'for standard HTTP/Hooks wrapper
Files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
**/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Use Tailwind CSS 4 for styling with shadcn/ui and Radix UI primitive components
Files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
src/app/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
src/app/**/*.tsx: Use the dual tRPC API pattern: direct calls in Server Components (api.team.getById) for 10x faster performance, and React hooks in Client Components (api.team.getById.useQuery)
Use getUserDisplayName(userId, members) utility (client-side sync) from @/lib/helpers/get-user-name for displaying user names in components
Files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
src/app/metric/_components/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
src/app/metric/_components/**/*.tsx: Create metric dialogs with pattern: [Provider]MetricDialog.tsx (dialog wrapper) + [Provider]MetricContent.tsx (form content) in src/app/metric/_components/[provider]/, then register in index.ts
Use shared MetricDialogBase component from base/ for all metric dialog implementations
Files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use @trivago/prettier-plugin-sort-imports with inline type imports for import organization
Files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/lib/metrics/transformer-types.tssrc/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.tssrc/lib/goals/types.ts
src/lib/metrics/**/*.ts
📄 CodeRabbit inference engine (GEMINI.md)
Metric transformation logic should be organized in
src/lib/metrics/to support the 3-stage pipeline: Ingestion → Aggregation → Visualization
Files:
src/lib/metrics/transformer-types.ts
src/server/api/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/server/api/**/*.ts: Use fetchUserDisplayName(userId) utility (server-side async WorkOS) from @/server/api/utils/get-user-display-name for server-side user name retrieval
Use enrichRolesWithUserNames() for flat role arrays and enrichChartRolesWithUserNames() for nested chart roles from src/server/api/utils/organization-members.ts
Files:
src/server/api/utils/enrich-charts-with-goal-progress.ts
src/app/**/*.ts
📄 CodeRabbit inference engine (GEMINI.md)
src/app/**/*.ts: Server Components must useimport { api } from '@/trpc/server'for direct DB calls without HTTP overhead
For API routes with cron jobs and webhooks, ensure proper authentication and input validation
Files:
src/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
🧠 Learnings (20)
📓 Common learnings
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.165Z
Learning: Applies to src/app/(metric|dashboard)/**/*.tsx : Use three-stage metrics transformation: API → DataPoints (DataIngestionTransformer), DataPoints → ChartConfig (ChartTransformer), ChartConfig → UI (DashboardMetricChart)
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/components/dashboard-metric-card.tsx,src/app/dashboard/[teamId]/_components/public-dashboard-metric-card.tsx : Dashboard metric cards are duplicated with public variant. Consolidate into single component with `readOnly` mode prop instead of maintaining separate components.
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.165Z
Learning: Applies to src/hooks/**/*.ts : For role-metric cache updates, optimistically update both role cache (role.getByTeamId) and dashboard cache (dashboard.getDashboardCharts) to maintain UI consistency
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.165Z
Learning: Applies to src/app/**/*.tsx : Use the dual tRPC API pattern: direct calls in Server Components (api.team.getById) for 10x faster performance, and React hooks in Client Components (api.team.getById.useQuery)
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/dashboard/[teamId]/**/*.{ts,tsx} : Dashboard cache updates for role-metric assignments must update both `role.getByTeamId` and `dashboard.getDashboardCharts` caches during mutations. Use onMutate for optimistic updates on both caches, then invalidate both on success.
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Use shared MetricDialogBase component from base/ for all metric dialog implementations
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Create metric dialogs with pattern: [Provider]MetricDialog.tsx (dialog wrapper) + [Provider]MetricContent.tsx (form content) in src/app/metric/_components/[provider]/, then register in index.ts
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Metric dialog components should follow the pattern: [Provider]MetricDialog.tsx (dialog wrapper) and [Provider]MetricContent.tsx (form content). Register in src/app/metric/_components/index.ts and inherit from shared MetricDialogBase.
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/(metric|dashboard)/**/*.tsx : Use three-stage metrics transformation: API → DataPoints (DataIngestionTransformer), DataPoints → ChartConfig (ChartTransformer), ChartConfig → UI (DashboardMetricChart)
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/lib/metrics/transformer-types.tssrc/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Metric dialog components have nearly identical wrapper patterns (5 files). Consider implementing a factory pattern or generic wrapper to reduce duplication across provider dialogs.
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/components/dashboard-metric-card.tsx,src/app/dashboard/[teamId]/_components/public-dashboard-metric-card.tsx : Dashboard metric cards are duplicated with public variant. Consolidate into single component with `readOnly` mode prop instead of maintaining separate components.
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/dashboard/[teamId]/**/*.{ts,tsx} : Dashboard cache updates for role-metric assignments must update both `role.getByTeamId` and `dashboard.getDashboardCharts` caches during mutations. Use onMutate for optimistic updates on both caches, then invalidate both on success.
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
📚 Learning: 2025-12-29T21:27:04.165Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.165Z
Learning: Applies to src/hooks/**/*.ts : For role-metric cache updates, optimistically update both role cache (role.getByTeamId) and dashboard cache (dashboard.getDashboardCharts) to maintain UI consistency
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/lib/metrics/**/*.ts : Metric transformation logic should be organized in `src/lib/metrics/` to support the 3-stage pipeline: Ingestion → Aggregation → Visualization
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/lib/metrics/transformer-types.tssrc/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/**/*/*.tsx : Client Components must use `import { api } from '@/trpc/react'` for standard HTTP/Hooks wrapper
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to **/*.{ts,tsx} : For client components using tRPC, use the React Query pattern with `import { api } from '@/trpc/react'` and access data via `api.[router].[procedure].useQuery()`. For server components, use direct calls with `import { api } from '@/trpc/server'` and await the result.
Applied to files:
src/app/metric/_components/manual/ManualMetricContent.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/**/*.tsx : Use the dual tRPC API pattern: direct calls in Server Components (api.team.getById) for 10x faster performance, and React hooks in Client Components (api.team.getById.useQuery)
Applied to files:
src/app/metric/_components/manual/ManualMetricContent.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to prisma/schema.prisma : When modifying the Prisma schema, especially for Metric Transformers, ensure AI-generated code generation and execution logic is updated accordingly
Applied to files:
src/lib/metrics/transformer-types.tssrc/lib/goals/types.ts
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: The Metrics Pipeline processes data through 3 stages: DataIngestionTransformer (Raw API → MetricDataPoint), ChartTransformer (MetricDataPoint → Chart Config), and Visualization (Chart Config → Recharts UI)
Applied to files:
src/lib/metrics/transformer-types.tssrc/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/server/api/**/*.ts : Use enrichRolesWithUserNames() for flat role arrays and enrichChartRolesWithUserNames() for nested chart roles from src/server/api/utils/organization-members.ts
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.ts
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Avoid modifying `enrichNodesWithRoleData` flow without understanding the complete canvas serialization logic for saving/loading React Flow nodes to the database
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.ts
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/lib/metrics/**/*.ts : Goal calculation utility is 271 lines and should be refactored to approximately 50 lines. Simplify logic and extract helper functions.
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.tssrc/lib/goals/types.ts
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : React Flow nodes must store minimal data (e.g., just `roleId`); fetch full Role data from TanStack Query cache in the Node component to keep canvas and sidebars in sync
Applied to files:
src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
📚 Learning: 2025-12-29T21:27:04.165Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.165Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Use shared React Flow primitives (BaseNode, BaseHandle, ZoomSlider) from src/components/react-flow/ in all canvas implementations
Applied to files:
src/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
🧬 Code graph analysis (6)
src/app/metric/_components/base/MetricDialogBase.tsx (1)
src/trpc/react.tsx (1)
RouterOutputs(42-42)
src/app/metric/_components/manual/ManualMetricContent.tsx (1)
src/trpc/react.tsx (1)
RouterOutputs(42-42)
src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx (1)
src/trpc/react.tsx (1)
RouterOutputs(42-42)
src/app/dashboard/[teamId]/_components/metric-settings-drawer.tsx (1)
src/trpc/react.tsx (1)
RouterOutputs(42-42)
src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx (1)
src/trpc/react.tsx (1)
RouterOutputs(42-42)
src/app/dashboard/[teamId]/_components/use-dashboard-charts.ts (1)
src/trpc/react.tsx (1)
RouterOutputs(42-42)
🔇 Additional comments (5)
src/server/api/utils/enrich-charts-with-goal-progress.ts (1)
13-14: LGTM - Clear documentation of circular dependency constraint.The added note appropriately documents why this type must be manually defined rather than derived from RouterOutputs, helping future maintainers understand the architectural constraint.
src/app/dashboard/[teamId]/_components/metric-settings-drawer.tsx (1)
34-41: LGTM! Type sourcing refactor aligns with PR objectives.The replacement of the centralized import with a
RouterOutputs-derived local alias ensures automatic synchronization with the tRPC endpoint definition, preventing type drift.src/lib/goals/types.ts (1)
1-4: LGTM! Prisma enum sourcing prevents type drift.Importing and re-exporting
CadenceandGoalTypefrom@prisma/clientestablishes the database schema as the single source of truth, ensuring automatic propagation of any schema changes to dependent code.src/lib/metrics/transformer-types.ts (1)
5-13: LGTM! Consistent Prisma enum sourcing.The import and re-export of
Cadencefrom@prisma/clientmaintains consistency with the refactoring insrc/lib/goals/types.tsand ensures transformer types remain synchronized with the database schema.src/app/dashboard/[teamId]/_components/use-dashboard-charts.ts (1)
5-8: LGTM! RouterOutputs-derived type ensures API contract alignment.Deriving
DashboardChartWithRelationsdirectly from the tRPC router outputs eliminates the centralized wrapper file and ensures the hook's type signature automatically reflects any changes to thegetDashboardChartsendpoint.
- Import Prisma enums (Cadence, GoalType) instead of redefining them - Remove unnecessary types/dashboard.ts wrapper file - Use tRPC RouterOutputs directly with inline type aliases - Add circular dependency note for server-side enrich util
0113a03 to
cf5532e
Compare
Code Review: Eliminate type duplications and use single source of truthSummaryThis PR successfully refactors type definitions to use Prisma enums as the single source of truth and consolidates tRPC output types using inline type aliases. The approach is solid and aligns well with the project's architecture patterns. ✅ Strengths
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Fix all issues with AI Agents 🤖
In @src/server/api/utils/enrich-charts-with-goal-progress.ts:
- Around line 13-14: The custom type DashboardChartWithRelations used by
enrichChartsWithGoalProgress is underspecified: it documents
metric.id/metric.goal/chartTransformer.cadence/chartTransformer.selectedDimension
but omits metric.roles required by enrichChartRolesWithUserNames, and the
current [key: string]: unknown` index signature hides this mismatch; update the
types so the Prisma shape is explicit—either expand DashboardChartWithRelations
to include metric.roles (and any other fields consumed downstream) or extract a
shared schema-driven type used by getDashboardCharts,
enrichChartsWithGoalProgress, and enrichChartRolesWithUserNames; additionally
add a short comment listing the exact Prisma selection fields required so future
changes to getDashboardCharts surface type errors rather than being masked by
the index signature.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsxsrc/app/dashboard/[teamId]/_components/metric-settings-drawer.tsxsrc/app/dashboard/[teamId]/_components/use-dashboard-charts.tssrc/app/metric/_components/base/MetricDialogBase.tsxsrc/app/metric/_components/manual/ManualMetricContent.tsxsrc/lib/goals/types.tssrc/lib/metrics/transformer-types.tssrc/server/api/utils/enrich-charts-with-goal-progress.tssrc/types/dashboard.ts
💤 Files with no reviewable changes (1)
- src/types/dashboard.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- src/app/dashboard/[teamId]/_components/dashboard-metric-card.tsx
- src/app/metric/_components/manual/ManualMetricContent.tsx
- src/lib/metrics/transformer-types.ts
- src/app/dashboard/[teamId]/_components/use-dashboard-charts.ts
- src/lib/goals/types.ts
- src/app/dashboard/[teamId]/_components/metric-settings-drawer.tsx
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (GEMINI.md)
Use TypeScript 5.9 with strict type checking for all frontend and backend code
Files:
src/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use @trivago/prettier-plugin-sort-imports with inline type imports for import organization
Files:
src/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
src/server/api/**/*.ts
📄 CodeRabbit inference engine (CLAUDE.md)
src/server/api/**/*.ts: Use fetchUserDisplayName(userId) utility (server-side async WorkOS) from @/server/api/utils/get-user-display-name for server-side user name retrieval
Use enrichRolesWithUserNames() for flat role arrays and enrichChartRolesWithUserNames() for nested chart roles from src/server/api/utils/organization-members.ts
Files:
src/server/api/utils/enrich-charts-with-goal-progress.ts
src/**/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Prefer Server Components for initial data fetching; use Client Components ('use client') only for interactivity
Files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
src/**/*/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Client Components must use
import { api } from '@/trpc/react'for standard HTTP/Hooks wrapper
Files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
**/*.tsx
📄 CodeRabbit inference engine (GEMINI.md)
Use Tailwind CSS 4 for styling with shadcn/ui and Radix UI primitive components
Files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
src/app/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
src/app/**/*.tsx: Use the dual tRPC API pattern: direct calls in Server Components (api.team.getById) for 10x faster performance, and React hooks in Client Components (api.team.getById.useQuery)
Use getUserDisplayName(userId, members) utility (client-side sync) from @/lib/helpers/get-user-name for displaying user names in components
Files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
src/app/metric/_components/**/*.tsx
📄 CodeRabbit inference engine (CLAUDE.md)
src/app/metric/_components/**/*.tsx: Create metric dialogs with pattern: [Provider]MetricDialog.tsx (dialog wrapper) + [Provider]MetricContent.tsx (form content) in src/app/metric/_components/[provider]/, then register in index.ts
Use shared MetricDialogBase component from base/ for all metric dialog implementations
Files:
src/app/metric/_components/base/MetricDialogBase.tsx
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/(metric|dashboard)/**/*.tsx : Use three-stage metrics transformation: API → DataPoints (DataIngestionTransformer), DataPoints → ChartConfig (ChartTransformer), ChartConfig → UI (DashboardMetricChart)
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/components/dashboard-metric-card.tsx,src/app/dashboard/[teamId]/_components/public-dashboard-metric-card.tsx : Dashboard metric cards are duplicated with public variant. Consolidate into single component with `readOnly` mode prop instead of maintaining separate components.
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/hooks/**/*.ts : For role-metric cache updates, optimistically update both role cache (role.getByTeamId) and dashboard cache (dashboard.getDashboardCharts) to maintain UI consistency
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/dashboard/[teamId]/**/*.{ts,tsx} : Dashboard cache updates for role-metric assignments must update both `role.getByTeamId` and `dashboard.getDashboardCharts` caches during mutations. Use onMutate for optimistic updates on both caches, then invalidate both on success.
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/**/*.tsx : Use the dual tRPC API pattern: direct calls in Server Components (api.team.getById) for 10x faster performance, and React hooks in Client Components (api.team.getById.useQuery)
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/(metric|dashboard)/**/*.tsx : Use three-stage metrics transformation: API → DataPoints (DataIngestionTransformer), DataPoints → ChartConfig (ChartTransformer), ChartConfig → UI (DashboardMetricChart)
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/server/api/**/*.ts : Use enrichRolesWithUserNames() for flat role arrays and enrichChartRolesWithUserNames() for nested chart roles from src/server/api/utils/organization-members.ts
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.ts
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/lib/metrics/**/*.ts : Goal calculation utility is 271 lines and should be refactored to approximately 50 lines. Simplify logic and extract helper functions.
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.ts
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/hooks/**/*.ts : For role-metric cache updates, optimistically update both role cache (role.getByTeamId) and dashboard cache (dashboard.getDashboardCharts) to maintain UI consistency
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Avoid modifying `enrichNodesWithRoleData` flow without understanding the complete canvas serialization logic for saving/loading React Flow nodes to the database
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.ts
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/dashboard/[teamId]/**/*.{ts,tsx} : Dashboard cache updates for role-metric assignments must update both `role.getByTeamId` and `dashboard.getDashboardCharts` caches during mutations. Use onMutate for optimistic updates on both caches, then invalidate both on success.
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/components/dashboard-metric-card.tsx,src/app/dashboard/[teamId]/_components/public-dashboard-metric-card.tsx : Dashboard metric cards are duplicated with public variant. Consolidate into single component with `readOnly` mode prop instead of maintaining separate components.
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: The Metrics Pipeline processes data through 3 stages: DataIngestionTransformer (Raw API → MetricDataPoint), ChartTransformer (MetricDataPoint → Chart Config), and Visualization (Chart Config → Recharts UI)
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/lib/metrics/**/*.ts : Metric transformation logic should be organized in `src/lib/metrics/` to support the 3-stage pipeline: Ingestion → Aggregation → Visualization
Applied to files:
src/server/api/utils/enrich-charts-with-goal-progress.tssrc/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Use shared MetricDialogBase component from base/ for all metric dialog implementations
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Create metric dialogs with pattern: [Provider]MetricDialog.tsx (dialog wrapper) + [Provider]MetricContent.tsx (form content) in src/app/metric/_components/[provider]/, then register in index.ts
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Metric dialog components should follow the pattern: [Provider]MetricDialog.tsx (dialog wrapper) and [Provider]MetricContent.tsx (form content). Register in src/app/metric/_components/index.ts and inherit from shared MetricDialogBase.
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-29T12:52:42.935Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T12:52:42.935Z
Learning: Applies to src/app/metric/_components/**/*.tsx : Metric dialog components have nearly identical wrapper patterns (5 files). Consider implementing a factory pattern or generic wrapper to reduce duplication across provider dialogs.
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsxsrc/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/**/*.tsx : Use the dual tRPC API pattern: direct calls in Server Components (api.team.getById) for 10x faster performance, and React hooks in Client Components (api.team.getById.useQuery)
Applied to files:
src/app/metric/_components/base/MetricDialogBase.tsx
📚 Learning: 2025-12-20T22:12:00.576Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: GEMINI.md:0-0
Timestamp: 2025-12-20T22:12:00.576Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : React Flow nodes must store minimal data (e.g., just `roleId`); fetch full Role data from TanStack Query cache in the Node component to keep canvas and sidebars in sync
Applied to files:
src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
📚 Learning: 2025-12-29T21:27:04.176Z
Learnt from: CR
Repo: drifter089/orgOS PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T21:27:04.176Z
Learning: Applies to src/app/teams/[teamId]/**/*.tsx : Use shared React Flow primitives (BaseNode, BaseHandle, ZoomSlider) from src/components/react-flow/ in all canvas implementations
Applied to files:
src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx
🧬 Code graph analysis (2)
src/app/metric/_components/base/MetricDialogBase.tsx (1)
src/trpc/react.tsx (1)
RouterOutputs(42-42)
src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx (1)
src/trpc/react.tsx (1)
RouterOutputs(42-42)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: claude-review
🔇 Additional comments (2)
src/app/dashboard/[teamId]/_components/dashboard-metric-drawer.tsx (1)
11-11: LGTM! Type derivation follows single source of truth pattern.The inline type alias derived from
RouterOutputseliminates the centralized wrapper and ensures automatic propagation of any tRPC schema changes. The use of inline type import (type RouterOutputs) follows the project's import organization guidelines.Also applies to: 23-24
src/app/metric/_components/base/MetricDialogBase.tsx (1)
17-17: LGTM! Consistent type derivation pattern.The inline type alias from
RouterOutputsmatches the pattern used in other dashboard components and eliminates dependency on the centralized type wrapper. The enriched result at line 100 correctly constructs the expected type by adding the requiredgoalProgress,valueLabel,dataDescription, andmetric.goalfields.Also applies to: 19-20
| * NOTE: This type must be manually defined here to avoid circular dependency. | ||
| * Cannot use tRPC RouterOutputs because AppRouter depends on this util file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cat -n src/server/api/utils/enrich-charts-with-goal-progress.tsRepository: drifter089/orgOS
Length of output: 6454
🏁 Script executed:
# Search for getDashboardCharts router definition
rg -n "getDashboardCharts" --type=ts -A 10 src/server/api/routers/Repository: drifter089/orgOS
Length of output: 974
🏁 Script executed:
# Look for the RouterOutputs type to understand tRPC output structure
rg -n "RouterOutputs" --type=ts src/server/Repository: drifter089/orgOS
Length of output: 197
🏁 Script executed:
cat -n src/server/api/routers/dashboard.ts | head -150Repository: drifter089/orgOS
Length of output: 5765
🏁 Script executed:
# Search for the complete getDashboardCharts definition and its return type
rg -n "getDashboardCharts" -A 50 src/server/api/routers/dashboard.ts | head -100Repository: drifter089/orgOS
Length of output: 1847
🏁 Script executed:
# Search for usages of getDashboardCharts in client components
rg -n "getDashboardCharts" --type=ts --type=tsx src/app/ | head -20Repository: drifter089/orgOS
Length of output: 87
🏁 Script executed:
# Check enrichChartsWithGoalProgress usage to see what fields are actually accessed
rg -n "enrichChartsWithGoalProgress" -B 2 -A 5 src/Repository: drifter089/orgOS
Length of output: 3914
🏁 Script executed:
# Look at enrichChartRolesWithUserNames to see what it adds to the type
cat -n src/server/api/utils/organization-members.ts | grep -A 30 "enrichChartRolesWithUserNames"Repository: drifter089/orgOS
Length of output: 1915
🏁 Script executed:
# Check if there are any TypeScript compilation errors in these files
rg -n "type DashboardChart" --type=ts src/server/api/Repository: drifter089/orgOS
Length of output: 156
🏁 Script executed:
# Verify the function is being used correctly and all required fields are present
cat -n src/server/api/utils/organization-members.ts | sed -n '196,220p'Repository: drifter089/orgOS
Length of output: 826
🏁 Script executed:
# Check how enrichChartRolesWithUserNames is called and what it receives
cat -n src/server/api/routers/dashboard.ts | sed -n '95,106p'Repository: drifter089/orgOS
Length of output: 528
🏁 Script executed:
# Search for any type mismatch issues or related tests
find src -name "*.test.ts" -o -name "*.spec.ts" | xargs grep -l "enrichChartsWithGoalProgress" 2>/dev/nullRepository: drifter089/orgOS
Length of output: 44
🏁 Script executed:
# Check the Prisma schema for DashboardChart and related models
rg -n "model DashboardChart" -A 20 prisma/schema.prismaRepository: drifter089/orgOS
Length of output: 960
🏁 Script executed:
# Check if there are any recent changes or related issues
rg -n "DashboardChartWithRelations" --type=ts src/Repository: drifter089/orgOS
Length of output: 1644
🏁 Script executed:
# Compare the type definitions in different files
for file in "src/server/api/utils/enrich-charts-with-goal-progress.ts" "src/app/metric/_components/manual/ManualMetricContent.tsx" "src/app/dashboard/\[teamId\]/_components/use-dashboard-charts.ts"; do
echo "=== $file ==="
rg -A 15 "type DashboardChartWithRelations" "$file"
doneRepository: drifter089/orgOS
Length of output: 1087
🏁 Script executed:
# Check if client-side code is using data from the server endpoint
rg -n "getDashboardCharts" src/app/ -B 2 -A 5 | head -50Repository: drifter089/orgOS
Length of output: 4145
🏁 Script executed:
# Check the AppRouter to see what RouterOutputs would infer
rg -n "export const appRouter" -A 20 src/server/api/root.tsRepository: drifter089/orgOS
Length of output: 672
🏁 Script executed:
# Verify that the manual type is actually missing fields by checking what fields are accessed
rg -n "metric\." src/server/api/utils/enrich-charts-with-goal-progress.tsRepository: drifter089/orgOS
Length of output: 652
🏁 Script executed:
# Check for metric.roles access in related code
rg -n "\.metric\.roles" src/server/api/ src/app/Repository: drifter089/orgOS
Length of output: 380
🏁 Script executed:
# Check the generic constraint of enrichChartRolesWithUserNames
rg -B 2 -A 8 "enrichChartRolesWithUserNames<" src/server/api/utils/organization-members.tsRepository: drifter089/orgOS
Length of output: 434
🏁 Script executed:
# Verify what the actual Prisma query returns for metric.roles
cat -n src/server/api/routers/dashboard.ts | sed -n '76,93p'Repository: drifter089/orgOS
Length of output: 614
Type drift risk exists but is partially mitigated by the index signature.
The manual DashboardChartWithRelations type only documents fields required by enrichChartsWithGoalProgress (metric.id, metric.goal, chartTransformer.cadence, chartTransformer.selectedDimension). However, enrichChartRolesWithUserNames requires metric.roles which isn't declared in this type. While the [key: string]: unknown index signature masks this gap, it creates an implicit contract: if the Prisma query in getDashboardCharts changes, there's no type-level verification that all downstream functions still receive their required fields.
Consider documenting the required fields in a comment listing which properties the Prisma query must include, or extract a shared schema-driven type to eliminate the manual maintenance burden.
🤖 Prompt for AI Agents
In @src/server/api/utils/enrich-charts-with-goal-progress.ts around lines 13-14,
The custom type DashboardChartWithRelations used by enrichChartsWithGoalProgress
is underspecified: it documents
metric.id/metric.goal/chartTransformer.cadence/chartTransformer.selectedDimension
but omits metric.roles required by enrichChartRolesWithUserNames, and the
current [key: string]: unknown` index signature hides this mismatch; update the
types so the Prisma shape is explicit—either expand DashboardChartWithRelations
to include metric.roles (and any other fields consumed downstream) or extract a
shared schema-driven type used by getDashboardCharts,
enrichChartsWithGoalProgress, and enrichChartRolesWithUserNames; additionally
add a short comment listing the exact Prisma selection fields required so future
changes to getDashboardCharts surface type errors rather than being masked by
the index signature.
Summary
Refactored type definitions to eliminate duplications and establish single sources of truth for Prisma enums and tRPC output types.
Key Changes
CadenceandGoalTypefrom@prisma/clientinstead of manually redefining themRouterOutputsdirectly with inline type aliases instead of centralized wrapper filesrc/types/dashboard.ts: Unnecessary abstraction layer that only wrapped tRPC typesBenefits
Summary by CodeRabbit
New Features
Refactor
Documentation
✏️ Tip: You can customize this high-level summary in your review settings.