Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ A single `app.intent` YAML file at a project root is the source of truth one alt

**Multi-model + layout additions (PRs [#6089](https://github.com/eclipse-dirigible/dirigible/pull/6089)-[#6092](https://github.com/eclipse-dirigible/dirigible/pull/6092)):** the DSL now supports building an app from **several intent models that reference each other cross-model** - a top-level `uses:` block names other models, and a relation gains an optional `model:` alias; a cross-model `manyToOne`/`oneToOne` is emitted as a read-only **PROJECTION** entity + integer FK + dropdown (the codbex cross-project pattern - no local table/DAO/controller for the target), resolved against the owner's already-generated `.model` (leaf-first generation; convention fallback otherwise). **n:m** is an explicit **intermediate entity** (composition to one side + `manyToOne` to the other, which may be cross-model, plus bridge fields like `amount`) - `manyToMany` is parsed but never materialized. New field attributes: `unique`, `precision`/`scale`, `calculatedOnCreate`/`calculatedOnUpdate` (a neutral arithmetic expression for numeric totals, else emitted verbatim into the runtime), `calculatedActionOnCreate`/`calculatedActionOnUpdate` (server-side call-out to a hand-written `@Component implements org.eclipse.dirigible.sdk.db.CalculatedField<E,T>`, invoked as `Beans.get(<class>.class).calculate(entity)`, taking precedence over the expression — for logic too custom to model, e.g. number generation); field `readOnly: true` (not editable; rendered in the Harmonia form's read-only details block — Label:Value above the buttons — via `isReadOnlyProperty`; `ProcessId`/audit columns/`uuid` are auto-flagged read-only, `status`-style fields opt in); field `major: false` (kept off the entity **list** table — the model's `widgetIsMajor="false"` — still shown in forms + the record details pane; defaults true); entity `imports:` (Java `import` lines injected into the generated repository so a calculated action can be referenced by simple name — Base64-encoded into the `.model`'s `importsCode`, which the Java DAO template emits; the editor's entity-level Imports tab is the model-editor equivalent); entity `audit: true` (the four standard audit columns); entity `group:` (the perspective's nav-group id in the shared application shell). **Depends-On** is exposed as `dependsOn: { relation, valueFrom?, filterBy? }` on a to-one relation (cascading/narrowed dropdown) or a field (auto-populated value) — emitted as the EDM `widgetDependsOn*` attributes (the AngularJS stacks consume them as-is; the Harmonia runtime — form/document watchers + the metadata-driven item-dialog cascade — was added alongside); defaults are the respective primary keys, names are the target's authored property names, cross-model triggers/targets supported. **Multi-language data** (the TS-era `multilingual` port): entity `multilingual: true` → the schema layer generates a sibling `<TABLE>_LANG` table (`GUID, Id, <PascalCase translatable columns>, Language` — the codbex-uoms-data convention) and the generated Java repository overlays translated values on every read for the request's `Accept-Language` (SDK `Translator`, name-based merge); the supported language set is a PLATFORM concern (`DIRIGIBLE_APPLICATION_LANGUAGES`, default `en`, tenant-overridable via the tenant configuration) — the Harmonia **Region & Language** Settings entry always offers that set (an Alpine `locale` store, localStorage `codbex.harmonia.language`, sent as `Accept-Language` by the shared fetch client — one flag drives UI, data, and the Print default), while the top-level `languages: [en, bg]` only declares which languages the module PROVIDES translations for; the application shell warns about modules missing a platform language, and untranslated content falls back to the default; translations are authored as seeds with `language: bg`, and large data sets reference an authored CSV via seed `file: data/x.csv` (subfolder mandatory — root `.csv` is scrub-owned) instead of inline rows. A master owning an `*Item` composition child renders as the **document (header-items) layout** (`MANAGE_DOCUMENT` + `documentItemsEntity`, `uiDocumentModels`), with `aggregate: true` fields shown in the totals footer. `IntentNaming.upperSnake` collapses kebab/space/`.`/`/` separators so a hyphenated model name yields a valid SQL identifier (`sales-invoices` -> `SALES_INVOICES`). Worked example: `dirigiblelabs/sample-intent-multi-model` (six interdependent projects + a navigation-groups project).

**First-class document numbering (`number:` + the `.numbers` artefact, `engine-numbering`):** a string field may declare `number: { series: Sales Invoice, per: Company, stampOn: create|issue }` — the intent references a **series by name only**; the number's shape (literal prefix + sequence zero-padded to a total width, no token grammar) lives OUTSIDE the model: declared per module in an authored **`.numbers`** artefact (`{"series": [{"name": "Sales Invoice", "prefix": "SI", "size": 10}]}`, a requirement declaration like `.roles`) and configured per tenant in the application shell's Document Numbering settings (`/services/core/numbering`). One per-tenant table `DIRIGIBLE_DOCUMENT_NUMBERS` holds shape AND counter, one row per (series, partition); the synchronizer only INSERTs missing rows, Settings writes prefix/size/next, the allocator (`sdk.numbering.DocumentNumbers.next`) increments the counter — sequences are continuous, never auto-reset, and allocating an undeclared series fails loudly. `per:` partitions a series by a to-one relation's value (per company — two legal entities never share a counter). A differing cross-module re-declaration fails that artefact naming both modules; the removed `format`/`scope`/`resetOn` keys are rejected at parse. Details in the engine-intent guide's numbering bullet.
**First-class document numbering (`number:` + the `.numbers` artefact, `engine-numbering`):** a string field may declare `number: { series: Sales Invoice, per: Company, stampOn: create|issue }` — the intent references a **series by name only**; the number's shape (literal prefix + sequence zero-padded to a total width, no token grammar) lives OUTSIDE the model: declared per module in an authored **`.numbers`** artefact (`{"series": [{"name": "Sales Invoice", "prefix": "SI", "size": 10}]}`, a requirement declaration like `.roles`) and configured per tenant in the application shell's Document Numbering settings (`/services/core/numbering`). One per-tenant table `DIRIGIBLE_DOCUMENT_NUMBERS` holds shape AND counter, one row per (series, partition); the synchronizer only INSERTs missing rows, Settings writes prefix/size/next, the allocator (`sdk.numbering.DocumentNumbers.next`) increments the counter — sequences are continuous, never auto-reset, and allocating an undeclared series fails loudly. `per:` partitions a series by a to-one relation's value (per company — two legal entities never share a counter); the declaration may name the **partition source** (`"partitions": {"table", "key", "label"}` — authored physical coordinates) so Settings labels partition rows by the entity's display name and lists a VIRTUAL row per value before its first allocation (saving provisions it — seed a company's starting number before its first document). A differing cross-module re-declaration fails that artefact naming both modules; the removed `format`/`scope`/`resetOn` keys are rejected at parse. Details in the engine-intent guide's numbering bullet.

**The general platform line this enshrines:** authoring artifacts (`.edm`, `.model`, `.form`, `.report`, `.intent`) get **workspace editors + an explicit Generate**; only runtime artifacts (`.roles`, `.bpmn`, `.csvim`, `.table`, jobs, listeners, …) get **synchronizers**. Applying the synchronizer hammer to an authoring artifact generates into the registry where no modeler, Projects view, or template can use it — that mistake was made once and reverted; the inventory of synchronizers (grep `extends BaseSynchronizer`) deliberately contains no authoring formats.

Expand Down
Loading
Loading