73 lines
3.3 KiB
Markdown
73 lines
3.3 KiB
Markdown
# 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` |
|