02 — PREFIX-NNN / meta_catalog Code Assignment Plan (B-3 CLOSED)
02 — Branch B: PREFIX-NNN / meta_catalog Code Assignment Plan (B-3 CLOSED)
Where the code rule actually lives
There is no central prefix-registry table. The PREFIX-NNN rule is enforced in exactly one place:
fn_pre_birth_checkCheck 3:IF p_code ~ '^[A-Z]+-[0-9]+$'→ pass. (Verified live, full body captured.)fn_birth_gateruns the 5 checks; default mode iswarning(app.birth_gate_modeis unset indot_config), so a bad code warns but does not block — which is why "đẻ rơi" raw inserts are technically possible and forbidden by law, not by trigger.
The family prefix is documented (not enforced) via entity_species.prefix (FIELD/FORM/TIER). So "registering the prefix" = setting entity_species.prefix + using a conforming collection_registry.code.
meta_catalog code path
gen_code_meta_catalog(BEFORE INSERT) auto-assignsCAT-<lpad(nextval('seq_meta_catalog_code'),3)>only whencodeis empty. If you supply an explicit code it is kept (proven: prior rehearsals' explicitCAT-1011was not overridden).meta_catalog.codehas no UNIQUE constraint (0 unique constraints live). A collision will not raise but will breakfn_pre_birth_checkCheck 5 logic downstream — so codes must be chosen collision-free.- Live
max(CAT-NNN number)= 1010. →CAT-1011,CAT-1012,CAT-1013are free.
Exact code assignment (activation-ready)
| Registry | collection_registry.code | meta_catalog.code | entity_species.code | entity_species.species_code | entity_species.prefix |
|---|---|---|---|---|---|
| field_registry | FIELD-001 |
CAT-1011 |
SPC-FIELD-001 |
field_registry_species |
FIELD |
| input_form_registry | FORM-001 |
CAT-1012 |
SPC-FORM-001 |
input_form_registry_species |
FORM |
| tier_registry | TIER-001 |
CAT-1013 |
SPC-TIER-001 |
tier_registry_species |
TIER |
All three FIELD-001/FORM-001/TIER-001 match ^[A-Z]+-[0-9]+$ → Check 3 PASS (proven live, doc 05). Decision: supply explicit CAT codes (not empty) for determinism and to avoid sequence drift, matching the proven rehearsal.
Pre-commit collision-avoidance / validation query
Run as workflow_admin immediately before commit; every row must return 0 / free:
SELECT
(SELECT count(*) FROM meta_catalog WHERE code IN ('CAT-1011','CAT-1012','CAT-1013')) AS meta_code_taken, -- expect 0
(SELECT count(*) FROM collection_registry WHERE code IN ('FIELD-001','FORM-001','TIER-001')) AS coll_code_taken, -- expect 0
(SELECT count(*) FROM entity_species WHERE code IN ('SPC-FIELD-001','SPC-FORM-001','SPC-TIER-001')) AS species_code_taken, -- expect 0
(SELECT count(*) FROM entity_species WHERE species_code IN ('field_registry_species','input_form_registry_species','tier_registry_species')) AS species_key_taken, -- expect 0
(SELECT max((regexp_replace(code,'\D','','g'))::int) FROM meta_catalog WHERE code ~ '^CAT-[0-9]+$') AS max_cat_num, -- expect 1010
bool_and('FIELD-001' ~ '^[A-Z]+-[0-9]+$' AND 'FORM-001' ~ '^[A-Z]+-[0-9]+$' AND 'TIER-001' ~ '^[A-Z]+-[0-9]+$') AS codes_format_ok; -- expect t
If max_cat_num has advanced past 1010 at commit time, bump the three CAT codes to CAT-<max+1..+3> accordingly (the activation pack, doc 06, computes them dynamically as a safety net).
Rollback impact
Codes are plain column values; rollback is trivial (rows removed in-tx or via retire/delete). No sequence is consumed when codes are supplied explicitly (gen_code skips nextval), so there is no sequence-drift side effect from a rolled-back or retired birth — a deliberate advantage of the explicit-code path.