Dansk skæreplanlægger. Det offentlige produktnavn er Skæreseddel. Next.js-app med den eksisterende planlægger, Clerk-login og skæresedler gemt på kontoen.
Værtsnavne kan stadig sige pladeplan, indtil der kommer et eget domæne: Vercel-projektet pladeplan, https://pladeplan.vercel.app og GitHub-repoet pcp183/pladeplan. De navne er hosting, ikke brand.
Planlæggeren kan bruges uden login. Gemte skæresedler på serveren og kontosiden kræver login. Pro kan tegnes med Stripe Checkout, når nøglerne og mindst én pris er sat. Uden den opsætning står der Pro kommer snart, og der vises ingen pris og intet køb.
npm install
cp .env.example .env.local
# udfyld nøglerne nedenfor
npm run dev
Åbn http://localhost:3000. Uden nøgler kan appen stadig bygges og planlæggeren bruges; login og kontolagring viser i stedet en opsætningsbesked.
npm test
npm run build
npm test tjekker pakkealgoritmen (ingen overlap, kantfraskær, fast standardplan) og validering af skæresedler.
| Variabel | Hvor | Formål |
|---|---|---|
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY |
Clerk Dashboard → API keys | Offentlig nøgle, pk_test_ eller pk_live_ |
CLERK_SECRET_KEY |
samme sted | Hemmelig nøgle, kun server. Må ikke i klientkode eller git |
NEXT_PUBLIC_CLERK_SIGN_IN_URL |
/sign-in |
Login-rute |
NEXT_PUBLIC_CLERK_SIGN_UP_URL |
/sign-up |
Opret-konto-rute |
NEXT_PUBLIC_CLERK_SIGN_IN_FALLBACK_REDIRECT_URL |
/ |
Efter login |
NEXT_PUBLIC_CLERK_SIGN_UP_FALLBACK_REDIRECT_URL |
/ |
Efter oprettelse |
DATABASE_URL |
Neon / Vercel Postgres | Skæresedler pr. Clerk-userId. Bruges også til abonnementsstatus, når den er sat |
POSTGRES_URL |
valgfri alias | Bruges kun hvis DATABASE_URL ikke er sat |
STRIPE_SECRET_KEY |
Stripe → API keys | sk_test_ eller sk_live_. Kun server |
STRIPE_WEBHOOK_SECRET |
Stripe → Webhooks | whsec_… for endpointet /api/stripe/webhook |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY |
Stripe → API keys | pk_test_ eller pk_live_, samme tilstand som secret |
STRIPE_PRICE_PRO_MONTHLY |
Stripe → Product → Price | price_… for et tilbagevendende månedsabonnement. Valgfri, hvis årlig er sat |
STRIPE_PRICE_PRO_YEARLY |
samme sted | price_… for et tilbagevendende årsabonnement. Valgfri, hvis månedlig er sat |
AI_GATEWAY_API_KEY |
Vercel AI Gateway | Nøgle til «Foto til skæreseddel». På Vercel kan OIDC (VERCEL_OIDC_TOKEN) bruges i stedet. Uden begge dele vises «Foto-funktionen er ikke sat op endnu» |
PHOTO_CABINET_ALLOWLIST |
kommasepareret | Clerk-bruger-id eller e-mail, der må prøve foto, også før Pro kan købes |
PHOTO_CABINET_MODEL |
valgfri | Model-id fra AI Gateway. Standard google/gemini-3.8-flash |
Se .env.example. Sæt variablerne i Vercel før deploy, og deploy igen hvis de ændres. Next.js indlejrer NEXT_PUBLIC_* ved build.
.env.local og i Vercel.http://localhost:3000 og https://pladeplan.vercel.app.@clerk/localizations (daDK) der, hvor oversættelsen findes.npx clerk@latest init kan også skrive udviklingsnøgler til .env.local. Nøglerne claim’es senere med npx clerk auth login.
Skæresedler ligger i Neon Postgres (erstatning for det tidligere Vercel Postgres). Tabellen pladeplan_projects oprettes ved første kald.
På det linkede Vercel-projekt:
vercel integration add neon
Det sætter DATABASE_URL. Uden database svarer /api/projects med 503, og planlæggeren gemmer videre i localStorage.
pladeplannpm run build. Output håndteres af Next.js.DATABASE_URL og Stripe-nøglerne fra afsnittet nedenfor. NEXT_PUBLIC_* kræver en ny deploy, når de ændres.https://pladeplan.vercel.app.vercel link --project pladeplan
vercel env pull .env.local
vercel --prod
GitHub Pages kan ikke køre Clerk eller API-ruterne. Den tidligere statiske index.html / dist/ er fjernet, så der kun er én app. Sæt det offentlige site til Vercel-deploymenten.
/konto): profil, log ud, planstatus, opgrader eller administrer Pro når Stripe er sat op, hent data og slet konto.PHOTO_CABINET_ALLOWLIST og uden aktivt Pro (når Stripe er sat op) vises kun indgangen og et link til abonnementet. Uden AI-nøgle eller Vercel OIDC står der «Foto-funktionen er ikke sat op endnu»./privatliv): hvad der gemmes, formål, retsgrundlag, opbevaring og rettigheder. Link i sidefoden og på kontoen.«Slet konto» kræver, at brugeren skriver sin e-mail. Serveren:
pladeplan_projects for Clerk-userId og tjekker, at ingen række er tilbage.users.deleteUser.Der laves ingen arkivkopi, papirkurv eller soft-delete. Mislykkes sletningen af skæresedlerne, slettes Clerk-brugeren ikke. Uden DATABASE_URL ligger der ingen skæresedler på serveren, og kun Clerk-brugeren slettes. Browseren, hvor der trykkes slet, rydder også localStorage-nøglerne pladeplan, pladeplan-projects, pladeplan-sheet-prices og pladeplan-own-sheets.
«Hent mine data (JSON)» er indsigt og udtræk af profil og gemte skæresedler.
Valgfri kontaktmail på privatlivssiden: PLADEPLAN_CONTACT_EMAIL. Uden den vises GitHub-projektet som kontakt.
Pro er et rigtigt abonnement via Stripe Checkout og kundeportalen. Der er ingen lokal kasse og ingen priser i koden. Når Stripe er sat op, gemmer gratisplanen op til 3 skæresedler. Pro giver ubegrænset gemte skæresedler og Fra foto. Uden den opsætning er der ingen grænse og intet køb. hasProAccess i lib/billing.ts er server-tjekket.
Clerk kan stadig være pk_test_ i produktion. Stripe-nøglerne følger deres egen tilstand: test med test, live med live. En test-nøgle og et live-pris-id dur ikke sammen.
price_….Sæt variablerne i .env.local og i Vercel (Production og Preview) for det projekt, der hedder pladeplan:
| Variabel | Eksempel |
|---|---|
STRIPE_SECRET_KEY |
sk_test_… eller sk_live_… |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY |
pk_test_… eller pk_live_… i samme tilstand |
STRIPE_WEBHOOK_SECRET |
whsec_… |
STRIPE_PRICE_PRO_MONTHLY |
price_… |
STRIPE_PRICE_PRO_YEARLY |
price_… |
Mindst én af de to priser skal være sat, sammen med begge nøgler og webhook-hemmeligheden, før knapperne vises. Beløbet hentes fra Stripe ved indlæsning af /konto og vises igen i Checkout, før der betales.
Webhook-endpoint:
https://pladeplan.vercel.app/api/stripe/webhookstripe listen --forward-to localhost:3000/api/stripe/webhook — CLI’en udskriver en whsec_…, som kun gælder lokalt. Produktionens hemmelighed står på endpointet i Dashboard.Hændelser, der skal sendes:
checkout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedPreview-deploymenter har deres egen URL. Et webhook-endpoint peger på én URL, så en preview-URL synkroniserer kun, hvis den har sit eget endpoint og sin egen STRIPE_WEBHOOK_SECRET.
Checkout opretter en Stripe-kunde med Clerk-userId i metadata. Webhooken skriver status til Clerk publicMetadata og, når DATABASE_URL er sat, til tabellen pladeplan_billing. Aktiv, prøveperiode og manglende betaling (past_due) tæller som Pro. Opsagt, ubetalt og ufuldstændig gør ikke.
«Administrer abonnement» åbner Stripes kundeportal (opsigelse, kort, kvitteringer). «Slet konto» sletter stadig skæresedlerne og Clerk-brugeren og sletter også Stripe-kunden, når secret-nøglen er sat. Eksporten på kontoen indeholder abonnementsstatus, ikke kortnummer.