feat(intent): multi-language data — Java Translator port, language/file seeds, Region & Language flag#6125
Merged
Merged
Conversation
…ation, language/file seeds, Harmonia Region & Language Ports the TS-era `multilingual` entity feature to the Java stack and exposes it through the intent DSL, with one per-user language flag driving frontend and backend. - SDK: new org.eclipse.dirigible.sdk.db.Translator (api-modules-java) — the db/translator.ts port with a name-based merge: reads <TABLE>_LANG (GUID, Id, <PascalCase property columns>, Language — the codbex-uoms-data convention), matches columns to entity fields case-insensitively (reads the whole table and filters in memory, so it is independent of identifier casing/quoting), normalizes locale tags to the primary subtag, tolerates a missing table and no-ops without a language. - DAO template: a multilingual="true" entity overrides ALL read paths — findById, findOne (the generated controller reads single records through findOne; findById alone missed GET-by-id, caught live), findAll x3, query — overlaying translations for the thread-bound Accept-Language (User.getLanguage(); listeners/jobs read base values). TS-parity caveat documented: editing under a non-base language saves displayed values. - Schema template: emits <TABLE>_LANG per multilingual model (string-typed non-PK/FK/calculated/audit properties, columns named after the PROPERTY, Language VARCHAR(2)); own loop before the base tables so the existing comma logic stays untouched. - Intent DSL: entity `multilingual: true` -> EDM attribute (same one the EDM editor writes); seeds gain `language: bg` (translation rows -> _LANG csvim with auto-numbered GUIDs) and `file: data/x.csv` (large data sets reference an authored CSV — only the .csvim is generated; the path must be in a subfolder since root-level .csv files are intent-owned and scrubbed); top-level `languages: [en, bg]` -> .model root -> Harmonia config.js. - Harmonia: shared locale Alpine store (localStorage codbex.harmonia.language) + Region & Language picker in the generated Settings page (mirrors the IDE settings-locale view); the shared fetch client sends the value as Accept-Language on every call; the document Print flow prefers the configured language. Harmonia itself has no i18n API (verified 1.24.2) — UI-label i18n stays a follow-up on top of the store. - Docs: intent-assistant-guide, engine-intent/root/engine-java CLAUDE.md (the aspirational "repository carries multi-language support" claim now describes the real mechanism), Harmonia README. Tests: Translator-stack IntentEngineIT (multilingual_entity_generates_the_ translation_stack) + IntentParserTest/EdmIntentGeneratorTest/ CsvimIntentGeneratorTest additions. Verified live on the adapted sample-intent-multi-model uoms: list + by-id reads translate under Accept-Language: bg, base values without it, untranslated rows fall back; countries load from an authored data/countries.csv file seed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 2, 2026
…tions) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(reports): cross-model dimensions + typed per-column filters (server-side)
Two report-stack upgrades driven by the multi-model sample:
- ReportIntentGenerator joins a CROSS-MODEL relation dimension
(dimensions: [Customer] where Customer is model: customers) against the
owning model's real table / primary-key column / label field, resolved
via CrossModelSupport exactly like the EDM FK (leaf-first, loud failure).
Previously the join used this model's intent-prefixed naming and pointed
at a non-existent local table; relation.field and filter (buildWhere)
paths are covered too.
- The generated report stack gains typed per-column filters applied
SERVER-side, so pagination, count and CSV export all reflect them:
- dao template (reportFileEntity): accepts conditions
[{column, operator, value}] validated against the report's own column
aliases + types (FILTER_COLUMNS from $columns) and wraps the query -
SELECT * FROM (QUERY) AS "REPORT_DATA" WHERE "alias" <op> :reportFilter<i>
with typed named parameters; operators EQ/NE/GT/GTE/LT/LTE/LIKE;
exportCsv(filter) honors the same conditions; the count subquery gains
the PostgreSQL-required alias.
- rest template: /search, /count and /export map an unknown
column/operator (IllegalArgumentException) to 400; /export accepts the
conditions body.
- Harmonia report page: generation-time typed column metadata
(reportColumns [{key, kind: date|number|boolean|text}] from the report
columns) renders a filter panel - date ranges, number ranges, boolean
select, text contains - with Apply/Clear, an active-count badge on the
toolbar toggle, and a POST /search + /count switch when filters are on.
Tests: IntentEngineIT.report_file_stack_generates_typed_column_filters.
Verified live on the multi-model sample's four new invoice reports:
cross-model joins return customer/product NAMES ("Acme Ltd", not FK ids);
GTE/LTE ranges, LIKE contains, combined ranges, filtered count and export
all correct over HTTP; unknown column -> 400.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(test): report UI files live under the RAW genFolderName (case-sensitive FS)
The generation service derives genFolderName from the report file name in
its ORIGINAL case ("OrdersByCustomer"), while the Java files use the
sanitized javaGenFolderName ("ordersbycustomer") - two distinct folders on
a case-sensitive filesystem. The IT asserted both under the sanitized name,
which only passed on macOS where the two paths collapse into one folder.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(reports): month()/year() date-bucket dimensions
`dimensions: ["month(date)"]` groups a date for aggregation as a sortable
YYYYMM integer ((EXTRACT(YEAR) * 100 + EXTRACT(MONTH)) - e.g. 202607);
`year(field)` emits the plain year. Enables monthly income/VAT reports:
- name: MonthlyRevenue
source: SalesInvoice
dimensions: ["month(date)"]
measures: ["count(*)", "sum(net)", "sum(vat)", "sum(total)"]
The YYYYMM integer pairs naturally with the number-range column filters.
Standard-SQL EXTRACT (H2/PostgreSQL; SQL Server lacks EXTRACT - documented
limitation). Covered by the OrdersByMonth assertions in IntentEngineIT;
verified live on the multi-model sample (June/July buckets with correct
net/VAT/total sums, month >= 202607 range filter).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(reports): right-align numeric columns and format by pattern, from the .report model
The .report model now carries per-column rendering metadata (single source
for every report UI): numeric columns (INTEGER/BIGINT/DECIMAL) get
`align: "right"`, decimals additionally the platform money pattern
(`### ### ### ##0.00`). ReportIntentGenerator emits them; the Harmonia
report-file template derives the same defaults from the column types for
.report files that predate the metadata.
Consumers:
- report-file page: headers + cells right-align via the metadata; decimal
cells format by the DecimalFormat-style pattern (grouped thousands, fixed
decimals - the document totals formatter); pattern-less numeric columns
(counts, year/month buckets) render as clean integers instead of the
DB's 1.0 / 202607.0.
- in-SPA EDM report table: same alignment + formatter, resolved at
generation time from the property types / formatPattern.
Covered by the align/pattern assertions in IntentEngineIT; verified live on
MonthlyRevenue (five right-aligned columns, patterned sums, clean buckets).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 3, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Ports the TS templates' multilingual entity feature (
multilingual="true"+<TABLE>_LANGoverlay, cf.db/translator.tsand codbex-uoms-data) to the Java stack, exposes it through the intent DSL, and adds a single per-user language flag — a Region & Language entry in the generated Settings page — driving both frontend and backend.How
org.eclipse.dirigible.sdk.db.Translator— name-based<TABLE>_LANGmerge (GUID, Id, <PascalCase property columns>, Language), case-insensitive column↔field matching (in-memory filter, independent of identifier casing/quoting), locale-tag normalization, missing-table tolerance.findById,findOne(the generated controller reads single records through it),findAll×3,query— overlaying for the thread-boundAccept-Language(User.getLanguage()); non-request callers (listeners, jobs) read base values.<TABLE>_LANGper multilingual model.multilingual: true, seedlanguage:(translation rows, auto-numbered GUIDs), seedfile:(authored CSV in a subfolder — root.csvis scrub-owned; keeps countries/currencies-sized data OUT of the intent), top-levellanguages:; parser validation for all of it.localeAlpine store (localStorage) + Region & Language picker in the generated Settings page (mirroring the IDE'ssettings-localeview); the shared fetch client sends the value asAccept-Languageon every call; Print prefers the configured language. Harmonia itself has no i18n API (verified against 1.24.2) — UI-label i18n remains a follow-up on top of the store; data translation is complete.Tests / verification
IntentEngineIT#multilingual_entity_generates_the_translation_stack(schema_LANG, repository overlays incl.findOne,_LANGcsvim, config languages) + parser/EDM/csvim unit-test additions — green.sample-intent-multi-model:GET UoMControllerwithAccept-Language: bgreturns Килограм/Литър (list AND by-id), base English without the header, untranslated rows fall back; 249 countries load from the authoreddata/countries.csvfile seed; served shell assets carry the picker/store/header wiring.Sample-repo update (multilingual uoms + CSV-file countries) follows after this merges — its
file:/language:seeds fail validation on a pre-feature platform.🤖 Generated with Claude Code