bae705aa97
- 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
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
# 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
# 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)
# 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
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
# 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
# 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
Senast uppdaterad: 2026-06-24
Version: Sprint 3 (UI & Observability)