Skip to content

Centralize Props/domain types (or update rule)

Problem

.cursor/rules/030-coding-best-practices.mdc mandates that all interfaces/types live under types/. Real-world layout:

  • LMS: 8 files under apps/lms/src/types/ plus a schemas/ Zod tree; ~39 component files still declare interface …Props inline.
  • CMS: 3 files under apps/cms/src/types/, with most domain types in apps/cms/src/lib/validations/, apps/cms/src/lib/widgets/types.ts, apps/cms/src/lib/rbac/types.ts, etc. — re-exported via apps/cms/src/types/index.ts.

The rule is partially followed in spirit (single re-export point) but inconsistent in letter. Either we tighten practice or we update the rule.

Proposal

This is a decision ticket with two acceptable outcomes; pick one in-ticket before implementation:

Resolved as Option B — update the rule and app AGENTS.md; no mass Props migration.

Option A — Tighten practice

  1. Move LMS component Props interfaces into per-feature types/ subtrees (e.g. apps/lms/src/components/admin/types.ts).
  2. Re-export from apps/lms/src/types/index.ts for the cross-cutting set.
  3. Keep schemas/ as the source of truth for Zod-inferred types; document in apps/lms/AGENTS.md.

Option B — Update the rule (chosen)

  1. Amend .cursor/rules/030-coding-best-practices.mdc to acknowledge that types/ is the re-export aggregator and that source-of-truth types may live next to their owning module (schemas/, lib/validations/, lib/rbac/, etc.).
  2. Add a short policy: component-local Props interfaces are allowed when they have no off-component consumers; shared Props must live in a types/ module.

Either option ends with a single concise paragraph in each app's AGENTS.md describing where to put a new type.

Acceptance criteria

  • Decision recorded in this ticket's notes log.
  • Either: relevant files moved (Option A) or rule + AGENTS.md updated (Option B).
  • npm run check passes.

Out of scope

  • Refactoring the Zod schema tree itself.
  • Generating types from migrations.
  • Mass migration of inline *Props interfaces.

Notes / decisions log

  • 2026-05-24: Ticket created from monorepo audit; option to be chosen before work begins.
  • 2026-05-25: Option B — flat per-app types/ as shared import surface; schema-owned domain (lib/validations/, schemas/cms/); colocated FooProps unless reused; cross-app contracts in workspace packages; Kysely shapes in db/types.ts. Updated .cursor/rules/030-coding-best-practices.mdc, apps/cms/AGENTS.md, apps/lms/AGENTS.md.