BIG FIX: profile save + sport classification + KUD separation

1) auth/auth_v2.py — update_me bug fix:
   PUT /auth/me return value was 'return me(user)' but me() is a
   FastAPI route handler, not callable directly. Replaced with explicit
   re-fetch returning correct JSON shape. Profile changes now persist
   in UI after save.

2) DB: HNK Goranin Delnice (id 782) sport='skijanje' → 'nogomet'
   + napomena cross-contamination cleaned (id 782, 192, 347, 2280)
   + general rule: NK/HNK/Nogometni klub → nogomet
   + RK/Rukometni klub → rukomet
   + OK/Odbojkaški klub → odbojka

3) DB: KUD/folklorne/lovačke/vatrogasne udruge marked as
   sport='kulturno-umjetnicko' + razina='NE-sportsko' so frontend
   can filter them out of sportski savezi list

4) Backup: pgz_sport.klubovi_backup_20260505_0857

Verified: PUT /auth/me with damir@pgz.hr persists telefon change to DB
and returns fresh data
This commit is contained in:
2026-05-05 08:57:09 +02:00
parent 125ba6dbfb
commit b95b2e8423
12 changed files with 6640 additions and 1 deletions
@@ -0,0 +1,38 @@
# Subagent A — HNS Player ID Reconciliation
Timestamp: 2026-05-05
## Counters
```json
{
"dup_groups": 3,
"merged": 3,
"soft_deleted": 3,
"errors": 0,
"fk_rows_reparented_total": 0,
"before_clanovi": 3243,
"after_clanovi": 3240,
"clanovi_purged_total": 3
}
```
## Per-group resolutions
### hns_key=209352
- auth_id: **301**
- dup_ids: [2454]
- reason: auth=301 (igraci_url=yes, non_null=30, created=1777448115)
- fk_moves: `{"clan_nagrada": {"now_on_auth": 0, "skipped_conflicts": 0}, "clan_sezona": {"now_on_auth": 0, "skipped_conflicts": 0}, "clan_utakmica": {"now_on_auth": 0, "skipped_conflicts": 0}, "clanarine": {"now_on_auth": 0, "skipped_conflicts": 0}, "lijecnicki_pregledi": {"now_on_auth": 0, "skipped_conflicts": 0}, "sportas_specifika": {"now_on_auth": 0, "skipped_conflicts": 0}, "user_klub_links": {"now_on_auth": 0, "skipped_conflicts": 0}, "expense_reports": {"now_on_auth": 0, "skipped_conflicts": 0}, "form_submissions": {"now_on_auth": 0, "skipped_conflicts": 0}, "utakmice_log": {"now_on_auth": 18, "skipped_conflicts": 0}}`
### hns_key=395328
- auth_id: **233**
- dup_ids: [2596]
- reason: auth=233 (igraci_url=yes, non_null=30, created=1777448092)
- fk_moves: `{"clan_nagrada": {"now_on_auth": 0, "skipped_conflicts": 0}, "clan_sezona": {"now_on_auth": 0, "skipped_conflicts": 0}, "clan_utakmica": {"now_on_auth": 0, "skipped_conflicts": 0}, "clanarine": {"now_on_auth": 0, "skipped_conflicts": 0}, "lijecnicki_pregledi": {"now_on_auth": 0, "skipped_conflicts": 0}, "sportas_specifika": {"now_on_auth": 0, "skipped_conflicts": 0}, "user_klub_links": {"now_on_auth": 0, "skipped_conflicts": 0}, "expense_reports": {"now_on_auth": 0, "skipped_conflicts": 0}, "form_submissions": {"now_on_auth": 0, "skipped_conflicts": 0}, "utakmice_log": {"now_on_auth": 14, "skipped_conflicts": 0}}`
### hns_key=436387
- auth_id: **481**
- dup_ids: [2600]
- reason: auth=481 (igraci_url=yes, non_null=29, created=1777451018)
- fk_moves: `{"clan_nagrada": {"now_on_auth": 0, "skipped_conflicts": 0}, "clan_sezona": {"now_on_auth": 0, "skipped_conflicts": 0}, "clan_utakmica": {"now_on_auth": 0, "skipped_conflicts": 0}, "clanarine": {"now_on_auth": 0, "skipped_conflicts": 0}, "lijecnicki_pregledi": {"now_on_auth": 0, "skipped_conflicts": 0}, "sportas_specifika": {"now_on_auth": 0, "skipped_conflicts": 0}, "user_klub_links": {"now_on_auth": 0, "skipped_conflicts": 0}, "expense_reports": {"now_on_auth": 0, "skipped_conflicts": 0}, "form_submissions": {"now_on_auth": 0, "skipped_conflicts": 0}, "utakmice_log": {"now_on_auth": 1, "skipped_conflicts": 0}}`
@@ -0,0 +1,13 @@
{
"dup_groups": 3,
"merged": 3,
"soft_deleted": 3,
"errors": 0,
"fk_rows_reparented_total": 0,
"fk_rows_already_on_auth": 33,
"fk_conflicts_skipped": 0,
"before_clanovi": 3243,
"after_clanovi": 3240,
"clanovi_purged_total": 3,
"remaining_dup_groups": 0
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,33 @@
# B — Name Normalization Engine — REPORT
**Run at:** 2026-05-05T08:55:53
**Table:** `pgz_sport.clanovi` (3240 rows live, backup `clanovi_backup_20260505_0836` 3243 rows untouched)
## Detection candidates
- Total rows scanned: 3240
- Candidates flagged: 4
- Skipped (clean / abbreviation guard): 1
## Problem-class counts (per-field hits)
- camelcase: 0
- allcaps: 4
- lowercase: 0
- trim: 1
- multispace: 0
- mixedcase: 0
## Applied (confidence >= 0.9): **1**
## Review-only (0.5 <= confidence < 0.9): **4**
## Sample applied (up to 5)
- id=634 field=ime `Zoran ``Zoran` conf=1.0 class=trim src=https://hrvatski-bocarski-savez.hr/klubovi/bribir/
## Review-only entries
- id=4863 field=ime `PETAR``Petar` conf=0.5 class=allcaps evidence=None
- id=4863 field=prezime `MARŠIĆ``Maršić` conf=0.5 class=allcaps evidence=None
- id=4904 field=ime `ANDRIJA``Andrija` conf=0.5 class=allcaps evidence=None
- id=4904 field=prezime `ZRINSKI``Zrinski` conf=0.5 class=allcaps evidence=None
## Outputs
- Applied JSON: `/opt/pgz-sport/_audit/data_integrity_20260505_0836/B_NAME_FIXES_applied.json`
- Review JSON: `/opt/pgz-sport/_audit/data_integrity_20260505_0836/B_NAME_FIXES_review.json`
- SQL transcript: `/opt/pgz-sport/_audit/data_integrity_20260505_0836/B_sql_transcript.sql`
@@ -0,0 +1,13 @@
[
{
"id": 634,
"field": "ime",
"before": "Zoran ",
"after": "Zoran",
"confidence": 1.0,
"problem_class": "trim",
"source_url": "https://hrvatski-bocarski-savez.hr/klubovi/bribir/",
"hns_igrac_id": null,
"source": "hbs_savez"
}
]
@@ -0,0 +1,50 @@
[
{
"id": 4863,
"field": "ime",
"before": "PETAR",
"after": "Petar",
"confidence": 0.5,
"problem_class": "allcaps",
"source_url": null,
"hns_igrac_id": null,
"source": "manual",
"evidence_url": null
},
{
"id": 4863,
"field": "prezime",
"before": "MARŠIĆ",
"after": "Maršić",
"confidence": 0.5,
"problem_class": "allcaps",
"source_url": null,
"hns_igrac_id": null,
"source": "manual",
"evidence_url": null
},
{
"id": 4904,
"field": "ime",
"before": "ANDRIJA",
"after": "Andrija",
"confidence": 0.5,
"problem_class": "allcaps",
"source_url": null,
"hns_igrac_id": null,
"source": "manual",
"evidence_url": null
},
{
"id": 4904,
"field": "prezime",
"before": "ZRINSKI",
"after": "Zrinski",
"confidence": 0.5,
"problem_class": "allcaps",
"source_url": null,
"hns_igrac_id": null,
"source": "manual",
"evidence_url": null
}
]
@@ -0,0 +1,4 @@
BEGIN;
UPDATE pgz_sport.clanovi SET ime='Zoran', updated_at=now() WHERE id=634;
INSERT INTO pgz_sport.sys_audit (action, target_type, target_id, target_text, payload, user_email) VALUES ('CLANOVI_NAME_NORMALIZE', 'clanovi', 634, 'normalized name fields (ime)', '{"id": 634, "changes": {"ime": {"before": "Zoran ", "after": "Zoran", "confidence": 1.0, "problem_class": "trim"}}}'::jsonb, 'subagent-B@pgz-sport');
COMMIT;