# Compilation Structure Cards Reference

Exact JSON format templates for specification compilation (step-03). All data MUST fit these schemas exactly.

## STRUCTURE CARD: analysis.entities[].attributes[]

**CRITICAL:** Entity attributes MUST use STRUCTURED properties, not free-text validation strings.

```json
{
  "name": "occupancyRate",
  "description": "Employee occupancy percentage",
  "type": "decimal",
  "maxLength": null,
  "nullable": true,
  "required": false,
  "unique": false,
  "indexed": false,
  "defaultValue": "100",
  "validation": "min:0, max:100, step:0.01",
  "foreignKey": null
}
```

**MANDATORY fields:** `name`, `type`
**type values:** `string`, `int`, `long`, `decimal`, `double`, `bool`, `DateTime`, `DateOnly`, `TimeOnly`, `Guid`, `enum:{EnumName}`, `byte[]`

### For FK attributes:

```json
{
  "name": "departmentId",
  "description": "FK to Department",
  "type": "Guid",
  "required": true,
  "foreignKey": { "targetEntity": "Department", "targetField": "Id", "onDelete": "restrict" }
}
```

### Type Inference Priority Table

| Attribute name pattern | Inferred type | Example |
|----------------------|---------------|---------|
| `name\|title\|code\|description\|label\|email\|phone\|address` | `string` | `positionTitle` → `string` |
| `*Id` (ends with Id) | `Guid` | `departmentId` → `Guid` |
| `*date\|*At` (ends with date/At) | `DateTime` | `hireDate` → `DateTime` |
| `is*\|has*\|active\|enabled` | `bool` | `isActive` → `bool` |
| `amount\|salary\|rate\|price\|total` | `decimal` | `hourlyRate` → `decimal` |
| `count\|number\|order\|sort\|index` | `int` | `displayOrder` → `int` |
| `validation` contains `max NNN` | `string` + `maxLength: NNN` | `"Max 200"` → `string`, `200` |
| No match | `string` (safe default) | — |

## STRUCTURE CARD: specification.actors[]

```json
{
  "role": "Sales Manager",
  "description": "Creates and approves orders",
  "permissions": [
    "{app}.{module}.read",
    "{app}.{module}.create",
    "{app}.{module}.update"
  ]
}
```

**MANDATORY fields:** `role`, `permissions` (array of permission paths)
**FORBIDDEN fields:** Do NOT use `systemRole`. Use `permissions` array.

## STRUCTURE CARD: specification.useCases[]

```json
{
  "id": "UC-{PREFIX}-001",
  "name": "Create Order",
  "primaryActor": "Sales Representative",
  "permission": "{app}.{module}.create",
  "preconditions": ["Customer exists", "Products in stock"],
  "postconditions": ["Order created with Draft status"],
  "mainScenario": [
    "1. User navigates to creation form",
    "2. User fills in required fields",
    "3. System validates data (BR-VAL-{PREFIX}-001)",
    "4. System creates the record",
    "5. System displays confirmation"
  ],
  "alternativeScenarios": [
    { "name": "Validation failure", "steps": ["1. System detects invalid data", "2. System highlights errors"] }
  ],
  "errorScenarios": [
    { "name": "Server error", "steps": ["1. System shows error message", "2. Data preserved for retry"] }
  ],
  "linkedRules": ["BR-VAL-{PREFIX}-001", "BR-WF-{PREFIX}-002"]
}
```

**MANDATORY fields:** `id`, `name`, `primaryActor`, `permission`, `mainScenario`, `linkedRules`
**FORBIDDEN fields:** Do NOT use `actor`, `linkedBRs`, `linkedFRs`

## STRUCTURE CARD: specification.functionalRequirements[]

```json
{
  "id": "FR-{PREFIX}-001",
  "statement": "System MUST validate customer budget before order creation",
  "priority": "must|should|could",
  "linkedRules": ["BR-VAL-{PREFIX}-001"],
  "linkedUseCases": ["UC-{PREFIX}-001"],
  "acceptanceCriteria": [
    "Order rejected if total > budget",
    "Error message displayed with remaining budget"
  ]
}
```

**MANDATORY fields:** `id`, `statement`, `priority`, `linkedUseCases`
**FORBIDDEN fields:** Do NOT use `name`/`description`, `linkedUCs`, `linkedBRs`

## STRUCTURE CARD: specification.permissionMatrix

