Kontrolplan og dataoperationer
App Console og partnerregistreringen udgør kontrolplanet: hvem der ejer appen, hvilken revision der er gennemgået, hvilke credentials der er aktive, og hvad kunden har autoriseret. Domæneoperationerne udgør dataplanet: det konkrete kald, der forbereder, opretter eller bogfører.
Opdelingen kræver ikke mange separate tjenester. Kontrolkoden ligger i Hours' eksisterende applikation. Den sikkerhedsmæssige forskel er, at registreringsoplysninger ikke bliver taget som bevis på en aktuel kundetilladelse, og at sandboxdata ligger i et separat projekt.
Oprettelse uden kundedata
Udvikleren logger ind med en verificeret Hours-identitet og opretter et arbejdsrum. Serveren opretter medlemsrelationen og appens første revision. Appens ønskede scopes gemmes som ønsker, ikke som produktionsrettigheder.
Der oprettes ikke en produktionsorganisation eller et abonnement i dette flow. Appens profil kan indeholde et juridisk navn og en privatlivsadresse, men det er indsendte oplysninger. Partner-API'et gennemfører ikke automatisk CVR-verifikation, domæneverifikation eller en juridisk vurdering, alene fordi felterne er udfyldt.
Test i den valgte app
Ved sandboxåbning opretter kontrolplanet en provisioningtilstand. Det separate projekt opretter de syntetiske referencer, som Hours' regnskabskerne kræver. Først efter bekræftet klargøring bliver generationen klar.
To databasekald i to projekter er ikke én transaktion. Derfor er klargøringen genoptagelig: gentagelsen finder eller færdiggør samme generation i stedet for at skabe en ekstra testvirksomhed for hvert timeout. Ingen fallback sender testinput til produktionsprojektet.
Review før produktion
En intern reviewer ser en bestemt apprevision. Reviewerens beslutning gemmes sammen med begrundelsen og det godkendte scopeloft. Appens udvikler kan ikke træffe den beslutning om sin egen app.
En ny profilrevision ophæver den tidligere produktionsadgang. Appen skal gennem nyt review, og nye kundegrants skal referere til den relevante revision. Det forhindrer, at en tidligere snæver integration efterfølgende får et helt andet formål eller en anden destination uden ny kontrol.
Kundens autorisation
Appen starter et OAuth authorization-code-flow med S256. Organisationsejeren bekræfter med tofaktor, ser appen, vælger et afgrænset scopesæt, de konti appen må se, og en udløbstid på højst 90 dage, og bekræfter eventuelt bogføringsmandatet særskilt. Kundens valg gemmes server-side.
Koden veksles til opaque tokens, som kun Hours' partnerlag kan fortolke gennem den gemte digest og grantrelation. Appen modtager ikke et Supabase-token, som automatisk kan benyttes mod database- eller storageflader. Se autentifikation for det præcise flow.
Beslutningen ved hvert kald
Serveren kontrollerer token, apprevision, arbejdsrum, grant, organisation, udløb, tilbagekaldelse, scope og miljø. Der er intet separat tjek af et produktmodul. Ukendt eller ufuldstændig kontekst giver et afvist kald, ikke en standardkunde.
Input normaliseres gennem en eksplicit model. Skrivninger har idempotens. Referencekontrol, den faktiske domænehandling, kvittering og den minimale webhookhændelse hænger sammen transaktionelt. Et HTTP-svar sendes først efter det autoritative udfald.
Resultater tilbage til appen
Appen får en minimal kvittering. Den får ikke automatisk en kopi af den interne række med bankfelter, noter eller andre relationer. Dette gælder også, når en intern upsert kunne have returneret en allerede eksisterende række.
Læseoperationerne viser organisationens eksisterende regnskabsdata: bogførte posteringer på tildelte konti, produkter og salgsfakturaer, uden bank- og betalingsfelter. Webhooken beskriver en gatewayoperation, ikke en vilkårlig ændring i hele Hours. Flowet er derfor ikke en fuld tovejssynkronisering af alle kundens data; læsningen er begrænset til de tildelte konti og de tre ressourcer.
Stop, udløb og oprydning
En tilbagekaldelse stopper nye kald og nye leveringer, som endnu ikke er sendt. Et allerede igangværende eksternt netværkskald kan ikke trækkes tilbage fra modtageren. Tilsvarende kan en sandboxrequest, som allerede er indsendt, nå at committe i den gamle isolerede generation.
At stoppe adgang er heller ikke det samme som at slette alle data. Kvitteringer, regnskab og revisionsspor kan have forskellige retentionkrav. Et revoke-kald sletter derfor ikke automatisk data; sletning og opbevaring følger Hours' slette- og driftsprocedurer.