Kassa — dokumentation

Vad som byggts, hur det fungerar, varför händelserna sker — och vägen till tillverkardeklaration. Version . Till kassan · Intern driftvy

Målet

Ett tillverkardeklarerat svenskt kassaregister (SKVFS 2014:9 i lydelse enligt SKVFS 2021:17, gäller register i drift från 2027-01-01) — byggt som webbapp med ett utbytbart kontrollager: kassan är aldrig låst till en specifik kontrollenhet eller molntjänst.

Strategin: bygg kärnflödet först, läs regelverket mot Skatteverkets riktiga schemafiler (inte sammanfattningar), och låt varje steg bevisas — journalexporten validerar mot den officiella XSD:n, och observatörsloggen är bevisat passiv (köp fullföljs även när loggen avsiktligt kraschats).

Så fungerar det

Kassa-UISurfplatta/webbläsare. Nota i localStorage — överlever omladdning. Skickar bara produkt-id + antal.
Kassa-APIPriser alltid ur databasen. Löpnummer utan luckor (lås per kassa). Moms per rad ur bruttopris. Allt i heltal öre.
ControlSystemAdapterDet ENDA sättet att nå kontrollsystem: anslut, signeraKvitto, hämtaRäknare, exporteraXML, ärTillgänglig, tillverkningsnummer.
KontrollsystemI dag: mock (formatriktiga 59-teckenskoder). I morgon: certifierad box eller molntjänst — byts via en rad konfiguration.

Två loggar med olika juridik — medvetet åtskilda

Journalexporten

Kvittona exporteras som XML enligt SKVFS 2021:16 och valideras mot Skatteverkets officiella schemafiler (ligger i repot, kassa/skatteverket/). Kvitton är oföränderliga — exporten läser, ändrar aldrig.

Pratar alla kontrollboxar samma språk? Nej — och så löser vi det

Skatteverket bestämmer vad en kontrollenhet ska göra och vilka uppgifter som ska skickas dit, samt exportformatet — men inte hur kassan tekniskt pratar med boxen. Varje tillverkare (CleanCash/Retail Innovation, Infrasec med flera) har sitt eget protokoll, oftast dokumenterat först när man blir integratörspartner.

Därför adaptermönstret: kassan pratar ETT internt språk (interfacet ovan). Varje leverantör får en egen liten översättare (adapter) — kassan i övrigt ändras aldrig. Så kopplar en och samma kassa mot vilken box eller molntjänst som helst, och du kan växla mellan modellerna i driftvyn för att testa: normal, långsam eller död box.

Händelser & varför de sker

Varje kontakt mellan kassan och kontrollsystemet loggas som en händelse. Detta betyder de:

HändelseVad det är — och varför det sker

Senaste händelserna (live)

Kräver adminnyckel — logga in i driftvyn så visas flödet även här.

Versionshistorik

Kassaregisterprogram ska ha unikt versionsnummer (4 kap. 3 §) — versionen följer med i journalexporten. Uppdateras vid varje förändring, i samma commit som koden.

Gap & färdplan — från körande kassa till deklarerbar

Fullständigt kravextrakt med källor: kassa/skatteverket/KRAV.md. Princip: minimera funktionsytan → minimera kravytan — villkorade funktioner byggs först när någon behöver dem.

Uppfyllt

Måste för tillverkardeklaration (byggordning)

Villkorat — bygg bara vid behov

Bra att ha — inte deklarationskrav

Dokumentationen bor i koden (kassa/app/public/dok.js) och uppdateras i samma commit som förändringen. Djupare: docs/kassa.md, kassa/PROJECT.md, kassa/decisions.md.