BC11 - TEKNISK ARKITEKTUR
BC11 - AI-driven Leverantörsfakturahantering (Hybrid-modell)
Projektkod: FAKTURA-2025-BC11
Version: 1.0
Datum: 2025-10-25
Arkitekt: Lars Diethelm
Status: Godkänd för implementation
Sammanfattning
Arkitekturval
Plattform: Optimate Core - Hub-and-Spoke Architecture
- Motivering: Modularitet och separation av capability (core) och configuration (kundspecifik logik). Beprövad i organisationen.
AI-plattform: Anthropic Claude Sonnet 4 (primär) + Ollama (lokal backup/embeddings)
- Motivering: Claude optimal för OCR och komplex fakturaanalys. Ollama som fallback och för embeddings/vektorsökning. LLM-agnostisk arkitektur.
Orkestrering (Hub): n8n
- Motivering: Visuell workflow-design för BC11-specifik affärslogik. Separation från core capability. Enkel anpassning och underhåll.
Capability Layer (Spokes): Optimate Core Engines (FastAPI Microservices)
- Ingestion Engine: Faktura-PDF parsing, OCR, dokumenthantering
- Agentic Engine: RAG-pipeline, AI-validering, projektnummerdetektion, konfidensgrad-beräkning
Deployment: Docker Compose (On-Premise) eller Render (Cloud)
- Motivering: Fas 4 börjar med Render för snabb deployment. Möjlighet till on-premise migration i framtiden om datakänslighetskrav ökar.
Säkerhet: Render Private Network (cloud) eller Cloudflare Tunnel (on-premise)
- Motivering: Säker kommunikation mellan services utan publika endpoints. Identity management via Keycloak (future).
Klassificering: Intern business data (ej offentlig men ej heller känslig enligt GDPR)
- Kryptering: TLS 1.3 för transit, AES-256 för lagring av API-nycklar
Huvudkomponenter (Optimate Core)
Hub Layer:
- n8n: BC11-specifika workflows (polling, beslutspunkter, reklamationer)
Capability Layer (Core Spokes):
- Ingestion Engine (FastAPI): PDF-parsing, OCR, Fortnox/WorkCloud-integration
- Agentic Engine (FastAPI): AI-validering, RAG-pipeline, projektnummerdetektion
- PostgreSQL (Supabase/Managed): Fakturalog, AI-beslut, projektcache, historik
- Qdrant: Vektordatabas för semantisk sökning i projekthistorik och fakturakontext
- Ollama: Lokal LLM för embeddings och backup-inferens
- Django (optional): Human-in-the-Loop UI för Matildas fakturahantering
External Integrations:
- Fortnox API, WorkCloud API, Microsoft Graph, Anthropic Claude API
1. Arkitekturöversikt
Konceptuell arkitektur (Optimate Core - Hub-and-Spoke)
┌─────────────────────────────────────────────────────────┐
│ PRESENTATION LAYER │
│ Django HIL Interface (Matildas portal) │
│ Custom React-komponenter │
└─────────────────┬───────────────────────────────────────┘
│ HTTPS (Render Private Network / Cloudflare Tunnel)
│
┌─────────────────▼───────────────────────────────────────┐
│ HUB LAYER (Configuration) │
│ n8n │
│ BC11-specifika workflows: Polling, Beslutspunkter, │
│ Reklamationer, Manuell godkännande │
└──┬────────┬─────────┬──────────┬────────────────────────┘
│ │ │ │
│ API │ API │ API │ API
│ │ │ │
┌──▼────────▼─────────▼──────────▼────────────────────────┐
│ CAPABILITY LAYER (Core Spokes) │
│ Optimate Core Engines │
│ │
│ ┌──────────────────┐ ┌────────────────────┐ │
│ │ Ingestion Engine │ │ Agentic Engine │ │
│ │ (FastAPI) │ │ (FastAPI) │ │
│ │ │ │ │ │
│ │ • PDF Parsing │ │ • RAG Pipeline │ │
│ │ • OCR (Claude) │ │ • AI-validering │ │
│ │ • Fortnox API │ │ • Projektnr-det. │ │
│ │ • WorkCloud API │ │ • Konfidens-kalk. │ │
│ └──────────────────┘ └────────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ Claude API │ │ Ollama │ │ Qdrant │ │
│ │ (Primär AI) │ │ (Embeddings │ │ (Vektor- │ │
│ │ │ │ + Backup AI)│ │ databas) │ │
│ └──────────────┘ └──────────────┘ └────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ PostgreSQL / Supabase │ │
│ │ (fakturalog, AI-beslut, cache, metadata) │ │
│ └─────────────────────────────────────────────────┘ │
└───────────────────┬─────────────────────────────────────┘
│
┌───────────────────▼─────────────────────────────────────┐
│ EXTERNAL INTEGRATIONS │
│ (anropas via Ingestion/Agentic Engines) │
│ │
│ Fortnox API │ WorkCloud API │ Microsoft Graph │
└──────────────────────────────────────────────────────────┘
Säker åtkomst (Render Cloud):
[Internet] → [Render Load Balancer] → [Private Network] →
[n8n + Django + Core Engines]
(Inga publika endpoints utom load balancer)
Säker åtkomst (On-Premise):
[Internet] → [Cloudflare Tunnel] → [Docker Network] →
[n8n + Django + Core Engines + PostgreSQL]
Hub-and-Spoke fördelar för BC11:
- Separerad affärslogik: BC11 workflows i n8n (configuration)
- Återanvändbara capabilities: Ingestion/Agentic engines används av flera kunder
- Enkel uppdatering: Core engines uppdateras centralt, BC11 workflows påverkas ej
- Skalbarhet: Fler fakturor/kunder = fler n8n workers, samma core engines
Teknisk stack (Optimate Core)
| Lager | Teknologi | Produkt/Ramverk | Version | Motivering |
|---|---|---|---|---|
| Hub (Configuration) | ||||
| Orkestrering | n8n | n8n | Latest | Visuell workflow för BC11-specifik affärslogik |
| Capability (Core Spokes) | ||||
| Core Engines | FastAPI | Optimate Ingestion Engine | 1.x | PDF-parsing, OCR, API-integration |
| Core Engines | FastAPI | Optimate Agentic Engine | 1.x | RAG, AI-validering, projektnummerdetektion |
| AI - Primär | Claude API | Anthropic Sonnet 4 | Latest | Bäst för OCR och NLP, kontextuell förståelse |
| AI - Lokal | Ollama | Llama 3.1/Mistral | Latest | Embeddings + backup-inferens, privacy-first |
| Vektordatabas | Qdrant | Qdrant | Latest | Snabb semantisk sökning, metadata-filtrering |
| Databas (Cloud) | PostgreSQL | Render Managed | 15.x | Relationsdatabas, managed service |
| Databas (On-Prem) | Supabase | Supabase Stack | Latest | PostgreSQL + auth + storage, self-hosted |
| Presentation | ||||
| Frontend | Django | Django | 4.x | Human-in-the-Loop för Matildas fakturahantering |
| Infrastructure | ||||
| Cloud Deployment | Render | Render | - | Managed private network, auto-scaling |
| On-Prem Security | Cloudflare | Cloudflare Tunnel | Latest | Säker access utan publika IP |
| Identity (Future) | Keycloak | Keycloak | Latest | SSO, centraliserad användarhantering |
| Containerisering | Docker | Docker Compose | Latest | Portabel mellan miljöer |
| Version Control | Git | GitHub | Latest | Three-repo strategy (core, template, customer) |
| Observability | LangSmith | LangSmith | Latest | AI interaction tracking, debugging |
2. AI-komponenter (Optimate Core)
Capability Architecture (Core Spokes)
Optimate Core separerar AI-kapacitet i återanvändbara microservices (spokes) som exponerar sina funktioner via REST API:er. BC11 använder följande core engines:
1. Ingestion Engine (FastAPI Microservice)
- Ansvar: Data intake, dokumentparsing, API-integration med externa system
- BC11-funktioner:
- PDF-parsing av fakturor från Fortnox Archive
- OCR via Claude Vision API
- Fortnox API-integration (polling, läsa fakturor/projekt/leverantörer)
- WorkCloud API-integration (projektregister, arbetsordrar)
- Metadata-extrahering och strukturering
- API-endpoints för BC11:
POST /api/v1/ingest/fortnox-invoice- Parse faktura-PDF + hämta metadataGET /api/v1/integrations/fortnox/invoices- Poll nya fakturorGET /api/v1/integrations/fortnox/projects- Hämta projektregisterGET /api/v1/integrations/workcloud/projects- Hämta från WorkCloud (eller CSV fallback)
- Prestanda: <5s för PDF-parsing + OCR per faktura
- Deployment: Docker container, skalas horisontellt vid behov
2. Agentic Engine (FastAPI Microservice)
- Ansvar: AI-driven reasoning, RAG-pipeline, beslutspunkter, validering
- BC11-funktioner:
- RAG-pipeline för projektnummerdetektion i fakturafritext
- Semantisk sökning i Qdrant (historisk leverantörs-projektmappning)
- AI-validering via Claude Sonnet 4 eller Ollama (fallback)
- Konfidensgrad-beräkning (≥95%, 80-94%, 60-79%, <60%)
- Referenspersons-validering
- Adress- och momsvalidering
- Reklamationsgenerering (AI-driven text)
- API-endpoints för BC11:
POST /api/v1/agent/validate-invoice- Fullständig AI-validering av fakturaPOST /api/v1/agent/detect-project- Projektnummerdetektion med RAGPOST /api/v1/agent/generate-complaint- Generera reklamationsmejlGET /api/v1/agent/confidence-threshold- Hämta/sätt konfidenstreshold
- Prestanda: <30s för komplett AI-analys (inkl. RAG-retrieval)
- Deployment: Docker container med GPU-stöd (optional för Ollama)
AI-modeller och tjänster
Modell 1: Claude Sonnet 4 (Primär AI - External API)
- Typ: Multimodal LLM (Vision + Text)
- Användning i BC11:
- OCR av faktura-PDF:er
- Projektnummerdetektion i fritext
- Kontextuell förståelse av fakturalayout
- Reklamationsgenerering
- Träningsdata (Prompt Context):
- 100+ anonymiserade exempelfakturor med projektnummer i fritext
- Projektregister från WorkCloud (1000+ projekt)
- Leverantörs-projekthistorik 12-24 månader från Fortnox
- Valideringsregler och beslutspunkter
- Prestanda:
- Målsättning: 80-90% träffsäkerhet
- Observerat: 85-95% med god prompt engineering
- Deployment: External API (Anthropic)
- Cost: ~$3-5 per 1000 requests (mid-tier plan)
Modell 2: Ollama (Lokal LLM - Backup + Embeddings)
- Modeller:
- Llama 3.1 8B: Backup för fakturaanalys om Claude ej tillgänglig
- nomic-embed-text: Text embeddings för Qdrant-vektorsökning
- Användning i BC11:
- Embeddings av projektnamn, fakturafritext, leverantörsinfo
- Backup-inferens vid Claude API-fel
- Privacy-first alternativ för känsliga fakturor (future)
- Träningsdata:
- Pre-trained modeller (ingen local fine-tuning i Fas 4)
- Context via RAG från Qdrant
- Prestanda:
- Embeddings: <1s per text chunk
- Inferens: 5-10s per faktura (CPU), <2s med GPU
- Deployment: Docker container lokalt eller på Render
- Cost: Infrastrukturkostnad endast (ingen API-avgift)
Modell 3: Regelbaserad validering (Hybrid)
- Typ: Python-logik med AI-assistans för edge cases
- Användning i BC11:
- Adressvalidering (match mot officiell lista)
- Momsvalidering (omvänd skattskyldighet, procentsatser)
- Projektstatus-kontroll (aktivt/inaktivt/ersatt)
- WW-prefixigenkänning (arbetsordrar)
- Prestanda: 95%+ accuracy (enklare problem)
- Deployment: Del av Agentic Engine
AI-pipeline (n8n → Core Engines → AI)
[Fortnox - Faktura inkommer]
↓
[n8n Schedule Trigger: Var 5:e minut]
↓
[n8n HTTP Request → Ingestion Engine]
POST /api/v1/integrations/fortnox/invoices?lastmodified={ts}
Response: Lista nya fakturor
↓
[n8n Loop: För varje ny faktura]
│
├─► [n8n HTTP → Ingestion Engine]
│ POST /api/v1/ingest/fortnox-invoice
│ Input: {invoice_number, fetch_pdf: true}
│ Output: {pdf_base64, metadata, ocr_text}
│
├─► [n8n HTTP → Agentic Engine]
│ POST /api/v1/agent/validate-invoice
│ Input: {
│ invoice_data: {...},
│ pdf_base64: "...",
│ context: {
│ projects: [...], # Från Ingestion Engine
│ supplier_history: [...], # Från Qdrant via Agentic Engine
│ validation_rules: {...}
│ }
│ }
│ Output: {
│ detected_project: "1313",
│ confidence: 0.92,
│ reasoning: "...",
│ alternatives: [{project: "1272", conf: 0.65}],
│ flags: ["project_inactive"]
│ }
│
├─► [n8n Function Node: Beslutspunkt baserat på confidence]
│ IF confidence >= 0.95:
│ action = "auto_approve"
│ ELSE IF confidence >= 0.80:
│ action = "suggest"
│ ELSE IF confidence >= 0.60:
│ action = "list_alternatives"
│ ELSE:
│ action = "manual_review"
│
├─► [n8n Switch Node: Beslutsväg]
│ │
│ ├─► [auto_approve] → [n8n HTTP → Ingestion Engine]
│ │ PUT /api/v1/integrations/fortnox/invoice/{id}
│ │ Update projektnummer i Fortnox
│ │
│ └─► [suggest/list/manual] → [n8n → PostgreSQL]
│ Spara för Matildas granskning i Django UI
│
└─► [n8n → PostgreSQL: Logga AI-beslut]
INSERT INTO ai_decisions_log (...)
│
└─► [n8n HTTP → Agentic Engine]
POST /api/v1/agent/update-embeddings
Uppdatera Qdrant med nytt projektnummer-exempel
[Django HIL UI: Matilda granskar flaggade fakturor]
↓
[n8n Webhook: Matilda godkänner/nekar]
↓
[n8n → Ingestion Engine: Uppdatera Fortnox ELLER Skicka reklamation]
↓
[n8n → PostgreSQL: Logga manuellt beslut för AI-träning]
Fördelar med Core Engine-approach:
- Separation of Concerns: BC11 workflows i n8n, AI-logik i engines
- Återanvändbarhet: Samma engines används för andra projekt
- Testbarhet: Engines kan testas isolerat via API
- Skalbarhet: Engines kan skalas oberoende av n8n
- Underhåll: Uppdatera engine-kod utan att röra BC11 workflows
AI-pipeline (n8n Workflow)
[Fortnox - Faktura inkommer]
↓
[n8n Schedule Trigger: Var 5:e minut]
↓
[n8n HTTP Request: Poll Fortnox /supplierinvoices?lastmodified={timestamp}]
↓
[n8n Function Node: Filter nya fakturor]
↓
[n8n Loop: För varje ny faktura]
│
├─► [n8n HTTP Request: Hämta faktura-PDF från Fortnox Archive]
│
├─► [n8n Supabase: Läs projektcache från PostgreSQL]
│
├─► [n8n Qdrant: Hämta historisk leverantörs-projektmappning (embeddings)]
│
├─► [n8n Function Node: Bygg kontext för AI]
│ - Projektregister
│ - Leverantörshistorik
│ - Tidigare fakturor
│
├─► [n8n HTTP Request: Claude API - Analysera faktura + kontext]
│ Input: base64 PDF + strukturerad prompt
│ Output: JSON {projektnummer, konfidensgrad, resonemang}
│
├─► [n8n Function Node: Konfidensgrad-beräkning och beslutspunkt]
│ ≥95%: Auto-godkänn
│ 80-94%: Föreslå
│ 60-79%: Lista alternativ
│ <60%: Flagga manuell
│
├─► [n8n Switch Node: Beslutsväg]
│ │
│ ├─► [≥95%] → [n8n Fortnox: Uppdatera faktura med projektnummer]
│ │
│ └─► [<95%] → [n8n Supabase: Spara för manuell granskning i OpenUI]
│
└─► [n8n Supabase: Logga AI-beslut i ai_decisions_log]
│
└─► [n8n Qdrant: Uppdatera embeddings med nytt projektnummer-exempel]
[OpenUI Portal: Matilda granskar flaggade fakturor]
↓
[n8n Webhook: Matilda godkänner/nekar]
↓
[n8n Fortnox: Uppdatera ELLER Skicka reklamation via Microsoft Graph]
↓
[n8n Supabase: Logga manuellt beslut för AI-träning]
n8n Workflow-komponenter:
- Schedule Trigger: Kör var 5:e minut
- HTTP Request nodes: Fortnox, WorkCloud, Claude, Microsoft Graph
- Supabase nodes: Databas-CRUD operationer
- Qdrant nodes: Vektor-sökning och uppdateringar
- Function nodes: JavaScript för affärslogik
- Switch nodes: Beslutspunkter baserade på konfidensgrad
- Webhook nodes: Mottagning från OpenUI
MLOps-struktur (Optimate Core)
Three-Repository Strategy:
Optimate Core följer en strategisk tre-repository-modell som separerar core product från kundkonfiguration:
optimate-core(Privat, central)- All proprietär källkod för Ingestion Engine och Agentic Engine
- FastAPI microservices, shared libraries, utilities
- CI/CD för att bygga och publicera versionerade Docker images
- BC11-utveckling sker här (nya features i engines)
optimate-customer-template(Privat, mall)- Standardiserad blueprint för deployment
docker-compose.yml(on-premise) ochrender.yaml(cloud)- Refererar till versionerade Docker images från optimate-core
- Mall för
.env-konfiguration
customer-prolux-bc11-site(Privat, kundspecifik)- Skapad från template-repository
- BC11-specifika n8n workflows (JSON-export)
- Kundspecifik
.envmed API-nycklar och secrets - Site-dokumentation och backup-historik
- Deployment-konfiguration för Render eller on-premise
Versionshantering (BC11-specifikt):
customer-prolux-bc11-site/
├── infra/
│ ├── docker-compose.yml # Refererar optimate-core images
│ └── render.yaml # Cloud deployment config
├── n8n/workflows/
│ ├── 01-poll-fortnox.json
│ ├── 02-ai-validate.json
│ ├── 03-manual-review-webhook.json
│ └── 04-send-complaint.json
├── config/
│ ├── ingestion-engine.yml # BC11-specifik config för engine
│ ├── agentic-engine.yml # RAG settings, confidence thresholds
│ └── validation-rules.json # Projektnummer-regler, mönster
├── data/
│ ├── training-examples/ # 100+ exempelfakturor
│ └── project-register-cache/ # WorkCloud-export
├── backup/
│ └── [Auto-genererade backups]
├── site-docs/
│ └── BC11-Setup.md
└── .env # Secrets (ej i Git)
CI/CD för Core Updates:
[optimate-core commit]
↓
[GitHub Actions: Build & Test]
↓
[Docker build → Push to registry]
Tag: ingestion-engine:1.2.3
Tag: agentic-engine:1.2.3
↓
[Dependabot PR till optimate-customer-template]
Update image version i docker-compose.yml
↓
[Manual review & approve]
↓
[Dependabot cascade till ALL customer sites]
PR: "Update ingestion-engine 1.2.2 → 1.2.3"
↓
[Customer site auto-test (staging)]
↓
[Manual deploy to production]
docker-compose pull
docker-compose up -d
CI/CD för BC11 Workflow Changes:
[n8n workflow edited via UI]
↓
[n8n automated export (nightly)]
API: GET /api/v1/workflows → JSON
↓
[Git commit to customer-prolux-bc11-site]
commit: "Updated poll-fortnox workflow"
↓
[GitHub Actions: Validate JSON]
↓
[Push to main branch]
Observability & Quality (LangSmith):
- All AI-interaktion trackas via LangSmith
- Varje Claude/Ollama-anrop loggat med:
- Input prompt + context
- Output response
- Latency, tokens used, cost
- User feedback (Matildas korrigeringar)
- Dashboard: AI accuracy over time, false positives, confidence distribution
- Automatic alerts vid degraderad prestanda (<75% accuracy)
Monitoring:
- Core Engines: FastAPI built-in metrics → Prometheus
- n8n: Execution logs → PostgreSQL
- Qdrant: Query latency metrics
- PostgreSQL: Supabase dashboard (cloud) eller pgAdmin (on-premise)
Träning och förbättring:
- Matildas manuella beslut loggas i PostgreSQL
- Weekly/monthly prompt optimization baserat på LangSmith data
- Qdrant-embeddings uppdateras automatiskt med nya fakturaexempel
- Kvartalsvis utvärdering: AI accuracy, cost per faktura, time saved
3. Systemintegration
Integrationspunkter
| System | Typ | Protokoll | Frekvens | Datavolym | Kritikalitet |
|---|---|---|---|---|---|
| Fortnox | Källa + Mål | REST API | Polling 5 min | 250 fakt/mån | Hög |
| WorkCloud | Källa | REST API (eller CSV fallback) | Polling 1h | 1000+ projekt | Hög |
| Microsoft Graph | Mål | REST API | On-demand | 5-10 email/dag | Medium |
| Anthropic Claude | Tjänst | REST API | Per faktura | 250 req/mån | Hög |
API-specifikation
API 1: Fortnox - Läsa leverantörsfakturor
endpoint: /3/supplierinvoices
method: GET
authentication: Access-Token + Client-Secret (Headers)
query params:
- lastmodified: {ISO 8601 datetime} (för polling)
- project: {projectNumber} (optional filtering)
request headers:
Access-Token: {API_KEY}
Client-Secret: {CLIENT_SECRET}
Content-Type: application/json
response: 200 OK
content-type: application/json
schema:
type: object
properties:
SupplierInvoices:
type: array
items:
type: object
properties:
GivenNumber: string
SupplierNumber: string
SupplierName: string
InvoiceDate: string (date)
DueDate: string (date)
Total: number
Balance: number
Project: string (ofta tomt - PROBLEMET)
Booked: boolean
rate_limit: 25 req/5s, 300 req/min
API 2: Fortnox - Hämta faktura-PDF
endpoint 1: /3/supplierinvoicefileconnections
method: GET
query params:
- supplierinvoicenumber: {GivenNumber}
response: FileId för PDF
endpoint 2: /3/archive/{FileId}
method: GET
response: PDF byte stream (binary)
API 3: Fortnox - Uppdatera faktura med projektnummer
endpoint: /3/supplierinvoices/{GivenNumber}
method: PUT
authentication: Access-Token + Client-Secret
request body:
{
"SupplierInvoice": {
"Project": "1313",
"Comments": "AI-validerad: 95% konfidens, Projekt: Stender VB 1966"
}
}
response: 200 OK (uppdaterad faktura)
API 4: WorkCloud - Läsa projektregister
endpoint: /api/projects (BEHÖVER VERIFIERAS)
method: GET
authentication: TBD (API-nyckel eller OAuth)
query params:
- status: active|inactive|completed
- updated_since: {ISO 8601 datetime}
response:
{
"projects": [
{
"projectNumber": "1313",
"projectName": "Stender VB 1966",
"projectLeader": "Jasmine Andersson",
"status": "active",
"startDate": "2024-08-01",
"endDate": "2025-02-28",
"customer": "Stender Fastigheter AB",
"address": "Symmetrivägen 19, Uppsala"
}
]
}
FALLBACK (om API saknas):
- Manuell CSV-export dagligen från WorkCloud
- Import till PostgreSQL via scheduled task
- Data max 24h gammal (acceptabelt)
API 5: Microsoft Graph - Skicka reklamation
endpoint: /v1.0/me/sendMail
method: POST
authentication: OAuth 2.0 (Bearer token)
request body:
{
"message": {
"subject": "Reklamation faktura {invoiceNumber}",
"body": {
"contentType": "HTML",
"content": "{genererad_professionell_text}"
},
"toRecipients": [
{
"emailAddress": {
"address": "[email protected]"
}
}
],
"attachments": [
{
"name": "Faktureringsriktlinjer.pdf",
"contentBytes": "{base64_encoded_pdf}"
}
]
}
}
response: 202 Accepted (email i kö)
API 6: Anthropic Claude - AI-analys
endpoint: https://api.anthropic.com/v1/messages
method: POST
authentication: x-api-key (Header)
request body:
{
"model": "claude-sonnet-4-20250514",
"max_tokens": 2000,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "application/pdf",
"data": "{base64_faktura_pdf}"
}
},
{
"type": "text",
"text": "{strukturerad_prompt_med_kontext}"
}
]
}
]
}
response:
{
"content": [
{
"type": "text",
"text": "{JSON_svar_med_projektnummer_och_konfidens}"
}
]
}
rate_limit: Beroende på Anthropic-plan, troligen 1000+ req/dag
Meddelandeflöden
Flöde 1: Ny faktura → AI-analys
[Fortnox] --webhook simulerad via polling--> [Backend Polling Service]
Meddelande: Ny faktura tillgänglig (GivenNumber: 12345)
Format: JSON via REST
[Backend] --fetch PDF--> [Fortnox Archive API]
Meddelande: Hämta PDF för faktura 12345
Format: Binary PDF
[Backend] --fetch context--> [PostgreSQL Cache]
Meddelande: Hämta projektregister, leverantörshistorik
Format: SQL query result
[Backend] --AI request--> [Claude API]
Meddelande: Analysera faktura + kontext
Format: JSON med base64 PDF
Garanti: At-least-once (retry vid fel)
[Claude API] --response--> [Backend]
Meddelande: Projektnummer + konfidensgrad + resonemang
Format: JSON
[Backend] --decision--> [PostgreSQL]
Meddelande: Logga AI-beslut
Format: INSERT SQL
[Backend] --update OR flag-->
OM konfidensgrad ≥95%:
[Fortnox API] Uppdatera faktura med projektnummer
ANNARS:
[Frontend Portal] Visa i Matildas gränssnitt
Flöde 2: Manuell godkännande → Fortnox-uppdatering
[Matildas Portal] --user action--> [Backend API]
Meddelande: Godkänn faktura 12345 med projekt 1313
Format: HTTP POST /api/invoices/{id}/approve
[Backend] --update--> [Fortnox API]
Meddelande: Uppdatera projektnummer
Format: PUT /3/supplierinvoices/{GivenNumber}
[Backend] --log--> [PostgreSQL]
Meddelande: Logga manuellt beslut
Format: UPDATE SQL
Flöde 3: Reklamation → Email
[Backend] --generate email--> [Email Template Engine]
Meddelande: Skapa reklamationsmejl baserat på felbeskrivning
Format: Python Jinja2 template
[Backend] --send email--> [Microsoft Graph API]
Meddelande: Skicka reklamation till leverantör
Format: HTTP POST /v1.0/me/sendMail
[Backend] --log--> [PostgreSQL]
Meddelande: Logga skickad reklamation
Format: INSERT SQL
4. Dataarkitektur
Dataflödesdiagram
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Fortnox │────▶│ Polling │────▶│ AI-analys │
│ (Källdata) │ │ (Backend) │ │ (Claude API) │
└──────────────┘ └──────────────┘ └──────┬───────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ PostgreSQL │◀────│ AI-resultat │
│ (Lagring) │ │ (JSON) │
└──────────────┘ └──────────────┘
│
▼
┌──────────────┐
│ Frontend │
│ (Matilda) │
└──────────────┘
Datamodell
Tabell 1: invoices
| Attribut | Typ | Beskrivning | Constraint |
|---|---|---|---|
| id | UUID | Unik identifierare (intern) | PRIMARY KEY |
| fortnox_invoice_number | VARCHAR(50) | GivenNumber från Fortnox | UNIQUE, NOT NULL |
| supplier_number | VARCHAR(50) | Leverantörsnummer | NOT NULL |
| supplier_name | VARCHAR(255) | Leverantörsnamn | NOT NULL |
| invoice_date | DATE | Fakturadatum | NOT NULL |
| due_date | DATE | Förfallodatum | NOT NULL |
| total_amount | DECIMAL(10,2) | Totalbelopp | NOT NULL |
| project_number | VARCHAR(10) | Projektnummer (AI-detekterat eller manuellt) | NULLABLE |
| status | ENUM | pending, ai_approved, manually_approved, rejected | NOT NULL |
| confidence_score | DECIMAL(3,2) | AI:s konfidensgrad (0.00-1.00) | NULLABLE |
| ai_reasoning | TEXT | AI:s resonemang | NULLABLE |
| pdf_file_id | VARCHAR(255) | FileId för PDF i Fortnox | NULLABLE |
| created_at | TIMESTAMP | Skapad tidpunkt | DEFAULT NOW() |
| updated_at | TIMESTAMP | Uppdaterad tidpunkt | DEFAULT NOW() |
| processed_by | VARCHAR(100) | ai, matilda, rebecka | NULLABLE |
Tabell 2: projects_cache
| Attribut | Typ | Beskrivning | Constraint |
|---|---|---|---|
| id | UUID | Unik identifierare | PRIMARY KEY |
| project_number | VARCHAR(10) | Projektnummer | UNIQUE, NOT NULL |
| project_name | VARCHAR(255) | Projektnamn | NOT NULL |
| project_leader | VARCHAR(100) | Projektledare | NULLABLE |
| status | ENUM | active, inactive, completed | NOT NULL |
| start_date | DATE | Startdatum | NULLABLE |
| end_date | DATE | Slutdatum | NULLABLE |
| address | VARCHAR(500) | Projektadress | NULLABLE |
| last_synced | TIMESTAMP | Senast synkad från WorkCloud | DEFAULT NOW() |
Tabell 3: workorders_cache
| Attribut | Typ | Beskrivning | Constraint |
|---|---|---|---|
| id | UUID | Unik identifierare | PRIMARY KEY |
| workorder_number | VARCHAR(10) | WW-nummer (ex: WW1245) | UNIQUE, NOT NULL |
| description | VARCHAR(500) | Beskrivning | NOT NULL |
| responsible | VARCHAR(100) | Ansvarig | NULLABLE |
| status | ENUM | active, inactive, completed | NOT NULL |
| location | VARCHAR(500) | Plats | NULLABLE |
| last_synced | TIMESTAMP | Senast synkad från WorkCloud | DEFAULT NOW() |
Tabell 4: supplier_project_history
| Attribut | Typ | Beskrivning | Constraint |
|---|---|---|---|
| id | UUID | Unik identifierare | PRIMARY KEY |
| supplier_number | VARCHAR(50) | Leverantörsnummer | NOT NULL |
| project_number | VARCHAR(10) | Projektnummer | NOT NULL |
| invoice_count | INTEGER | Antal fakturor historiskt | DEFAULT 0 |
| total_amount | DECIMAL(12,2) | Totalt fakturerat | DEFAULT 0 |
| last_invoice_date | DATE | Senaste fakturadatum | NULLABLE |
| created_at | TIMESTAMP | Skapad tidpunkt | DEFAULT NOW() |
Tabell 5: ai_decisions_log
| Attribut | Typ | Beskrivning | Constraint |
|---|---|---|---|
| id | UUID | Unik identifierare | PRIMARY KEY |
| invoice_id | UUID | Referens till invoices-tabell | FOREIGN KEY |
| decision_type | ENUM | auto_approved, suggested, flagged, rejected | NOT NULL |
| confidence_score | DECIMAL(3,2) | Konfidensgrad | NOT NULL |
| detected_project | VARCHAR(10) | Detekterat projektnummer | NULLABLE |
| alternative_projects | JSONB | Array av alternativa projekt | NULLABLE |
| ai_reasoning | TEXT | AI:s resonemang | NULLABLE |
| manual_override | BOOLEAN | Matilda överklagar AI | DEFAULT FALSE |
| correct_project | VARCHAR(10) | Korrekt projekt (för träning) | NULLABLE |
| timestamp | TIMESTAMP | Beslutstidpunkt | DEFAULT NOW() |
Tabell 6: email_log
| Attribut | Typ | Beskrivning | Constraint |
|---|---|---|---|
| id | UUID | Unik identifierare | PRIMARY KEY |
| invoice_id | UUID | Referens till invoices-tabell | FOREIGN KEY |
| recipient | VARCHAR(255) | Mottagare email | NOT NULL |
| subject | VARCHAR(500) | Emailämne | NOT NULL |
| body | TEXT | Emailtext | NOT NULL |
| sent_at | TIMESTAMP | Skickad tidpunkt | DEFAULT NOW() |
| status | ENUM | sent, failed, bounced | NOT NULL |
Datalagring
| Datatyp | Lagring | Retention | Backup | Kryptering |
|---|---|---|---|---|
| Fakturalog (invoices) | PostgreSQL | 7 år (bokföringskrav) | Daglig | AES-256 at rest |
| AI-beslut (ai_decisions_log) | PostgreSQL | 3 år | Daglig | AES-256 at rest |
| Projekt-cache | PostgreSQL | 2 år | Daglig | Ej nödvändigt (ej känslig) |
| PDF-filer | Fortnox Archive | 7 år | Fortnox-ansvar | TLS 1.3 in transit |
| API-nycklar | Environment variables | Permanent | Manuell backup | AES-256 encrypted config |
| Session-cache | Redis | 24h | Ej nödvändigt | TLS 1.3 in transit |
| Loggar (application) | PostgreSQL | 90 dagar | Veckovis | Ej nödvändigt |
5. Säkerhetsarkitektur
Säkerhetslager
[Internet] → [Cloudflare/CDN] → [Load Balancer] → [Web Server (Nginx)] →
↓ ↓ ↓
[DDoS Protection] [Rate Limiting] [TLS Termination]
↓
[Application]
(FastAPI)
↓
[Authentication/Authorization]
↓
[PostgreSQL]
(Encrypted at rest)
Autentisering och auktorisering
Autentiseringsmetod:
- Initial: Basic Auth via Optimate platform (Matilda + Rebecka har konton)
- Framtida: OAuth 2.0 via Azure AD (om integreras med Prolux-infrastruktur)
Identity Provider:
- Fas 4: Optimate-plattform (intern användarhantering)
- Fas 5: Möjlig migration till Azure AD
Rollbaserad åtkomst (RBAC):
- Matilda (Huvudanvändare): Full åtkomst, godkänna/neka fakturor, se all historik, skicka reklamationer
- Rebecka (Backup/IT-support): Samma som Matilda + systemadministration
- Liza (Ekonomi/PÄ): Read-only, dashboard, rapporter
- Lars (Utvecklare): Admin, systemkonfiguration, AI-träning, logs
API-säkerhet:
- Fortnox: API-nyckel + Client-Secret (Headers)
- WorkCloud: TBD (verifieras i vecka 42)
- Anthropic Claude: API-nyckel (x-api-key header)
- Microsoft Graph: OAuth 2.0 Bearer token
Datasäkerhet
| Aspekt | Implementation | Standard |
|---|---|---|
| Kryptering i vila | AES-256 för API-nycklar, PostgreSQL-data | FIPS 140-2 compliant |
| Kryptering i transit | TLS 1.3 för alla API-anrop | RFC 8446 |
| Nyckelhantering | Environment variables (encrypted config) | Principle of least privilege |
| Datamaskning | Leverantörsnamn maskeras i logs (GDPR) | GDPR Article 25 |
| Loggning | All API-access loggad, inga känsliga data i klartext | ISO 27001 |
| Access control | RBAC, 2FA för admin-konton | NIST 800-53 |
6. Infrastruktur (Optimate Core)
Deployment-modeller
Optimate Core stödjer två deployment-modeller. För BC11 Fas 4 rekommenderas Render (Cloud) för snabb implementation.
Deployment Model 1: Render (Cloud) - REKOMMENDERAD FAS 4
Fördelar:
- Snabb setup (dagar istället för veckor)
- Managed infrastructure (ingen server-administration)
- Private Network (säker kommunikation mellan services)
- Auto-scaling vid ökad belastning
- Built-in monitoring och logging
- Enkel staging/production-separation
Nackdelar:
- Månatlig kostnad ($50-150/mån beroende på skalning)
- Mindre kontroll över infrastruktur
- Beroende av Render-plattform
Arkitektur (Render Cloud):
┌──────────────────────────────────────────────────────┐
│ Render Private Network │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ n8n │ │ Ingestion │ │ Agentic │ │
│ │ (Web Svc) │ │ Engine │ │ Engine │ │
│ │ │ │ (Web Svc) │ │ (Web Svc) │ │
│ └─────────────┘ └──────────────┘ └────────────┘ │
│ │ │ │ │
│ └────────────────┴─────────────────┘ │
│ │ │
│ ┌─────────────┐ ┌───────▼──────┐ ┌────────────┐ │
│ │ Django │ │ PostgreSQL │ │ Qdrant │ │
│ │ HIL Portal │ │ (Managed) │ │ (Web Svc) │ │
│ └─────────────┘ └──────────────┘ └────────────┘ │
│ │ │
│ ┌───────▼───────┐ │
│ │ Ollama │ (Optional - costly on Render) │
│ │ (Web Svc) │ (Alternativ: Ollama via API) │
│ └───────────────┘ │
└──────────────────────────────────────────────────────┘
│
│ Public HTTPS (endast Load Balancer)
↓
[Internet Users: Matilda, Rebecka]
render.yaml - BC11 Deployment:
# render.yaml - BC11 Fakturahantering på Render
services:
# n8n - Workflow Hub
- type: web
name: bc11-n8n
env: docker
dockerfilePath: ./Dockerfile.n8n
envVars:
- key: N8N_ENCRYPTION_KEY
sync: false # Secret
- key: DATABASE_URL
fromDatabase:
name: bc11-postgres
property: connectionString
plan: standard # $25/mån
# Ingestion Engine (Core)
- type: web
name: bc11-ingestion-engine
env: docker
dockerfilePath: ./Dockerfile
dockerContext: .
dockerCommand: uvicorn ingestion_engine.main:app --host 0.0.0.0 --port 8000
envVars:
- key: FORTNOX_ACCESS_TOKEN
sync: false
- key: WORKCLOUD_API_KEY
sync: false
- key: DATABASE_URL
fromDatabase:
name: bc11-postgres
property: connectionString
plan: standard # $25/mån
# Agentic Engine (Core)
- type: web
name: bc11-agentic-engine
env: docker
dockerfilePath: ./Dockerfile
dockerContext: .
dockerCommand: uvicorn agentic_engine.main:app --host 0.0.0.0 --port 8000
envVars:
- key: ANTHROPIC_API_KEY
sync: false
- key: QDRANT_URL
value: http://bc11-qdrant:6333
- key: DATABASE_URL
fromDatabase:
name: bc11-postgres
property: connectionString
- key: LANGSMITH_API_KEY
sync: false
plan: standard # $25/mån
# Qdrant Vector Database
- type: web
name: bc11-qdrant
env: docker
dockerfilePath: ./Dockerfile.qdrant
disk:
name: bc11-qdrant-data
mountPath: /qdrant/storage
sizeGB: 10
plan: starter # $7/mån
# Django HIL Portal
- type: web
name: bc11-django-portal
env: python
buildCommand: pip install -r requirements.txt && python manage.py migrate
startCommand: gunicorn bc11_portal.wsgi:application
envVars:
- key: DATABASE_URL
fromDatabase:
name: bc11-postgres
property: connectionString
- key: N8N_WEBHOOK_URL
value: http://bc11-n8n:5678/webhook
plan: starter # $7/mån
databases:
# PostgreSQL (Managed)
- name: bc11-postgres
databaseName: fakturahantering
user: bc11_user
plan: starter # $7/mån (1GB storage)
Totalkostnad Render (Fas 4):
- n8n: $25/mån
- Ingestion Engine: $25/mån
- Agentic Engine: $25/mån
- Qdrant: $7/mån
- Django Portal: $7/mån
- PostgreSQL: $7/mån
- Total: ~$96/mån ($1152/år)
- Med staging-miljö: ~$150/mån ($1800/år)
Deployment Model 2: On-Premise (Docker Compose) - FRAMTIDA OPTION
Fördelar:
- Full datakontroll (inget lämnar infrastrukturen)
- Ingen löpande cloud-kostnad
- GPU-acceleration för Ollama (om server har GPU)
Nackdelar:
- Kräver server-administration
- Längre setup-tid
- Backup och monitoring måste hanteras manuellt
Arkitektur (On-Premise):
[Cloudflare Tunnel] → [Docker Network: bc11-network]
│
┌───────────────────────┼────────────────────────┐
│ │ │
┌───▼────┐ ┌────────┐ ┌──▼─────┐ ┌──────────┐ │
│ n8n │ │Django │ │Ingest. │ │ Agentic │ │
│ │ │Portal │ │Engine │ │ Engine │ │
└────────┘ └────────┘ └────────┘ └──────────┘ │
│ │ │ │ │
└────────────┴───────────┴────────────┘ │
│ │
┌───────────┴───────────┐ │
│ │ │
┌────▼─────┐ ┌─────────┐ ┌▼────────┐ │
│PostgreSQL│ │ Qdrant │ │ Ollama │ │
│(Supabase)│ │ │ │ (GPU) │ │
└──────────┘ └─────────┘ └─────────┘ │
│
└────────────────────────────────────────────────────┘
Migration till On-Premise (År 2):
- Exportera PostgreSQL från Render
- Exportera Qdrant snapshots
- Exportera n8n workflows
- Deploy docker-compose.yml på egen server
- Konfigurera Cloudflare Tunnel
- Cutover under lågtrafik-period
Miljöer och Konfiguration
| Miljö | Deployment | Användning | Åtkomst |
|---|---|---|---|
| Development | Lokal Docker Compose | Lars utveckling | Lokal |
| Staging | Render (separate services) | Test innan prod | Rebecka, Lars, Matilda |
| Production | Render | Live fakturahantering | Matilda, Rebecka, Liza (read) |
Environment Variables (.env template för local dev):
# Core Engines
DATABASE_URL=postgresql://user:pass@localhost:5432/fakturahantering
QDRANT_URL=http://localhost:6333
# External APIs
FORTNOX_ACCESS_TOKEN=your_token
FORTNOX_CLIENT_SECRET=your_secret
WORKCLOUD_API_KEY=your_key
ANTHROPIC_API_KEY=sk-ant-api03-xxx
MICROSOFT_GRAPH_CLIENT_ID=xxx
MICROSOFT_GRAPH_CLIENT_SECRET=xxx
# n8n
N8N_ENCRYPTION_KEY=random_32_char_string
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=secure_pass
# Observability
LANGSMITH_API_KEY=lsv2_xxx
LANGSMITH_PROJECT=bc11-fakturahantering
Skalbarhet
| Komponent | Render Start | Render Max | Skalningsstrategi |
|---|---|---|---|
| n8n workflows | Standard ($25) | Pro ($85) | Lägg till workers, optimize workflows |
| Ingestion Engine | Standard ($25) | Pro ($85) | Horizontal scaling (2-3 instances) |
| Agentic Engine | Standard ($25) | Pro ($85) + GPU | GPU for Ollama, scale instances |
| Qdrant | Starter ($7) | Standard ($25) | RAM upgrade för fler vectors |
| PostgreSQL | Starter ($7) | Pro ($90) | Storage + connection pool expansion |
Skalningsplan BC11:
- År 1 (250 fakt/mån): Render Standard plans OK
- År 2 (375 fakt/mån, +50%): Upgrade Agentic Engine till Pro
- År 3 (500+ fakt/mån): Överväg on-premise för cost optimization
Deployment-arkitektur
Deployment-metod: Docker Compose enligt Ahrens standard
- Alla komponenter definierade som services i
docker-compose.yml - Site-specifik konfiguration via
.env-fil - Version-kontrollerat i dedikerat GitHub site-repository
Miljöer
| Miljö | Syfte | Konfiguration | Åtkomst |
|---|---|---|---|
| Dev | Utveckling | Docker Compose (lokal), SQLite/Postgres | Lars, Rebecka |
| Test | Testing | Docker Compose (dedicated server), full stack | Lars, Rebecka, Matilda |
| Prod | Produktion | Docker Compose (prod server), Cloudflare Tunnel | Matilda, Rebecka, Liza (read-only) |
Produktionsmiljö - Docker Compose Stack
# docker-compose.yml (förenklad)
version: "3.8"
services:
n8n:
image: n8nio/n8n:latest
ports: ["5678:5678"]
volumes:
- ./n8n:/home/node/.n8n
env_file: .env
restart: unless-stopped
supabase-postgres:
image: supabase/postgres:15
ports: ["5432:5432"]
volumes:
- ./supabase/data:/var/lib/postgresql/data
- ./supabase/schema.sql:/docker-entrypoint-initdb.d/schema.sql
env_file: .env
restart: unless-stopped
supabase-storage:
image: supabase/storage-api:latest
depends_on: [supabase-postgres]
env_file: .env
qdrant:
image: qdrant/qdrant:latest
ports: ["6333:6333"]
volumes:
- ./qdrant:/qdrant/storage
restart: unless-stopped
ollama:
image: ollama/ollama:latest
volumes:
- ollama:/root/.ollama
# GPU support om tillgänglig
# deploy:
# resources:
# reservations:
# devices:
# - capabilities: [gpu]
openui:
build: ./openui
ports: ["3000:3000"]
depends_on: [n8n, supabase-postgres]
env_file: .env
cloudflared:
image: cloudflare/cloudflared:latest
command: tunnel run
env_file: .env
restart: unless-stopped
volumes:
ollama:
networks:
default:
name: bc11-network
Server-specifikation (Produktionsmiljö):
Server: Dedicated VPS eller On-premise
CPU: 8 vCores (för Ollama-inferens)
RAM: 16 GB (Ollama: 8GB, Postgres: 4GB, övrigt: 4GB)
Storage: 200 GB SSD
OS: Ubuntu 22.04 LTS
GPU: Optional (NVIDIA för snabbare Ollama)
Postgres (Supabase):
Version: 15.x
RAM allocation: 4 GB
Storage: 100 GB (projektioner: 20 GB efter 1 år)
Qdrant:
RAM allocation: 2 GB
Storage: 10 GB (vektorindex + metadata)
Ollama:
RAM per modell: ~7GB (Llama 3.1 8B)
Models: instructor-xl (embeddings), Llama 3.1 (backup AI)
n8n:
Workers: 2 (parallel workflow execution)
Storage: 5 GB (workflows, logs, temp files)
Cloudflare Tunnel Setup
Säker åtkomst utan publika IP:er:
# Installation (körs automatiskt vid docker-compose up)
cloudflared tunnel create bc11-faktura
cloudflared tunnel route dns bc11-faktura faktura.proluxfasad.se
# Config i .env
TUNNEL_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Cloudflare Access - Identity-baserad autentisering:
- n8n UI: Endast Rebecka + Lars (admin)
- OpenUI fakturahantering: Matilda + Rebecka + Liza (read-only)
- Supabase Studio: Rebecka + Lars
- Autentisering: Email-validering eller Google OAuth
Skalbarhet
| Komponent | Nuvarande | Max kapacitet | Skalningsstrategi |
|---|---|---|---|
| n8n workflows | ~500 exec/h | 5000 exec/h | Lägg till n8n workers, queue-system |
| AI-inference (Claude) | 250 req/mån | 1000 req/mån | Upgrade Anthropic plan, fallback Ollama |
| AI-inference (Ollama) | 100 req/h | 500 req/h | GPU-upgrade, modell-optimering |
| Fortnox API | 100 req/h | 300 req/h (rate limit) | Intelligent batching, caching i Supabase |
| Qdrant vectors | 10k vectors | 1M vectors | RAM-upgrade eller distributed deployment |
| Postgres storage | 20 GB År 1 | 200 GB | Disk expansion, archiving till Supabase Storage |
Skalningsplan:
- År 1 (250 fakt/mån): Nuvarande Docker Compose-setup räcker
- År 2 (375 fakt/mån, +50%): Öka Claude API-plan, eventuellt GPU för Ollama
- År 3 (500+ fakt/mån): Överväg Kubernetes för multi-site deployment
7. Prestanda och SLA
Prestandakrav
| Metrik | Krav | Mätmetod | Frekvens |
|---|---|---|---|
| Response time (Portal) | <500ms p95 | Browser DevTools, Lighthouse | Veckovis |
| AI inference time | <30s per faktura | Backend timer | Per request |
| Fortnox polling interval | 5 minuter | Scheduled cron job | Kontinuerlig |
| Database query time | <100ms p95 | PostgreSQL explain analyze | Daglig |
| Availability | 99% (7.2h downtime/mån OK) | Uptime monitor (UptimeRobot) | Kontinuerlig |
Service Level Agreement (SLA)
Tillgänglighet: 99% (43.8 min downtime/månad acceptabelt för Fas 4)
- Underhållsfönster: Lördagar 06:00-08:00 (ej räknas som downtime)
- Måltid: 99.5% År 2 (med mer robust infrastruktur)
Response tid:
- Portal load: 95% av requests <500ms
- AI-analys per faktura: <30 sekunder
- Fortnox-uppdatering: <2 sekunder
Dataförlust:
- RPO (Recovery Point Objective): 24h (dagliga backups PostgreSQL)
- RTO (Recovery Time Objective): 4h (manuell restore + system-restart)
Support:
- Kontorstid (08:00-17:00 mån-fre): Rebecka primär, Lars sekundär
- Utanför kontorstid: Best-effort, email-support
- Kritiska fel (system helt nere): 4h responstid kontorstid, 24h utanför
8. Monitoring och observability (Ahrens Automate)
Monitoring stack
[n8n Workflows] → [Execution logs i n8n UI] → [Supabase logs-tabell]
↓ ↓
[Docker logs] → [Supabase logging] → [n8n Alert Workflow] → [Email/Slack]
↓
[Cloudflare Analytics] → [Access logs & DDoS metrics]
Verktyg:
- n8n: Inbyggd workflow execution logging, error tracking, retry-hantering
- Supabase: Strukturerad loggning i PostgreSQL-tabeller
- Docker: Container logs via
docker compose logs - Cloudflare: Analytics och access logs
- Sentry: (Optional) Error tracking för OpenUI frontend
- Grafana: (Future) Visualisering av metrics
KPI:er och larm (n8n Alert Workflows)
n8n Alert Workflow - Systemhälsa:
Trigger: Schedule (var 5:e minut)
[n8n Schedule]
↓
[Check Docker Container Status]
↓
[Query Supabase: AI error rate senaste timmen]
↓
[Query Supabase: Average confidence senaste dagen]
↓
[Check Fortnox API status (test-anrop)]
↓
[Switch Node: Alert på threshold]
│
├─► [>5% AI errors] → [Send email to Rebecka + Lars]
├─► [<75% avg confidence] → [Send warning email]
├─► [Fortnox API down] → [Send CRITICAL alert]
└─► [All OK] → [Log status i Supabase]
| KPI | Threshold | Alert Type | n8n Action |
|---|---|---|---|
| AI error rate | >5% | Warning | Email → [email protected] |
| AI average confidence | <75% | Warning | Email med prompt-review instruktioner |
| Fortnox API errors | >3 på rad | Critical | Email + SMS (via Twilio node) |
| n8n workflow failures | >2 samma workflow | Warning | Email med workflow-länk |
| Disk usage | >85% | Warning | Email med cleanup-instruktioner |
| Qdrant query latency | >2s p95 | Warning | Email, optimera index |
| Container down | Any critical service | Critical | Email + SMS, auto-restart attempt |
n8n Performance Monitoring Workflow:
Trigger: Schedule (daglig kl 08:00)
[n8n Schedule]
↓
[Query Supabase: Execution metrics senaste 24h]
- Antal fakturor processade
- Auto-godkända vs manuella
- Average AI-svarstid
- Felfrekvens per problemtyp
↓
[Generate daily report (HTML)]
↓
[Send email till Matilda + Liza]
Alarm-kanaler:
- Email: [email protected], [email protected] (alla alerts)
- SMS: Endast critical alerts (container down, Fortnox API down)
- Slack: (Optional) #bc11-alerts channel för team-synlighet
- n8n UI: Execution history med filterering på failures
9. Disaster Recovery (Ahrens Automate Standard)
Backup-strategi
Automatiserad backup via n8n workflow (enligt Ahrens standard):
n8n Backup Workflow - "Backup Site BC11"
Trigger: Schedule (daglig kl 03:00)
[n8n Schedule Trigger: 03:00 daily]
↓
[Execute Command: pg_dump Supabase database]
→ Output: /backup/postgres/YYYY-MM-DD/bc11-fakturahantering.sql.gz
↓
[HTTP Request: Qdrant snapshot export]
→ API: POST http://qdrant:6333/collections/bc11-fakturahistorik/snapshots
→ Output: /backup/qdrant/YYYY-MM-DD/snapshot.tar
↓
[n8n API: Export all workflows]
→ API: GET http://n8n:5678/api/v1/workflows
→ Output: /backup/n8n/YYYY-MM-DD/workflows.json
↓
[Execute Command: Backup .env och docker-compose.yml]
→ cp .env /backup/env/YYYY-MM-DD/.env.backup
→ cp docker-compose.yml /backup/env/YYYY-MM-DD/
↓
[Execute Command: Create checksum file]
→ sha256sum * > checksums.txt
↓
[Git: Commit och push till GitHub]
→ git add backup/
→ git commit -m "Automated backup YYYY-MM-DD"
→ git push origin main
↓
[Send notification email]
→ Subject: "BC11 Backup framgångsrik - YYYY-MM-DD"
→ To: [email protected]
→ Includes: Backup size, checksum, GitHub commit link
Backup-innehåll:
| Data | Metod | Frekvens | Retention | Location |
|---|---|---|---|---|
| Supabase Postgres | pg_dump (compressed) | Daglig 03:00 | 30 dagar lokal, 90 dagar GitHub | /backup/postgres/ + GitHub |
| Qdrant vektorindex | Snapshot API | Daglig 03:00 | 30 dagar | /backup/qdrant/ + GitHub |
| n8n workflows | JSON export via API | Daglig 03:00 | Permanent (Git history) | /backup/n8n/ + GitHub |
| .env + docker-compose | File copy (encrypted) | Daglig 03:00 | 30 dagar | /backup/env/ + GitHub (encrypted) |
| Faktura-PDF:er | Fortnox Archive | N/A (Fortnox-ansvar) | 7 år | Fortnox system |
GitHub Site Repository Backup:
- Repository:
github.com/prolux-fasad/bc11-faktura-site - Branch:
main(production),staging(test) - Automatiska commits via n8n backup workflow
- Encrypted .env-fil (via git-crypt eller liknande)
DR-plan (Disaster Recovery)
| Scenario | RTO | RPO | Procedur |
|---|---|---|---|
| n8n container crash | 5 min | 0 | Docker auto-restart, workflows intact |
| Supabase corruption | 4h | 24h | Restore från senaste pg_dump backup |
| Qdrant data loss | 2h | 24h | Re-import från snapshot, re-embed saknade fakturor |
| Full server-fel | 8h | 24h | Deploy till ny server: clone GitHub repo → docker-compose up → restore backups |
| Accidental workflow deletion | 1h | 0 | Restore från Git history, re-import till n8n |
| Ransomware | 24h | 24h | Isolera, restore från offsite GitHub backup, security audit |
| Cloudflare Tunnel down | 1h | 0 | Fallback: Direkt åtkomst via port-forwarding temporärt |
Restore-procedur (Full DR):
# 1. Klona site-repository
git clone https://github.com/prolux-fasad/bc11-faktura-site.git
cd bc11-faktura-site
# 2. Dekryptera och återställ .env
git-crypt unlock
cp backup/env/2025-10-25/.env.backup .env
# 3. Starta Docker Compose stack
docker-compose up -d
# 4. Vänta på att containers startar
docker-compose ps
# 5. Restore Supabase database
docker exec -i supabase-postgres pg_restore -U postgres -d fakturahantering < backup/postgres/2025-10-25/bc11-fakturahantering.sql
# 6. Restore Qdrant snapshots
curl -X POST 'http://localhost:6333/collections/bc11-fakturahistorik/snapshots/upload' \
-H 'Content-Type: multipart/form-data' \
-F 'snapshot=@backup/qdrant/2025-10-25/snapshot.tar'
# 7. Import n8n workflows
curl -X POST http://localhost:5678/api/v1/workflows/import \
-H "X-N8N-API-KEY: $N8N_API_KEY" \
-d @backup/n8n/2025-10-25/workflows.json
# 8. Verifiera alla services
docker-compose logs --tail=100
# 9. Test basic functionality
# - Logga in på n8n UI
# - Kör manuell test av "Poll Fortnox" workflow
# - Verifiera Supabase data
# - Test OpenUI fakturahantering
Testning av DR-plan:
- Fas 4: Ingen formell DR-test (accepterad risk)
- Vecka 51 (projektavslut): Staging-test av full restore
- År 2: Kvartalsvisa DR-drills i test-miljö
10. Utvecklingsmiljö (Ahrens Automate Stack)
Development setup
# Lokalt utvecklingsmiljö (Ahrens standard)
# 1. Klona site-repository
git clone https://github.com/prolux-fasad/bc11-faktura-site.git
cd bc11-faktura-site
# 2. Setup environment variables
cp .env.example .env
# Redigera .env med API-nycklar:
# - ANTHROPIC_API_KEY=sk-ant-...
# - FORTNOX_ACCESS_TOKEN=...
# - FORTNOX_CLIENT_SECRET=...
# - WORKCLOUD_API_KEY=... (om tillgänglig)
# - N8N_ENCRYPTION_KEY=...
# - SUPABASE_PASSWORD=...
# 3. Starta full stack
docker-compose up -d
# 4. Vänta på containers (30-60 sek)
docker-compose ps
# 5. Åtkomst till services
# n8n UI: http://localhost:5678
# OpenUI: http://localhost:3000
# Supabase Studio: Ej exposed (använd Supabase CLI eller direkt Postgres)
# Qdrant: http://localhost:6333/dashboard
# 6. Import initiala n8n workflows
curl -X POST http://localhost:5678/api/v1/workflows/import \
-H "X-N8N-API-KEY: ${N8N_API_KEY}" \
-d @n8n/workflows/poll-fortnox-fakturor.json
# 7. Setup Ollama models (första gången)
docker exec -it ollama ollama pull llama3.1
docker exec -it ollama ollama pull nomic-embed-text # För embeddings
# 8. Initialize Supabase schema
docker exec -i supabase-postgres psql -U postgres -d fakturahantering < supabase/schema.sql
Krav för utveckling:
- Docker Desktop 24+ (eller Docker Engine + Docker Compose)
- Git
- API-nycklar för Fortnox, Claude, WorkCloud (test-miljö)
- (Optional) Cloudflare account för Tunnel-test
- Minst 16GB RAM (för Ollama)
CI/CD pipeline (GitHub Actions)
.github/workflows/backup.yml:
name: Automated Backup
on:
schedule:
- cron: '0 3 * * *' # Daglig kl 03:00 UTC
workflow_dispatch: # Manuell trigger
jobs:
backup:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Setup SSH
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SERVER_SSH_KEY }}
- name: Run backup script on server
run: |
ssh [email protected] << 'EOF'
cd /opt/bc11-faktura-site
docker-compose exec -T n8n n8n execute --workflow "Backup Site BC11"
EOF
- name: Pull latest backups
run: git pull origin main
- name: Verify backup integrity
run: |
cd backup/postgres/$(date +%Y-%m-%d)
sha256sum -c checksums.txt
.github/workflows/deploy.yml:
name: Deploy to Production
on:
push:
branches: [main]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Deploy to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
cd /opt/bc11-faktura-site
git pull origin main
docker-compose pull
docker-compose up -d
docker-compose logs --tail=50
Deployment-flöde:
- Utveckling i lokal miljö
- Commit workflow-ändringar till Git
- Push till
stagingbranch → Auto-deploy till test-server - Manuell test och godkännande
- Merge till
mainbranch → Auto-deploy till produktion - n8n workflows exporteras automatiskt nattligen och commitas
Testing:
- n8n workflows: Manuell test i n8n UI (trigger test execution)
- OpenUI: Lokal utveckling med hot-reload
- Integrations: Mock API-svar för Fortnox/WorkCloud i test
- End-to-end: Staging-miljö med riktiga API:er (test-data)
Bilagor
Bilaga A: Site Repository Struktur (Ahrens Standard)
BC11-projektet följer Ahrens Automate site repository template:
bc11-faktura-site/
│
├── infra/ # Docker Compose och infrastruktur
│ ├── docker-compose.yml # Full stack-definition
│ ├── docker-compose.dev.yml # Development overrides
│ └── .env.example # Template för environment variables
│
├── n8n/ # n8n workflows och konfiguration
│ ├── workflows/
│ │ ├── 01-poll-fortnox-fakturor.json
│ │ ├── 02-ai-fakturaanalys.json
│ │ ├── 03-manuell-godkannande-webhook.json
│ │ ├── 04-skicka-reklamation.json
│ │ ├── 05-backup-site.json
│ │ ├── 06-daily-performance-report.json
│ │ └── 07-system-health-monitoring.json
│ ├── credentials/ # Credentials (encrypted i Git)
│ └── settings/ # n8n settings och configuration
│
├── supabase/ # Database schema och seeds
│ ├── schema.sql # Full database schema
│ ├── seed.sql # Initial/demo data
│ ├── migrations/ # Database migrations
│ │ ├── 001_initial_schema.sql
│ │ ├── 002_add_confidence_scoring.sql
│ │ └── 003_add_email_log.sql
│ └── storage.json # Supabase Storage buckets config
│
├── qdrant/ # Qdrant configuration
│ ├── collections.json # Collection definitions
│ └── embedding_config.json # Embedding strategy
│
├── openui/ # Frontend portal
│ ├── src/
│ │ ├── components/
│ │ │ ├── InvoiceList.jsx
│ │ │ ├── InvoiceDetail.jsx
│ │ │ ├── ProjectSelector.jsx
│ │ │ └── ConfidenceIndicator.jsx
│ │ ├── pages/
│ │ │ ├── Dashboard.jsx
│ │ │ ├── FakturaGranskning.jsx
│ │ │ └── Historik.jsx
│ │ ├── api/
│ │ │ └── n8n-webhooks.js
│ │ └── App.jsx
│ ├── public/
│ ├── package.json
│ └── Dockerfile
│
├── backup/ # Automated backups (genereras automatiskt)
│ ├── postgres/
│ │ └── 2025-10-25/
│ │ ├── bc11-fakturahantering.sql.gz
│ │ └── checksums.txt
│ ├── qdrant/
│ │ └── 2025-10-25/
│ │ └── snapshot.tar
│ ├── n8n/
│ │ └── 2025-10-25/
│ │ └── workflows.json
│ └── env/
│ └── 2025-10-25/
│ ├── .env.backup (encrypted)
│ └── docker-compose.yml
│
├── rag/ # RAG-konfiguration och scripts
│ ├── chunker.py # Faktura-chunking logic (om används)
│ ├── embedding_config.json # Embedding model och strategi
│ └── prompts/
│ ├── projektnummer_detektion.txt
│ ├── referensperson_validering.txt
│ └── reklamation_generation.txt
│
├── site-docs/ # Projektet-specifik dokumentation
│ ├── BC11-Setup.md # Installation och setup
│ ├── BC11-Användning.md # Användardokumentation för Matilda
│ ├── BC11-Teknisk-Arkitektur.md # Detta dokument
│ ├── BC11-Troubleshooting.md # Felsökningsguide
│ └── BC11-API-Integration.md # Integration med Fortnox/WorkCloud
│
├── .github/ # CI/CD workflows
│ └── workflows/
│ ├── backup.yml # Automatisk backup
│ ├── deploy.yml # Deployment till prod
│ └── test.yml # Testing workflows
│
├── .env # Environment variables (EJ i Git)
├── .gitignore # Git ignore rules
├── README.md # Projektöversikt
└── LICENSE # License
Viktiga filer och deras syfte:
- docker-compose.yml - Definierar hela BC11-stacken (n8n, Supabase, Qdrant, Ollama, OpenUI, Cloudflare Tunnel)
- n8n/workflows/ - Alla n8n workflows exporterade som JSON. Versionshanterade och kan re-importeras vid DR.
- supabase/schema.sql - Komplett databasschema. Används vid initial setup och DR-restore.
- openui/ - Custom React-frontend för Matildas fakturahantering. Kommunicerar med n8n via webhooks.
- backup/ - Auto-genererade backups från n8n backup-workflow. Commitas till Git (encrypted .env).
- site-docs/ - All projektdokumentation inkl. användarmanualer och teknisk dokumentation.
Deployment från site-repository:
# 1. Klona repo
git clone https://github.com/prolux-fasad/bc11-faktura-site.git
cd bc11-faktura-site
# 2. Setup .env
cp infra/.env.example .env
# Redigera .env med production-värden
# 3. Starta stack
cd infra
docker-compose up -d
# 4. Initialize database
docker exec -i supabase-postgres psql -U postgres < ../supabase/schema.sql
# 5. Import workflows
for workflow in ../n8n/workflows/*.json; do
curl -X POST http://localhost:5678/api/v1/workflows/import \
-H "X-N8N-API-KEY: $N8N_API_KEY" \
-d @$workflow
done
# 6. Verifiera
docker-compose ps
Bilaga B: Detaljerad nätverksdiagram
(Skulle inkludera visuell Visio/Draw.io-diagram med exakta IP-adresser, portar, brandväggsregler)
Simplified text-version (Ahrens Stack):
Internet (HTTPS 443)
↓
Cloudflare (CDN + DDoS protection + Tunnel endpoint)
↓
Cloudflare Tunnel (encrypted tunnel till server)
↓
Server: bc11-server.proluxfasad.se
│
├─► Docker Network: bc11-network
│ │
│ ├─► n8n (5678, endast intern)
│ ├─► OpenUI (3000, via Tunnel)
│ ├─► Supabase Postgres (5432, endast intern)
│ ├─► Qdrant (6333, endast intern)
│ ├─► Ollama (11434, endast intern)
│ └─► Cloudflared (tunnel client, outbound only)
│
└─► Outbound API calls (443):
- Fortnox API (api.fortnox.se)
- WorkCloud API (TBD)
- Anthropic API (api.anthropic.com)
- Microsoft Graph (graph.microsoft.com)
Cloudflare Access Policies:
- faktura.proluxfasad.se (OpenUI) → Matilda, Rebecka, Liza
- n8n.proluxfasad.se (n8n UI) → Rebecka, Lars
- Auth: Email verification eller Google OAuth
Bilaga C: API-dokumentation
Swagger/OpenAPI spec genereras automatiskt av FastAPI:
- URL: https://ai-faktura.proluxfasad.se/docs (production)
- URL: http://localhost:8000/docs (development)
Inkluderar:
- Alla endpoints (/api/invoices, /api/projects, /api/decisions)
- Request/response schemas (JSON)
- Authentication requirements
- Example requests
Bilaga D: n8n Workflow API och Webhooks
n8n Workflow API:
Export alla workflows:
curl http://localhost:5678/api/v1/workflows \
-H "X-N8N-API-KEY: ${N8N_API_KEY}" \
| jq . > all-workflows.json
Import workflow:
curl -X POST http://localhost:5678/api/v1/workflows \
-H "X-N8N-API-KEY: ${N8N_API_KEY}" \
-H "Content-Type: application/json" \
-d @poll-fortnox-fakturor.json
OpenUI Webhooks (n8n endpoints):
| Endpoint | Metod | Beskrivning | Request Body |
|---|---|---|---|
| /webhook/bc11-godkann-faktura | POST | Matilda godkänner faktura | {invoice_id, project_number, comment} |
| /webhook/bc11-neka-faktura | POST | Matilda nekar och reklamerar | {invoice_id, reason, correct_project} |
| /webhook/bc11-hamta-flaggade | GET | Hämta fakturor för granskning | Query: ?status=pending&confidence=<80 |
| /webhook/bc11-historik | GET | AI-beslutshistorik | Query: ?from_date=2025-10-01&to_date=2025-10-31 |
Bilaga E: Docker Compose - Fullständig Konfiguration
# docker-compose.yml - BC11 Fakturahantering
version: "3.8"
services:
# n8n - Workflow orchestration
n8n:
image: n8nio/n8n:latest
container_name: bc11-n8n
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=${N8N_USER}
- N8N_BASIC_AUTH_PASSWORD=${N8N_PASSWORD}
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- WEBHOOK_URL=https://n8n.proluxfasad.se
- N8N_HOST=n8n.proluxfasad.se
- N8N_PROTOCOL=https
volumes:
- ./n8n:/home/node/.n8n
env_file:
- .env
restart: unless-stopped
networks:
- bc11-network
depends_on:
- supabase-postgres
- qdrant
# Supabase PostgreSQL
supabase-postgres:
image: supabase/postgres:15
container_name: bc11-supabase-postgres
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=${SUPABASE_DB_PASSWORD}
- POSTGRES_USER=postgres
- POSTGRES_DB=fakturahantering
volumes:
- ./supabase/data:/var/lib/postgresql/data
- ./supabase/schema.sql:/docker-entrypoint-initdb.d/01-schema.sql
- ./supabase/seed.sql:/docker-entrypoint-initdb.d/02-seed.sql
restart: unless-stopped
networks:
- bc11-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
# Supabase Storage (optional, för PDF-lagring)
supabase-storage:
image: supabase/storage-api:latest
container_name: bc11-supabase-storage
environment:
- DATABASE_URL=postgresql://postgres:${SUPABASE_DB_PASSWORD}@supabase-postgres:5432/fakturahantering
- STORAGE_BACKEND=file
volumes:
- ./supabase/storage:/var/lib/storage
depends_on:
- supabase-postgres
networks:
- bc11-network
restart: unless-stopped
# Qdrant - Vector database
qdrant:
image: qdrant/qdrant:latest
container_name: bc11-qdrant
ports:
- "6333:6333"
volumes:
- ./qdrant/storage:/qdrant/storage
restart: unless-stopped
networks:
- bc11-network
# Ollama - Local LLM
ollama:
image: ollama/ollama:latest
container_name: bc11-ollama
ports:
- "11434:11434"
volumes:
- ollama-models:/root/.ollama
restart: unless-stopped
networks:
- bc11-network
# Uncomment for GPU support
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: 1
# capabilities: [gpu]
# OpenUI - Frontend portal
openui:
build:
context: ./openui
dockerfile: Dockerfile
container_name: bc11-openui
ports:
- "3000:3000"
environment:
- REACT_APP_N8N_WEBHOOK_URL=https://n8n.proluxfasad.se/webhook
- REACT_APP_API_URL=http://n8n:5678
depends_on:
- n8n
networks:
- bc11-network
restart: unless-stopped
# Cloudflare Tunnel
cloudflared:
image: cloudflare/cloudflared:latest
container_name: bc11-cloudflared
command: tunnel run
environment:
- TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}
restart: unless-stopped
networks:
- bc11-network
volumes:
ollama-models:
name: bc11-ollama-models
networks:
bc11-network:
name: bc11-network
driver: bridge
.env Template:
# n8n Configuration
N8N_USER=admin
N8N_PASSWORD=change_me_secure_password
N8N_ENCRYPTION_KEY=generate_random_32_char_string
N8N_API_KEY=generate_api_key_for_external_access
# Supabase Configuration
SUPABASE_DB_PASSWORD=change_me_secure_db_password
# Fortnox API
FORTNOX_ACCESS_TOKEN=your_fortnox_access_token
FORTNOX_CLIENT_SECRET=your_fortnox_client_secret
# WorkCloud API (om tillgänglig)
WORKCLOUD_API_KEY=your_workcloud_api_key
WORKCLOUD_API_URL=https://api.workcloud.se
# Anthropic Claude API
ANTHROPIC_API_KEY=sk-ant-api03-your_key_here
# Microsoft Graph API (för email)
MICROSOFT_GRAPH_CLIENT_ID=your_azure_app_client_id
MICROSOFT_GRAPH_CLIENT_SECRET=your_azure_app_secret
MICROSOFT_GRAPH_TENANT_ID=your_tenant_id
# Cloudflare Tunnel
CLOUDFLARE_TUNNEL_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
ER-diagram skulle genereras med verktyg som dbdiagram.io eller DbVisualizer
Text-representation:
invoices (1) ─────── (*) ai_decisions_log
│
└─ (0-1) email_log
projects_cache (standalone, no foreign keys)
workorders_cache (standalone, no foreign keys)
supplier_project_history (standalone, no foreign keys)
Bilaga D: Säkerhetscertifikat
Planerade säkerhetstester:
- Vecka 47 (Staging): Manuell penetrationstesting (basic)
- SQL injection tests
- XSS tests
- Authentication bypass tests
- Vecka 49 (Production): Vulnerability scan (automated)
- Nessus eller OpenVAS
- År 2: Formell pen-test av extern konsult (budget: 20-30 kkr)
SSL/TLS-certifikat:
- Let's Encrypt (gratis, auto-renew var 90:e dag)
- Cloudflare SSL (om används)
Dokumentinformation
Version: 2.0
Arkitekt: Lars Diethelm
Platform: Optimate Core (Hub-and-Spoke Architecture)
Stack: n8n (Hub) + FastAPI Core Engines (Spokes) + PostgreSQL + Qdrant + Claude/Ollama
Deployment: Render (Cloud) primär, Docker Compose (On-Premise) sekundär
Granskad av: Rebecka Englund (IT), Matilda Björklind (Process)
Godkänd av: Liza Fyhr (Processägare)
Datum: 2025-11-01
Nästa revision: Vid större ändringar eller efter BP4 (vecka 47)
Repositories:
- Core:
github.com/optimate/optimate-core(privat) - Template:
github.com/optimate/optimate-customer-template(privat) - Customer Site:
github.com/optimate/customer-prolux-bc11-site(privat)
Versionshistorik
| Version | Datum | Författare | Ändringar |
|---|---|---|---|
| 0.1 | 2025-10-24 | Lars Diethelm | Initial utkast, generisk arkitektur |
| 0.5 | 2025-10-25 | Lars Diethelm | Anpassad till hybrid-modell från BC11 |
| 1.0 | 2025-10-25 | Lars Diethelm | Komplett teknisk arkitektur anpassad till Ahrens Automate Stack |
| 2.0 | 2025-11-01 | Lars Diethelm | MAJOR UPDATE: Optimate Core Architecture |
Huvudsakliga ändringar v2.0:
- Hub-and-Spoke Architecture: Separerad capability (core engines) från configuration (n8n workflows)
- FastAPI Microservices: Ingestion Engine + Agentic Engine som återanvändbara spokes
- Three-Repository Strategy: optimate-core → customer-template → customer-site
- Render Cloud Deployment: Primär deployment-modell för Fas 4 (managed infrastructure)
- On-Premise Optional: Docker Compose som sekundärt alternativ för framtiden
- LangSmith Integration: Full observability av AI-interactions
- Keycloak Identity: SSO-möjlighet för framtida multi-user scenarios
- Django HIL Portal: Ersätter OpenUI, integrerat med Optimate Core
- Dependabot Updates: Automatiserade core engine-uppdateringar till alla customer sites
Arkitekturella förbättringar:
- Bättre separation mellan BC11-specifik logik och återanvändbar AI-capability
- Enklare underhåll: Uppdatera engines centralt, påverkar alla kunder
- Snabbare deployment: Render managed infrastructure istället för manuell server-setup
- Bättre skalbarhet: Engines kan skalas oberoende av orchestration layer
- Förbättrad observability: LangSmith tracking av alla AI-beslut
Signering och Godkännande
Detta dokument utgör den tekniska grunden för implementation av BC11 Fas 4 (Vecka 44-51) enligt Optimate Core Architecture.
| Roll | Namn | Signatur | Datum |
|---|---|---|---|
| Processägare | Liza Fyhr | ____________ | ______ |
| Processexpert | Matilda Björklind | ____________ | ______ |
| IT-ansvarig | Rebecka Englund | ____________ | ______ |
| Arkitekt/Utvecklare | Lars Diethelm | ____________ | ______ |
Denna tekniska arkitektur definierar systemets struktur baserat på Optimate Core och utgör grunden för implementation i Fas 4.
Nästa steg:
- Godkännande av detta dokument v2.0 (Vecka 43)
- Setup Render deployment + customer-prolux-bc11-site repository (Vecka 43)
- Utveckling av BC11-specifika endpoints i Ingestion/Agentic Engines (Vecka 43-44)
- BP3-beslut (Vecka 43)
- Start implementation - n8n workflows + Django HIL portal (Vecka 44)