Files
boc/AAMOS_INFRASTRUCTURE_ANALYSIS_PART2.md
T
Bernt 05ed037fe8 pilot.landvex.com: HTTPS + Full Stack Verified
- 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!
2026-07-02 17:34:19 +00:00

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:

  1. Standardiserat mönster — Varje tjänst följer samma konvention: /api/svc/<namn>/<namn>.wavult.com:<port>
  2. Ingen affärslogik i gateway — Nginx gör endast routing, SSL-terminering och rate limiting. All affärslogik finns i tjänsterna.
  3. Deklarativ konfiguration — Nya tjänster läggs till med två rader (upstream + location)
  4. Health checks — Varje tjänst exponerar /health som Nginx kan använda
  5. 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:

  1. Standardiserat schema — Alla tjänster följer samma mönster: tenant_id, trace_id, created_at
  2. Multi-tenant designtenant_id på varje rad möjliggör SaaS-modell
  3. Audit-first — Varje operation loggas i ledger_audit_log
  4. JSONB för flexibilitetmetadata-fält möjliggör utökning utan migrationer
  5. 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_entries vä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_entries per fiscal_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:

  1. Universal event envelope — Samma schema för ALLA händelser oavsett tjänst
  2. Trace propagationtrace_id och correlation_id följer genom hela systemet
  3. Tenant isolationtenant_id i varje event säkerställer multi-tenant
  4. Decision source'user'|'system'|'agent' möjliggör audit och AI-spårning
  5. Fallback-arkitektur — Redis nere? JSONL-fil garanterar durabilitet
  6. Schema versioningschema_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:

  1. Modern stack — React 19 + Vite + Tailwind är branschstandard
  2. Komponentbaserad — Layout, AuthContext kan återanvändas
  3. TypeScript — Typer definierade för alla domänobjekt
  4. API-abstraktionapi.ts ger ett lager ovanpå fetch

Begränsningar:

  1. Ej kopplad till backend — API-klienten pekar på fel URL (localhost:3000 istället för amos.wavult.com:3250)
  2. Mock-auth — Ingen riktig JWT-flöde implementerat
  3. Ingen state management — Ingen Zustand/Redux/React Query
  4. Inga formulär — Ingen react-hook-form eller liknande
  5. 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:

  1. Omedelbart: Uppdatera API_BASE_URL till https://amos.wavult.com/api/ledger
  2. Sprint 1: Implementera Dashboard-sida med riktig data
  3. Sprint 2: Verifikat-lista och detaljvy
  4. Sprint 3: Verifikat-inmatning med formulär
  5. 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

  1. Omedelbart: Koppla Ouroboros frontend till aamos-ledger backend
  2. Vecka 1: Implementera Dashboard med riktig data
  3. Vecka 2: Implementera verifikat-lista och detaljvy
  4. Vecka 3: PostgreSQL-replikering och partitionering
  5. Vecka 4: Hermes event-katalog och log rotation

Analys baserad på:

  • aamos-ledger/index.mjs — Ledger Engine API
  • aamos-ledger/hermes.mjs — Event fabric
  • aamos-ledger/schema.sql — Databasschema
  • ouroboros-frontend/ — React frontend
  • memory/nginx-upstreams-result.md — Nginx konfiguration
  • landvex-plugin-architecture.md — Plugin-arkitektur