You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Within `src/features/*`, prefer scoped subdirectories such as `components`, `hooks`, `utils`, `server`, and `shared` instead of flat feature folders.
36
-
- Routers in `src/server/api/routers/` are thin orchestration layers. They handle auth context, schema-validated input, repository/service calls, and response formatting.
36
+
- Feature-owned modules may colocate client, server, and shared code under
37
+
`src/features/<domain>/<module>/`.
38
+
- Use this feature module structure for new or actively-refactored domain code:
39
+
-`shared/` contains Zod schemas, types, constants, and pure formatting helpers usable by client and server.
40
+
-`server/` contains repositories, services, policies, mappers, and feature-owned tRPC routers.
41
+
-`client/` contains hooks, reusable components, and workflow views. Add client API wrappers only when they remove real duplication or encode a stable UI contract.
42
+
-`client/admin/` is allowed for admin-only workflows.
43
+
- Import direction matters more than folder names:
44
+
-`client/` may import from its feature `shared/` and app-wide client-safe utilities.
45
+
-`server/` may import from its feature `shared/`, server utilities, and repositories.
46
+
-`shared/` must not import from `client/`, `server/`, `src/app`, or server-only libraries.
47
+
-`src/app/**` routes/pages should compose feature modules; feature modules should not import from `src/app/**`.
48
+
- tRPC routers are transport adapters. Feature-specific routers should live in the feature `server/` folder when that feature owns the full use case; `src/server/api/root.ts` should only compose them.
49
+
- Legacy routers in `src/server/api/routers/` are thin orchestration layers. They handle auth context, schema-validated input, repository/service calls, and response formatting.
37
50
- Do not put raw Prisma queries or business logic in routers.
38
-
- Define Zod schemas in `src/schemas/*`; do not define inline schemas in router `.input(...)` calls.
39
-
- All database access belongs in repository classes under `src/server/repositories/` extending `BaseRepository`.
51
+
- Define Zod schemas in feature `shared/*.schemas.ts` for feature-owned code, or in `src/schemas/*` for legacy/shared code. Do not define inline schemas in router `.input(...)` calls.
52
+
- Feature-owned tRPC procedures should declare `.output(...)` with Zod schemas. Compatibility transports that must keep legacy shapes should still have explicit legacy output schemas instead of returning raw Prisma payloads by convention.
53
+
- All database access belongs in repository classes. Feature-owned repositories may live in feature `server/` folders; legacy/shared repositories may remain under `src/server/repositories/`.
54
+
- New or actively-refactored feature-owned Prisma repositories should extend `PrismaRepository` or `PrismaWriteRepository` from `src/server/persistence/prisma.repository.ts` for Prisma client ownership and shared write handling. Do not extend the legacy `BaseRepository` unless the inherited behavior is deliberately required and documented.
55
+
- Do not add generic CRUD methods to shared repository bases. Prisma already provides typed CRUD; feature repositories should expose domain/use-case persistence operations with named select contracts.
56
+
- For feature-owned Prisma repositories, prefer a `server/persistence/` subfolder for named `select` contracts, query builders, and Prisma error translation. Derive repository record types from Prisma `GetPayload` plus those named `select` contracts instead of hand-maintaining structural copies.
57
+
- Services should depend on the concrete feature repository by default. Do not add service-owned `Pick<Repository, ...>` contracts only for tests.
58
+
- Add repository interfaces only for real boundaries: multiple implementations, external provider adapters, lifecycle concerns that route composition cannot handle directly, or domain/application layers that intentionally must not depend on infrastructure.
40
59
- Repositories should use project error helpers and consistent database operation handling.
41
-
- Multi-step business logic, external API orchestration, and complex calculations belong in services under `src/server/services/`.
60
+
- Multi-step business logic, external API orchestration, and complex calculations belong in services under feature `server/` folders or legacy `src/server/services/`.
61
+
- Use policy functions for reusable authorization/business access rules that must be shared across transports. Routers may still use broad auth procedures, but services should enforce feature-level capabilities when the use case can be called from multiple transports.
42
62
- Use `AppError` and `ResourceError` helpers instead of raw `Error`, raw strings, or one-off `TRPCError` usage.
43
63
- Use specialized procedures such as `protectedProcedure`, `adminProcedure`, and `permissionProcedure(...)` instead of ad hoc permission checks.
44
64
65
+
## API Compatibility And Legacy Contracts
66
+
67
+
- Before introducing any `legacy` select, repository method, route, endpoint,
68
+
schema, type, mapper, compatibility branch, or response shape, audit known
69
+
consumers first. For mobile/public API work, this includes
70
+
`/Volumes/T9/Coding/personal/2026/Emulation/EmuReadyApp` when it is available,
71
+
or a temporary clone of `Producdevity/EmuReadyApp` on the `master` branch when
72
+
the local app checkout is unavailable or not production-synced.
73
+
- Record which fields consumers actually read. Do not preserve fields only
74
+
because they existed in an old Prisma payload, old inferred type, or old API
75
+
response.
76
+
- Decide compatibility case by case: remove unused old fields, migrate the
77
+
consumer, keep one standardized endpoint with a small low-cost superset, or
78
+
keep a separate legacy contract only when the audited consumer behavior truly
79
+
requires it.
80
+
- Legacy contracts must have an owner, a reason, and an expected removal path.
81
+
Remove legacy code as soon as audited consumers do not need it.
82
+
45
83
## Database And Prisma
46
84
47
85
- Treat database changes as high risk.
@@ -60,6 +98,12 @@ This file is the source of working guidance for AI coding agents in this reposit
60
98
- Do not use casts to hide type problems. Fix the underlying type issue.
61
99
- Handle null and undefined explicitly.
62
100
- Use generated Prisma types where appropriate.
101
+
- Prefer deriving types from existing contracts instead of hand-maintaining
102
+
structural copies. Use Prisma `GetPayload`, Zod `z.input`/`z.output`, tRPC
103
+
`RouterInput`/`RouterOutput`, `ReturnType`, and `typeof` on const contracts
104
+
before adding a new interface or structural type alias. Add new manual
105
+
interfaces/types only for genuinely new UI/application state or external
106
+
boundaries that cannot be inferred, and keep them narrow and local.
63
107
- Do not add unused functions, exports, or speculative helpers.
64
108
- Remove dead code when refactoring.
65
109
- Do not remove or rewrite existing TODO comments unless the user explicitly
0 commit comments