Refactor izolare multi-tenant:
- Schema Oracle rezolvată din id_firma via CONTAFIN_ORACLE.V_NOM_FIRME (cached 24h)
- server_id propagat din JWT (request.state.server_id) la oracle_pool.get_connection
- Elimină _SCHEMA='MARIUSM_AUTO' și literal 'mariusm_test' din toate query-urile
- Autorizare firmă la router (_company_id): 403 dacă id_firma nu e în JWT companies[]
Tier 3 — lookup endpoints cached 24h:
- GET /asiguratori (DEV_NOM_ASIGURATORI ← NOM_PARTENERI)
- GET /inspectori?id_asigurator=N (DEV_NOM_INSPECTORI per asig)
- GET /operatii (DEV_NOM_NORME)
- GET /parteneri?q=... (typeahead LIKE escape)
- GET /masini/{id}/detalii (VIN, cilindree, putere)
- POST /comenzi: PACK_SERII_NUMERE.aloca_numar + compensating dezaloca;
pc_nr VFP-format prefix+seq/nrinmat; ORA-06512 stripped din detail
D1 PartnerCreateDialog (nou):
- POST /api/service-auto/parteneri → PartnerCreateRequest; 409 pe CUI
duplicat (NOM_PARTENERI fără UNIQUE constraint — check manual);
id_part = MAX+1 cu retry pe ORA-00001 (fără sequence în schema VFP legacy)
- Frontend PartnerCreateDialog.vue — PrimeVue, design tokens, dark-mode safe
- Integrat în ComandaNoua.vue via AutoComplete empty-action hook
Shared AsyncAutoComplete (nou):
- src/shared/components/AsyncAutoComplete.vue — typeahead async debounced
cu emptyAction slot, force-selection, keyboard (Enter/Esc), design tokens
- ComandaNoua.vue refactorizat să folosească shared component
- SupplierDualField (data-entry) skipped — documentat în
docs/service-auto/autocomplete-dual-decision.md (pattern diferit)
Mobile chrome (CLAUDE.md):
- ComandaNoua.vue + ComenziBrowseView.vue: MobileTopBar, BottomSheet
filtre, MobileBottomNav, card list, isMobile resize listener
Migrații grant-uri idempotente:
- ff_2026_04_13_01_AUTO.sql — SELECT/EXECUTE pe tabele Tier 3 + index
IX_NOM_PARTENERI_DEN_UPPER
- ff_2026_04_13_02_AUTO.sql — INSERT pe NOM_PARTENERI pentru D1
Live smoke pe MARIUSM_AUTO: /ping 1ms, /tip-deviz 7, /masini 261,
POST /parteneri id_part=70241, firma neautorizată → 403.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
109 lines
2.5 KiB
Python
109 lines
2.5 KiB
Python
from datetime import date
|
|
from typing import List, Optional
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
class ComandaRequest(BaseModel):
|
|
tip_id: int
|
|
id_masiniclient: int
|
|
id_firma: int
|
|
id_sucursala: Optional[int] = None
|
|
id_asigurator: Optional[int] = None
|
|
id_inspector: Optional[int] = None
|
|
id_part_ref: Optional[int] = None
|
|
sir_id_operatii: Optional[List[int]] = None
|
|
observatii: str = ""
|
|
defectiuni: Optional[str] = None
|
|
km_int: int = 0
|
|
ore_functionare: int = 0
|
|
nr_dosar: str = ""
|
|
termen: Optional[date] = None
|
|
|
|
|
|
class ComandaResponse(BaseModel):
|
|
id_ordl: int
|
|
nrord: str
|
|
mesaj: str
|
|
|
|
|
|
class AsiguratorItem(BaseModel):
|
|
id_asigurator: int
|
|
denumire: str
|
|
|
|
|
|
class InspectorItem(BaseModel):
|
|
id_inspector: int
|
|
denumire: str
|
|
id_asigurator: int
|
|
|
|
|
|
class OperatieItem(BaseModel):
|
|
id_norme: int
|
|
codop: str
|
|
denop: str
|
|
timpn: Optional[float] = None
|
|
|
|
|
|
class PartenerItem(BaseModel):
|
|
id_part: int
|
|
denumire: str
|
|
|
|
|
|
class PartnerCreateRequest(BaseModel):
|
|
"""Payload pentru POST /parteneri — creare partener nou în NOM_PARTENERI."""
|
|
denumire: str = Field(min_length=2, max_length=100)
|
|
cui: Optional[str] = Field(default=None, max_length=30)
|
|
adresa: Optional[str] = Field(default=None, max_length=150)
|
|
id_firma: int = Field(ge=1)
|
|
|
|
|
|
class MasinaDetails(BaseModel):
|
|
id_masiniclient: int
|
|
label: str
|
|
nr_inmatriculare: Optional[str] = None
|
|
marca: Optional[str] = None
|
|
model: Optional[str] = None
|
|
serie_sasiu: Optional[str] = None
|
|
cilindree: Optional[int] = None
|
|
putere_cp: Optional[int] = None
|
|
putere_kw: Optional[int] = None
|
|
client_nume: Optional[str] = None
|
|
|
|
|
|
class FirmaItem(BaseModel):
|
|
id_firma: int
|
|
firma: str
|
|
schema_name: str
|
|
id_mama: Optional[int] = None
|
|
|
|
|
|
class TipDevizItem(BaseModel):
|
|
id_tip: int
|
|
denumire: str
|
|
inch_validare: int
|
|
|
|
|
|
class MasinaClientItem(BaseModel):
|
|
id_masiniclient: int
|
|
label: str # "PARTENER — MARCA MASINA, NRINMAT (ANFABRICATIE)"
|
|
|
|
|
|
class ComandaListItem(BaseModel):
|
|
id_ordl: int
|
|
nrord: str
|
|
datai: Optional[str] # ISO date "YYYY-MM-DD"
|
|
validat: int # 0=deschisă, 1=validată
|
|
inchis_fortat: int # 1=arhivată fără validare
|
|
id_tip: int
|
|
tip_denumire: str
|
|
vehicul: str # "PARTENER — MARCA MASINA, NRINMAT (AN)"
|
|
id_masiniclient: Optional[int]
|
|
|
|
|
|
class ComandaListResponse(BaseModel):
|
|
comenzi: List[ComandaListItem]
|
|
total: int
|
|
page: int
|
|
per_page: int
|