szolgáltatók beálltásai, szerkesztése , létrehozása
This commit is contained in:
123
plans/logic_spec_provider_update_fix.md
Normal file
123
plans/logic_spec_provider_update_fix.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# 🔧 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`](../backend/app/services/provider_service.py:207)
|
||||
```python
|
||||
(Organization.external_integration_config["source"].astext == "crowdsourced", literal("crowd_added")),
|
||||
```
|
||||
- **Root Cause**: Az [`external_integration_config`](../backend/app/models/marketplace/organization.py:109) `JSON` típusú oszlop. A `["source"]` subscript `BinaryExpression`-t ad vissza, amelyen NINCS `.astext`.
|
||||
- **Javítás**: `cast` használata:
|
||||
```python
|
||||
(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`](../backend/app/services/provider_service.py:477) 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`](../backend/app/scripts/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`](../backend/app/services/provider_service.py:207) | `.astext` → `cast()` | **KRITIKUS** |
|
||||
| [`provider_service.py:477-562`](../backend/app/services/provider_service.py:477) | Multi-source update | **MAGAS** |
|
||||
| Új: `heal_provider_addresses.py` | Adat-healing script | **MAGAS** |
|
||||
| [`pre_start.sh`](../backend/app/scripts/pre_start.sh) | `--reload` dev módban | **ALACSONY** |
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Részletes Javítási Terv
|
||||
|
||||
### 1. `.astext` → `cast()` javítás
|
||||
|
||||
**Fájl**: [`provider_service.py`](../backend/app/services/provider_service.py:207)
|
||||
|
||||
**Jelenlegi:**
|
||||
```python
|
||||
(Organization.external_integration_config["source"].astext == "crowdsourced", literal("crowd_added")),
|
||||
```
|
||||
|
||||
**Javított:**
|
||||
```python
|
||||
(cast(Organization.external_integration_config["source"], String) == "crowdsourced", literal("crowd_added")),
|
||||
```
|
||||
|
||||
### 2. Multi-source Update Logika
|
||||
|
||||
**Fájl**: [`provider_service.py:477`](../backend/app/services/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
|
||||
```bash
|
||||
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
|
||||
```bash
|
||||
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())
|
||||
"
|
||||
```
|
||||
Reference in New Issue
Block a user