Skip to content

File Naming (Canonical)

This is the single normative rule for source filenames in the monorepo. Other docs link here instead of restating policy.

Exports vs files: React components, types, and interfaces use PascalCase symbols. Filenames use kebab-case (or the exceptions below). The filename does not have to mirror the export name character-for-character.

Example: theme-provider.tsx exports ThemeProvider; sign-in.ts exports signInAction.

Default (apps and packages)

Artifact Filename Primary export
React component kebab-case.tsx PascalCase FooBar
Hook use-kebab-case.ts camelCase useFooBar
Pure util / lib module kebab-case.ts camelCase functions
Co-located test kebab-case.test.ts(x) next to the source file
Multi-segment folder kebab-case/ per path segment

Remote unit tests (tests/unit/**): kebab-case.test.ts, or parent-segment.module-name.test.ts when mirroring query modules (e.g. enrollments.by-user.test.ts).

Exceptions (do not “normalize” away)

Location Pattern Rationale
packages/ui/src/components/ui/* shadcn lowercase single-word (button.tsx) or kebab-case multi-word (confirm-dialog.tsx) shadcn CLI regeneration
packages/widget-renderers/** kebab-case aligned with widget type slugs (word-search-widget.tsx) Wire format + CMS widget files
Barrels and shared type files index.ts, types.ts, domain.ts Conventional module entrypoints
Next.js App Router page.tsx, layout.tsx, route.ts, [param]/, (group)/ Framework conventions

Per-app status

App / area Status
apps/cms components Compliant — kebab-case under src/components/; tests often in __tests__/ with matching kebab names
apps/cms modules Compliant — kebab-case under src/lib/** (minor outlier: tokenVersion.ts in src/lib/auth/)
apps/lms components Compliant — kebab-case under src/components/ and src/app/**/_components/; co-located kebab-case.test.tsx
apps/lms modules Compliant — kebab-case under src/lib/**, src/auth/**, src/db/**, src/types/**, and route-colocated action modules
apps/lms test harness Complianttests/utils/render-with-theme.tsx (export renderWithTheme stays camelCase)
packages/* Compliant — follow table above; no PascalCase component filenames

Cross-app ticket: T-027 CMS vs LMS Drift.

Enforcement

  • Report-only audit: npm run audit:filenames (future CI gate support via --strict).
  • Component/module migration scripts are historical and should not be re-run unless restoring from a bad state.
  • Canonical script details (scope, flags, and usage) live in Root Scripts Reference.
  • Git blame: root .git-blame-ignore-revs lists the migration commit so blame skips renames. GitHub uses it automatically; locally run git config blame.ignoreRevsFile .git-blame-ignore-revs once per clone.

New files under apps/lms/src/** and apps/lms/tests/utils/** must use kebab-case filenames and folders. Component tests: co-located kebab-case.test.tsx (see apps/lms/.cursor/rules/030-testing.mdc).