Files
service-finder/plans/logic_spec_provider_update_fix.md

5.4 KiB

🔧 Logic Spec: Provider Update & Search Fix Csomag

🎯 Cél

A szolgáltató cégek adatainak rögzítésében és szerkesztésében fellépő hibák javítása, valamint az adatok részletes rögzíthetőségének biztosítása.

📋 Problémák Összefoglalása

1. PUT /api/v1/providers/{id} → 404 Not Found ( MEGOLDVA)

  • Root Cause: A sf_api konténer nem volt újraindítva a providers modul kódfrissítése után. A pre_start.sh fájlban uvicorn --reload flag nélkül fut.
  • Javítás: docker compose restart sf_api (végrehajtva)
  • Verifikáció: PUT /providers/58 → 200 OK

2. GET /api/v1/providers/search → 500 Internal Server Error ( JAVÍTANDÓ)

  • Hiba: AttributeError: Neither 'BinaryExpression' object nor 'Comparator' object has an attribute 'astext'
  • Hibás kód: provider_service.py:207
    (Organization.external_integration_config["source"].astext == "crowdsourced", literal("crowd_added")),
    
  • Root Cause: Az external_integration_config JSON típusú oszlop. A ["source"] subscript BinaryExpression-t ad vissza, amelyen NINCS .astext.
  • Javítás: cast használata:
    (cast(Organization.external_integration_config["source"], String) == "crowdsourced", literal("crowd_added")),
    

3. Adat-healing: Régi címformátumú Organization rekordok ( JAVÍTANDÓ)

  • Probléma: Az Organization id=58 (Autónyíri Kft.) adatai a régi formátumban:
    • street_name = "Egressy u. 4." (nem atomizált)
    • address_street_name = NULL, address_street_type = NULL, address_house_number = NULL
    • zip = NULL
  • Következmény: A frontend DetailModal üres címet mutat.
  • Javítás: Adat-healing script a street_name mezőből atomizált komponensek kinyerésére.

4. Multi-source Update Probléma ( JAVÍTANDÓ)

  • Probléma: Az update_provider CSAK Organization-ben keres. A search UNION-nal dolgozza fel a szolgáltatókat 3 forrásból (Organization, ServiceStaging, ServiceProvider).
  • Javítás: Multi-source update logika.

5. Szerver Restart Workflow Hiánya ( JAVÍTANDÓ)

  • Probléma: A pre_start.sh --reload nélkül indul.
  • Javítás: --reload flag fejlesztői módban.

🗺️ Érintett Fájlok

Fájl Változtatás Prioritás
provider_service.py:207 .astextcast() KRITIKUS
provider_service.py:477-562 Multi-source update MAGAS
Új: heal_provider_addresses.py Adat-healing script MAGAS
pre_start.sh --reload dev módban ALACSONY

🛠️ Részletes Javítási Terv

1. .astextcast() javítás

Fájl: provider_service.py

Jelenlegi:

(Organization.external_integration_config["source"].astext == "crowdsourced", literal("crowd_added")),

Javított:

(cast(Organization.external_integration_config["source"], String) == "crowdsourced", literal("crowd_added")),

2. Multi-source Update Logika

Fájl: provider_service.py:477

Az update_provider ellenőrizze mindhárom forrást:

  1. db.get(Organization, provider_id) → meglévő logika
  2. db.get(ServiceStaging, provider_id) → migrálás Organization-be
  3. db.get(ServiceProvider, provider_id) → migrálás Organization-be
  4. Ha egyikben sem → ValueError

3. Adat-healing Script

Fájl: backend/app/scripts/heal_provider_addresses.py

  1. Lekérdezni Organization rekordokat, ahol org_type='service_provider' ÉS address_street_name IS NULL ÉS street_name IS NOT NULL
  2. Regex: r'^([^\d]+?)\s+(u\.|utca|út|tér|köz|sor|körút|liget|part|fasor|sétány|park|híd|sugárút|rakpart|dűlő|telep|szőlő)\s*(.*)$'
  3. Frissíteni az atomizált mezőket
  4. Naplózás

🧪 Tesztelési Terv

Teszt 1: search működés

docker compose exec sf_api python3 -c "
import httpx, asyncio
async def t():
    async with httpx.AsyncClient(base_url='http://localhost:8000') as c:
        r = await c.post('/api/v1/auth/login', data={'username': 'admin@profibot.hu', 'password': 'Admin123!'})
        t = r.json()['access_token']
        r2 = await c.get('/api/v1/providers/search', params={'q': 'Dunakeszi', 'limit': 5}, headers={'Authorization': f'Bearer {t}'})
        print(f'Search: {r2.status_code}')
        print(r2.text[:500])
asyncio.run(t())
"

Teszt 2: PUT működés

docker compose exec sf_api python3 -c "
import httpx, asyncio
async def t():
    async with httpx.AsyncClient(base_url='http://localhost:8000') as c:
        r = await c.post('/api/v1/auth/login', data={'username': 'admin@profibot.hu', 'password': 'Admin123!'})
        t = r.json()['access_token']
        r2 = await c.put('/api/v1/providers/58',
            json={'address_zip': '2120', 'city': 'Dunakeszi', 'name': 'Autónyíri Kft.'},
            headers={'Authorization': f'Bearer {t}'})
        print(f'PUT: {r2.status_code}')
        print(r2.text)
asyncio.run(t())
"