# đŸ—ïž Logic Spec: Provider Taxonomy Audit & Smart Search API ## 1. Modul CĂ©lja Ă©s Masterbook 2.0 IlleszkedĂ©s **MĂ©rföldkƑ:** Crowdsourced PartnerkeresƑ (Marketplace Engine) **CĂ©l:** A szolgĂĄltatĂłi kategĂłriarendszer (taxonĂłmia) feltöltĂ©se Ă©s egy okos, egyesĂ­tett keresƑ API (search + quick-add) megvalĂłsĂ­tĂĄsa a crowdsourced partnerkeresĂ©shez. ### Masterbook 2.0 KapcsolĂłdĂĄs - **Epic:** Marketplace & Service Discovery (08_Marketplace) - **Robot Kapcsolat:** A meglĂ©vƑ `service_staging` adatok (robotok ĂĄltal gyƱjtött) publikusan kereshetƑvĂ© tĂ©tele - **Üzleti Logika:** BĂĄrki (mĂ©g nem verifikĂĄlt) gyorsan felvehet egy szolgĂĄltatĂłt, ami automatikusan a `service_staging` tĂĄblĂĄba kerĂŒl, ahol a robotok kĂ©sƑbb feldolgozhatjĂĄk ## 2. AdatbĂĄzis Audit EredmĂ©nyek ### MeglĂ©vƑ TĂĄblĂĄk Állapota | TĂĄbla | SĂ©ma | Állapot | Rekordok | |-------|------|---------|----------| | `expertise_tags` | `marketplace` | **ÜRES** - nincs egyetlen kategĂłria sem | 0 | | `service_specialties` | `marketplace` | **ÜRES** - egyszerƱ (id, parent_id, name, slug) | 0 | | `service_providers` | `marketplace` | **ÜRES** - crowdsourced provider tĂĄbla | 0 | | `organizations` (org_type='service_provider') | `fleet` | **NINCS** ilyen rekord | 0 | | `service_staging` | `marketplace` | Van benne ~2000+ rekord (robot gyƱjtĂ©s) | ~2000 | ### HasznĂĄlandĂł MeglĂ©vƑ StruktĂșrĂĄk 1. **`marketplace.expertise_tags`** - A kategĂłria mestertĂĄbla (twin: name_hu/name_en, search_keywords JSONB). Ez a legalkalmasabb. 2. **`fleet.organizations.aliases`** - JSONB mezƑ a szolgĂĄltatĂł alternatĂ­v neveihez (mĂĄr lĂ©tezik!) 3. **`fleet.organizations.tags`** - JSONB mezƑ a crowdsourced cĂ­mkĂ©khez (mĂĄr lĂ©tezik!) 4. **`marketplace.service_staging`** - Robotok ĂĄltal gyƱjtött adatok (mĂĄr lĂ©tezik adatokkal) 5. **`marketplace.service_providers`** - Crowdsourced provider tĂĄbla (ĂŒres, de hasznĂĄlhatĂł) ## 3. Technikai Terv ### 3.1 Seed Script: `backend/app/scripts/seed_expertise_tags.py` **FĂĄjl:** `backend/app/scripts/seed_expertise_tags.py` Feltölti az `expertise_tags` tĂĄblĂĄt az alĂĄbbi alapkategĂłriĂĄkkal: | key | name_hu | name_en | category | search_keywords | |-----|---------|---------|----------|-----------------| | auto_szerelo | AutĂłszerelƑ | Car Mechanic | vehicle_service | ["szerelƑ", "autĂłszerelƑ", "mechanic", "garage"] | | motor_szerelo | MotorkerĂ©kpĂĄr szerelƑ | Motorcycle Mechanic | vehicle_service | ["motor", "motorszerelƑ", "motorcycle"] | | gumiszerviz | Gumiszerviz | Tire Service | vehicle_service | ["gumi", "gumis", "tire", "tyre", "abroncs"] | | karosszerialakatos | KarosszĂ©rialakatos | Body Shop | body_paint | ["karosszĂ©ria", "lakatos", "bodyshop"] | | fĂ©nyezƑ | FĂ©nyezƑ | Painter | body_paint | ["fĂ©nyezƑ", "fĂ©nyezĂ©s", "painter", "spray"] | | autĂłmentƑ | AutĂłmentƑ / MotormentƑ | Tow Truck / Roadside | roadside | ["mentƑ", "autĂłmentƑ", "tow", "roadside"] | | benzinkĂșt | BenzinkĂșt | Gas Station | fuel | ["benzin", "kĂșt", "gas station", "fuel"] | | alkatrĂ©sz_kereskedĂ©s | AlkatrĂ©sz kereskedĂ©s | Parts Store | parts | ["alkatrĂ©sz", "parts", "spares"] | | vizsgaĂĄllomĂĄs | VizsgaĂĄllomĂĄs | Inspection Station | inspection | ["vizsga", "mƱszaki", "inspection", "MOT"] | | autĂłkozmetika | AutĂłkozmetika | Car Detailing | detailing | ["kozmetika", "detailing", "takarĂ­tĂĄs"] | | egyĂ©b | EgyĂ©b szolgĂĄltatĂł | Other Service | other | ["egyĂ©b", "other", "szolgĂĄltatĂł"] | **FuttatĂĄs:** `docker exec sf_api python3 /app/backend/app/scripts/seed_expertise_tags.py` ### 3.2 API VĂ©gpont: `GET /api/v1/providers/search` **FĂĄjl:** `backend/app/api/v1/endpoints/providers.py` #### VĂ©gpont SpecifikĂĄciĂł ``` GET /api/v1/providers/search?q={keresƑszĂł}&category={kategĂłria}&city={vĂĄros}&limit={limit}&offset={offset} ``` #### KeresĂ©s LogikĂĄja (hĂĄrom tĂĄbla egyesĂ­tĂ©se) ```mermaid flowchart TD A[GET /providers/search?q=keresƑ] --> B{EllenƑrizd a q paramĂ©tert} B -->|Van| C[HĂĄrom tĂĄbla egyesĂ­tett keresĂ©se] B -->|Nincs| D[KategĂłria/VĂĄros szƱrĂ©s, ha van] C --> E1[1. fleet.organizations] C --> E2[2. marketplace.service_staging] C --> E3[3. marketplace.service_providers] E1 --> F1{org_type = service_provider} F1 --> G1[ILIKE a name-re] F1 --> G2[ILIKE az aliases JSONB-ben] E2 --> G3[ILIKE a name-re] E2 --> G4[ILIKE a city-re] E3 --> G5[ILIKE a name-re] D --> H[Közös UNION / egysĂ©gesĂ­tĂ©s] H --> I[ForrĂĄs jelölĂ©s: verified_org / staged_data / crowd_added] I --> J[Rendezes + lapozĂĄs] J --> K[Response] ``` #### Response Schema (ProviderSearchResult) ```json { "results": [ { "id": 1, "name": "MOL AutĂłszerviz", "category": null, "specialization": ["autĂłszerelƑ", "gumiszerviz"], "city": "Budapest", "address": "Budapest, Kossuth u. 1", "source": "verified_org", "is_verified": true, "rating": 4.5 } ], "total": 42, "page": 1, "per_page": 20 } ``` ### 3.3 API VĂ©gpont: `POST /api/v1/providers/quick-add` **FĂĄjl:** `backend/app/api/v1/endpoints/providers.py` #### VĂ©gpont SpecifikĂĄciĂł ``` POST /api/v1/providers/quick-add Content-Type: application/json { "name": "Teszt AutĂłszerviz", "category_id": 1, "city": "Budapest", "street": "Kossuth utca 1", "tags": ["olcsĂł", "gyors"] } ``` #### Folyamat ```mermaid flowchart TD A[POST /providers/quick-add] --> B[AuthentikĂĄciĂł: current_user] B --> C[ValidĂĄciĂł: name kötelezƑ] C --> D{KategĂłria ID ellenƑrzĂ©se} D -->|LĂ©tezik| E[LĂ©trehozĂĄs: Organization] D -->|Nem lĂ©tezik| F[400: Invalid category] E --> G[Organization lĂ©trehozĂĄsa] G --> H[org_type = service_provider] H --> I[is_verified = False] I --> J[tags = megadott tömbbƑl] J --> K[ServiceProfile lĂ©trehozĂĄsa] K --> L[expertise_tags kapcsolat] L --> M[Branch lĂ©trehozĂĄsa a cĂ­mmel] M --> N[commit] N --> O[Response: quick-add success] ``` #### Request Schema (ProviderQuickAddIn) | MezƑ | TĂ­pus | KötelezƑ | LeĂ­rĂĄs | |------|-------|----------|--------| | name | string | Igen | SzolgĂĄltatĂł neve (2-200 karakter) | | category_id | int | Igen | KategĂłria ID (expertise_tags.id) | | city | string | Nem | VĂĄros | | street | string | Nem | Utca/hĂĄzszĂĄm | | tags | string[] | Nem | CĂ­mkĂ©k (pl. ["olcsĂł", "gyors"]) | #### Response Schema (ProviderQuickAddResponse) | MezƑ | TĂ­pus | LeĂ­rĂĄs | |------|-------|--------| | id | int | Az Ășj szervezet ID-ja | | name | string | A szolgĂĄltatĂł neve | | status | string | "pending_verification" | | message | string | Sikeres ĂŒzenet | ### 3.4 Router RegisztrĂĄciĂł A `providers.py`-t be kell regisztrĂĄlni az `api.py`-ban: ```python from app.api.v1.endpoints import providers api_router.include_router(providers.router, prefix="/providers", tags=["Providers"]) ``` ### 3.5 SzĂŒksĂ©ges SchĂ©mĂĄk **FĂĄjl:** `backend/app/schemas/provider.py` (ÚJ) ```python class ProviderSearchResult(BaseModel): id: int name: str category: Optional[str] = None specialization: List[str] = [] city: Optional[str] = None address: Optional[str] = None source: str # "verified_org" | "staged_data" | "crowd_added" is_verified: bool = False rating: Optional[float] = None model_config = ConfigDict(from_attributes=True) class ProviderSearchResponse(BaseModel): results: List[ProviderSearchResult] total: int page: int = 1 per_page: int = 20 class ProviderQuickAddIn(BaseModel): name: str = Field(..., min_length=2, max_length=200) category_id: int = Field(..., ge=1) city: Optional[str] = Field(None, max_length=100) street: Optional[str] = Field(None, max_length=255) tags: List[str] = Field(default_factory=list) class ProviderQuickAddResponse(BaseModel): id: int name: str status: str = "pending_verification" message: str = "SzolgĂĄltatĂł sikeresen rögzĂ­tve. EllenƑrzĂ©s alatt." ``` ### 3.6 Service RĂ©teg **FĂĄjl:** `backend/app/services/provider_service.py` (ÚJ) A service rĂ©teg tartalmazza: - `search_providers(db, q, category, city, limit, offset)` - EgyesĂ­tett keresĂ©s - `quick_add_provider(db, data, user_id)` - Gyors szolgĂĄltatĂł felvĂ©tel ## 4. Adatmodell VĂĄltozĂĄsok ### 4.1 NINCS Ășj modell vagy migrĂĄciĂł! A meglĂ©vƑ modellek Ă©s adatbĂĄzis tĂĄblĂĄk TELJESEN lefedik a funkcionalitĂĄst: - `marketplace.expertise_tags` - mĂĄr lĂ©tezik, csak adat kell - `fleet.organizations` - mĂĄr van `aliases`, `tags`, `org_type` mezƑ - `marketplace.service_staging` - mĂĄr lĂ©tezik adatokkal - `marketplace.service_providers` - mĂĄr lĂ©tezik (ĂŒres) ### 4.2 Csak Seed Adat Kell A `seed_expertise_tags.py` INSERT utasĂ­tĂĄsokkal tölti fel az `expertise_tags` tĂĄblĂĄt. ## 5. MegvalĂłsĂ­tĂĄsi Terv ### 5.1 VĂ©grehajtandĂł LĂ©pĂ©sek | # | LĂ©pĂ©s | FĂĄjl | LeĂ­rĂĄs | |---|-------|------|--------| | 1 | Seed script | `backend/app/scripts/seed_expertise_tags.py` | Feltölti a 11 alapkategĂłriĂĄt | | 2 | Seed futtatĂĄs | TerminĂĄl | `docker exec sf_api python3 /app/backend/app/scripts/seed_expertise_tags.py` | | 3 | Pydantic schĂ©mĂĄk | `backend/app/schemas/provider.py` (ÚJ) | ProviderSearchResult, ProviderQuickAddIn | | 4 | Service rĂ©teg | `backend/app/services/provider_service.py` (ÚJ) | search_providers, quick_add_provider | | 5 | Endpointok | `backend/app/api/v1/endpoints/providers.py` | GET /search, POST /quick-add | | 6 | Router regisztrĂĄciĂł | `backend/app/api/v1/api.py` | providers router hozzĂĄadĂĄsa | | 7 | EllenƑrzƑ teszt | TerminĂĄl | API hĂ­vĂĄsok tesztelĂ©se | ### 5.2 FĂŒggƑsĂ©gek - **Bemenet:** MeglĂ©vƑ modell rĂ©teg (Organization, ServiceStaging, ServiceProvider, ExpertiseTag) - **Kimenet:** A `/api/v1/providers/search` Ă©s `/api/v1/providers/quick-add` vĂ©gpontok - **BlokkolĂł:** Nincs - minden meglĂ©vƑ kĂłd hasznĂĄlhatĂł ## 6. Admin Kontroll A Seed script FUTTATHATÓ többször is (idempotens) - `ON CONFLICT DO NOTHING` klauzulĂĄval. A kategĂłriĂĄk kĂ©sƑbb az Admin felĂŒleten keresztĂŒl mĂłdosĂ­thatĂłk/bƑvĂ­thetƑk. ## 7. Geo-Logika A keresĂ©s jelenleg NEM tartalmaz PostGIS tĂĄvolsĂĄgszƱrĂ©st (az kĂŒlön endpoint: `/search/match`). A `/providers/search` csak szöveges keresĂ©s (ILIKE).