☰ Contents

Schema Quirks

F verified factP decided planC open challenge

The names, keys and errors of the Serdica configuration schema that are not what a reader would guess. Every entry was true when someone hit it.

Observations, not truth. The schema moves. When one of these contradicts what an agent has just introspected, the introspection is right and this page is wrong — the belief order of Agents Memory: running system over consuming code over knowledge base.

Why prose and not a correction map. The predecessor carried these as hardcoded correction maps in the tooling. They are recorded as knowledge instead, because a map that silently patches a name hides the day the name changes — the agent keeps working, the estate has moved, and nothing reports it. That argument generalises: a compensation belongs in a document a person can read, not in a code path that suppresses its own evidence.

Provenance. From the PC 9951 run on the Ablera dev database, 31.08.2026, found by exporting a real product (Product Configurator § SRC, full text in the extract). Not re-measured on the customer estate.

1. The keying pattern

F Two families key differently, and the pattern is worth more than the list: product-level entities key on the basic-product id; pricing-factor entities key on the product code. The endpoint field names follow the family, not the table — so the product-level entities expose basicProductId where a reader expects productCode, the pricing-factor entities the reverse, and the basic-product entity itself exposes basicProductCode rather than productCode. Likewise the generic name field is the entity's own …Name, not a shared genericName.

F PR_ANNEX_TYPES extends the split beyond the pricing-factor family: it keys on PRODUCT_CODE, not the basic-product id, and its code column is ANNEX_TYPE — there is no SOURCE_TRANSACTION_CODE column and no lookup step for one.

2. Natural keys

F Surrogate ids are sequence-defaulted and are never supplied. The identity that matters for an existence check (Write Envelopes § 8) is the natural key:

Entity Natural identity
basic product the basic product code
basic cover basic product id + cover code
pricing factor product code + factor code
pricing factor value the above + the value
pricing factor dependency product code + main code/value + dependent code/value
message the message id — a string, created through the message path, not as an ordinary record (Translations)

3. Table names the inherited documentation got wrong

F Prose sometimes singularises a table name, and the annex family is where it bites both ways. Found by export: the product-document table is PR_BASIC_PRODUCT_DOCUMENTS (plural) and the annex-type table is PR_ANNEX_TYPES (plural), where the inherited documentation had both singular. The counter-case is PR_PRICING_FACTOR_ANNEX — the per-product annex change-sensitivity list, measured 02.09.2026 at 501 rows / 42 products on STAGING and PROD (Measurements § DB-2) — which is singular and must not be “corrected” to a plural. Plurality is not a rule; the catalogue is.

P The rule that survives the specific cases: confirm a table exists by introspection before building a query on a name read in a document — including this one.

4. Backend spellings to match, not correct

F Typos that are part of the contract. Matching them is required; "correcting" them fails:

5. Read-only computed fields

F Anything ending in TextcoverCodeText, objectCodeText, ldCodeText, eventCodeText, riskCodeText — is generated from lookup translations for display and is rejected on a create, update or copy. This bites hardest when a queried record is sent straight back as a mutation input: strip the *Text fields first.

6. Oracle errors, and what they usually mean here

F In this schema the common codes are near-diagnostic:

Error Usually
ORA-02291 foreign key — a lookup code does not exist yet. Find the right one, or create it (Shared Vocabulary § 3). On a route id it is a byte-order problem instead (Write Envelopes § 6)
ORA-00001 duplicate key — the row already exists; read it before deciding to update
ORA-02292 children exist — delete in reverse dependency order: events/risks/definitions → covers → names → product
ORA-12899 value too large — check the column width; the loading-type column is three characters
ORA-02290 check constraint, i.e. an invalid enum — loading type admits no DIS, a discount is a loading with a negative sign
ORA-00904 invalid identifier — the column is spelled differently than assumed. The factor range columns are PRICING_FACTOR_RANGE_FROM/_TO, not RANGE_FROM/_TO

PDiagnose, correct, retry once or twice — then stop and report. A third identical attempt is a loop. This is the same bound as the peer-consult rule of pattern P-15 in Product Configurator § P (a configurator pattern id, not the platform requirement P-15 of the Requirements Register), applied to an error rather than to an unknown contract, and it is a runtime limit rather than an instruction (Agent Runtime).

7. Reading a CLOB through the Oracle connector

F Selecting a CLOB column directly — the rating-file content, for instance — fails with a serialisation error reporting not connected to database, because the LOB is read lazily after the transport has moved on. It reads like an outage and is not one: the connection is fine, and a non-LOB query against the same schema answers immediately.

P Wrap it — select a TO_CHAR of a bounded substring, and search inside a CLOB with an instring predicate rather than by fetching it. P More generally: an error that names the transport is not evidence about the target, and the estate prober's availability report distinguishes the two before anything is called unreachable.

8. The premium specification is a design intent, not a description

F The document the premium vocabulary of the Glossary is drawn from is a specification of how premium should work, and it carries recorded defects — two of which contradict the live database outright (Requirements § GV):

P So the rule for that document, and for any inherited specification used as a vocabulary source: take the words from it and check every column against the database. A term is safe to adopt; a column, a flag value or a default from the same page is a claim to verify with one probe before anything is written against it. The code branches on those columns, so the code settles them, not the document.

Related: Write Envelopes · Stage IPAL · Shared Vocabulary · Product Configurator § SRC