feat(service-auto): multi-tenant + tier 3 lookups + D1 partener + AsyncAutoComplete
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>
This commit is contained in:
38
docs/service-auto/autocomplete-dual-decision.md
Normal file
38
docs/service-auto/autocomplete-dual-decision.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# SupplierDualField — refactor decision
|
||||
|
||||
**Decizie**: `SupplierDualField.vue` **NU** se refactorizează cu `AsyncAutoComplete`.
|
||||
|
||||
## Context
|
||||
Task #3 a extras `AsyncAutoComplete` (shared) din pattern-ul typeahead async din
|
||||
`ComandaNoua.vue`. Candidatul pentru refactor a fost
|
||||
`src/modules/data-entry/components/receipts/SupplierDualField.vue`.
|
||||
|
||||
## Motive pentru skip
|
||||
|
||||
1. **Filtru client-side, nu async remote**
|
||||
`SupplierDualField` filtrează o listă `partners` **preîncărcată în memorie** (`props.partners.filter(...)` pe nume + CUI).
|
||||
`AsyncAutoComplete` e construit pe `searchFn: (q) => Promise<Item[]>` (remote).
|
||||
Adaptarea ar cere un wrapper artificial `async (q) => partners.filter(...)` care nu aduce valoare.
|
||||
|
||||
2. **`force-selection: false` vs `force-selection: true`**
|
||||
SupplierDualField permite intrare free-text (`forceSelection: false`) pentru că
|
||||
users pot tasta manual CUI/nume furnizor. `AsyncAutoComplete` impune
|
||||
`force-selection: true` ca invariant de securitate (evită ID-uri fantomă).
|
||||
Schimbarea ar rupe flow-ul existent.
|
||||
|
||||
3. **Dropdown manual + câmp CUI separat**
|
||||
Componenta e **composite**: AutoComplete (nume) + `InputText` (CUI) + toggle adresă
|
||||
+ sync-button + status badges (oracle/local/warning), totul cu propriile `update:*`
|
||||
emits. AutoComplete-ul e doar o parte — extragerea lui izolat ar lăsa componenta
|
||||
într-o stare hibridă, mai complicată decât acum.
|
||||
|
||||
4. **Prop `dropdown`**
|
||||
SupplierDualField folosește `dropdown` (buton chevron care arată toată lista).
|
||||
`AsyncAutoComplete` nu expune acest mod (ar contrazice pattern-ul async „caută
|
||||
minim N caractere").
|
||||
|
||||
## Concluzie
|
||||
Pattern-urile diferă fundamental. Păstrăm `SupplierDualField` neschimbat.
|
||||
`AsyncAutoComplete` rămâne dedicat pattern-urilor de typeahead async, cu sursa
|
||||
de date remote (ex: `ComandaNoua.vue` → partener service-auto, și viitoare
|
||||
formulare similare).
|
||||
26
docs/service-auto/migrations/ff_2026_04_13_01_AUTO.sql
Normal file
26
docs/service-auto/migrations/ff_2026_04_13_01_AUTO.sql
Normal file
@@ -0,0 +1,26 @@
|
||||
-- grant-uri ROA_WEB pe tabele asiguratori, inspectori, norme, parteneri + index typeahead
|
||||
|
||||
-- Rulat conectat ca schema MARIUSM_AUTO (sau DBA cu privilegii de GRANT)
|
||||
|
||||
GRANT SELECT ON MARIUSM_AUTO.DEV_NOM_NORME TO ROA_WEB;
|
||||
GRANT SELECT ON MARIUSM_AUTO.DEV_NOM_INSPECTORI TO ROA_WEB;
|
||||
GRANT SELECT ON MARIUSM_AUTO.DEV_NOM_ASIGURATORI TO ROA_WEB;
|
||||
GRANT SELECT ON MARIUSM_AUTO.NOM_PARTENERI TO ROA_WEB;
|
||||
GRANT EXECUTE ON MARIUSM_AUTO.pack_serii_numere TO ROA_WEB;
|
||||
|
||||
-- SER_SERII / SER_PLAJE: adaugati manual DACA pack_serii_numere are AUTHID CURRENT_USER
|
||||
-- GRANT SELECT, INSERT, UPDATE ON MARIUSM_AUTO.SER_SERII TO ROA_WEB;
|
||||
-- GRANT SELECT, INSERT, UPDATE ON MARIUSM_AUTO.SER_PLAJE TO ROA_WEB;
|
||||
|
||||
-- Index functional pentru typeahead parteneri (UPPER pe denumire)
|
||||
-- Rulat ca MARIUSM_AUTO owner; ONLINE pentru zero-downtime pe Enterprise Edition
|
||||
BEGIN
|
||||
IF PACK_MIGRARE.OBJECTEXIST('IX_NOM_PARTENERI_DEN_UPPER','INDEX') = 0 THEN
|
||||
EXECUTE IMMEDIATE
|
||||
'CREATE INDEX MARIUSM_AUTO.IX_NOM_PARTENERI_DEN_UPPER
|
||||
ON MARIUSM_AUTO.NOM_PARTENERI (UPPER(DENUMIRE))';
|
||||
END IF;
|
||||
END;
|
||||
/
|
||||
|
||||
exec pack_migrare.UpdateVersiune('ff_2026_04_13_01_AUTO'); commit;
|
||||
8
docs/service-auto/migrations/ff_2026_04_13_02_AUTO.sql
Normal file
8
docs/service-auto/migrations/ff_2026_04_13_02_AUTO.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
-- grant INSERT pe NOM_PARTENERI pentru creare partener nou din UI Service Auto
|
||||
|
||||
-- Rulat conectat ca schema MARIUSM_AUTO (sau DBA cu privilegii de GRANT)
|
||||
-- GRANT este idempotent: re-rulare = no-op.
|
||||
|
||||
GRANT INSERT ON MARIUSM_AUTO.NOM_PARTENERI TO ROA_WEB;
|
||||
|
||||
exec pack_migrare.UpdateVersiune('ff_2026_04_13_02_AUTO'); commit;
|
||||
Reference in New Issue
Block a user