DI exec: applied CC-DI Subagent A+B SQL — 3245 clanovi, Manuel Boras merged
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# Subagent D — Schema Quality Constraints (pgz_sport.clanovi)
|
||||
|
||||
Date: 2026-05-05
|
||||
Live row count: 3240 (backup retained at `pgz_sport.clanovi_backup_20260505_0836` = 3243)
|
||||
|
||||
## Summary table
|
||||
|
||||
| # | Candidate | Type | Pre-flight violators | Status | Object name |
|
||||
|---|-----------|------|----------------------|--------|-------------|
|
||||
| C1 | No internal CamelCase boundary | CHECK | 0 | APPLIED | `clanovi_no_camelcase_chk` |
|
||||
| C2 | ime/prezime trimmed | CHECK | 0 | APPLIED | `clanovi_trimmed_chk` |
|
||||
| C3 | length(ime) >= 2 AND length(prezime) >= 2 | CHECK | 22 | SKIPPED (see D_violations.md) | — |
|
||||
| C4 | spol IN ('M','Ž',NULL) | CHECK | 0 | ALREADY PRESENT | `clanovi_spol_check` (pre-existing) |
|
||||
| C5 | hns_igrac_id partial UNIQUE | UNIQUE INDEX | 0 dup-groups | APPLIED | `clanovi_hns_uniq` |
|
||||
| C6 | (klub_id, lower(ime), lower(prezime), datum_rodenja) UNIQUE | UNIQUE INDEX | 68 dup-groups | SKIPPED (see D_violations.md) | — |
|
||||
| C7 | BEFORE INSERT/UPDATE normalize trigger | TRIGGER | n/a | APPLIED | `clanovi_normalize_trigger` + `pgz_sport.clanovi_normalize_fn()` |
|
||||
|
||||
## Trigger semantics
|
||||
|
||||
`clanovi_normalize_fn`:
|
||||
1. Always `trim()` `NEW.ime` and `NEW.prezime`.
|
||||
2. On `INSERT`, or on `UPDATE` only when `ime` or `prezime` actually change:
|
||||
- reject CamelCase boundary (lenient: only ascii+Croatian-diacritic lower→upper pairs);
|
||||
- reject `length(ime) < 2` or `length(prezime) < 2`.
|
||||
3. The "only-when-name-changes" rule preserves the 22 legitimate historical short-name rows (e.g. `id=1852..2141`, mostly placeholder `'-'` ime + surname-only entries) so they can still receive `UPDATE`s on other fields.
|
||||
|
||||
## Smoke insert tests (all wrapped in BEGIN/ROLLBACK so live data unchanged)
|
||||
|
||||
| # | Scenario | Expected | Result |
|
||||
|---|----------|----------|--------|
|
||||
| 1 | INSERT `('IvoIvic','Test')` | reject (CamelCase) | REJECTED — `CamelCase rejected in ime: IvoIvic` |
|
||||
| 2 | INSERT `('PetarPan','Test')` | reject | REJECTED |
|
||||
| 3 | INSERT `(' Ivo ',' Ivić ')` | trim then succeed | INSERTED — stored as `('Ivo','Ivić')` |
|
||||
| 4 | INSERT `('A','Test')` | reject (length) | REJECTED — `ime too short (<2 chars): A` |
|
||||
| 5 | INSERT `('Ivan',' X ')` | trim → `'X'` len 1 → reject | REJECTED — `prezime too short (<2 chars): X` |
|
||||
| 6 | INSERT `('Marko ',' Marković')` | trim then succeed | INSERTED — stored as `('Marko','Marković')` |
|
||||
| 7 | INSERT duplicate `hns_igrac_id='209352'` | reject | REJECTED — `duplicate key value violates unique constraint "clanovi_hns_uniq"` |
|
||||
| 8 | 2× NULL + 2× `''` `hns_igrac_id` rows | all 4 succeed (partial uniqueness ignores NULL/empty) | 4 INSERTS OK |
|
||||
| 9 | UPDATE `id=1852` (`ime='-'`) `napomena=...` (no name change) | succeed | UPDATED — short-name row still mutable |
|
||||
| 10 | UPDATE `id=1852` `ime='?'` (single char) | reject | REJECTED — `ime too short (<2 chars): ?` |
|
||||
|
||||
All 10 behaviours match expectations. No live row was modified — every test ROLLBACKed.
|
||||
|
||||
## Final lockdown state on `pgz_sport.clanovi`
|
||||
|
||||
CHECK constraints in force:
|
||||
- `clanovi_no_camelcase_chk` (NEW)
|
||||
- `clanovi_trimmed_chk` (NEW)
|
||||
- `clanovi_spol_check` (pre-existing)
|
||||
|
||||
UNIQUE indexes in force:
|
||||
- `clanovi_pkey` (id)
|
||||
- `uq_clanovi_klub_profile` (klub_id, profile_url) — pre-existing
|
||||
- `clanovi_hns_uniq` (hns_igrac_id) WHERE not null/empty — NEW
|
||||
|
||||
User triggers in force (BEFORE INSERT OR UPDATE):
|
||||
- `clanovi_normalize_trigger` (NEW)
|
||||
- `clanovi_validate_source` (pre-existing)
|
||||
- `pgz_sport_clanovi_fts_trg` (pre-existing)
|
||||
|
||||
Row count unchanged at 3240.
|
||||
Reference in New Issue
Block a user