Expert usage of the Database Compiler. Handles the additive Schema Ontology (models.yaml) and the Generated Prisma Client.
You MUST follow the standards defined in:
core/ARCHITECTURE.md: 3-Tier Modular Monolith Architecture.core/MODULES.md: Additive Schema Design & Mixed Directories.core/CODE.md: Service Layer Patterns.any: The use of any is strictly prohibited. You MUST use specific types, unknown with validation, or proper interfaces. There are NO exceptions to this rule.prisma or db directly inside apps/backend/modules/{name}/src/pages/api/ or apps/backend/modules/{name}/src/actions/.db. They must use Services or the Federated SDK.src/middleware.ts) should delegate data operations to Services. If you find db imports outside of apps/backend/modules/{name}/src/services/, they are architectural debt. NEVER add import { db } to middleware.Service class located in apps/backend/modules/{name}/src/services/.db.$transaction.static.models.yaml)We DO NOT- Core Models: core/prisma/models.yaml (Base User/Auth models).
apps/backend/modules/{name}/models.yaml (Feature-specific models).ation**: The compiler merges these fragments into prisma/schema.prisma.apps/backend/modules/{name}/models.yaml.nexical or npx tsx scripts/generate-prisma.ts.npm run db:pushnpm run db:migrateAccess to data follows a strict hierarchy: Action -> Service -> DB.
modules/{name}/src/actions/)Actions handle validation and orchestrate business logic across multiple services.
apps/backend/modules/{name}/src/actions/{kebab-case}.ts (Manual){kebab-case}.ts. Do not add group suffixes like -ops.ts.public static async run(input: unknown, context: APIContext).static schema (Zod) and perform this.schema.parse(input) inside .run(). This is non-negotiable for security and decoupling.context.locals.actor. If the actor is missing, return an error (e.g., 401 Unauthorized). NEVER skip actor verification in actions.db here.templates/action.tsmodules/{name}/src/services/)Services are the ONLY tier allowed to import db from @/lib/core/db.
apps/backend/modules/{name}/src/services/ contains both machine-generated and manual code.
// GENERATED CODE headers. Do NOT modify these files.{kebab-case}-ops-service.ts suffixes.public static async, accept an actor: ApiActor parameter (even for read-only ops if they trigger hooks), and return Promise<ServiceResponse<T>>.HookSystem.filter for Input/Output.HookSystem.dispatch for side effects.templates/service.tsFile operations related to database records (e.g., attachments, avatars, generated artifacts) must use the Storage Provider.
getStorageProvider() factory from @/lib/core/storage.Data mutations must trigger lifecycle events via the HookSystem.
HookSystem.filter('model.beforeCreate', ...) before database operations.HookSystem.dispatch('model.created', ...) after successful mutations.HookSystem.filter('model.afterCreate', ...) to sanitize or transform data before returning to the caller.apps/backend/modules/{name}/src/server-init.ts file via the static init() method (handled by the generator).Agents (JobProcessors) in apps/backend/modules/{name}/src/agent/ must follow strict isolation.
JobProcessor<T> from @nexical/agent.public static jobType: string. It is NOT an instance property.public schema (Zod) to validate job data.job.payload to access the validated data (do not use .data).context.api). NEVER import db in an agent.templates/agent-processor.tsBefore finalizing any DB-related change, perform these checks:
grep -r "import { db } from '@/lib/core/db'" and ensure it ONLY matches files in apps/backend/modules/*/src/services/..ts file in apps/backend/modules/*/src/actions/ defines a static schema and calls .parse().actor: ApiActor.// GENERATED CODE has been modified manually.