Work / DwarSeva / Wiki / Concepts
field-resolver-standards
Conceptverified 2026-10-30
field-resolver-standards
A field resolver goes in the domain folder that owns the service required to resolve the relation. Never place it by parent type. Why: field-resolver-placement. This rule has been violated 20+ times; a resolver in the wrong domain is rejected. Before creating one, ask: "What service do I need? Which domain has that service?"
Placement
- Identify the service needed. Find the domain folder that contains it. Create the file in that feature folder.
- Does the target domain already import the required service's module? Yes: place it there. No: if the service's domain already imports the target domain's module, place it in the service's domain. Otherwise choose the domain with fewer new imports.
- Never add a module import solely to satisfy a relation if placing the resolver in the other domain resolves it.
- If both sides need new imports, choose the side already importing the dependency transitively.
| Service | Folder (under apps/server/src/api/) |
|---|---|
BillService |
finance/bill/ |
PaymentService |
finance/payment/ |
SocietyService |
society/society/ |
UnitService |
society/unit/ |
UserService |
users/user/, or a domain that already imports UserModule |
Real files: finance/bill/user.billsCreated, society/unit/society.units, society/society/announcement.society, users/user/payment.user, users/user/announcement.createdBy, society/society-member/user.societyMemberships (each .fields.resolver.ts).
Known exception in the code: society/unit/unit.society.fields.resolver.ts uses SocietyService.
Standards
- File
{parentType}.{relation}.fields.resolver.ts; class{Parent}{Relation}FieldsResolverwith@Resolver("Parent"). - One relation per file. Never group unrelated relations.
@UseGuards(AuthGuard, ScopeGuard)at method level, plus@RequireScope({ requireSociety: true })when needed. Class level is acceptable only if every field shares identical requirements; be consistent.- Try/catch with
logger.warn; returnnullor[]on failure. - Services only, no direct database calls. Do not inject unused services. Import types from
gql/server.
Common violations
User.*resolvers inusers/when they need other services.Society.*resolvers insociety/unit/when they needSocietyService.- New module imports just to satisfy a placement.
- Several unrelated relations in one resolver file.
- Placing by parent type instead of required service.
Checklist before creating one
- Which service, and which domain folder holds it?
- Does that domain already import the service's module?
- If not, would adding the import create a circular dependency?
- Is there a placement that avoids new imports?
If you cannot answer these, do not create the resolver. Template: server-patterns.