# P0 Architecture Audit: AddressManager Usage Verification **Date:** 2026-07-01 **Auditor:** Rendszer-Architect **Scope:** Backend models, services, endpoints **Goal:** Verify that no direct SQL/ORM inserts/updates are bypassing the AddressManager --- ## 1. Model Analysis ### ✅ Organization (`backend/app/models/marketplace/organization.py`) - **Status: CLEAN** — Zero denormalized address fields - Uses only FK columns: `address_id`, `billing_address_id`, `notification_address_id` → `system.addresses.id` - Has proper SQLAlchemy relationship definitions for all three address types ### ✅ Branch (`backend/app/models/marketplace/organization.py:324-366`) - **Status: CLEAN** — Zero denormalized address fields - Uses only `address_id` FK → `system.addresses.id` ### ✅ ServiceStaging (in `backend/app/models/marketplace/service.py:170-195`) - **Status: CLEAN** — Uses `address_id` FK → `system.addresses.id` ### ✅ Address (`backend/app/models/identity/address.py:39-74`) - **Status: CLEAN** — Uses proper FK-based architecture - `zip` and `city` are **properties** resolved via the `postal_code` relationship ### ⚠️ ServiceProvider (`backend/app/models/identity/social.py:23-71`) - **Status: INTENTIONAL DENORMALIZATION** — Contains flat address fields - Marked "P0 HYBRID VENDOR REFACTOR" design choice --- ## 2. Critical Bugs Found ### 🔴 P0 CRITICAL: `admin.py:943` — `Organization.address_city` REMOVED from ORM **File:** `backend/app/api/v1/endpoints/admin.py:943` The `search_organizations_by_name` endpoint selects `Organization.address_city` which is **not defined** in the `Organization` SQLAlchemy model. SQLAlchemy will raise an error at runtime. **Impact:** Admin organization search (`/admin/organizations/search?name=...`) is broken. ### 🟡 P1: `admin_persons.py:670-699` — Direct Address writes bypassing AddressManager Directly writes `address.street_name = ...` without calling `AddressManager.create_or_update()`. No `postal_code_id` resolution. ### 🟡 P1: `admin_organizations.py` — Flat address fields silently ignored `OrganizationUpdate` schema has `address_zip`, `address_city` etc. but `hasattr(org, "address_zip")` returns False → silently ignored. --- ## 3. Database Ghost Columns The following old denormalized columns **still exist** in `fleet.organizations` table but have NO ORM mapping: `address_city`, `address_zip`, `address_street_name`, `address_street_type`, `address_house_number`, `address_hrsz`, `billing_city/zip/street_name/street_type`, `notification_city/zip/street_name/street_type` --- ## 4. Summary | Severity | Issue | File:Line | |----------|-------|-----------| | 🔴 P0 | `Organization.address_city` removed from ORM, still referenced | `admin.py:943` | | 🟡 P1 | Direct Address writes bypassing AddressManager | `admin_persons.py:670-699` | | 🟡 P1 | Flat address fields silently ignored on update | `admin_organizations.py:1242-1343` | | 🟡 P2 | Ghost columns in DB from old schema | `fleet.organizations` | | ✅ PASS | Organization model uses FKs only | `organization.py` | | ✅ PASS | Branch model uses FK only | `organization.py:333` | | ✅ PASS | admin_organizations.py correctly uses AddressManager | `admin_organizations.py:1313-1335` | | ✅ PASS | Address model properly normalized | `address.py` |