Files
KIS-TOiR/domain/dsl-spec.md
2026-03-25 21:01:31 +03:00

6.1 KiB
Raw Blame History

DSL Language Specification

This document describes the single DSL (Domain Specific Language) used to specify fullstack CRUD applications. The only required DSL input is domain/*.dsl.

domain-summary.json is a derived artifact generated from this DSL to stabilize LLM-first generation and feed the lightweight validation gate. It must never replace the DSL as the source of truth. The active prompt corpus that consumes this contract lives in prompts/.


DSL Responsibility

The domain DSL defines only:

  • domain model
  • relations
  • enums

The domain DSL is the single source of truth for:

  • entities
  • attributes
  • primary keys
  • foreign keys
  • enums

The following layers are always derived from the domain DSL and must not be authored as standalone authoritative DSL inputs:

  • DTO
  • API
  • UI

Optional extension mechanism:

overrides/
  api-overrides.dsl
  ui-overrides.dsl

Override rules:

  • Overrides are optional.
  • The generator must work without them.
  • Overrides may refine derived API or UI behavior, but they must not duplicate or redefine entities, attributes, primary keys, foreign keys, relations, or enums.

DSL Grammar Concepts

entity

An entity is a domain object that becomes a database table and a first-class resource in the backend and frontend.

entity Equipment {
  attribute id { type uuid; key primary; }
  attribute name { type string; is required; }
}
  • Domain: Defines the canonical model; one entity = one Prisma model, one NestJS module, one React Admin resource.
  • Naming: PascalCase (e.g. Equipment, EquipmentType, RepairOrder).

attribute

An attribute is a field of an entity. It has a type and optional modifiers.

attribute name {
  description "Наименование";
  type string;
  is required;
  is unique;
}

Modifiers:

  • type — required; one of: string, uuid, integer, decimal, date, text, or an enum name.
  • key primary — this attribute is the primary key.
  • key foreign { relates Entity.field } — foreign key to another entity's field.
  • is required — non-nullable.
  • is unique — unique constraint.
  • default Value — default value (for enums or literals).
  • description "..." — human-readable description.

enum

An enum defines a fixed set of values. Used for attributes that can only take one of these values.

enum EquipmentStatus {
  value Active { label "В эксплуатации"; }
  value Repair { label "В ремонте"; }
}
  • value — identifier used in data and code.
  • label — optional display label for UI.

primary key

Exactly one attribute per entity must be marked as primary key.

attribute id {
  type uuid;
  key primary;
}

Or for a natural key:

attribute code {
  type string;
  key primary;
  is required;
  is unique;
}

foreign key

A foreign key links to another entity's primary key. The attribute type must match the referenced primary key type.

attribute equipmentTypeCode {
  type string;
  key foreign {
    relates EquipmentType.code;
  }
  is required;
}
  • relates Entity.attribute — references Entity's attribute (must be primary key).
  • FK type must equal referenced PK type (e.g. stringEquipmentType.code, uuidEquipment.id).

required

  • is required — attribute is non-nullable in the domain model and drives requiredness in derived DTO/API/UI artifacts.
  • Absence of is required means the attribute is optional (nullable).

default

  • default Value — applied when no value is provided (e.g. enum defaults like default Active).
  • Value must exist in the enum when the attribute type is an enum.

DSL → System Component Mapping

DSL → Prisma

DSL Concept Prisma Result
entity model
attribute field
enum enum
key primary @id or @id @default(uuid())
key foreign relation + references
type string String
type uuid String @id @default(uuid())
type integer Int
type decimal Decimal
type date DateTime
type text String

DSL → NestJS

DSL Concept NestJS Result
entity One module (e.g. equipment.module.ts)
entity Controller with CRUD endpoints
entity Service with Prisma CRUD
entity + attribute metadata create-{entity}.dto.ts
entity + attribute metadata update-{entity}.dto.ts
entity + attribute metadata Response DTO / API shape

API paths are derived from entity name: PascalCase → kebab-case, pluralized (e.g. Equipment/equipment, RepairOrder/repair-orders).


DSL → React Admin

DSL Concept React Admin Result
entity Resource (name = kebab-case plural)
attribute Form field / column
type string TextInput, TextField
type integer/decimal NumberInput, NumberField
type date DateInput, DateField
enum SelectInput with choices
foreign key ReferenceInput, ReferenceField

Derived Layer Mapping

  • Create DTO — derived from domain attributes and must not include generated primary keys (for example no id for uuid PKs).
  • Update DTO — derived from the same domain attributes with all fields optional for partial updates.
  • API response shape — derived from domain attributes and must expose React Admin-compatible identifiers when needed.
  • UI field mapping — derived from attribute types, descriptions, enums, and foreign keys without a separate UI DSL.