Badge system wiring

Table of Contents

1. Summary

ORE Studio resolves pill badges from the database through a three- layer system: ores.dq owns the four domain entities (badge_severity, code_domain, badge_definition, badge_mapping); ores.sql seeds them at install time; and the UI resolves a (domain, entity_code) pair to a colour. An entity's presentation drawer carries the badge in two table columns (is_badge=/=badge_key). Only the SQL population entry is manual. Because a missing SQL entry fails silently (the resolver falls back to the shared fallback colour, not an error), it is the step most often forgotten. The UI-side resolver went with the Qt client and is not rebuilt yet — see §UI resolution below. Return to Knowledge.

2. Detail

2.1. The four domain entities

All four live in the dq schema and are managed by ores.dq.

Entity Table Purpose
badge_severity ores_dq_badge_severities_tbl Named severity levels (secondary, info, success, warning, danger, primary). Codes align with Bootstrap 5 classes.
code_domain ores_dq_code_domains_tbl Named namespace that disambiguates codes across entity types (e.g. account_type, login_status).
badge_definition ores_dq_badge_definitions_tbl One row per visual variant: label, background colour, text colour, severity, CSS class hint.
badge_mapping ores_dq_badge_mappings_tbl Junction: maps (code_domain, entity_code) → badge_definition.

2.2. SQL population

All badge metadata lives in one idempotent script:

projects/ores.sql/populate/dq/dq_badge_system_populate.sql

The script uses upsert functions so it is safe to re-run. The structure per new badge domain is always three blocks:

  1. Code domain — one ores_dq_code_domains_upsert_fn call naming the domain and its display_order.
  2. Badge definitions — one ores_dq_badge_definitions_upsert_fn call per distinct visual variant (label, hex colours, severity code, CSS class, display_order).
  3. Badge mappings — one ores_dq_badge_mappings_upsert_fn call per value, mapping (domain, entity_code) → badge_definition_code.

2.3. UI resolution — not built yet

The Qt client held the badge resolver: ores.qt.api's BadgeCache, filled at login and injected into an EntityItemDelegate that painted the badge columns and resolved the combo entries. That client is removed. The TypeScript web client in ores.web carries no badge resolver yet, so nothing resolves or paints a badge today. Do not look for a live resolver; there is none.

What survives is the contract on the model side. A column or detail field carries is_badge and badge_key in the entity's presentation drawer. A screen that reads those keys resolves them against the code domains below and paints the badge definition's colours. Two rules from the old resolver are kept here, because they are the part most easily got wrong:

  • The entity code passed to the resolver must exactly match the string the screen shows for that value. If it shows a translated label, the mapping key must use that label's value. If it shows the raw DB code ("user"), the mapping key must use the raw code.
  • A cache miss or an unresolved value falls back to the shared fallback colour (orange), never an error.

2.4. Available badge collections (code domains)

Every code_domain currently seeded by dq_badge_system_populate.sql, in display_order. Check here before adding a new domain — an existing one (or its badge_definition colours) may already fit.

Domain Order Purpose
party_status 1 Lifecycle status codes for party and counterparty records.
book_status 2 Lifecycle status codes for book records.
portfolio_status 3 Lifecycle status codes for portfolio records.
portfolio_type 4 Type codes for portfolio records (Virtual, Physical).
book_type 5 Type codes for book records (Trading, Banking).
login_status 6 Login activity status for user accounts (Never, Old, Recent, Online).
account_locked 7 Account lock status (Locked, Unlocked).
compute_task_state 8 State codes for compute task records.
compute_task_outcome 9 Outcome codes for completed compute tasks.
report_concurrency_policy 10 Concurrency policy codes for report definitions (Skip, Queue, Fail).
report_fsm_state 11 FSM lifecycle state codes for report definitions.
dq_origin 12 Data quality origin dimension codes.
dq_nature 13 Data quality nature dimension codes.
dq_treatment 14 Data quality treatment dimension codes.
tenant_status 15 Lifecycle status codes for tenant records.
workspace_status 16 Lifecycle status codes for workspace records.
account_type 17 Classification of account types (user, service, algorithm, llm).
account_online 18 Boolean online indicator for accounts (Yes, No).
regulatory_book_type 19 Basel III/IV FRTB trading book / banking book classification a book carries.
currency_pair_classification 21 Liquidity classification codes for currency pairs (major, minor, exotic, commodity).
monetary_nature 25 Nature classification codes for currencies (fiat, commodity, synthetic, supranational).
currency_market_tier 26 Liquidity tier classification codes for currencies (G10, emerging, exotic, frontier, historical).

badge_definition.name (the human-readable label, 2nd argument to ores_dq_badge_definitions_upsert_fn) has a database-wide unique index — not scoped per domain. Two domains both wanting a "Commodity" or "Exotic" badge must pick distinct labels (Commodity Currency vs Commodity, Exotic Tier vs Exotic); grep the population script for your label before adding it. Violating this fails the population script partway through and leaves the DB half-populated — re-run db recreate after fixing.

2.5. Worked example — account_type

account_type badge (added in sprint 19):

  • Code domain: account_type, display_order 17.
  • Four badge definitions: account_type_user (info/#3b82f6), account_type_service (secondary/#6b7280), account_type_algorithm (warning/#eab308), account_type_llm (primary/#7c3aed).
  • Four mappings keyed on the raw DB codes: 'user', 'service', 'algorithm', 'llm' (because ClientAccountModel returns account.account_type verbatim).
  • UI wiring: the account_type column carries is_badge and badge_key: account_type in the presentation drawer. The delegate and the combo painting went with the Qt client (§UI resolution above).

Emacs 29.3 (Org mode 9.6.15)