1. Vision & Scope
Panda Accounting är ett automatiserat ekonomi-nav för fåmansbolag. Fortnox är datahub, AI-agenter hanterar flöden, k3s isolerar bolag från varandra.
Automatiserade flöden
- Tid → Fakturagrund → Faktura → Betalning → Bokförd intäkt
- Kvitto/faktura in → OCR-tolkning → Kontering → Bokföring
- Bankimport → Matchning → Avstämning
- Lön → AGI → Skattekonto
- Moms-sammanställning → Deklaration
- Årsredovisning → Bokslut
Vad det inte är
- Inte full ERP (inget lager, inget CRM)
- Inte moms utomlands (initialt)
- Inte personaladministration (bara lönekost)
- Fokus: Fåmansbolag med 1–3 ägare
- Första bolag: Panda Rock Holding AB, LDCAB, FTUAB, TASAB
2. Systemarkitektur
Bygger på tre-lagersystemet: panda-gitea (change control), panda-ai-agent-organisation (företagsmodell), panda-k3s (runtime). Infisical säkrar secrets. Mainframe visualiserar.
Strukturerar idé"] F["Forge
Grundar repo & org"] CO["Commissioner
Spawnar agenter"] end subgraph GITEA["Gitea (change control)"] REPO["panda-accounting repo
Issues • PRs • Releases"] end subgraph K3S["k3s Runtime"] subgraph NS_LDCAB["Namespace: ldcab"] A1["Finance Lead"] A2["Integration Specialist"] A3["Validation Agent"] end subgraph NS_PRH["Namespace: panda-rock-holding"] A4["Finance Lead"] A5["Integration"] A6["Validation"] end subgraph NS_FTUAB["Namespace: ftuab"] A7["Finance Lead"] A8["Integration"] end subgraph NS_TASAB["Namespace: tasab"] A9["Finance Lead"] A10["Integration"] end end subgraph SECRETS["Infisical"] S1["/ldcab/* (Svea)"] S2["/panda-rock-holding/* (Svea)"] S3["/ftuab/* (SEB)"] S4["/tasab/* (Svea)"] end subgraph EXTERNAL["Externa system"] FN["Fortnox API"] BANK["SEB Bank"] SKV["Skatteverket"] KIM["Kimai"] end MF["Mainframe Dashboard"] D --> F --> CO --> K3S F --> REPO K3S --> SECRETS NS_LDCAB --> FN NS_LDCAB --> BANK NS_PRH --> FN NS_FTUAB --> FN NS_TASAB --> FN K3S --> MF KIM --> K3S
panda-gitea
Change control. Hur arbete förändras: branching, PRs, releases, labels, milestones. Spårbarhet för alla ändringar.
panda-ai-agent-organisation
Företagsmodell. Roller (ROLE-001–011), avdelningar (DEPT-001–007), kärnflöden (FLOW-001–003). Definierar vad agenter gör.
panda-k3s
Runtime-plattform. Company CRD → Operator → Namespace → Pods. Definierar var agenter kör, isolerat och deklarativt.
3. Teknisk plattform — k3s + Infisical under huven
Hur allting faktiskt hänger ihop tekniskt. Från YAML-fil till körande agent med rätt secrets, isolerad från alla andra.
Livscykel: Från YAML till körande agent
När du kör kubectl apply -f company-ldcab.yaml — vad händer steg för steg?
Klusterarkitektur: Namespaces, pods och isolering per bolag
(watchar Company + Agent CRDs)"] ARGO["ArgoCD
(GitOps sync)"] INOP["Infisical Operator
(secret injection)"] end subgraph NS_PRH["namespace: panda-rock-holding"] direction TB PRH_FL["Finance Lead
Sonnet • 512Mi"] PRH_INT["Integration
Sonnet • 512Mi"] PRH_VAL["Validation
Haiku • 256Mi"] PRH_NP["NetworkPolicy
egress: Fortnox + Svea Bank"] PRH_SA["ServiceAccount
+ Infisical Identity"] PRH_PVC["PVC 1Gi workspace"] PRH_CM["ConfigMap
SOUL.md • AGENTS.md"] end subgraph NS_LDCAB["namespace: ldcab"] direction TB LDCAB_FL["Finance Lead
Sonnet • 512Mi"] LDCAB_INT["Integration
Sonnet • 512Mi"] LDCAB_VAL["Validation
Haiku • 256Mi"] LDCAB_NP["NetworkPolicy
egress: Fortnox + Svea Bank"] LDCAB_SA["ServiceAccount
+ Infisical Identity"] end subgraph NS_FTUAB["namespace: ftuab"] direction TB FTUAB_FL["Finance Lead
Sonnet • 512Mi"] FTUAB_INT["Integration
Sonnet • 512Mi"] FTUAB_VAL["Validation
Haiku • 256Mi"] FTUAB_NP["NetworkPolicy
egress: Fortnox + SEB"] FTUAB_SA["ServiceAccount
+ Infisical Identity"] end subgraph NS_TASAB["namespace: tasab"] direction TB TASAB_FL["Finance Lead
Sonnet • 512Mi"] TASAB_INT["Integration
Sonnet • 512Mi"] TASAB_VAL["Validation
Haiku • 256Mi"] TASAB_NP["NetworkPolicy
egress: Fortnox + Svea Bank"] TASAB_SA["ServiceAccount
+ Infisical Identity"] end end NS_PRH -.-x|BLOCKERAD| NS_LDCAB NS_LDCAB -.-x|BLOCKERAD| NS_FTUAB NS_FTUAB -.-x|BLOCKERAD| NS_TASAB NS_PRH -.-x|BLOCKERAD| NS_TASAB
Total isolering per bolag
Varje bolag får eget namespace med egen NetworkPolicy, ServiceAccount och Infisical-identity. FTUAB (SEB) har annan bank-egress än de andra (Svea).
Resursbudget
Per pod: 250m–1000m CPU, 256Mi–512Mi RAM
Totalt kluster: ~4–6 GB RAM, ~3–4 CPU cores
Workspace: 1Gi PVC per namespace (local-path)
kube-system
Agent Operator: Watchar CRDs, skapar resurser
Infisical Operator: Injicerar secrets
ArgoCD: GitOps sync från Gitea
CoreDNS: Intern DNS
Infisical: Secrets-flöde i detalj
FORTNOX_KEY
SVEA_BANK_TOKEN"] L["/ldcab
FORTNOX_KEY
SVEA_BANK_TOKEN"] F["/ftuab
FORTNOX_KEY
SEB_BANK_TOKEN"] T["/tasab
FORTNOX_KEY
SVEA_BANK_TOKEN"] SH["/shared
SKATTEVERKET_CERT
KIMAI_TOKEN"] end subgraph IDS["Machine Identities (1 per agent)"] I0["prh-finance-svc
read: /panda-rock-holding, /shared"] I1["ldcab-finance-svc
read: /ldcab, /shared"] I2["ftuab-finance-svc
read: /ftuab, /shared"] I3["tasab-finance-svc
read: /tasab, /shared"] end end I0 -->|allow| PRH I0 -->|allow| SH I0 -.-x|DENY| L I0 -.-x|DENY| F I1 -->|allow| L I1 -->|allow| SH I1 -.-x|DENY| PRH I2 -->|allow| F I2 -->|allow| SH I2 -.-x|DENY| L
Least Privilege + Deny-test
- En identity per agent — inte delad
- Scoped till sin path — LDCAB ser bara
/ldcab/* - Deny-testad — verifierat att läsning av /panda-rock nekas
- Delad path —
/shared/*för Skatteverket, Kimai - Token-rotation — access tokens har TTL 1h
Universal Auth → K8s Operator → OIDC
- PoC: Init Container auth:ar med Client ID + Secret
- Prod: Infisical K8s Operator injicerar secrets som K8s Secrets automatiskt
- Enterprise: Pod ServiceAccount JWT → Keycloak OIDC → Infisical (noll statiska credentials)
Nätverksisolering: Vad får prata med vad?
Inom eget namespace
Agenter i samma bolag pratar fritt. Finance Lead delegerar till Integration Specialist.
Godkänd egress
Fortnox, SEB, Infisical — bara HTTPS 443. Konfigureras per bolag i Helm values.
Cross-namespace + random
LDCAB-pod når aldrig panda-rock-namespace. K3s NetworkPolicy på kernel-nivå (iptables/nftables).
CRD-exempel: Hur YAML:en ser ut
company-ldcab.yaml
apiVersion: panda.rocks/v1
kind: Company
metadata:
name: ldcab
spec:
name: "Landvetter Datacenter AB"
owner: simon
template: panda-ai-agent-organisation
orgSlice: light
infisicalProject: panda-ops
networkPolicy:
isolateNamespace: true
allowedEgress:
- secrets.panda-rock.com
- apps.fortnox.se
- api.sveabank.se
agents:
- role: ROLE-003
name: finance-lead
model: anthropic/claude-sonnet-4-20250514
- role: ROLE-005
name: integration
- role: ROLE-008
name: validation
model: anthropic/claude-haiku-4-5
Genereras av Operator
apiVersion: panda.rocks/v1
kind: Agent
metadata:
name: finance-lead
namespace: ldcab
spec:
role: ROLE-003
department: DEPT-005
model: anthropic/claude-sonnet-4-20250514
secrets:
infisicalIdentity: ldcab-finance-svc
scope:
- /ldcab
- /shared
resources:
cpu: "500m"
memory: "512Mi"
skills:
- fortnox-api
- bank-reconciliation
GitOps: Från git push till körande ändring
Ändra YAML i Git → Gitea webhook → ArgoCD sync → Operator reconcile → pods uppdateras. Ingen manuell kubectl i produktion. Allt spårbart i Git-historiken.
Observability: Prometheus → Grafana → Mainframe
Prometheus + Grafana (redan igång)
ServiceMonitor i k3s exponerar metrics → Prometheus skrapar automatiskt. UPS-dashboard, Docker-metrics — nu även agent-metrics.
Agent-specifika alerts
- Pod restarts — agent kraschar
- Secret fetch failures — Infisical nere
- Fortnox API errors — 429 rate limit / 500
- Avvikelsekö-djup — övermycket exceptions
4. Orkestrering — Vem gör vad?
Från idé till körande system. Steering layer hanterar setup, org-tier kör arbetet.
Roller i detta projekt
Setup & Provisionering
- Distiller — Tar rå idé → strukturerad brief
- Forge — Skapar repo, mappar org-struktur
- Commissioner — Spawnar & verifierar agenter
Steering layer äger inte projektet — de skapar det och lämnar över.
Dagligt arbete
- Finance Lead (ROLE-003 CFO) — Övervakar KPIs, styr prioritet
- Integration Specialist (ROLE-005 CASO) — Bygger API-kopplingar
- Validation Agent (ROLE-008 Quality) — Verifierar data, moms, avstämningar
- Ops Lead (ROLE-007) — Daglig orkestrering
5. Huvudflöden
Sju kärnflöden från v2-verksamhetsflöde.md. Varje objekt har states från entities-and-states.md. Fortnox API-stöd från fortnox-api-karta.md.
Flöde 1 — Tid → Fakturagrund → Faktura → Betald intäkt
Primära intäktskedjan. Källa: slice-1-spec.md (v2.1). Fullständigt definierad med idempotens, states och felhantering.
Flöde 2 — Leverantörskostnader & Kvitton
(OCR + Vision)"] B --> C["Kontering
(momskod, konto, projekt)"] C --> D["Review
(manuell gate)"] D --> E["Fortnox
POST /supplierinvoices"] E --> F["Betalning
(scheduled)"] F --> G["Avstämd"] B -->|Exception| EX["Avvikelsekö
Saknat underlag / Okänd moms"]
- States: received → interpreted → coded → reviewed → booked → paid → reconciled
- API: POST /3/supplierinvoices + filkoppling
- Attestflöde fullt API-stött
- Insamling: Mobil → Nextcloud → Pipeline
- Alternativ: Telegram-bot (foto → auto-bokför)
- States: received → interpreted → coded → booked → reconciled
Flöde 3 — Bank & Skattekonto (kontrollagret)
reskontra/lön/skatt"] MATCH --> POST["Bokföring"] POST --> REC["Avstämning"] MATCH -->|Omatchad| EX["Avvikelse"] SKV["Skattekonto"] --> SKVIMP["Import"] SKVIMP --> SKVMATCH["Matchning
moms/AGI/prelskatt"] SKVMATCH --> SKVREC["Avstämning"]
Viktigt: Fortnox exponerar inte banktransaktioner via API. Bankmatchning sker i Fortnox UI eller via deras interna bankintegration. Vår pipeline registrerar betalningar (Invoice Payments / Supplier Invoice Payments) och pollar status — själva avstämningen är en manuell checkpoint.
Flöde 4 — Lön
lönetransaktioner"] REG --> CALC["Lönekörning
(Fortnox UI)"] CALC --> BESKED["Lönebesked"] BESKED --> PAY["Nettolön utbetalas"] PAY --> AGI["AGI rapporteras
(Fortnox UI)"] AGI --> SKV["Skattekonto
reglering"] SKV --> BOK["Bokförd
lönekostnad"]
Lönekörning (beräkning av skatt, avgifter, nettolön), AGI-rapportering och lönebesked sker i Fortnox UI — inte via API. Vår automation förbereder (lönetransaktioner via API) och efterkontrollerar (avstämning mot skattekonto).
Flöde 5 — Moms
och kostnader"] --> CALC["Sammanställ
momsgrund"] CALC --> REPORT["Momsrapport"] REPORT --> REVIEW["Kontroll
(manuell gate)"] REVIEW --> DECL["Deklaration
(Skatteverket)"] DECL --> PAY["Betalning/återbetalning
via skattekonto"] PAY --> CLOSE["Period stängd"]
Momsrapport och momsdeklaration kan inte genereras via Fortnox API. Däremot säkerställer vår pipeline att varje transaktion har rätt momskod vid bokföring — det är det som avgör om rapporten blir korrekt. States: open → prepared → reviewed → filed → paid-or-refunded → closed.
Flöde 6 — Bokslut & Årsredovisning
bank + reskontra + skattekonto"] CHECK --> PER["Periodiseringar
& justeringar"] PER --> BOKSLUT["Bokslut"] BOKSLUT --> AR["Årsredovisning"] AR --> DECL["Deklaration (INK2)"]
Bokslut är kvalitetstestet på alla tidigare flöden. Om bank, reskontra, moms och skattekonto stämmer är bokslutet en formalisering. Vår automation säkerställer att förutsättningarna är uppfyllda; själva årsredovisningen är semi-manuell.
Fortnox API-stöd per domän
Källa: fortnox-api-karta.md. Rate limit: 25 req/5s per access-token.
| Domän | Bedömning | Kommentar |
|---|---|---|
| Kunder & Projekt | ● Byggbart | Full CRUD |
| Tid → Fakturaunderlag | ● Workaround | Kimai → egen pipeline → Fortnox |
| Kundfakturor | ● Byggbart | Hela livscykeln API-bar |
| Leverantörsfakturor | ● Byggbart | Inkl. attest och filkoppling |
| Bokföringsverifikationer | ● Byggbart | Skapa + läsa (ej ändra, by design) |
| Bankmatchning | ● Ej via API | Fortnox black box. Betalningsreg. möjlig. |
| Lön | ● Workaround | Data in/ut OK, lönekörning = Fortnox UI |
| Moms/Skatt | ● Rapportering ej API | Kontering = API-bar (det som spelar roll) |
| Bilagor | ● Byggbart | Upload + koppling fullt stödd |
6. Säkerhet & Isolering
Agenter får bara åtkomst till sitt bolags data. K3s namespace + Infisical scoped secrets + NetworkPolicy.
ldcab-finance-svc
Path: /ldcab/*"] I2["Machine Identity:
pr-finance-svc
Path: /panda-rock/*"] end subgraph K3S["k3s kluster"] subgraph NS1["Namespace: ldcab
(NetworkPolicy: isolerad)"] P1["Finance Pod"] P2["Integration Pod"] end subgraph NS2["Namespace: panda-rock
(NetworkPolicy: isolerad)"] P3["Finance Pod"] P4["Integration Pod"] end end I1 -.->|"read-only"| P1 I1 -.->|"read-only"| P2 I2 -.->|"read-only"| P3 I2 -.->|"read-only"| P4 P1 -->|"HTTPS 443"| FN["Fortnox API"] P3 -->|"HTTPS 443"| FN NS1 -.-x|"BLOCKED"| NS2
k3s
Varje bolag = eget namespace. NetworkPolicy: bara utgående till godkända endpoints (Fortnox, SEB). Inget cross-namespace.
Infisical
Machine identity per agent. Scoped till /bolag/*. Deny-testad: LDCAB-agent kan inte läsa Panda Rocks secrets.
Loggning
Alla API-anrop loggas. Avvikelser flaggas automatiskt. Prometheus + Grafana för driftövervakning.
7. Multi-bolag Design
Systemet är designat från grunden för flera bolag. Lägg till nytt bolag = ny Company CRD + Infisical-path.
bank: Svea
agents: 3"] C1["company: ldcab
bank: Svea
agents: 3"] C2["company: ftuab
bank: SEB
agents: 3"] C3["company: tasab
bank: Svea
agents: 3"] end CONFIG -->|"kubectl apply"| K3S["k3s Operator"] K3S --> NS0["NS: panda-rock-holding"] K3S --> NS1["NS: ldcab"] K3S --> NS2["NS: ftuab"] K3S --> NS3["NS: tasab"]
4 steg
- Skapa Company YAML — Namn, Fortnox-instans, önskade agenter
- Lägg till secrets i Infisical —
/nytt-bolag/fortnox-key,/nytt-bolag/bank-token kubectl apply -f company-nytt-bolag.yaml— Operator skapar namespace, spawnar pods- Verifiera — Agent hämtar rätt secrets? NetworkPolicy blockerar cross-namespace?
8. Implementationsplan
Prioriterad byggordning. Bygg det som gör resten möjligt först.
Slice 1 — Definition of Done (16 krav)
Källa: slice-1-spec.md v2.1. Slicen är klar när:
- Tid kan hämtas från Kimai API och valideras mot mappningsregler
- Fakturagrund byggs automatiskt med korrekt gruppering och summering
- Fakturagrunden visar råtid + fakturerbar tid (avrundad per 0.25h)
- Manuell granskning kan godkänna / avvisa / justera fakturagrund
- Manuella justeringar loggas med vem/vad/varför (audit trail)
- Godkänd fakturagrund skapar korrekt faktura i Fortnox via API
- Fakturan bokförs i separat steg efter skapande
- Fakturan skickas i separat steg efter bokföring
- Pipeline pollar fakturastatus med trippelverifiering
- Vid full betalning verifieras att intäkten är bokförd
- Behandlade tidrader markeras som exporterade i Kimai
- Om Kimai-lock misslyckas hanteras det via terminalstate + periodisk retry
- Alla avvikelsefall (E01–E13) loggas i kö med typ och allvarlighet
- Hela kedjan kan köras om utan dubbletter (idempotens)
- Manuella gates är explicita och dokumenterade
- Delbetalning är explicit out-of-scope och stoppar progression
9. Risker & Begränsningar
Kända risker och hur vi hanterar dem.
Bankmatchning är en black box
Fortnox exponerar inte banktransaktioner via API. Avstämning sker i Fortnox UI. Mitigation: Registrera betalningar via API, acceptera manuell gate för avstämning.
Fortnox rate limits
25 requests / 5 sekunder per token. Med flera bolag + agenter = risk för throttling. Mitigation: Staggera anrop, respektera Retry-After, köa requests.
Lön/moms kräver manuella steg
Lönekörning, momsdeklaration och AGI-rapportering kan inte automatiseras fullt via API. Mitigation: Automation förbereder och efterkontrollerar; manuellt steg i Fortnox UI.
Multi-bolag Fortnox
Separata Fortnox-instanser per bolag? Eller en gemensam med sub-accounts? Påverkar kostnad och isolering. Beslut krävs.
10. Öppna frågor för beslut
Dessa måste besvaras innan byggstart. Markerade med prioritet.
Q1: Fortnox API-åtkomst
Finns OAuth-app registrerad? Vilka scopes? Behöver registreras via Fortnox Developer-portal.
Q2: Fortnox-instanser
En per bolag (isolerat, dyrare) eller en gemensam med kostnadsställen (billigare, delad)?
Q3: Kimai-instans
Vilken Kimai ska vi ansluta mot? URL + API-token. Vilka projekt finns redan?
Q4: Avrundningsregler
Timmar: närmaste 0.25h (15 min) upprundat? Default-förslag i slice-1-spec.
Q5: Fakturautsändning
E-post, e-faktura, eller båda? Påverkar steg 5c i slice 1.
Q6: Org-tier
Full (10 roller) eller Light (3 agenter: Foreman, Smith, Warden)? Rekommendation: Light för PoC, uppgradera vid behov.