Skip to content

Backlog & Beslissingen

Formele beslissingen met context, overwegingen en gevolgen. Volledige documenten in docs/beslissingen/.

#BeslissingStatusDetail
ADR-001Vercel naar CloudflareBeslotenLees meer
ADR-002Next.js naar Vite SPABeslotenLees meer
ADR-003Server Actions naar Hono APIBeslotenLees meer
ADR-004CF for SaaS naar CF Pages Custom DomainsBeslotenLees meer
ADR-005ESLint 10 Flat ConfigBeslotenLees meer
ADR-006Layered Context ArchitectureBeslotenLees meer
ADR-008KV Cache voor Publieke Site (ISR)BeslotenLees meer
ADR-009Embla Carousel als standaard carousel-engineBeslotenLees meer
#VraagNodig voorImpact
OQ-1Onboarding app: aparte Vite app of route binnen dashboard?Vision Fase 1Architectuur + deploy
OQ-2Supabase: gedeeld of apart project voor onboarding?Vision Fase 1Database + auth
OQ-3AI model: Claude (voorkeur) of configureerbaar?Vision Fase 3API kosten + vendor lock
OQ-4Style Packs: hardcoded seed data of admin-interface?Vision Fase 4Data management
OQ-5Addon public site rendering: middleware of file-based routing?Vision Fase 4Astro architectuur
OQ-6Stockfoto’s in Asset Packs: API bij activatie of vooraf R2 cache?Vision Fase 7Storage kosten
OQ-7Achievements: beam_events tabel of CF Queue?Vision Fase 5Infra keuze
OQ-8Directory screenshots: Puppeteer of CF Browser Rendering API?Vision Fase 6Vendor + kosten
OQ-9Pricing: per addon, per vertical pack, of flat-rate per tier?Voor launchBusiness model
OQ-10GDPR: welke data is exporteerbaar/verwijderbaar?Voor launchJuridisch
#ItemStatusDetail
1Error monitoring (Sentry)Voltooid
2E2E tests (Playwright)Voltooid
3Staging environmentOpen
4Pages PUT mass assignment fixOpenZod schema toevoegen aan apps/api/src/routes/pages.ts — blokkeert overschrijven van user_id, site_id, created_at. Zie [Security Audit #3]
5Unbounded queries — .limit() toevoegenOpengetPages(), getMenus(), getMenusWithCounts(), updateLinkedButtonHrefs(), patterns usage endpoint. Max 500 rijen
#ItemStatus / Aanpak
6Database backup verificatieMaandelijkse restore-test naar staging
7Database backup documentatieOpen — Documenteer Supabase backup config, PITR status, R2 lifecycle rules in docs/
7bDisaster recovery proceduresOpen — Documenteer RTO/RPO, recovery stappen, rollback procedures
8Analytics (Plausible/PostHog)Privacy-first events: page views, editor sessions, media uploads
9Rate limitingVoltooid
10Structured loggingVoltooid
11Blur placeholdersVoltooid
12Env var fail-fast validatieOpen — Voeg check toe in apps/dashboard/src/lib/supabase.ts voor ontbrekende VITE_* vars
13Session expiry redirectOpen — Handle SIGNED_OUT event in auth-context.tsx met redirect naar /login
14FOUT (Flash of Unstyled Text)Open — Font preload werkt niet op subdomein-sites. Check <link rel="preload"> in public site [...slug].astro
#ItemAanpak
15Brand Export tabDesign tokens exporteren als CSS custom properties, Tailwind v4 theme, en W3C Design Tokens JSON
16Page version historypage_versions tabel, max 10 per pagina, restore UI
17Collaborative editing lockSupabase Realtime presence: “X bewerkt deze pagina”
18Billing (Stripe)Plan tiers, quota enforcement, webhooks
19GDPR complianceData export, account deletion cascade, privacy policy, cookie consent
20API documentatie@hono/zod-openapi of handmatige OpenAPI YAML
21Site restore (undo soft-delete)UI voor het herstellen van verwijderde sites binnen 14-dagen grace period
22getSession()getUser() migratieProject-breed: vervang getSession() door getUser() in security-kritieke flows (6+ bestanden). RLS vangt het server-side op, maar client-side is niet geverifieerd
23Patterns tab met presetsPatterns-tab in de block picker/editor uitbreiden met preset-varianten per block type (bv. Reviews Grid / Featured / Carousel, Pricing 3-tier / 2-tier highlight, Hero center / left / split). Presets hergebruiken de BlockPickerEntry.preset infrastructuur uit blocks.ts en tonen thumbnail + beschrijving per variant. Eén block-type, meerdere start-configuraties. Later uitbreidbaar met categorieën (Marketing / Social proof / Media / Conversion)

Roadmap voor het opschalen van Beam naar 500+ sites. Elke fase wordt getriggerd door groei, niet door planning.

FaseTriggerUpgradeEffortImpact
S1Nu (< 50 sites)KV voor site config + ISR pattern — CF KV als edge cache voor site config, brand tokens en gerenderde page data. Elimineert DB calls voor public site reads2-3 dagenTTFB ~100ms → ~1-5ms, DB load -95%
S2~50 sitesBilling (Stripe) — Plan tiers, quota enforcement via Stripe webhooks, metered billing2-3 wekenRevenue, quota enforcement
S3~100 sitesCF KV site-level cache tags — Purge per site i.p.v. globaal. Fijnmazige invalidatie1-2 dagenSnellere purge, minder cache misses
S4~200 sitesDurable Objects voor quota + rate limiting — Gedeelde state tussen Workers isolates. Exacte counters per site/user voor storage, pages, team size1-2 wekenExacte billing metering, geen race conditions
S5~200 sitesNeon Postgres migratie — Serverless Postgres met HTTP driver, read replica voor public site, database branching voor staging2-3 wekenConnection pooling, read replica latency, gratis staging
S6~300 sitesPartyKit realtime — Edge-native realtime (vervangt Supabase Realtime). Per-page rooms, presence, block-level locking2-3 wekenCollaborative editing, edge latency
S7~500 sitesCF Queues voor async taken — Media processing, bulk export, email campagnes, webhook delivery. Dead letter queue + retry1-2 wekenLagere API response times, betere reliability
S8~500 sitesImage pre-generation pipeline — Upload → Queue → genereer 8 srcSet variants (AVIF + WebP) → R2. Geen on-the-fly resize meer1-2 wekenLagere CF Image Resizing kosten, snellere delivery

Geschatte infra-kosten bij 500 sites: ~€210/mo (CF Workers $25, R2 $4, KV $5, DO $10, Queues $5, Neon $69, Supabase Auth $25, PartyKit $20, Resend $20, Sentry $26)

Principe: Upgrade pas wanneer de groei het rechtvaardigt. De huidige stack draagt 100+ sites zonder wijzigingen.

#Item
22bProactieve monitoring/alerting
23Multi-language dashboard (i18n)
24Analytics dashboard (bezoekerstatistieken per klant-site)
25React Native mobile app
26sessionStorage als auth storage adapter (i.p.v. localStorage, veiliger bij XSS)
27Background color upgrade — mesh/grain optie
28Visual regression tests voor blocks — Playwright screenshots op key block × variant combinaties (cardStyle × quoteMark × background type). Automatisch vergeleken in CI.
29Import van Trustpilot/Google reviews — automatisch testimonials importeren via externe review-API. Mapping naar TestimonialItem schema in API Worker.
30compactLabelField override voor repeater compact-labels — betere UX voor review-repeaters: toon auteursnaam als compact-label i.p.v. generiek “Item 1”.
31Testimonials-block — brand-token voor rating-kleurreview-card.css hardcodet #f59e0b voor sterren. Vervangen door var(--brand-accent, #f59e0b) zodra een dedicated brand-accent token bestaat of per user-preference instelbaar is.
32Testimonials-block — dark mode card styling.review-card--card.review-card--dark gebruikt #ffffff. Support voor prefers-color-scheme: dark toevoegen zodra dark-mode-first sites in scope komen.
33Testimonials-block — defaultTestimonial() helper hergebruikenapps/dashboard/src/lib/blocks.ts bevat bijna-duplicate inline defaults voor featured-testimonial en testimonials-grid. Consolideren naar één helper zodat nieuwe defaults één plek hebben.
34Testimonials-block — escape verbetering title-escape toolsescapeHtml() in packages/shared/src/testimonials/classes.ts inlinen in een algemene shared-helper als meer Astro-blocks dynamische heading tags krijgen.
35Testimonials-block — BlockRegistry interface driftapps/dashboard/src/lib/types.ts BlockRegistry mist benoemde keys voor testimonials-grid, featured-testimonial, testimonials-carousel, faq, columns. Index-signature vangt het, maar benoemde keys geven IDE-hints.
36Testimonials-block — E2E pageIds array opruimene2e/blocks-testimonials.spec.ts heeft een pageIds accumulator die niet gebruikt wordt in de cleanup. Verwijderen of koppelen aan ID-based delete.
37Testimonials-block — quote-mark font-family.review-quote-mark--classic gebruikt Georgia, serif. Overwegen om brand-font te gebruiken zodra een typography-token voor display-type bestaat.
38Testimonials-block — Embla resize-transition — Grid-carousel herinit nu correct bij mobile→desktop. Bij desktop→mobile opnieuw wordt de observer opnieuw ge-armed maar dit kan strakker: één centrale media-query-watcher per block zodat we niet steeds IO opzetten. Nu acceptabel.