# Tekniske Valg ## Hvad jeg byggede En SvelteKit-baseret produktivitetsapp med login, projekter, tasks, GitHub App installation, repository linking, issue-sync og live opdateringskanal (SSE). ## Hvorfor SvelteKit - Server `load` gør det enkelt at hente data tæt på routen. - Form actions passer godt til mutationer uden tung klientlogik. - SSR giver hurtig første render og bedre default UX. - SSE passer til lette live-opdateringer uden fuld websocket-kompleksitet. ## Hvordan det virker i praksis - Brugeren logger ind via Better Auth (GitHub OAuth). - Dashboardet henter projekter, tasks og issues server-side. - Brugeren kan oprette projekter og tasks via form actions. - Projekter har en GitHub App-installationsknap, der sender brugeren til GitHub. - GitHub App installeres på en konto, og der vælges repositorier på GitHub's side. - Efter installation redirectes brugeren til en setup-side i appen, hvor de vælger et projekt og krydser repos fra. - De valgte repos gemmes som `githubRepositoryLink`-rækker. - På projektets detailside kan brugeren synce issues fra det linkede repo via GitHub App's installation access token. - SSE-endpoint (`/api/events`) sender notifikationer om task-ændringer og issue-sync, så klienten reloader data. ## GitHub App flow i detaljer 1. `getGitHubInstallUrl()` genererer en URL med en HMAC-signeret state (indeholder `userId` og `redirect`). 2. GitHub sender brugeren tilbage til `GITHUB_APP_SETUP_URL` med `installation_id` og `state`. 3. Callback-validering: state afkodes og verficeres, `installation_id` gemmes i `githubInstallation`. 4. Hvis `GITHUB_APP_PRIVATE_KEY` er sat, hentes account-login fra GitHub API. Ellers bruges en fallback. 5. Brugeren redirectes til `/install/setup?installation={id}` for at vælge repos og projekt. 6. Setup-siden bruger `listGitHubInstallationRepositories()` til at vise repos. 7. Form action opretter `githubRepositoryLink`-rækker og redirecter til projektet. ## Hvad der virkede godt - SvelteKit gjorde dataflowet kort og tydeligt (load → form action → redirect). - Server actions holdt mutationerne samlede og eliminerede behov for klient-state. - Drizzle passede godt til schema-drevet udvikling med relations og foreign keys. - GitHub App JWT-auth var overskuelig med `node:crypto` og RS256-signering. - HMAC-signeret state gav en sikker callback-verifikation uden session storage. ## Hvad der var udfordrende - GitHub App kræver en PEM-private key, som skal formateres som en enkelt linje med `\n` i `.env`. - Private key skal være til stede før JWT-signerede API-kald kan fungere. - `githubRepositoryLink.installationId` er en foreign key til den interne `githubInstallation.id`, ikke GitHub's `installationId` — skal joins for at få den rigtige værdi. - SSE er nemt til énvejskommunikation, men websocket kan blive nødvendig senere. - Progress bør helst beregnes robust i databasen eller via en service. ## Professionel brug Løsningen kan bruges som intern project tracker, support-overblik eller developer dashboard med integrerede GitHub issues og statusopdateringer.