security: Add proper authentication, RBAC, and tenant isolation
- Add password hashing with bcrypt - Add AuthService with proper login - Add password strength validation - Add RBAC middleware (AdminOnly, ManagerOrAdmin) - Add tenant isolation middleware - Update CRM handler with tenant filtering - Add JWT fallback for development mode - Add user context helpers - Build successful
This commit is contained in:
@@ -0,0 +1,270 @@
|
||||
# quiXzoom — Audit Spec
|
||||
*Beslutad: 2026-06-17. Körs innan Smart Scan, AVO och Liveness byggs ut.*
|
||||
|
||||
---
|
||||
|
||||
## Kill-kriterier (commitas INNAN körning)
|
||||
|
||||
| Kriterie | Kill om |
|
||||
|----------|---------|
|
||||
| Evidenstäckning Fas 1 | <70% av sekvenser ger alla required datapunkter |
|
||||
| Extraherbarhet Fas 2 | OCR/detection <80% på serienummer under verkliga förhållanden |
|
||||
| Tid per claim Fas 2 | >3 min genomsnitt → marginalproblemet |
|
||||
| Liveness Fas 3 | >20% av replay-attacker passerar utan detection |
|
||||
| Översättning Fas 4 | <80% av uppdrag kan formuleras som datakrav (ej bildkrav) |
|
||||
|
||||
Bryts ett kill-kriterium → stopp, omvärdering innan kod.
|
||||
|
||||
---
|
||||
|
||||
## Fas 4 först — 5 pilot-claims (gör detta innan WoZ)
|
||||
|
||||
Formulera datakrav för dessa 5 objekt. Det är linjalen för Fas 1.
|
||||
|
||||
### Claim 1: Elmätare
|
||||
|
||||
```
|
||||
Claim: electricity_meter_verified
|
||||
Datakrav:
|
||||
- serienummer (OCR, alfanumerisk sträng)
|
||||
- mätarställning (OCR, numerisk)
|
||||
- plombering synlig (presence_check)
|
||||
- GPS inom 15m från uppdragsadress
|
||||
Tröskel för godkänt: alla 4 datapunkter extraherbara med confidence >0.85
|
||||
Kill-signal: serienummer <80% läsbart i testset
|
||||
```
|
||||
|
||||
### Claim 2: Fordonsregistreringsskylt
|
||||
|
||||
```
|
||||
Claim: reg_plate_verified
|
||||
Datakrav:
|
||||
- registreringsnummer (OCR, format: ABC 123)
|
||||
- framruta/bakruta tydlig (framing_check)
|
||||
- GPS inom 50m
|
||||
Tröskel: reg_nr confidence >0.90
|
||||
Kill-signal: avläsningsfel >15% i testset (smutsiga/blinkande skyltar)
|
||||
```
|
||||
|
||||
### Claim 3: Butiksskylt/fasad
|
||||
|
||||
```
|
||||
Claim: storefront_condition_verified
|
||||
Datakrav:
|
||||
- butiksnamn läsbart (OCR)
|
||||
- fasadens helhet synlig (coverage >85%)
|
||||
- skador dokumenterade om synliga (anomaly_detection)
|
||||
- GPS inom 20m
|
||||
Tröskel: namn + helhet = godkänt; skador är bonus
|
||||
Kill-signal: <70% av uppdrag ger täckning >85%
|
||||
```
|
||||
|
||||
### Claim 4: Livboj (maritim säkerhet)
|
||||
|
||||
```
|
||||
Claim: lifebuoy_present_and_accessible
|
||||
Datakrav:
|
||||
- livboj identifierad (object_detection, class: lifebuoy)
|
||||
- position synlig (framing)
|
||||
- tillgänglighet verifierbar (ej blockerad)
|
||||
- GPS inom 10m
|
||||
Tröskel: object_detection confidence >0.88
|
||||
Kill-signal: dark/backlit environments → detection <70%
|
||||
```
|
||||
|
||||
### Claim 5: Serienummerplåt (industrimaskiner)
|
||||
|
||||
```
|
||||
Claim: machine_serial_verified
|
||||
Datakrav:
|
||||
- serienummer (OCR, variabelt format)
|
||||
- maskintyp identifierad (object_detection)
|
||||
- position dokumenterad (GPS)
|
||||
Tröskel: OCR confidence >0.85
|
||||
Kill-signal: graverade/inpräglade serienummer → OCR <60% (hårt kill-kriterium)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fas 1 — Wizard of Oz (20–50 uppdrag)
|
||||
|
||||
**Frågan:** Får vi tillräckligt med evidens utan att användaren tar ett enda foto?
|
||||
|
||||
### Setup
|
||||
|
||||
- Zoomer filmar med vanlig telefon-kamera (videoläge)
|
||||
- Operatör bakom kulisserna skickar textinstruktioner i realtid via Telegram/chat
|
||||
- Ingen AI — bara en människa som läser videon live
|
||||
|
||||
### Instruktionsvokabulär (samma som AVO)
|
||||
|
||||
```
|
||||
"Gå närmare — ca 30 cm"
|
||||
"Visa etiketten"
|
||||
"Vrid kameran lite åt höger"
|
||||
"Håll still"
|
||||
"Visa undersidan"
|
||||
"Zooma in serienumret"
|
||||
"Visa hela objektet"
|
||||
"Perfekt — klar"
|
||||
```
|
||||
|
||||
### Mätpunkter per sekvens
|
||||
|
||||
```yaml
|
||||
session_id: WoZ_001
|
||||
object_type: electricity_meter
|
||||
duration_seconds: 0
|
||||
instruction_count: 0
|
||||
datakrav_uppfyllda:
|
||||
serienummer: null # true/false/partial
|
||||
matarstandning: null
|
||||
plombering: null
|
||||
gps: null
|
||||
evidens_tillracklig: null # true/false
|
||||
anteckningar: ""
|
||||
```
|
||||
|
||||
### Gränsvärde
|
||||
|
||||
>70% av sekvenser måste ge alla datakrav uppfyllda. Annars: kill.
|
||||
|
||||
---
|
||||
|
||||
## Fas 2 — Evidensaudit (100–500 sekvenser)
|
||||
|
||||
**Frågan:** Vad misslyckas, hur ofta, och vad kostar det?
|
||||
|
||||
### Per sekvens
|
||||
|
||||
```yaml
|
||||
session_id: EA_001
|
||||
object_type: electricity_meter
|
||||
zoomer_id: anonymized
|
||||
|
||||
timing:
|
||||
total_seconds: 0
|
||||
instructions_given: 0
|
||||
first_clear_frame_at_s: 0
|
||||
|
||||
extraction_results:
|
||||
serienummer:
|
||||
extracted: null
|
||||
confidence: null
|
||||
attempts: 0
|
||||
matarstandning:
|
||||
extracted: null
|
||||
confidence: null
|
||||
plombering:
|
||||
visible: null
|
||||
|
||||
environment:
|
||||
lighting: good/bad/mixed
|
||||
distance_issues: false
|
||||
occlusion: false
|
||||
|
||||
outcome: approved/rejected/partial
|
||||
reject_reason: ""
|
||||
```
|
||||
|
||||
### Nyckeltal att samla
|
||||
|
||||
```
|
||||
Genomsnittstid per claim: X sek
|
||||
Instruktioner per claim: X st
|
||||
Extraktionssäkerhet serienummer: X%
|
||||
Extraktionssäkerhet numeriska värden: X%
|
||||
Presence detection: X%
|
||||
Vanligaste felpunkter: [lista]
|
||||
Kostnad per claim (tid × Zoomer-ersättning): X kr
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fas 3 — Livenessaudit (attackscenarier)
|
||||
|
||||
**Frågan:** Vilka signaler skiljer verklighet från bedrägeri?
|
||||
|
||||
### Attackscenarier att testa
|
||||
|
||||
| # | Attack | Förväntat utfall | Faktiskt utfall |
|
||||
|---|--------|-----------------|-----------------|
|
||||
| L1 | Foto av objekt på annan telefon | Fail — ingen parallax | |
|
||||
| L2 | Video av annan telefon (replay) | Fail — ingen challenge-respons | |
|
||||
| L3 | Utskrivet foto | Fail — platt, ingen djupinfo | |
|
||||
| L4 | Skärm som spelar upp video | Fail — moiré-mönster + platt | |
|
||||
| L5 | AI-genererad bild (DALL-E/Midjourney) | Fail — inga sensordata | |
|
||||
| L6 | Zoom/Teams-samtal som visar objektet | Fail — kompression + latens | |
|
||||
| L7 | Äkta video men fel plats (GPS-spoof) | Fail — GPS matchar ej | |
|
||||
| L8 | Äkta video men för gammalt (timestamp) | Fail — timestamp-drift | |
|
||||
|
||||
### Liveness-signaler att mäta
|
||||
|
||||
```
|
||||
Parallax-detektionsrate: X%
|
||||
Gyro-avvikelse från naturlig rörelse: X%
|
||||
Fokusförändrings-frekvens: X/min
|
||||
GPS-timestamp-korrelation: X%
|
||||
Challenge-respons-pass-rate (äkta): X%
|
||||
Challenge-respons-pass-rate (attack): X%
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Fas 4 fullständig — 50 verkliga uppdrag
|
||||
|
||||
Upprepa pilot-processen på 50 uppdrag från verkliga kundkategorier:
|
||||
|
||||
| Kategori | Antal | Datakrav formulerade? |
|
||||
|----------|-------|-----------------------|
|
||||
| Fastighetsfasader | 10 | |
|
||||
| Infrastruktur (skyltar, vägmärken) | 10 | |
|
||||
| Fordon | 10 | |
|
||||
| Industrimaskiner | 10 | |
|
||||
| Maritim säkerhet | 5 | |
|
||||
| Retail/butiker | 5 | |
|
||||
|
||||
**Frågan per uppdrag:** Kan vi formulera detta som datakrav (inte bildkrav)?
|
||||
|
||||
Kill: <80% översättningsbara → affärsmodellen håller inte.
|
||||
|
||||
---
|
||||
|
||||
## Audit-verktyget (minimalt)
|
||||
|
||||
Bygg detta, inte Smart Scan:
|
||||
|
||||
```
|
||||
Video in (upload)
|
||||
↓
|
||||
Manuell taggning per datapunkt (UI: checkbox + confidence slider)
|
||||
↓
|
||||
Automatisk sammanräkning mot claim-kraven
|
||||
↓
|
||||
Output: covered ✓ / missing ✗ / partial ~ per datapunkt
|
||||
↓
|
||||
Aggregerat per objekt-typ
|
||||
```
|
||||
|
||||
Stack: enkel HTML-sida + SQLite. En dag att bygga. Kör 1000 videor på den.
|
||||
|
||||
---
|
||||
|
||||
## Tidslinje
|
||||
|
||||
```
|
||||
Dag 1: Fas 4 pilot (5 claims) → datakravsmall klar
|
||||
Dag 2–3: Fas 1 WoZ (20 uppdrag, 2 objekt-typer)
|
||||
Dag 4: Utvärdering Fas 1 — kill check
|
||||
Dag 5–10: Fas 2 evidensaudit (100 sekvenser)
|
||||
Dag 11: Fas 3 liveness (8 attackscenarier)
|
||||
Dag 12: Fas 4 fullständig (50 uppdrag)
|
||||
Dag 13: Sammanställning → go/kill per komponent
|
||||
```
|
||||
|
||||
**Innan dag 14 byggs inget mer av Smart Scan.**
|
||||
|
||||
---
|
||||
|
||||
*Bygger på: QUIXZOOM_VISION.md, QUIXZOOM_AVO_MASTERPROMPT_V3.md*
|
||||
*Nästa steg: Bygg audit-verktyget (dag 1, en dag).*
|
||||
Reference in New Issue
Block a user