```json
{
  "permissions": [
    { "path": "{app}.{module}.read", "action": "read", "description": "View records" },
    { "path": "{app}.{module}.create", "action": "create", "description": "Create new records" },
    { "path": "{app}.{module}.update", "action": "update", "description": "Update existing records" },
    { "path": "{app}.{module}.delete", "action": "delete", "description": "Delete records" },
    { "path": "{app}.{module}.export", "action": "export", "description": "Export data" },
    { "path": "{app}.{module}.dashboard.read", "action": "read", "description": "View dashboard (section-level)" }
  ],
  "roleAssignments": [
    { "role": "{App} Admin", "permissions": ["{app}.{module}.read", "{app}.{module}.create", "{app}.{module}.update", "{app}.{module}.delete", "{app}.{module}.export", "{app}.{module}.dashboard.read"] },
    { "role": "{App} Manager", "permissions": ["{app}.{module}.read", "{app}.{module}.create", "{app}.{module}.update", "{app}.{module}.dashboard.read"] },
    { "role": "{App} Viewer", "permissions": ["{app}.{module}.read"] }
  ]
}
```

**STRUCTURE:** Object with 2 arrays: `permissions[]` and `roleAssignments[]`
**Permission levels:** Module-level = `{app}.{module}.{action}` (3 segments). Section-level = `{app}.{module}.{section}.{action}` (4 segments).

## STRUCTURE CARD: specification.navigation

```json
{
  "entries": [
    { "level": "module", "code": "{module}", "labels": {"fr": "...", "en": "...", "it": "...", "de": "..."}, "route": "/{app}/{module}", "icon": "list" },
    { "level": "section", "code": "list", "labels": {"fr": "Liste", "en": "List", "it": "Elenco", "de": "Liste"}, "route": "/{app}/{module}", "icon": "list" },
    { "level": "section", "code": "dashboard", "labels": {"fr": "Tableau de bord", "en": "Dashboard", "it": "Cruscotto", "de": "Dashboard"}, "route": "/{app}/{module}/dashboard", "icon": "chart-bar", "isNew": true }
  ]
}
```

## STRUCTURE CARD: specification.seedDataCore

```json
{
  "navigationApplications": [
    { "code": "{app}", "label": "{Application Name}", "icon": "{icon}", "route": "/{app-kebab}", "sort": 1 }
  ],
  "applicationRoles": [
    { "code": "admin", "name": "{App} Admin", "permissions": "*" },
    { "code": "manager", "name": "{App} Manager", "permissions": "CRU" },
    { "code": "contributor", "name": "{App} Contributor", "permissions": "CR" },
    { "code": "viewer", "name": "{App} Viewer", "permissions": "R" }
  ],
  "navigationModules": [
    { "code": "{module}", "label": "{Module Name}", "icon": "list", "route": "/{app}/{module}", "parentCode": "{app}", "sort": 1 }
  ],
  "navigationSections": [
    { "code": "list", "label": "Liste", "icon": "List", "route": "/{app}/{module}", "parentCode": "{module}", "permission": "{app}.{module}.read", "sort": 1 },
    { "code": "detail", "label": "Détail", "icon": "FileText", "route": "/{app}/{module}/:id", "parentCode": "{module}", "permission": "{app}.{module}.read", "sort": 2, "navigation": "hidden" },
    { "code": "dashboard", "label": "Dashboard", "icon": "BarChart", "route": "/{app}/{module}/dashboard", "parentCode": "{module}", "permission": "{app}.{module}.dashboard.read", "sort": 3 }
  ],
  "navigationResources": [
    { "code": "{module}-grid", "type": "SmartTable", "entity": "{Entity}", "parentCode": "list", "permission": "{app}.{module}.read" },
    { "code": "{module}-detail-card", "type": "DetailCard", "entity": "{Entity}", "parentCode": "detail", "permission": "{app}.{module}.read" }
  ],
  "navigationTranslations": [
    { "moduleCode": "{module}", "language": "fr", "label": "..." },
    { "moduleCode": "{module}", "language": "en", "label": "..." },
    { "moduleCode": "{module}", "language": "it", "label": "..." },
    { "moduleCode": "{module}", "language": "de", "label": "..." }
  ],
  "permissions": [
    { "path": "{app}.{module}.read", "action": "read", "description": "View {module}" },
    { "path": "{app}.{module}.create", "action": "create", "description": "Create {module}" },
    { "path": "{app}.{module}.dashboard.read", "action": "read", "description": "View {module} dashboard (section-level)" }
  ],
  "rolePermissions": [
    { "role": "{App} Admin", "permissionPath": "{app}.{module}.*" },
    { "role": "{App} Manager", "permissionPath": "{app}.{module}.read" }
  ],
  "permissionConstants": [
    { "constantName": "{Module}Read", "path": "{app}.{module}.read" },
    { "constantName": "{Module}Create", "path": "{app}.{module}.create" }
  ]
}
```

