Files
boc/landvex-finance-sprint3/README.md
T
Bernt bae705aa97 ARCHITECTURE: NFC roadmap, edge AI, audit logging
- Add NFC ePassport roadmap (ICAO 9303, eIDAS)
- Add TensorFlow.js edge face detection (BlazeFace)
- Add structured audit logger (GDPR-compliant)
- Risk scoring support

Part of KYC Apple Native UX v1.1.0
2026-06-29 16:24:48 +00:00

344 lines
12 KiB
Markdown

# LandveX Finance
> Banking-grade bokföringsgränssnitt för LandveX AB
> Byggt på Ouroboros Ledger API med realtidsintegration mot Revolut, Nordea och SIE4-export.
---
## Arkitekturöversikt
```
┌─────────────────────────────────────────────────────────────────┐
│ LANDVEX FINANCE │
│ (Single-Page Application) │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────┐ │
│ │ Översikt │ │Transaktioner│ │ Fakturor │ │ Moms │ │
│ │ (KPI) │ │ (Journal) │ │ (Invoice) │ │ (VAT) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ └────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────┐ │
│ │ Löner │ │ Period │ │ Tasks │ │ Prognos│ │
│ │ (Payroll) │ │ (Close) │ │(Onboarding) │ │(Forecast)│
│ └─────────────┘ └─────────────┘ └─────────────┘ └────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ UI: Vanilla JS ES Modules + CSS Custom Properties │
│ State: In-memory med localStorage-persistens │
│ API: Fetch → LandveX Ledger Proxy → Ouroboros Ledger (port 3250)│
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ LANDVEX LEDGER PROXY │
│ (/opt/amos/api/landvex/ledger-proxy.mjs) │
├─────────────────────────────────────────────────────────────────┤
│ • Server-side auth (JWT → ledger token) │
│ • Trial balance beräknas server-side (prestanda) │
│ • Revolut integration (JWT assertion + refresh token) │
│ • SIE4-export │
└─────────────────────────────────────────────────────────────────┘
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────┐ ┌──────────┐ ┌──────────┐
│Ledger │ │ Revolut │ │ Nordea │
│(3250) │ │ (B2B) │ │ (API) │
└─────────┘ └──────────┘ └──────────┘
```
### Teknisk Stack
| Lager | Teknik |
|-------|--------|
| Frontend | Vanilla JS (ES2022), CSS Custom Properties, inget framework |
| Backend Proxy | Node.js + Express (ES modules) |
| Ledger API | Ouroboros Ledger (port 3250) |
| Bankintegration | Revolut B2B API, Nordea Open Banking |
| Datalagring | PostgreSQL (ledger), JSONL-filer (backup) |
| Cache | Redis |
| Auth | JWT (wavult_token cookie) |
---
## Deployment-guide
### Förutsättningar
- Node.js ≥ 20
- PostgreSQL ≥ 15
- Redis ≥ 7
- Nginx (reverse proxy + SSL)
### Miljövariabler
```bash
# Databas
DATABASE_URL=postgresql://user:pass@host:5432/wavult_identity
LEDGER_DB_URL=postgresql://user:pass@host:5432/ledger
# Redis
REDIS_URL=redis://localhost:6379
# Auth
AMOS_JWT_SECRET=your-jwt-secret-here
# Revolut (B2B)
REVOLUT_CLIENT_ID=your-client-id
REVOLUT_REFRESH_TOKEN=your-refresh-token
REVOLUT_PRIVATE_KEY_PATH=/opt/amos/data/revolut_private_prod.pem
# Intern kommunikation
LEDGER_BASE=http://localhost:3250
LEDGER_TOKEN=wavult-amos-internal-2026
# Server
PORT=3100
BIND_HOST=0.0.0.0
NODE_ENV=production
```
### Installation
```bash
# 1. Klona repo (om separat)
cd /opt/amos
# 2. Installera beroenden
npm install
# 3. Verifiera miljövariabler
cp .env.example .env
nano .env
# 4. Starta ledger-tjänsten (om separat)
cd /opt/amos/services/ledger
npm start # port 3250
# 5. Starta huvudservern
npm start # port 3100
# 6. Verifiera health checks
curl http://localhost:3100/health
curl http://localhost:3100/health/finance
curl http://localhost:3100/prom-metrics
```
### PM2 (produktion)
```bash
# ecosystem.config.cjs
module.exports = {
apps: [{
name: 'amos-finance',
script: './scripts/server.mjs',
instances: 1,
exec_mode: 'fork',
env: { NODE_ENV: 'production' },
log_file: '/var/log/amos/finance.log',
error_file: '/var/log/amos/finance-error.log',
out_file: '/var/log/amos/finance-out.log',
merge_logs: true,
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
}]
};
```
### Nginx-konfiguration
```nginx
server {
listen 443 ssl http2;
server_name finance.wavult.com;
ssl_certificate /etc/letsencrypt/live/wavult.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/wavult.com/privkey.pem;
location / {
root /opt/amos/public/ouroboros/finance;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://localhost:3100;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /prom-metrics {
proxy_pass http://localhost:3100;
allow 10.0.0.0/8; # Interna nätverk endast
deny all;
}
}
```
---
## API-endpoints
### Finance Proxy (`/api/landvex/*`)
| Metod | Endpoint | Beskrivning |
|-------|----------|-------------|
| GET | `/api/landvex/ledger/journal` | Journal (verifikat) |
| GET | `/api/landvex/ledger/trial-balance` | Saldobalans (server-side) |
| POST | `/api/landvex/ledger/journal` | Skapa verifikat |
| POST | `/api/landvex/ledger/journal/:id/post` | Bokför verifikat |
| GET | `/api/landvex/ledger/accounts` | Kontoplan |
| GET | `/api/landvex/ledger/periods` | Räkenskapsperioder |
| GET | `/api/landvex/ledger/invoices` | Fakturor |
| POST | `/api/landvex/ledger/invoices` | Skapa faktura |
| GET | `/api/landvex/ledger/export/sie4` | SIE4-export |
| POST | `/api/landvex/ledger/journal/:id/upload` | Ladda upp kvitto |
| GET | `/api/landvex/ledger/journal/:id/receipts` | Hämta kvitton |
### Health & Metrics
| Endpoint | Beskrivning |
|----------|-------------|
| `GET /health` | Simpel health check |
| `GET /health/detailed` | Vault + OPA status |
| `GET /health/finance` | DB + Redis + disk + ledger + Revolut |
| `GET /prom-metrics` | Prometheus metrics (intern) |
| `GET /metrics` | JSON metrics (legacy) |
---
## Miljövariabler (komplett lista)
### Obligatoriska
| Variabel | Beskrivning | Exempel |
|----------|-------------|---------|
| `DATABASE_URL` | PostgreSQL för identity/tenant | `postgresql://.../wavult_identity` |
| `AMOS_JWT_SECRET` | JWT-signering | `super-secret-key` |
| `LEDGER_BASE` | Ouroboros Ledger URL | `http://localhost:3250` |
| `LEDGER_TOKEN` | Intern token för ledger | `wavult-amos-internal-2026` |
### Bankintegration (valfria)
| Variabel | Beskrivning |
|----------|-------------|
| `REVOLUT_CLIENT_ID` | Revolut B2B client ID |
| `REVOLUT_REFRESH_TOKEN` | Refresh token för Revolut |
| `REVOLUT_PRIVATE_KEY_PATH` | Sökväg till RSA-nyckel |
| `NORDEA_CLIENT_ID` | Nordea Open Banking |
| `NORDEA_CLIENT_SECRET` | Nordea secret |
### Operativa
| Variabel | Beskrivning | Standard |
|----------|-------------|----------|
| `PORT` | Serverport | `3100` |
| `BIND_HOST` | Bind-adress | `0.0.0.0` |
| `NODE_ENV` | Miljö | `development` |
| `REDIS_URL` | Redis-anslutning | `redis://localhost:6379` |
| `LOG_LEVEL` | Loggnivå | `info` |
---
## Utveckling
### Lokal utveckling
```bash
# 1. Starta med utvecklingsläge
NODE_ENV=development npm start
# 2. UI-filer serveras från /public/ouroboros/finance/
# Ändringar i index.html syns direkt (ingen build)
# 3. Testa API
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:3100/api/landvex/ledger/journal?limit=5
```
### Filstruktur (frontend)
```
public/ouroboros/finance/
├── index.html # Huvudfil (177KB, ska brytas ner)
├── ledger.html # Äldre ledger-vy
└── docs/
├── UI-REFACTOR-PLAN.md # Refaktoreringsplan
└── ARCHITECTURE.md # Arkitekturbeskrivning
```
### Filstruktur (backend)
```
api/
├── finance/ # Finance-specifika moduler (nya)
│ ├── metrics.mjs # Prometheus metrics
│ ├── logger.mjs # Strukturerad loggning
│ └── health.mjs # Health checks
├── landvex/
│ └── ledger-proxy.mjs # Huvud-proxy för LandveX
├── finance/ # Generella finance-routes
│ ├── ledger.mjs
│ ├── invoices.mjs
│ └── ...
└── ...
```
---
## Övervakning
### Prometheus Metrics
```bash
# Scrape-config för Prometheus
scrape_configs:
- job_name: 'landvex-finance'
static_configs:
- targets: ['localhost:3100']
metrics_path: '/prom-metrics'
```
### Viktiga metrics
| Metric | Typ | Beskrivning |
|--------|-----|-------------|
| `finance_journal_entries_total` | Counter | Antal verifikat |
| `finance_invoices_total` | Gauge | Fakturor per status |
| `finance_vat_payable` | Gauge | Moms att betala |
| `finance_api_duration_seconds` | Histogram | API-svarstider |
| `amos_http_requests_total` | Counter | HTTP-requests |
### Larm (förslag)
| Larm | Condition | Åtgärd |
|------|-----------|--------|
| DB nere | `health/finance` != 200 | PagerDuty |
| Disk full | `disk.free_gb < 1` | Rensa loggar |
| Revolut auth fail | `revolut.authenticated == false` | Rotera token |
| API-latens | `p95 > 2s` | Skala upp |
---
## Säkerhet
- **Auth:** JWT i httpOnly-cookie, Bearer-token i header
- **CORS:** Endast `*.wavult.com`
- **Rate limiting:** 100 req/min per IP
- **Input validation:** Alla POST/PUT valideras
- **SQL injection:** Parameteriserade queries (pg)
- **XSS:** `esc()`-funktion i UI, CSP-headers
- **CSRF:** SameSite=Lax på cookies
---
## Support
- **Slack:** #finance-dev
- **On-call:** finance-oncall@wavult.com
- **Runbook:** [Confluence/Runbooks/Finance](https://wiki.wavult.com)
---
*Senast uppdaterad: 2026-06-24*
*Version: Sprint 3 (UI & Observability)*