Skip to content

Work / DwarSeva / Wiki / Concepts

server-patterns

Conceptverified 2026-10-30

server-patterns

Shapes every server feature follows; geography/city/ is a clean copy. Layers: layered-architecture.

// Field resolver: guards on the method, failure returns null/[]
@ResolveField("relationField")
@UseGuards(AuthGuard, ScopeGuard)
@RequireScope({ requireSociety: true })
async relationField(@Parent() parent: ParentType): Promise<RelationType[]> {
  try {
    return await this.service.findByParentId(parent.id);
  } catch (error) {
    this.logger.warn(
      `Failed to resolve relationField for ${parent.id}: ${error instanceof Error ? error.message : "Unknown error"}`,
      "ClassName.relationField"
    );
    return [];
  }
}

// Service: extends AbstractBaseService (@/shared/base/base.service)
export class CityService extends AbstractBaseService<
  City, CityConnection, CityFilter, CreateCityInput, UpdateCityInput,
  Prisma.CityOrderByWithRelationInput, Prisma.CityWhereInput
> {
  constructor(private readonly cities: CityRepository, logger: AppLogger) {
    super(logger, "CityService", {
      autoFilterBySociety: false, // Geography entities are global
      autoSetCreatedBy: true,
      autoSetUpdatedBy: true,
    });
  }
}

// Repository: extends AbstractRepository (@/shared/base/base.repository), Prisma types only
constructor(prisma: PrismaService, logger: AppLogger) { super(prisma, "City", logger); }
  • A service must implement findById, connection, findFirst, create, update, delete, exists and buildWhereClause. buildWhereClause() adds entity filtering and deletedAt: null: soft-delete.
  • Type conversion happens in services; Prisma to GraphQL goes through {entity}.mapper.ts (toGqlCity).
  • Lists use the connection pattern with cursors: buildConnection in shared/utils/connection.util.ts.
  • RequestContext carries society/unit filtering: society-scope.
  • Log with AppLogger and proper context. Meaningful names, proper abstractions. Reuse existing patterns before creating new ones.
  • Testing: focus on critical business paths. No test suite exists yet.

Errors: ErrorFactory (shared/errors/error.factory.ts)

databaseError(operation, error) · unauthorized(message) · forbidden(message) · resourceNotFound(resource) · validationError(details) · businessRuleViolation(rule, message)

Related: generated-types, api-security