- DNS: pilot.landvex.com -> 16.170.83.169 - TLS: Let's Encrypt certificate (expires 2026-09-30) - Nginx: reverse proxy with SSL termination - API: https://pilot.landvex.com/api/v1/missions - UI: https://pilot.landvex.com/ - Upload: POST /api/v1/missions/import (multipart/form-data) Verified: ✅ https://pilot.landvex.com/health ✅ https://pilot.landvex.com/version ✅ https://pilot.landvex.com/api/v1/missions (list) ✅ https://pilot.landvex.com/api/v1/missions/:id (get) ✅ POST /api/v1/missions/import (video upload) ✅ UI loads with title 'LandveX Intelligence Lab' Next: Pilot 001 — Break the system!
15 KiB
AAMOS Infrastrukturanalys — Del 2
LandveX Enterprise Platform — Återanvändningsbarhet & Anpassningskostnad
Datum: 2026-07-02
Analytiker: Subagent (AAMOS Infrastructure Analysis)
Status: Fortsättning på Del 1 (Auth/Identity Service: 5/5 ⭐, Låg anpassningskostnad)
Sammanfattning
| Komponent | Nuvarande användning | Återanvändningsbarhet | Anpassningskostnad |
|---|---|---|---|
| 1. API-gateway | Nginx reverse proxy + Rust-tjänster | ⭐⭐⭐⭐⭐ (5/5) | Låg |
| 2. Databaslager | PostgreSQL + Redis + PostGIS | ⭐⭐⭐⭐ (4/5) | Låg |
| 3. Event-buss | Hermes (Redis pub/sub + JSONL fallback) | ⭐⭐⭐⭐⭐ (5/5) | Låg |
| 4. Frontend-ramverk | React 19 + Vite + Tailwind (Ouroboros) | ⭐⭐⭐ (3/5) | Medium |
1. API-gateway
Nuvarande användning
AAMOS använder Nginx som central reverse proxy och API-gateway för alla 28+ Rust-tjänster:
Nginx (amos.wavult.com)
├── /api/svc/rule-engine/ → port 3201
├── /api/svc/api-gateway/ → port 3206 (intern gateway)
├── /api/svc/ledger/ → port 3250
├── /api/svc/bank-import/ → port 3253
├── /api/svc/sie-import/ → port 3254
├── /api/svc/people-core/ → port 3271
├── /api/svc/operations-core/ → port 3272
├── /api/svc/commerce-rust/ → port 3280
├── /api/svc/analytics-rust/ → port 3281
├── /api/svc/crm-rust/ → port 3282
├── /api/svc/campaign-rust/ → port 3283
├── /api/svc/hr-rust/ → port 3284
├── /api/svc/payroll-rust/ → port 3285
├── /api/svc/invoice-rust/ → port 3286
├── /api/svc/compliance-rust/ → port 3287
├── /api/svc/landvex-engine/ → port 3391
├── /api/svc/quixzoom-engine/ → port 3390
└── ... (28 tjänster totalt)
Konfigurationsfiler:
/etc/nginx/conf.d/aamos-upstreams.conf— upstream-blocks/etc/nginx/snippets/rust-services.conf— location-blocks- URL-prefix:
/api/svc/<service>/
Återanvändningsbarhet: ⭐⭐⭐⭐⭐ (5/5)
Varför hög återanvändningsbarhet:
- Standardiserat mönster — Varje tjänst följer samma konvention:
/api/svc/<namn>/→<namn>.wavult.com:<port> - Ingen affärslogik i gateway — Nginx gör endast routing, SSL-terminering och rate limiting. All affärslogik finns i tjänsterna.
- Deklarativ konfiguration — Nya tjänster läggs till med två rader (upstream + location)
- Health checks — Varje tjänst exponerar
/healthsom Nginx kan använda - TLS/SSL centraliserat — Certifikat hanteras på ett ställe
Exempel på återanvändning:
# Lägg till ny tjänst (2 rader)
upstream rust_new_service {
server localhost:3400;
}
location /api/svc/new-service/ {
proxy_pass http://rust_new_service/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Anpassningskostnad: Låg
| Aspekt | Kostnad | Kommentar |
|---|---|---|
| Ny tjänst | ~5 min | Kopiera befintligt block, ändra port |
| Ny domän | ~15 min | SSL-cert + server block |
| Rate limiting | ~10 min | Nginx limit_req_zone |
| Auth | ~30 min | JWT-validering i Nginx (lua) eller i tjänsterna |
| Load balancing | ~20 min | Flera instanser i upstream |
Risker:
- Nginx-konfigurationen växer med varje tjänst (28+ redan)
- Ingen service discovery — alla tjänster är hårdkodade
- Ingen centraliserad API-dokumentation (Swagger/OpenAPI)
Rekommendation: Behåll nuvarande lösning. Vid >50 tjänster, överväg en dynamisk service registry (Consul/Etcd).
2. Databaslager
Nuvarande användning
AAMOS använder en polyglot persistence-strategi:
| Databas | Användning | Tjänster |
|---|---|---|
| PostgreSQL | Primär transaktionsdatabas | aamos-ledger, people-core, operations-core |
| Redis | Cache + Event bus (Hermes) | Alla tjänster |
| PostGIS | Geografisk data (implicit via PostgreSQL) | quixzoom-engine, landvex-engine |
| ClickHouse | Analys och rapportering | aamos-analytics-engine |
PostgreSQL-schema (aamos-ledger):
-- Kärntabeller
ledger_accounts -- Kontoplan (BAS 2024)
ledger_journal_entries -- Verifikationer (IMMUTABLE)
ledger_journal_lines -- Kontolinjer (dubbel bokföring)
ledger_periods -- Perioder (open/closed)
ledger_audit_log -- Audit trail (append-only)
ledger_reconciliation_items -- Kontoavstämning
Återanvändningsbarhet: ⭐⭐⭐⭐ (4/5)
Varför hög återanvändningsbarhet:
- Standardiserat schema — Alla tjänster följer samma mönster:
tenant_id,trace_id,created_at - Multi-tenant design —
tenant_idpå varje rad möjliggör SaaS-modell - Audit-first — Varje operation loggas i
ledger_audit_log - JSONB för flexibilitet —
metadata-fält möjliggör utökning utan migrationer - BAS 2024 standard — Svensk kontoplan kan bytas mot IFRS/US GAAP
Exempel på återanvändning (ny tjänst):
-- Samma mönster för ny tjänst
CREATE TABLE new_service_entities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id TEXT NOT NULL,
trace_id TEXT NOT NULL,
user_id TEXT NOT NULL,
data JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
Anpassningskostnad: Låg
| Aspekt | Kostnad | Kommentar |
|---|---|---|
| Ny tenant | ~1 min | INSERT INTO tenants ... |
| Ny kontoplan | ~2 timmar | Kopiera BAS 2024, anpassa |
| Ny tabell | ~15 min | Följ befintligt mönster |
| Migration | ~30 min | ALTER TABLE eller ny tabell |
| Backup/restore | ~10 min | pg_dump / pg_restore |
| PostGIS | ~1 timme | Aktivera extension, spatiala index |
Risker:
- PostgreSQL är single-node (ingen replikering dokumenterad)
- ClickHouse är separat — data dupliceras potentiellt
- Ingen connection pooling (PgBouncer) dokumenterad
ledger_journal_entriesväxer obegränsat — partitionering behövs vid skala
Rekommendation:
- Sätt upp PostgreSQL-replikering (primary-replica) för läs-skala
- Överväg PgBouncer vid >100 samtidiga anslutningar
- Partitionera
ledger_journal_entriesperfiscal_year
3. Event-buss (Hermes)
Nuvarande användning
Hermes är AAMOS event fabric — en thin adapter mellan tjänster:
┌─────────────────────────────────────────────────────────────┐
│ HERMES EVENT FABRIC │
├─────────────────────────────────────────────────────────────┤
│ Transport: Redis pub/sub (primär) │
│ Fallback: JSONL-fil (/tmp/hermes/events.jsonl) │
│ Kanal: aamos:hermes │
├─────────────────────────────────────────────────────────────┤
│ Event envelope: │
│ { id, trace_id, correlation_id, event_type, source, │
│ tenant_id, user_id, entity_type, entity_id, │
│ decision_source, payload, ts, schema_version } │
└─────────────────────────────────────────────────────────────┘
Användning i aamos-ledger:
// Vid varje operation
await hermes.emit('finance.journal.posted', ctx, {
entry_id: id, entry_number, period, fiscal_year
});
await hermes.emit('finance.account.created', ctx, {
account_number, name, coa_standard
});
await hermes.emit('finance.period.closed', ctx, {
period, fiscal_year, closed_by
});
Återanvändningsbarhet: ⭐⭐⭐⭐⭐ (5/5)
Varför maximal återanvändningsbarhet:
- Universal event envelope — Samma schema för ALLA händelser oavsett tjänst
- Trace propagation —
trace_idochcorrelation_idföljer genom hela systemet - Tenant isolation —
tenant_idi varje event säkerställer multi-tenant - Decision source —
'user'|'system'|'agent'möjliggör audit och AI-spårning - Fallback-arkitektur — Redis nere? JSONL-fil garanterar durabilitet
- Schema versioning —
schema_version: '1.0'möjliggör evolution
Exempel på återanvändning (ny tjänst):
import hermes from './hermes.mjs';
// Publicera
await hermes.emit('crm.deal.won', ctx, { deal_id, value, customer });
// Prenumerera
await hermes.subscribe((event) => {
if (event.event_type === 'finance.journal.posted') {
// Uppdatera CRM med betalningsstatus
}
});
Anpassningskostnad: Låg
| Aspekt | Kostnad | Kommentar |
|---|---|---|
| Nytt event | ~2 min | hermes.emit('domain.action', ctx, payload) |
| Ny prenumerant | ~5 min | hermes.subscribe(handler) |
| Ny kanal | ~5 min | Ändra HERMES_CHANNEL env-var |
| Redis-cluster | ~1 timme | Konfigurera sentinel/cluster |
| Kafka-migrering | ~1 dag | Byta transport, behålla envelope |
Risker:
- Redis pub/sub är fire-and-forget (ingen persistens utanför JSONL)
- Inga dead-letter queues dokumenterade
- Ingen event replay-mekanism
- JSONL-filen växer obegränsat — rotation behövs
Rekommendation:
- Sätt upp log rotation för JSONL-filen
- Överväg Redis Streams (istället för pub/sub) för persistens
- Dokumentera event-katalog (alla event_type som används)
4. Frontend-ramverk (Ouroboros)
Nuvarande användning
Ouroboros är LandveX Fortnox-klon — ett React-baserat webbgränssnitt:
Ouroboros Frontend
├── React 19.2.7
├── Vite 8.1.0 (build tool)
├── TypeScript 6.0.2
├── Tailwind CSS 4.3.1
├── React Router 7.18.0
├── Recharts 3.9.0 (diagram)
├── Lucide React 1.21.0 (ikoner)
└── API-client: Fetch + localStorage JWT
Struktur:
src/
├── App.tsx # Huvudkomponent (just nu: Vite-default)
├── main.tsx # Entry point
├── index.css # Tailwind + global styles
├── components/
│ └── Layout.tsx # Sidebar + navigation
├── contexts/
│ └── AuthContext.tsx # JWT auth (mock just nu)
├── types/
│ └── index.ts # TypeScript interfaces
└── utils/
└── api.ts # API client (ej kopplad till backend)
Nuvarande status:
- ✅ Byggt med modern stack (React 19, Vite, Tailwind)
- ✅ TypeScript för typsäkerhet
- ✅ Layout-komponent med navigation
- ✅ AuthContext med JWT-hantering
- ⚠️ App.tsx är fortfarande Vite-default (räknare, loggor)
- ⚠️ API-klienten är ej kopplad till aamos-ledger (localhost:3000)
- ⚠️ Auth är mock (hardkodad användare)
- ⚠️ Inga sidor implementerade (endast Layout)
Återanvändningsbarhet: ⭐⭐⭐ (3/5)
Varför medelhög återanvändningsbarhet:
- Modern stack — React 19 + Vite + Tailwind är branschstandard
- Komponentbaserad — Layout, AuthContext kan återanvändas
- TypeScript — Typer definierade för alla domänobjekt
- API-abstraktion —
api.tsger ett lager ovanpå fetch
Begränsningar:
- Ej kopplad till backend — API-klienten pekar på fel URL (
localhost:3000istället föramos.wavult.com:3250) - Mock-auth — Ingen riktig JWT-flöde implementerat
- Ingen state management — Ingen Zustand/Redux/React Query
- Inga formulär — Ingen react-hook-form eller liknande
- Inga tester — Inget test-ramverk konfigurerat
Anpassningskostnad: Medium
| Aspekt | Kostnad | Kommentar |
|---|---|---|
| Koppla till backend | ~2 timmar | Uppdatera API_BASE_URL, anpassa endpoints |
| Implementera sidor | ~2-3 dagar | Dashboard, verifikat, kontoplan, rapporter |
| JWT-auth | ~4 timmar | Integrera med aamos-ledger auth.mjs |
| State management | ~1 dag | Zustand eller React Query för server-state |
| Formulär | ~1 dag | react-hook-form för verifikat-inmatning |
| Tester | ~2 dagar | Vitest + React Testing Library |
| Mobilanpassning | ~1 dag | Tailwind responsive (redan delvis) |
Risker:
- Stor gap mellan design (Layout.tsx) och implementation (App.tsx)
- API-klienten har typer som inte matchar backend (Voucher vs journal_entry)
- Ingen error handling eller loading states
- Ingen pagination för stora listor (verifikat, konton)
Rekommendation:
- Omedelbart: Uppdatera
API_BASE_URLtillhttps://amos.wavult.com/api/ledger - Sprint 1: Implementera Dashboard-sida med riktig data
- Sprint 2: Verifikat-lista och detaljvy
- Sprint 3: Verifikat-inmatning med formulär
- Sprint 4: Rapporter (P&L, balansräkning)
Jämförelse med Auth/Identity Service (Del 1)
| Komponent | Återanvändningsbarhet | Anpassningskostnad | Nyckelskillnad |
|---|---|---|---|
| Auth/Identity | ⭐⭐⭐⭐⭐ | Låg | Redan abstraherad, tenant-aware |
| API-gateway | ⭐⭐⭐⭐⭐ | Låg | Samma mönster, deklarativ config |
| Databaslager | ⭐⭐⭐⭐ | Låg | Standardiserat schema, men skalning behövs |
| Event-buss | ⭐⭐⭐⭐⭐ | Låg | Universal envelope, fallback-arkitektur |
| Frontend | ⭐⭐⭐ | Medium | Modern stack men ej kopplad till backend |
Rekommendationer per komponent
API-gateway: ✅ Behåll
- Nginx är beprövad, stabil och kräver minimal anpassning
- Överväg endast dynamisk service registry vid >50 tjänster
Databaslager: ⚠️ Förbättra
- Sätt upp PostgreSQL-replikering
- Partitionera
ledger_journal_entries - Överväg PgBouncer för connection pooling
Event-buss: ✅ Behåll, förbättra
- Hermes-envelopen är utmärkt
- Lägg till log rotation för JSONL
- Dokumentera event-katalog
Frontend: 🔴 Prioritera
- Största gapet mellan design och implementation
- Koppla till backend omedelbart
- Implementera sidor i prioritetsordning: Dashboard → Verifikat → Rapporter
Nästa steg
- Omedelbart: Koppla Ouroboros frontend till aamos-ledger backend
- Vecka 1: Implementera Dashboard med riktig data
- Vecka 2: Implementera verifikat-lista och detaljvy
- Vecka 3: PostgreSQL-replikering och partitionering
- Vecka 4: Hermes event-katalog och log rotation
Analys baserad på:
aamos-ledger/index.mjs— Ledger Engine APIaamos-ledger/hermes.mjs— Event fabricaamos-ledger/schema.sql— Databasschemaouroboros-frontend/— React frontendmemory/nginx-upstreams-result.md— Nginx konfigurationlandvex-plugin-architecture.md— Plugin-arkitektur