# 🔧 Provider Admin SzerkesztĂ©s — Teljes ElemzĂ©s Ă©s Terv ## 🎯 ÖsszefoglalĂł **KĂ©rdĂ©s:** Hogyan lehet a szolgĂĄltatĂłi adatokat mĂłdosĂ­tani? Hol van a jĂłvĂĄhagyĂĄs/adatmĂłdosĂ­tĂĄs elƑzmĂ©nye? Ki mikor rögzĂ­tette? Kik validĂĄltĂĄk? Admin felĂŒletrƑl mĂłdosĂ­thatĂł-e? **VĂĄlasz röviden:** Az adatok **NINCSENEK bekĂłdolva** — teljes egĂ©szĂ©ben az adatbĂĄzisban vannak. A moderĂĄciĂł (approve/reject/flag/delete) **admin felĂŒletrƑl mƱködik**, de a provider adatmezƑinek szerkesztĂ©se (nĂ©v, cĂ­m, telefonszĂĄm, email mĂłdosĂ­tĂĄsa) **mĂ©g NINCS implementĂĄlva** az admin felĂŒleten. Javaslat: Ășj PUT vĂ©gpont + frontend edit modal. --- ## ✅ 1. ADATOK TÁROLÁSA (NINCSENEK bekĂłdolva) ### `marketplace.service_providers` — Alap szolgĂĄltatĂł adatok | Oszlop | TĂ­pus | LeĂ­rĂĄs | |--------|-------|--------| | `id` | integer (PK) | Automatikus ID | | `name` | varchar(255) | **SzolgĂĄltatĂł neve** | | `address` | varchar(255) | Teljes cĂ­m (legacy, deprecated) | | `city` | varchar(100) | **VĂĄros** | | `address_zip` | varchar(20) | **IrĂĄnyĂ­tĂłszĂĄm** | | `address_street_name` | varchar(255) | **UtcanĂ©v** | | `address_street_type` | varchar(50) | UtcatĂ­pus (utca, tĂ©r, stb.) | | `address_house_number` | varchar(20) | **HĂĄzszĂĄm** | | `plus_code` | varchar(100) | Google Plus Code | | `contact_phone` | varchar(50) | **TelefonszĂĄm** | | `contact_email` | varchar(255) | **Email** | | `website` | varchar(255) | **Weboldal** | | `category` | varchar(100) | **KategĂłria** (ExpertiseTag ID string) | | `status` | ENUM (ModerationStatus) | `pending` / `approved` / `rejected` / `flagged` | | `source` | ENUM (SourceType) | `crowd` / `admin` / `robot` | | `validation_score` | integer | ValidĂĄciĂłs pontszĂĄm | | `evidence_image_path` | varchar(500) | KĂ©p bizonyĂ­tĂ©k | | `added_by_user_id` | integer (FK→users) | **Ki vette fel** | | `created_at` | timestamptz | **Mikor vettĂ©k fel** | ### `marketplace.service_profiles` — RĂ©szletes profil Ă©s Ă©rtĂ©kelĂ©sek **Kapcsolat:** `service_profiles.service_provider_id` → `service_providers.id` | Oszlop | TĂ­pus | LeĂ­rĂĄs | |--------|-------|--------| | `id` | integer (PK) | Automatikus ID | | `service_provider_id` | integer (FK) | KapcsolĂłdĂł service_provider | | `organization_id` | integer (FK) | OpcionĂĄlis szervezeti kapcsolat | | `location` | GEOMETRY (PostGIS) | Földrajzi hely | | `status` | ENUM (ServiceStatus) | `active` / `inactive` / `suspended` | | `trust_score` | integer | **Bizalmi pontszĂĄm** | | `is_verified` | boolean | EllenƑrzött-e | | `verification_log` | jsonb | ValidĂĄciĂłs naplĂł | | `rating` | double precision | Google ĂĄtlagĂ©rtĂ©kelĂ©s | | `user_ratings_total` | integer | Google Ă©rtĂ©kelĂ©sek szĂĄma | | `rating_verified_count` | integer | EllenƑrzött Ă©rtĂ©kelĂ©sek szĂĄma | | `rating_price_avg` | double precision | **Ár ĂĄtlag pontszĂĄm** | | `rating_quality_avg` | double precision | **MinƑsĂ©g ĂĄtlag pontszĂĄm** | | `rating_time_avg` | double precision | **IdƑ ĂĄtlag pontszĂĄm** | | `rating_communication_avg` | double precision | **KommunikĂĄciĂł ĂĄtlag pontszĂĄm** | | `rating_overall` | double precision | **ÖsszesĂ­tett ĂĄtlag pontszĂĄm** | | `specialization_tags` | jsonb | SpecializĂĄciĂłs cĂ­mkĂ©k | | `opening_hours` | jsonb | NyitvatartĂĄs | | `contact_phone` | varchar(50) | Profil telefonszĂĄm | | `contact_email` | varchar(255) | Profil email | | `website` | varchar(255) | Profil weboldal | | `bio` | text | LeĂ­rĂĄs | | `created_at` | timestamptz | LĂ©trehozva | | `updated_at` | timestamptz | **UtolsĂł mĂłdosĂ­tĂĄs** | ### `marketplace.service_reviews` — FelhasznĂĄlĂłi Ă©rtĂ©kelĂ©sek ⭐ **Kapcsolat:** `service_reviews.service_id` → `service_profiles.id` | Oszlop | TĂ­pus | LeĂ­rĂĄs | |--------|-------|--------| | `id` | integer (PK) | Automatikus ID | | `service_id` | integer (FK) | Melyik service_profile-ra | | `user_id` | integer (FK→users) | **Ki Ă©rtĂ©kelt** | | `price_rating` | integer | **Ár pontszĂĄm** (1-5) | | `quality_rating` | integer | **MinƑsĂ©g pontszĂĄm** (1-5) | | `time_rating` | integer | **IdƑ/gördĂŒlĂ©kenysĂ©g pontszĂĄm** (1-5) | | `communication_rating` | integer | **KommunikĂĄciĂł pontszĂĄm** (1-5) | | `comment` | text | Szöveges vĂ©lemĂ©ny | | `is_verified` | boolean | EllenƑrzött tranzakciĂłhoz tartozik | | `transaction_id` | uuid | KapcsolĂłdĂł tranzakciĂł | | `created_at` | timestamptz | ÉrtĂ©kelĂ©s ideje | ### `marketplace.provider_validations` — ValidĂĄciĂłs elƑzmĂ©nyek | Oszlop | TĂ­pus | LeĂ­rĂĄs | |--------|-------|--------| | `id` | integer (PK) | Automatikus ID | | `provider_id` | integer (FK) | Melyik provider | | `voter_user_id` | integer (FK→users) | **Ki validĂĄlt** | | `validation_type` | varchar(20) | `approve` / `reject` / `flag` | | `weight` | integer | SĂșly Ă©rtĂ©k | | `metadata` | jsonb | Extra adatok (reason, stb.) | | `created_at` | timestamptz | ValidĂĄciĂł ideje | **UNIQUE:** `(voter_user_id, provider_id)` — egy user csak egyszer szavazhat. ### `marketplace.votes` — Szavazatok | Oszlop | LeĂ­rĂĄs | |--------|--------| | `vote_value` | integer (+1/-1) | ### `marketplace.ratings` — ÁltalĂĄnos Ă©rtĂ©kelĂ©s | Oszlop | LeĂ­rĂĄs | |--------|--------| | `score` | numeric(3,2) (max 9.99) | | `comment` | text | | `images` | jsonb | ### `gamification.point_rules` — PontszabĂĄlyok | ID | action_key | points | description | is_active | |----|-----------|--------|-------------|-----------| | 3 | `ADD_NEW_PROVIDER` | 500 | Új szolgĂĄltatĂł rögzĂ­tĂ©se | ✅ | | 4 | `USE_UNVERIFIED_PROVIDER` | 200 | SzervizesemĂ©ny nem ellenƑrzött szolgĂĄltatĂłnĂĄl | ✅ | | 5 | `RATE_PROVIDER` | 250 | SzolgĂĄltatĂł Ă©rtĂ©kelĂ©se (tagekkel) | ✅ | | 6 | `UPDATE_PROVIDER` | 100 | SzolgĂĄltatĂł adatainak szerkesztĂ©se | ✅ | --- ## ✅ 2. AUDIT TRAIL — Ki mit csinĂĄlt, mikor? ### `audit.audit_logs` — Központi audit naplĂł ```sql user_id → FK users (ki) severity → ENUM (info, warning, error) action → varchar (pl. "admin_provider_approve") target_type → varchar (pl. "service_provider") target_id → varchar (pl. "42") old_data → JSON (elƑzƑ ĂĄllapot) new_data → JSON (Ășj ĂĄllapot) ip_address → varchar user_agent → text timestamp → timestamptz (mikor) ``` Az [`admin_providers.py`](backend/app/api/v1/endpoints/admin_providers.py:147) `_log_moderation_action()` fĂŒggvĂ©nye minden moderĂĄciĂłs mƱveletet naplĂłz ide. ### Kapcsolati hĂĄlĂł ``` identity.users ├── added_by_user_id ──→ marketplace.service_providers (ki adta hozzĂĄ) ├── user_id ──→ marketplace.service_reviews (ki Ă©rtĂ©kelt) │ └── service_id ──→ service_profiles ├── author_id ──→ marketplace.ratings (ki Ă©rtĂ©kelt ĂĄltalĂĄban) ├── user_id ──→ marketplace.votes (ki szavazott) │ └── provider_id ──→ service_providers └── voter_user_id ──→ marketplace.provider_validations (ki validĂĄlt) └── provider_id ──→ service_providers ``` --- ## ✅ 3. ADMIN FELÜLETRƐL MÓDOSÍTHATÓ? — ÁLLAPOTFELMÉRÉS ### ✅ MEGLÉVƐ — ModerĂĄciĂłs mƱveletek admin felĂŒletrƑl | MƱvelet | Backend vĂ©gpont | Frontend oldal | |---------|----------------|----------------| | ListĂĄzĂĄs | `GET /admin/providers` | `/providers` (index.vue) | | Statisztika | `GET /admin/providers/stats` | `/providers` (index.vue) | | RĂ©szletek | `GET /admin/providers/{id}` | `/providers/[id]` | | **JĂłvĂĄhagyĂĄs** | `POST /admin/providers/{id}/approve` | `/providers/[id]` | | **ElutasĂ­tĂĄs** | `POST /admin/providers/{id}/reject` | `/providers/[id]` | | **MegjelölĂ©s** | `POST /admin/providers/{id}/flag` | `/providers/[id]` | | **TörlĂ©s** | `DELETE /admin/providers/{id}` | `/providers/[id]` | | FĂŒggƑben queue | — | `/providers/pending` | ### ❌ HIÁNYZÓ — Adatok szerkesztĂ©se admin felĂŒletrƑl | FunkciĂł | Backend | Frontend | |---------|---------|----------| | **Provider adatok szerkesztĂ©se** (nĂ©v, cĂ­m, tel., email, web, kategĂłria) | ❌ Nincs PUT/PATCH vĂ©gpont | ❌ Nincs edit form | | **Provider history/log nĂ©zet** | ❌ Nincs GET history vĂ©gpont | ❌ Nincs history panel | | **PontszabĂĄlyok bƑvĂ­tĂ©se** (PROVIDER_DISCOVERY, stb.) | ❌ HiĂĄnyzĂł DB rekordok | — | --- ## 📋 4. TERV — JAVASOLT FEJLESZTÉSEK ### 🟱 P0 — Admin Provider Edit (KötelezƑ — HiĂĄny #1) #### Backend: Új PUT vĂ©gpont (admin_providers.py) ```python class ProviderUpdateInput(BaseModel): name: Optional[str] = None city: Optional[str] = None address_zip: Optional[str] = None address_street_name: Optional[str] = None address_street_type: Optional[str] = None address_house_number: Optional[str] = None plus_code: Optional[str] = None contact_phone: Optional[str] = None contact_email: Optional[str] = None website: Optional[str] = None category: Optional[str] = None @router.put("/{provider_id}", response_model=ModerationResponse) async def update_provider( provider_id: int, data: ProviderUpdateInput, db: AsyncSession = Depends(get_db), current_user: User = Depends(require_admin), ): """Admin ĂĄltali provider adatmĂłdosĂ­tĂĄs. AuditLog capture old vs new values.""" # 1. LekĂ©ri a meglĂ©vƑ provider-t # 2. Elmenti a rĂ©gi Ă©rtĂ©keket (old_data JSON) # 3. FrissĂ­ti a megadott mezƑket # 4. AuditLog Ă­rĂĄs: action="admin_provider_update", old_data → new_data # 5. ProviderValidation lĂ©trehozĂĄsa: validation_type="admin_edit" # 6. validation_score reset 0-ra (Ășjra kell validĂĄlni) # 7. Ha van service_profile, annak updated_at frissĂ­tĂ©se ``` **AdatbĂĄzis Ă©rintettsĂ©g:** - `marketplace.service_providers` → UPDATE - `audit.audit_logs` → INSERT (old_data → new_data JSON capture) - `marketplace.provider_validations` → INSERT (admin_edit record) - `marketplace.service_profiles.updated_at` → UPDATE (ha van kapcsolĂłdĂł profil) #### Frontend: Edit modal (providers/[id].vue) - **"SzerkesztĂ©s" gomb** a provider detail nĂ©zetben (csak approved stĂĄtuszĂșaknĂĄl) - **Modal vagy inline form** a következƑ mezƑkkel: - **NĂ©v** (name) — text input - **CĂ­m blokk**: vĂĄros, irĂĄnyĂ­tĂłszĂĄm, utcanĂ©v, utcatĂ­pus, hĂĄzszĂĄm, plus_code - **Kapcsolat**: telefon, email, weboldal - **KategĂłria** (category) — select a meglĂ©vƑ kategĂłriĂĄkbĂłl - **MentĂ©s gomb** → `PUT /admin/providers/{id}` hĂ­vĂĄs - **Sikeres mentĂ©s** utĂĄn: adatok frissĂ­tĂ©se a nĂ©zetben + toast "Sikeres mĂłdosĂ­tĂĄs" - **Validation**: mezƑk validĂĄlĂĄsa mentĂ©s elƑtt ### 🟱 P0 — PontszabĂĄlyok bƑvĂ­tĂ©se (KötelezƑ — HiĂĄny #4) Új rekordok beszĂșrĂĄsa a `gamification.point_rules` tĂĄblĂĄba: | action_key | points | description | |-----------|--------|-------------| | `PROVIDER_DISCOVERY` | 300 | Új, mĂ©g nem lĂ©tezƑ provider felfedezĂ©se | | `PROVIDER_CONFIRMATION` | 150 | MeglĂ©vƑ provider adatainak megerƑsĂ­tĂ©se | | `PROVIDER_VERIFIED_USE` | 100 | MĂĄr validĂĄlt provider hasznĂĄlata költsĂ©g rögzĂ­tĂ©snĂ©l | **LĂ©trehozĂĄs:** Seed script vagy egyszerƱ SQL INSERT. ### 🟡 P1 — Provider History Panel (Javasolt — HiĂĄny #3) #### Backend: Új GET vĂ©gpont ```python @router.get("/{provider_id}/history", response_model=List[AuditLogEntry]) async def get_provider_history(...): """Visszaadja a provider-hez kapcsolĂłdĂł összes audit log rekordot.""" ``` - LekĂ©rdezĂ©s az `audit.audit_logs` tĂĄblĂĄbĂłl: `target_type='service_provider' AND target_id='{provider_id}'` - RendezĂ©s: `timestamp DESC` #### Frontend: History tab - Új "ElƑzmĂ©nyek" fĂŒl a provider detail oldalon (`providers/[id].vue`) - TĂĄblĂĄzatos nĂ©zet: | DĂĄtum | MƱvelet | Ki | RĂ©szletek | |-------|---------|-----|-----------| | 2026-06-30 | LĂ©trehozĂĄs | JĂĄnos | Ășj provider | | 2026-06-30 | JĂłvĂĄhagyĂĄs | Admin | +50 score | | 2026-06-30 | SzerkesztĂ©s | Admin | nĂ©v, cĂ­m mĂłdosĂ­tva | --- ## 📊 5. ADATBÁZIS ÉRINTETTSÉG ÖSSZESÍTÉS | SĂ©ma | TĂĄbla | MƱvelet | LeĂ­rĂĄs | |------|-------|---------|--------| | `marketplace` | `service_providers` | UPDATE | Admin ĂĄltali mezƑmĂłdosĂ­tĂĄs | | `marketplace` | `service_profiles` | UPDATE | `updated_at` frissĂ­tĂ©s | | `marketplace` | `provider_validations` | INSERT | Admin edit naplĂłzĂĄsa | | `audit` | `audit_logs` | INSERT | VĂĄltozĂĄsnaplĂłzĂĄs (old→new) | | `gamification` | `point_rules` | INSERT | Új pontszabĂĄlyok | --- ## đŸ—‚ïž 6. ÉRINTETT FÁJLOK | FĂĄjl | MƱvelet | |------|---------| | [`backend/app/api/v1/endpoints/admin_providers.py`](backend/app/api/v1/endpoints/admin_providers.py) | **MÓDOSÍTÁS**: ÚJ PUT vĂ©gpont + ProviderUpdateInput schema | | [`frontend_admin/pages/providers/[id].vue`](frontend_admin/pages/providers/[id].vue) | **MÓDOSÍTÁS**: Edit modal/Ʊrlap hozzĂĄadĂĄsa (P0) + History tab (P1) | | [`frontend_admin/i18n/locales/hu.json`](frontend_admin/i18n/locales/hu.json) | **MÓDOSÍTÁS**: Magyar szövegek | | [`frontend_admin/i18n/locales/en.json`](frontend_admin/i18n/locales/en.json) | **MÓDOSÍTÁS**: Angol szövegek | | `backend/app/scripts/seed_provider_point_rules.py` | **LÉTREHOZÁS**: Seed script az Ășj pontszabĂĄlyokhoz | | [`backend/app/models/identity/social.py`](backend/app/models/identity/social.py) | **NINCS vĂĄltozĂĄs** — meglĂ©vƑ modell hasznĂĄlhatĂł | --- ## 🚀 7. JAVASOLT GITEA KÁRTYÁK (JĂłvĂĄhagyĂĄs utĂĄn) ### 1. kĂĄrtya — Backend: Admin provider edit PUT vĂ©gpont **CĂ­m:** `Backend: Admin provider edit PUT /admin/providers/{id} vĂ©gpont` **MĂ©rföldkƑ:** P0 Service Provider Admin **CĂ©l:** Admin ĂĄltali provider adatmĂłdosĂ­tĂĄs lehetƑvĂ© tĂ©tele **FĂŒggƑsĂ©gek:** - **Bemenet:** `admin_providers.py`, `ServiceProvider` modell, `AuditLog` modell - **Kimenet:** Admin frontend edit form (2. kĂĄrtya) **LeĂ­rĂĄs:** ÚJ PUT vĂ©gpont a `admin_providers.py`-ban, ami lehetƑvĂ© teszi admin szĂĄmĂĄra a provider adatmezƑk szerkesztĂ©sĂ©t (name, city, address_*, contact_*, website, category). AuditLog capture (old_data → new_data JSON). ProviderValidation record lĂ©trehozĂĄsa `validation_type='admin_edit'`. validation_score reset 0-ra. ### 2. kĂĄrtya — Frontend: Admin provider edit modal **CĂ­m:** `Frontend: Admin provider edit modal/Ʊrlap` **MĂ©rföldkƑ:** P0 Service Provider Admin **CĂ©l:** Admin felĂŒleti lehetƑsĂ©g a provider adatok szerkesztĂ©sĂ©re **FĂŒggƑsĂ©gek:** - **Bemenet:** 1. kĂĄrtya (PUT vĂ©gpont) - **Kimenet:** — (frontend feature) **LeĂ­rĂĄs:** Edit modal hozzĂĄadĂĄsa a `providers/[id].vue` oldalhoz. "SzerkesztĂ©s" gomb, form mezƑk (nĂ©v, cĂ­m, kapcsolat, kategĂłria), validĂĄlĂĄs, PUT hĂ­vĂĄs, sikeres mentĂ©s utĂĄni frissĂ­tĂ©s. Magyar Ă©s angol i18n szövegek. ### 3. kĂĄrtya — PontszabĂĄlyok bƑvĂ­tĂ©se **CĂ­m:** `Seed: Új gamification pontszabĂĄlyok provider rendszerhez` **MĂ©rföldkƑ:** P0 Gamification **CĂ©l:** Provider discovery Ă©s confirmation pontozĂĄs bevezetĂ©se **FĂŒggƑsĂ©gek:** - **Bemenet:** `gamification.point_rules` tĂĄbla - **Kimenet:** Gamification motor (pontozĂĄs mƱködĂ©se) **LeĂ­rĂĄs:** 3 Ășj pontszabĂĄly beszĂșrĂĄsa: PROVIDER_DISCOVERY (300p), PROVIDER_CONFIRMATION (150p), PROVIDER_VERIFIED_USE (100p). Seed script lĂ©trehozĂĄsa. ### 4. kĂĄrtya — Provider history nĂ©zet (P1) **CĂ­m:** `Backend+Frontend: Provider audit history megjelenĂ­tĂ©se` **MĂ©rföldkƑ:** P1 Admin Experience **CĂ©l:** Provider teljes Ă©letciklusĂĄnak ĂĄttekinthetƑsĂ©ge **FĂŒggƑsĂ©gek:** - **Bemenet:** `audit.audit_logs` tĂĄbla - **Kimenet:** Jobb admin ĂĄttekinthetƑsĂ©g **LeĂ­rĂĄs:** GET `/admin/providers/{id}/history` vĂ©gpont az `audit.audit_logs`-bĂłl. History tab a frontenden: dĂĄtum, mƱvelet, ki, rĂ©szletek.