Tre tilstande, der ikke må blandes sammen
Dokumentationen viser navigation, tekster, illustrationer og lokale inputkontroller. Den har ingen serveridentitet og kan ikke oprette en ægte sandbox. App Console på app.hours.dk/console er den autentificerede administrationsflade, hvor teamet registrerer appen og anmoder om et testmiljø. Sandboxdatabasen er et særskilt konfigureret projekt, hvor de understøttede regnskabsoperationer kan køres med syntetiske referencer.
Et grønt lokalt preflight-resultat betyder derfor kun, at inputtet bestod de kontroller, som resultatet udtrykkeligt opregner. Et grønt sandboxresultat viser en handling i testmiljøet. Ingen af delene giver kunden et produktionsgrant. Skift mellem faner, URL-parametre eller browserlagring kan ikke vælge et andet databaseprojekt.
Isolationens konkrete grænse
Sandbox kører mod et separat databaseprojekt med egen servernøgle og eksplicit projektreference. Runtime afviser samme origin som produktionsprojektet og genbrug af den samme servernøgleværdi. Databasekonfigurationen skal samtidig være markeret som sandbox. Sandboxfunktionerne fejler, hvis de kaldes mod kontrolplanet eller en deaktiveret installation.
Sandbox bruger ikke et almindeligt stagingmiljø. Staging kan indeholde andre tests, adgangsmodeller eller data og er ikke egnet som ekstern udviklersandbox. Sandboxprojektet indeholder ingen produktionskopier, og eksterne sideeffekter er deaktiveret.
Produktionsbanknøgler, SMTP-afsendelse, betalingsudførelse, e-signering og eksterne automatiseringer er ikke tilgængelige i testmiljøet. Sandboxoperationerne foretager ingen af disse handlinger.
Oprettelse er en eksplicit operation
Når Opret sandbox vælges, registrerer kontrolplanet app-id og generation. Provisioneringen opretter derefter en syntetisk organisation og et syntetisk medlems-id i det separate projekt samt tre regnskabsreferencer: salg af ydelser, driftsudgift og leverandørgæld. Der oprettes ikke en loginbruger, kundeprofil, kundesubscription eller bankforbindelse.
Dette genbruger regnskabskernens krav om aktivt organisationsmedlemskab. Medlemskontrollen svækkes ikke, og der oprettes ikke en produktionskunde for at få testdata.
Fejler provisioneringen mellem de to projekter, forbliver kontrolrækken i provisioning. Der findes ingen distribueret databasetransaktion mellem projekterne. Gentag oprettelsen: den samme app og generation identificerer den samme fixture, så genforsøget ikke skaber endnu et testregnskab. Konsollen viser først ready, efter det separate projekt har bekræftet provisioneringen.
Testtoken og rettigheder
Et hsk_-token er bundet til appen, de valgte scopes, den aktuelle sandboxgeneration og den udvikler, der udstedte det. Det udløber efter én time, og der kan højst være 10 aktive sandboxtokens. Kun ejere, administratorer og udviklere i arbejdsrummet må udstede det. En læserrolle kan ikke gøre det ved at aktivere en skjult knap.
Tokenet sendes i Authorization: Bearer … til /api/partner/sandbox/v1. Produktions-token, Hours-login-token og konsollens login-cookie erstatter ikke dette token. Efter medlemsfjernelse, suspension, tilbagekaldelse, udløb eller generationsskifte afvises et nyt kald.
Sandboxscopes er begrænset af appens registrerede ønsker. Det giver mulighed for at teste ønskede rettigheder før produktionsreview, men ikke for at teste en bankfunktion, der slet ikke er publiceret. Ret appens profil, når testens adgangsbehov ændres; skriv ikke egne scopeværdier ind i et token.
Hent referencer, før du skriver
Begynd med GET /configuration. Svaret indeholder de syntetiske konto-id’er og valutaen. Brug id’erne i journalinput. Testdata er ikke globalt faste id’er, og den samme dokumentations-UUID skal ikke bruges af alle udviklere.
Kør derefter POST /journal/prepare med to modstående linjer i hele ørebeløb. Resultatet viser, at input og referencer er kontrolleret, men posted er stadig false. Kør kun POST /journal, når testen faktisk skal bogføre, og medtag en ny idempotensnøgle for denne tilsigtede handling.
Hours’ regnskabskerne kaldes i sandboxprojektet; dens periodelåse og balancekrav gælder også her. Produktoprettelse og fakturakladder bruger ligeledes de afgrænsede kontrakter. Der er ikke et generisk endpoint, hvor udvikleren kan vælge en tabel, funktion eller kundekonto.
Nulstilling uden sletning af regnskabshistorik
Nulstilling er en ny generation, ikke en sletning af immutable hovedbogsposter. Handlingen kræver app-id, forventet generation og teksten NULSTIL SANDBOX. Serveren afviser en forældet generation med konflikt, så to åbne faner ikke lydløst nulstiller hinandens miljø.
Tidligere sandboxtokens tilbagekaldes. Hent nye referencer og udsted et nyt token til den nye generation. Produkt-id’er, journal-id’er og idempotensresultater fra den gamle generation må ikke betragtes som referencer i den nye. Produktive grants bliver ikke oprettet, ændret eller aktiveret af nulstillingen.
Et request, der allerede har passeret kontrolplanet, kan nå at afslutte en handling i den gamle isolerede generation. Det er en kendt grænse i to-projektmodellen. Det fortsætter aldrig i den nye generation ved automatisk remapping. En strengere annullering af alle igangværende testrequests kræver et særskilt drain-forløb.
Prøver, der bør bestå før produktionsbrug
Test med mindst to udviklerarbejdsrum, to apps i samme arbejdsrum, to sandboxgenerationer og en produktionsorganisation. Bevis både positiv adgang til de egne syntetiske data og negativ adgang på tværs af app, generation, arbejdsrum og miljø. En tom database er ikke tilstrækkelig til at opdage en lækage: prøverne skal indeholde forskellige kendte værdier.
Test også samtidig nulstilling og skrivning, tabt HTTP-svar efter commit, genbrug af idempotensnøgler, konti der deaktiveres mellem preflight og bogføring, samt manglende sandboxnøgle. Afprøv også, at et partner-token ikke kan bruges mod Hours’ direkte database-, lager- eller realtidsflader som en almindelig brugers session.
Lokale enhedstests og transporttests erstatter ikke prøver mod et rigtigt sandboxmiljø. Når du dokumenterer teststatus, så navngiv miljø, build, kontraktversion og udførte prøver. “Sandbox virker” uden disse oplysninger er ikke et brugbart driftsbevis.
Token og valgt app skal stemme overens
Konsollens testklient sender X-Hours-App-Id med den valgte apps identitet. Gatewayen sammenligner den med den app, som det verificerede token faktisk tilhører, før en domæneoperation udføres. En uoverensstemmelse giver 403 permission_denied. Headeren er en ekstra beskyttelse mod at indsætte et testtoken fra en anden app; den tildeler ingen adgang og erstatter aldrig tokenkontrollen. Eksterne klienter kan udelade headeren, men kan ikke bruge den til at skifte app eller organisation.