🏗️ Arkitektur & Dokumentation
Et universelt paradigme - ikke bare bogføring
Orphan System
SKNs hjerte - håndtering af uafsluttede transaktioner der venter på resolution.
Hvad er en Orphan?
En orphan er en transaktion der venter på at blive parret. Den kan være:
- Banktransaktion der mangler modkonto og bilag
- Faktura der venter på betaling
- Kvittering der ikke er bogført endnu
- Enhver ubalanceret post i regnskabet
Intelligent Autokontering
Når orphans skal parres, scorer 20+ algoritmer hver kandidat:
| Algoritme | Score | Beskrivelse |
|---|---|---|
| Modsatte beløb | +1000 pt | Perfekt match: +500 og -500 |
| Levenshtein | variabel | Stavefejl i beskrivelser |
| similar_text | variabel | Omformuleringer |
| DueDate match | +500 pt | Samme forfaldsdato |
| Dato-proximity | op til +300 pt | Tæt på hinanden |
| Cosine similarity | variabel | Semantisk lighed |
| Metaphone | variabel | Lydlighed |
| Invoice reference | +800 pt | Fakturanummer match |
Confidence Display
Den samlede score vises farvekodet i terminalen:
OrphanFZF - Interaktiv Terminal Matcher
Når du arbejder med orphans i terminalen, bruger du OrphanFZF - en fzf-baseret matcher med live preview:
$ orphanfzf
# Viser alle orphans med farvekodet confidence
# Keyboard shortcuts:
# [Q] Quick-confirm bedste match
# [1-9] Vælg specifik kandidat
# [/] Søg i alle orphans
# [R] Refresh liste
# [?] Vis hjælp
Familie-relationer
Siblings/parent YAML-baseret gruppering med unlimited nesting:
# Familie-struktur i YAML
Family:
Parent: parent_file.yaml
Siblings:
- sibling1.yaml
- sibling2.yaml
Children:
- child1.yaml
# Eksempel: Split-posteringer
# En faktura med flere linjer arver alle metadata fra parent
Transaktioner kan arve metadata fra forældre og dele attributter med søskende.
Budget & Forecasting
Automatisk fremskrivning baseret på historik - "set it and forget it".
Rullende Budget
Automatisk beregning baseret på X måneders historik:
- gobackmonths - hvor mange måneder at kigge tilbage
- forecast - antal perioder at fremskrive
- Bagatelgrænse - filtrer småbeløb fra
- Trend detection - opdager sæsonvariationer
$ gobackmonths=6 forecast=12 budgetstart=2025-01-01 php rullendebudget.php
VAT Forecasting
Forudsig hvornår momsen rammer:
- Automatisk beregning af forventet momsafregning
- Kvartalsvis eller månedlig visning
- Integration med cashflow-rapporter
- Varsling ved store afvigelser
getmomspayments() beregner forventede betalinger baseret på afregningsmønster.
Budget Expansion
Budgetfiler kan bruge specielle expansion-regler:
# Budget med hashtag-expansion
- Date: 2025-01-01
Transactions:
- Account: Expenses:#marketing
Amount: 50000
Period: monthly # Fordeles over alle måneder
Expand: true # Expandér hashtag til alle underkonti
# Resultat: 50.000/12 ≈ 4.167 kr/md fordelt på alle #marketing konti
Shadow Accounts & Konsolidering
Regnskaber i regnskaber - subdirectory-baserede shadow ledgers med unlimited nesting.
Features
- Komprimering: --daily, --weekly, --monthly, --quarterly, --halfyear, --yearly
- Private shadows: ~/.shadow_* til følsomme data
- .sa og .sa2: Markerfiler for shadow directories
- Unlimited nesting: Shadows i shadows i shadows...
- Alias-baseret sammenlægning: Konsolider via konto-aliaser
Multi-Tpath Konsolidering
Kør rapporter på tværs af flere regnskaber:
$ tpath=/reg/firma1:/reg/firma2 php balance.php
# Konsoliderer firma1 og firma2
$ tpath=/reg/holding --include-shadows php balance.php
# Inkluderer alle shadow accounts automatisk
Periodisering med Shadow Accounts
Dato-override med automatisk balancering:
# Original transaktion
- Date: 2025-01-15
Transactions:
- Account: Expenses:Rent
Amount: 12000
Date: 2025-02-01 # Override til februar
# Automatisk periodiseringspostering oprettes
Rapporter & KPI'er
Fuld økonomisk indsigt med side-by-side sammenligning og real-time KPI'er.
Balance Reports
- Side-by-side periodesammenligning
- Multi-format export: HTML, CSV, JSON, PDF
- Terminal ASCII + Web charts
- Drilldown til enkeltposter
- Sammenligning med budget
KPI Dashboard
Rapport-typer
Notifikationer
12 notifikationstyper med multi-channel delivery.
Notifikationstyper
- orphan_created - Ny orphan venter
- orphan_matched - Match fundet
- budget_exceeded - Budget overskredet
- invoice_due - Faktura forfalder
- payment_received - Betaling modtaget
- balance_warning - Lav likviditet
- report_ready - Rapport genereret
- sync_complete - Bank sync færdig
Channels
Prioritetsniveauer: critical, high, normal, low
Power Tools
Terminal-værktøjer der gør dig hurtigere end GUI'er nogensinde kunne.
RabbitHole
Stack-baseret tmux session management - som CPU stack frames:
- Hierarkiske sessions med parent/child
- Window transfer mellem sessions
- "Dyk ned, pop tilbage"
- Context preservation på tværs af niveauer
$ rabbithole push projekt-x
# Arbejd i nested session
$ rabbithole pop
# Tilbage til parent session med fuld kontekst
$ rabbithole status
# Se stack: main → projekt-x → detalje
HackIt
"Hack det du ser" - symbol-baseret navigation:
- [@symbol] extraction fra skærm
- Direkte fil+linje åbning
- #scriptpurpose auto-detection
- Fuzzy matching af symboler
# I din kode/output:
[@renderInvoice]
# HackIt finder og åbner:
vim /lib/invoice.php:187
# Med AI-assist:
$ hackit --ai "tilføj validering"
# → Claude implementerer, du godkender
Brain
Tmux session launcher via #ns tags:
- Lock management (5 min timeout)
- Session enumeration med preview
- Force mode for stuck locks
- Prioritetsbaseret sortering
$ brain regnskab
# Åbner/genoptager regnskab-session
$ brain --list
# Viser alle sessions med prioritet
Adjust
Hurtige balance-justeringer og lookups:
- SimpleAdjust - hurtig justering
- Lookup - browse eksisterende poster
- "Ingen" funktion for quick-fix
- Preview før commit
QuickTrans
Tastatur-genveje til hurtig bogføring:
Code.bash
Hashtag-baseret kodemaintenance:
- Scanner koden for #todo, #fixme, #urgent
- Scrabble-scoring af prioritet
- Sorteret output med fil+linje
$ code.bash scan
# #urgent=10pts #fixme=7pts #todo=5pts
# Sorteret liste med højeste prioritet først
Ledger Core
De centrale komponenter der driver SKNs datalag.
NewL (Hovedwrapper)
Main ledger wrapper - læser, expanderer og outputter:
- YAML/JSON reading med SHM caching
- VAT-kode expansion
- Alias management
- Daemon mode for performance
| ENV | Beskrivelse |
|---|---|
| tpath | Sti til regnskab |
| LEDGER_BEGIN | Startdato |
| LEDGER_END | Slutdato |
| budget | Inkluder budget |
| anonymize | Anonymiser output |
NNL (Hierarchical Viewer)
Interaktiv hierarkisk visualisering:
- alt-y Year view
- alt-q Quarter view
- alt-m Month view
- alt-w Week view
- alt-d Day view
Rekursive subgroup headers med summer og AccGuide integration.
OwnLedger (Balanceberegning)
Custom ledger implementation for fuld kontrol:
- Optimeret til 100k+ transaktioner
- SHM-baseret caching
- Hash-based change detection
- Lazy loading af perioder
AccGuide (Kontoplan)
Intelligent kontoplan-hjælper:
- Hierarkisk kontostruktur
- Auto-suggest baseret på beskrivelse
- Popularitet-baseret sortering
- VAT-kode nedarvning
DynFunc System
Modulær function loader med 47 kategorier og 150+ moduler.
Namespace via underscores
Funktioner navngives med underscores der mapper til filsystem-struktur:
// Kald en dynfunc:
call("orphan_calculate_confidence", $item);
// Mapper til fil:
// dynfuncs/orphan/calculate/confidence.php
// Auto-genereret stub hvis fil ikke findes:
// function orphan_calculate_confidence($item) { ... }
Kategorier (47 stk)
Daemons & Performance
Baggrundstjenester der sikrer lynhurtig respons.
Multi-Tpath Daemon
Process monitoring og .run file execution:
- Multi-tpath instance support (hash-baseret)
- Orphan matching API
- PID file management
- Inotify file watching
$ daemon.bash start
# Starter daemon for alle tpaths
$ daemon.bash status
# Viser aktive daemons og load
Terminal Session Daemon
WebSocket + tmux for browser-terminal:
- Node.js WebSocket server
- Tmux session management
- Per-tab session isolation
- Auto-reconnect ved disconnect
Redis Caching
In-memory cache for hot data:
- Balance cache per periode
- Session state
- User preferences
- TTL-baseret expiry
ZMQ Client (Parkeret)
Ultra-low latency daemon access:
- 2-10ms responstid
- ZeroMQ socket kommunikation
- In-memory cache
Status: Parkeret - mulig genaktivering ved 200k+ transaktioner.
Konfigurationssystem
Fleksibel konfiguration via SKNConfig klasse.
SKNConfig Klasse
Centraliseret konfigurationshåndtering:
- YAML-baseret konfiguration
- User vs System config separation
- Environment variable override
- Type-safe getters
// Hent config value:
$vat_rate = SKNConfig::get('vat.rate', 0.25);
// User-specific config:
$theme = SKNConfig::user('ui.theme', 'dark');
Entity Types
Forskellige konfigurationsprofiler:
YAML Konfigurationsstruktur
# ~/.skn/config.yaml
entity:
type: company
name: "Firma A/S"
cvr: "12345678"
accounting:
fiscal_year_start: "01-01"
vat_rate: 0.25
currency: DKK
ui:
theme: dark
terminal_font: "JetBrains Mono"
date_format: "Y-m-d"
notifications:
email: true
push: false
channels:
- orphan_created
- budget_exceeded
Gæstesystem
Sikker sandbox for demo og gæsteadgang.
30-dages Udløb
Gæstekonti slettes automatisk efter 30 dage inaktivitet:
- Automatisk cleanup via cronjob
- Warning email før sletning
- Data export mulighed
Rate Limiting
Beskyttelse mod misbrug:
- Max 100 requests/minut
- Max 1000 transaktioner/dag
- Max 10 MB upload/dag
- Automatisk throttling
Sandbox Isolation
Gæster kører i isoleret miljø:
Integration APIs
Forbind SKN med eksterne systemer.
PostgreSQL
YAML → PostgreSQL med hash-based change detection
Bank Sync
Automatisk bankimport via API
Systemarkitektur
┌─────────────────────────────────────────────────────────────────────────────┐
│ INPUT STREAMS │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Bank │ │ Email │ │ Webhook │ │ Manual │ │ OCR │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │
│ └────────────┴─────┬──────┴────────────┴────────────┘ │
│ ▼ │
├─────────────────────────────────────────────────────────────────────────────┤
│ PARSER LAYER │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ CSV Parser │ XML Parser │ JSON Parser │ YAML Parser │ PDF/OCR │ │
│ │ Standardiserer alle inputs til fælles transaction format │ │
│ └──────────────────────────────┬───────────────────────────────────────┘ │
│ ▼ │
├─────────────────────────────────────────────────────────────────────────────┤
│ ORPHAN STORE │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ orphans/*.yaml (plain text, git-versioneret) │ │
│ │ Familie-relationer │ Metadata │ Attachments │ History │ │
│ └──────────────────────────────┬───────────────────────────────────────┘ │
│ ▼ │
├─────────────────────────────────────────────────────────────────────────────┤
│ MATCHING ENGINE │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │Levensh.│ │ Cosine │ │Opposite│ │ Date │ │Metaphon│ │Invoice │ │
│ └───┬────┘ └───┬────┘ └───┬────┘ └───┬────┘ └───┬────┘ └───┬────┘ │
│ └──────────┴─────┬────┴──────────┴──────────┴──────────┘ │
│ ▼ │
│ Ensemble voting → Confidence Score (0-100%) │
│ ▼ │
├─────────────────────────────────────────────────────────────────────────────┤
│ CONFIRMATION UI │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ Terminal (orphanfzf) │ TekstTV │ Web UI │ API │ │
│ │ │ │
│ │ [Q] Bekræft [1-9] Vælg [/] Søg [R] Repeat [?] Hjælp │ │
│ └──────────────────────────────┬───────────────────────────────────────┘ │
│ ▼ │
├─────────────────────────────────────────────────────────────────────────────┤
│ OUTPUT LAYER │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Ledger │ │ CSV │ │ JSON │ │ Reports │ │ Notify │ │
│ │ Files │ │ Export │ │ API │ │ (PDF) │ │ System │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
AI & Intelligent Matching
90%+ hitrate med klassiske algoritmer — maskinen foreslår, mennesket beslutter
6-Algoritme Highscore
I stedet for at stole på én algoritme, kører vi 6 forskellige og tager gennemsnittet. Det giver en robust score der fanger forskellige typer af lighed.
Fortegns-Antagelsen
Den vigtigste regel: Debet = Kredit. En orphan med +5.000 kr kan kun matches med en orphan på -5.000 kr.
Modsatte beløb = +1000 points = 🟢 100% confidence
Confidence Scoring
Hver match får en farvekodet confidence score:
I orphanfzf terminalen ser du øjeblikkeligt hvilke matches du kan stole på. Tryk Q for quick-accept på grønne.
similar_text() vs Levenshtein
Levenshtein straffer lange ord urimeligt hårdt. similar_text() finder det der matcher:
"ABC Corporation" → "ABC Corp"
50% match
"ABC Corporation" ↔ "ABC Corp"
85% match
Perfekt til "ACME Corporation A/S" vs "ACME Corp"
Anonymisering — Outsourcing uden databekymringer
Vi arbejder på anonymisering af både tekst og tal i et format hvor man stadig kan løse de logiske og matematiske udfordringer der er i et regnskab. Resultatet: en revisor fra udlandet kan føre dit regnskab uden adgang til følsomme data.
Revolut, OLSENS REVISION APS
Butterfly, MOUNTAIN HARMONY LLC
Konceptet: Tekst erstattes med tilfældige ord fra en wordlist, men lignende ord får lignende erstatninger (75% similarity threshold). Tallene bevares i struktur så balancer stadig balancerer.
Indtil dette er fuldt klar, arbejder systemet med den velafprøvede klassiske teknologi beskrevet ovenfor.
OCR — Open Source Bilagsscanning
Vi har haft success med AI-baseret open source OCR, som let afløfter linjer fra fakturaer. Kombinerer cloud-services med lokale open source modeller.
Bemærk: P.t. mangler kapital til udstyr — specifikt VRAM til lokale AI-modeller. Donationer eller investering vil accelerere denne udvikling markant.
Fremtiden: Digitalisering, ikke AI
Et ChatGPT-svar bruger 10x mere strøm end en Google-søgning. Det er ikke holdbart for milliarder af daglige transaktioner.
PEPPOL — Åben handelsstandard
Når data er struktureret fra starten, behøver vi ikke gætte. Åbne standarder gør matching trivielt.
Klassiske algoritmer
Indtil digitaliseringen er komplet, bruger vi 6 gennemtestede algoritmer — hurtige, præcise, og med minimalt energiforbrug.
90%+ hitrate på virkelige data
IPFS & Linked Accounts
Decentral datadeling og abonnement på andres regnskaber
Regnskabsabonnementer
Med IPFS kan du abonnere på andre brugeres regnskaber. Når de opdaterer, får du automatisk ændringerne — uden central server.
Linked Accounts
Link to regnskaber sammen så de automatisk synkroniserer:
- Moderselskab ⟷ Datterselskab — Automatisk konsolidering
- Revisor ⟷ Klient — Real-time adgang
- Partner A ⟷ Partner B — Fælles projekter
Regnskab A kan abonnere på specifikke konti fra Regnskab B med filtreringsregler.
Content Addressing
IPFS bruger hash-baseret adressering. Data identificeres ved indhold, ikke lokation:
# Samme data = samme hash
QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG
# Ændring = ny hash = fuld audit trail
Perfekt til revision: Data kan ikke ændres uden ny hash.
Selektiv Synkronisering
Du bestemmer præcis hvad du deler:
Rules & Mass Updates
Automatisér gentagne handlinger med kraftfulde regler
Rule Engine
Definer regler der automatisk udføres når betingelser matches:
# Eksempel: Automatisk kategorisering
rule "Strøm til elregning":
when:
description contains "Ørsted"
OR description contains "EWII"
then:
set account: 4210 Elomkostninger
set vat: standard
auto_confirm: true
# Eksempel: Linked account sync
rule "Sync salg til revisor":
when:
account starts_with: 1000
amount > 10000
then:
publish_to: ipfs://QmRevisor...
notify: email
Mass Updates
Opdater hundredvis af poster på én gang med batch-kommandoer:
$ mass-update --where "year:2024 account:4*" \
--set "vat:reverse_charge"
Found 847 matching transactions
Preview: [Y]es / [N]o / [D]etails?
Altid preview først. Aldrig destruktive ændringer uden bekræftelse.
Komplekse Kriterier
Kombiner betingelser med AND/OR/NOT:
amount > 5000 AND account:1* AND NOT vat:exemptdescription ~ /^INV-\d{4}/ OR reference matches invoicedate between 2024-01-01..2024-03-31
Audit Trail
Alle mass updates logges med:
- Tidspunkt og bruger
- Før/efter snapshot
- Anvendt regel
- Antal berørte poster
Git-versionering gør det nemt at rulle tilbage.
Blockchain Bogføring
Uforanderlig revision med hash-kæder
Hash-Chain Princippet
Hver transaktion indeholder hash af den forrige — præcis som blockchain, men uden mining og energispild.
Ændres én post, brydes hele kæden. Perfekt til revisionsspor.
Periodisk Forsegling
Ved månedsafslutning forsegles perioden:
$ seal-period 2024-01
Sealed: 1,247 transactions
Root hash: 7f3a2b9c...
Published to: ipfs://Qm...
Verification
Verificer integriteten af enhver periode:
$ verify-chain 2024
✓ Jan: 7f3a2b9c... OK
✓ Feb: 8d4e5f6a... OK
✓ Mar: 9b7c8d2e... OK
Chain integrity: VALID
PostgreSQL & Redis
YAML som kilde — SQL og cache som acceleration
YAML → PostgreSQL Sync
Plain text YAML filer er single source of truth. PostgreSQL bruges til hurtige queries:
Redis Cache Layer
Hyppigt brugte data caches i Redis:
- Kontobalancer — Sub-millisekund lookup
- Orphan counts — Dashboard widgets
- Session data — Terminal state
- Computed reports — KPI'er
Cache invalideres automatisk ved YAML-ændringer via inotifywait.
Query Acceleration
PostgreSQL muliggør queries der ville være langsomme på flat files:
-- Find alle uafstemte over 10.000
SELECT * FROM orphans
WHERE amount > 10000
AND status = 'pending'
ORDER BY created_at;
-- 2ms på 100.000 poster
Hybrid Architecture
Det bedste fra begge verdener:
| YAML (Source) | PostgreSQL (Query) |
|---|---|
| ✓ Git versionering | ✓ Complex joins |
| ✓ Human readable | ✓ Full-text search |
| ✓ Offline first | ✓ Aggregations |
| ✓ No lock-in | ✓ Transactions |
ZMQ Daemon
Hurtig inter-process kommunikation
ZeroMQ Architecture
ZMQ (ZeroMQ) giver socket-baseret messaging mellem processer — hurtigere end HTTP, mere fleksibelt end pipes.
REQ/REP Pattern
Request-Reply for synkrone operationer:
# Client sender request
socket.send("GET_BALANCE:1000")
# Daemon svarer
balance = socket.recv() # "125430.50"
PUB/SUB Pattern
Publish-Subscribe for real-time events:
# Subscribe til orphan events
sub.subscribe("orphan.*")
# Modtag live updates
event = sub.recv()
# "orphan.matched:id=1234"
Performance
ZMQ er designet til høj throughput:
- ~1 million msg/sec på moderne hardware
- Microsekund latency — ikke millisekunder
- Ingen broker — direkte peer-to-peer
Status: Parked — aktiveres når multi-user support er prioriteret.