feat(ai): add AI trace tracking and admin panel
- Add AiTrace model to Prisma schema with relations to User - Implement AiTraceService with CRUD operations for AI traces - Add new admin panel for AI traces with filtering and detail views - Integrate trace persistence in receipt import flow - Add API endpoints for listing and retrieving AI traces - Update Flutter admin UI with new AI tab and navigation - Add new domain models for AI traces and details - Add migration for AiTrace table creation BREAKING CHANGE: None
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
# Plan: Separat Admin-AI huvudtabb + AI-insyn för Kvitto/Flyer
|
||||
|
||||
## Mål
|
||||
- Flytta ut `AI` från `Admin > Databas` till en egen huvudtabb i admin (samma nivå som `Users` och `Database`).
|
||||
- På nya `AI`-fliken visa två underflikar:
|
||||
- `Kvitto` (AI-funktioner för receipt-import)
|
||||
- `Flyer` (AI-funktioner för flyer-import)
|
||||
- Ge admin insyn i:
|
||||
- Prompt (vad modellen fick)
|
||||
- Output (vad modellen returnerade)
|
||||
- Per import/sessionshistorik
|
||||
|
||||
## Nuvarande läge (verifierat)
|
||||
- Huvudtabbar i admin definieras i:
|
||||
- `flutter/lib/features/admin/presentation/admin_screen.dart`
|
||||
- `flutter/lib/core/ui/app_shell.dart`
|
||||
- `AI` ligger idag som intern databas-tab i:
|
||||
- `flutter/lib/features/admin/presentation/admin_database_panel.dart`
|
||||
- Nuvarande `AdminAiPanel` visar bara modellinfo:
|
||||
- `flutter/lib/features/admin/presentation/admin_ai_panel.dart`
|
||||
- Flyer har sessions-API och sparar parsat resultat, men ingen API-yta för prompt/output:
|
||||
- `backend/src/flyer-import/flyer-import.controller.ts`
|
||||
- `backend/src/flyer-import/dto/flyer-import.response.ts`
|
||||
- Receipt-import har ingen sessionhistorik i recipe-api och ingen prompt/output i svar:
|
||||
- `backend/src/receipt-import/receipt-import.controller.ts`
|
||||
- `backend/src/receipt-import/dto/parsed-receipt-item.dto.ts`
|
||||
|
||||
## UX-förslag (enkelt och snyggt)
|
||||
- Ny huvudflik `AI` i admin med tydlig struktur:
|
||||
- Topp: två chips/segmenterade knappar `Kvitto` och `Flyer`
|
||||
- Innehåll: 2-kolumnslayout på desktop, enkel stack på mobil
|
||||
- Vänster: lista med senaste importer (tid, användare, fil, status)
|
||||
- Höger: detaljer för vald import
|
||||
- Detaljvyn har tre kort:
|
||||
1. **Prompt** (monospace, copy-knapp, expand/collapse)
|
||||
2. **Model Output** (formatterad JSON, copy-knapp)
|
||||
3. **Sammanfattning** (modell, duration, chunk/retry, warnings)
|
||||
- Filter högst upp:
|
||||
- Källa: Kvitto/Flyer
|
||||
- Period: senaste 24h / 7d / 30d
|
||||
- Endast fel
|
||||
- Default-beteende:
|
||||
- Välj senaste import automatiskt
|
||||
- Visa läs-only data (ingen redigering av prompt i denna iteration)
|
||||
|
||||
## Föreslagen implementation
|
||||
|
||||
### 1) Flutter: ny Admin-huvudtabb AI
|
||||
1. Utöka enum och query-hantering:
|
||||
- `AdminViewTab` får `ai`
|
||||
- query-stöd: `?tab=ai`
|
||||
2. Uppdatera admin-title chips i `AppShell`:
|
||||
- Lägg till `AI` bredvid `Användare` och `Databas`
|
||||
3. Rendra ny panel i `AdminScreen`:
|
||||
- `AdminAiPanel` blir panel för huvudtabben
|
||||
4. Ta bort AI från `AdminDatabasePanel` interna tabs
|
||||
|
||||
Berörda filer:
|
||||
- `flutter/lib/features/admin/presentation/admin_screen.dart`
|
||||
- `flutter/lib/core/ui/app_shell.dart`
|
||||
- `flutter/lib/features/admin/presentation/admin_database_panel.dart`
|
||||
|
||||
### 2) Flutter: bygg om `AdminAiPanel` till AI-observability
|
||||
1. Inför underflikar `Kvitto` / `Flyer`
|
||||
2. Lägg till vänster lista + höger detalj
|
||||
3. Lägg till komponenter:
|
||||
- `PromptCard` (text/copy)
|
||||
- `OutputJsonCard` (pretty JSON/copy)
|
||||
- `TraceMetaCard` (modell, tid, status)
|
||||
4. Lägg till `adminRepository`-metoder för att hämta traces
|
||||
|
||||
Berörda filer:
|
||||
- `flutter/lib/features/admin/presentation/admin_ai_panel.dart`
|
||||
- `flutter/lib/features/admin/data/admin_repository.dart`
|
||||
- `flutter/lib/core/api/api_paths.dart`
|
||||
- ev. nya domänmodeller under `flutter/lib/features/admin/domain/`
|
||||
|
||||
### 3) Backend: exponera AI trace-data (admin-only)
|
||||
1. Lägg till admin-endpoints för trace-lista + detalj
|
||||
2. Returnera prompt/output samt metadata
|
||||
3. Begränsa åtkomst till admin
|
||||
|
||||
Föreslagen API-yta:
|
||||
- `GET /ai/traces?source=receipt|flyer&limit=...&cursor=...`
|
||||
- `GET /ai/traces/:id`
|
||||
|
||||
### 4) Datalagring för prompt/output
|
||||
För stabil UX behövs persistens, inte bara loggar.
|
||||
|
||||
Föreslagen modell:
|
||||
- Ny Prisma-tabell `AiTrace`
|
||||
- `id`, `source` (`receipt`/`flyer`), `userId`, `sessionId?`, `model`, `prompt`, `rawOutput`, `normalizedOutput`, `status`, `error`, `durationMs`, `createdAt`
|
||||
|
||||
Integration:
|
||||
- Flyer: skapa trace i `AiFlyerParserService` vid varje AI-anrop/chunk (sammanfatta till en sessionsrad eller flera child-rader)
|
||||
- Receipt: recipe-api behöver trace från importer-service eller egen instrumentation av prompt/output
|
||||
|
||||
## Viktig teknisk avgränsning (receipt)
|
||||
- I nuvarande repo byggs flyer-prompt i `recipe-api` och är enkel att visa.
|
||||
- Receipt-AI sker i importer-flöde; prompt/output finns sannolikt inte i recipe-api idag.
|
||||
- Därför två realistiska steg:
|
||||
1. **Steg 1 (snabbt):** full trace-visning för Flyer + modellinfo för Kvitto
|
||||
2. **Steg 2:** utöka receipt/importer så prompt/output skickas eller lagras som trace och visas i samma UI
|
||||
|
||||
## Säkerhet
|
||||
- Endast admin får läsa traces.
|
||||
- Prompt/output kan innehålla känslig text från uppladdade filer:
|
||||
- visa som read-only
|
||||
- möjlighet till maskning av persondata i senare steg
|
||||
- paginering + kort retention (t.ex. 30 dagar) rekommenderas
|
||||
|
||||
## Testplan
|
||||
- Flutter widget-test:
|
||||
- Ny huvudtabb `AI` syns och route `?tab=ai` fungerar
|
||||
- Underflikar `Kvitto`/`Flyer` växlar korrekt
|
||||
- Prompt/output renderas och copy-knappar fungerar
|
||||
- Backend tester:
|
||||
- admin-only behörighet på trace-endpoints
|
||||
- lista/detalj svarar korrekt
|
||||
- trace skapas för flyer parse-flöde
|
||||
- Regression:
|
||||
- Admin `Users`/`Database` fungerar oförändrat
|
||||
|
||||
## Genomförandeordning
|
||||
1. Flytta AI till huvudtabb i Flutter (utan backend-ändring först)
|
||||
2. Bygg ny AI-panelstruktur med underflikar
|
||||
3. Inför backend trace-endpoints + Prisma-migration
|
||||
4. Koppla Flyer trace end-to-end
|
||||
5. Koppla Receipt trace (beroende på importer-instrumentation)
|
||||
6. Sluttest + docs
|
||||
|
||||
## Rekommenderat beslut inför implementation
|
||||
- Implementera i två faser för låg risk:
|
||||
- Fas A: Ny UX + full Flyer-insyn direkt
|
||||
- Fas B: Receipt prompt/output när importer-trace är tillgänglig
|
||||
Reference in New Issue
Block a user