**MANDATORY:** All 9 arrays must be present. Each element must be an object, NOT a string.

## STRUCTURE CARD: specification.validations[]

```json
{
  "entity": "Order",
  "field": "amount",
  "rules": ["required", "decimal", "min:0.01", "max:999999.99"],
  "errorMessageKey": "validation.{module}.amount.invalid"
}
```

**MANDATORY fields:** `entity`, `field`, `rules` (array), `errorMessageKey`

## STRUCTURE CARD: specification.messages[]

```json
{
  "code": "{MODULE}-SUCCESS-CREATE",
  "type": "success|error|warning|info",
  "title": "Record Created",
  "message": "The record {code} has been created successfully.",
  "i18nKey": "message.{module}.created"
}
```

**MANDATORY fields:** `code`, `type`, `message`, `i18nKey`

## STRUCTURE CARD: specification.lifeCycles[]

```json
{
  "entity": "Order",
  "field": "status",
  "initialState": "draft",
  "states": [
    { "id": "draft", "displayName": "Brouillon", "color": "gray", "allowedTransitions": ["submitted"], "isTerminal": false },
    { "id": "submitted", "displayName": "Soumis", "color": "blue", "allowedTransitions": ["approved", "rejected"], "isTerminal": false },
    { "id": "approved", "displayName": "Approuvé", "color": "green", "allowedTransitions": ["archived"], "isTerminal": false },
    { "id": "rejected", "displayName": "Rejeté", "color": "red", "allowedTransitions": [], "isTerminal": true }
  ],
  "transitions": [
    {
      "from": "draft", "to": "submitted", "action": "submit",
      "label": { "fr": "Soumettre", "en": "Submit" },
      "permission": "{app}.{module}.update",
      "guards": ["BR-VAL-{PREFIX}-001"],
      "effects": [{ "type": "notification", "target": "role:manager", "template": "{module}-submitted" }],
      "confirm": true
    }
  ]
}
```

**Colors:** gray (draft/new), blue (in-progress), green (active/approved), yellow (warning/pending), orange (review), red (error/rejected), purple (archived/terminal)

## STRUCTURE CARD: specification.apiEndpoints[]

```json
{
  "method": "GET|POST|PUT|PATCH|DELETE",
  "path": "/api/{app}/{module}",
  "permission": "{app}.{module}.read",
  "requestDto": "Get{Module}Query",
  "responseDto": "{Module}Dto[]",
  "description": "List all records with pagination and filters"
}
```

**MANDATORY fields:** `method`, `path`, `permission`, `description`

## STRUCTURE CARD: specification.i18nKeys

**CRITICAL:** ALL leaf translation keys MUST have 4 languages (fr, en, it, de).

```json
{
  "title": { "fr": "{Module}", "en": "{Module}", "it": "{Module}", "de": "{Module}" },
  "list": {
    "title": { "fr": "Liste", "en": "List", "it": "Elenco", "de": "Liste" },
    "empty": { "fr": "Aucun enregistrement", "en": "No records", "it": "Nessun record", "de": "Keine Einträge" }
  },
  "create": { "title": { "fr": "Nouveau", "en": "New", "it": "Nuovo", "de": "Neu" } },
  "detail": { "title": { "fr": "Détail", "en": "Detail", "it": "Dettaglio", "de": "Detail" } },
  "buttons": {
    "create": { "fr": "Créer", "en": "Create", "it": "Crea", "de": "Erstellen" },
    "edit": { "fr": "Modifier", "en": "Edit", "it": "Modifica", "de": "Bearbeiten" },
    "delete": { "fr": "Supprimer", "en": "Delete", "it": "Elimina", "de": "Löschen" },
    "save": { "fr": "Enregistrer", "en": "Save", "it": "Salva", "de": "Speichern" },
    "cancel": { "fr": "Annuler", "en": "Cancel", "it": "Annulla", "de": "Abbrechen" }
  },
  "validation": {
    "required": { "fr": "Ce champ est requis", "en": "This field is required", "it": "Campo obbligatorio", "de": "Pflichtfeld" }
  }
}
```
