Skip to content

Misssthing/mdwvdmnd

Repository files navigation

medewerkervandemaand.com

Productieklare UGC-app voor nominaties van “medewerker van de maand”. Publieke feed + detailpagina’s, inzendformulier zonder account, moderatieflow, rapportages, anti-spam, SEO en juridische pagina’s.

Stack

  • Next.js (App Router) + TypeScript
  • TailwindCSS v4 + shadcn/ui
  • Supabase (Postgres + Auth + Storage)
  • Zod + React Hook Form
  • sharp voor server-side image processing

Snel starten

  1. Install dependencies
npm install
  1. Zet .env.local op basis van .env.example (gebruik service role key alleen server-side):
SUPABASE_URL=...
SUPABASE_ANON_KEY=...
SUPABASE_SERVICE_ROLE_KEY=...
SUPABASE_JWT_SECRET=...
RATE_LIMIT_SALT=change-me
SITE_URL=http://localhost:3000
STORAGE_BUCKET=nominations
ADMIN_SEED_EMAILS=admin@example.com,moderator@example.com
  1. Migrations + seed uitvoeren (vereist Supabase CLI en een database URL):
supabase db push --db-url "$SUPABASE_DB_URL"
supabase db execute --file ./db/seed/seed.sql --db-url "$SUPABASE_DB_URL"
  1. Dev server:
npm run dev

Kernfeatures

  • Publieke feed met zoek & maandfilter, detailpagina met signed image URLs.
  • Nominatieformulier: foto-upload (jpg/png/webp), compressie/resize → webp, honeypot, rate-limit (3 per 24h per IP-hash), keyword blocklist.
  • Moderatie: pending → approved/rejected, redactie, audit log, soft delete + storage cleanup.
  • Rapportages (open/closed), verwijderverzoeken (open/closed).
  • SEO: slug /nominatie/{id}-{slug}, sitemap.xml met alleen approved, robots.txt.
  • Juridisch: /privacy, /richtlijnen, /verwijderverzoek.

Supabase details

  • Tabellenschema: db/migrations/001_init.sql (nominations, reports, audit_log, removal_requests, admins + RLS policies).
  • Bucket nominations (private). Signed URLs voor alle foto’s; placeholders leven in public/placeholders.
  • RLS: publieke read alleen status='approved' AND is_deleted=false; inserts voor anon op nominations/reports/removal_requests; updates/deletes alleen admin/mod via admins-tabel en JWT email claim.
  • Admin detectie: voeg e-mails toe aan admins tabel (seedbestand bevat voorbeelden).

Scripts

  • npm run dev – development server
  • npm run lint – lint met Next/ESLint
  • npm run test – Vitest smoke tests
  • npm run build – productie build

Tests

Vitest smoke tests:

  • tests/nominations.test.ts: mockt storage/Supabase en test create-nomination flow (slug + insert call).
  • tests/feed.test.tsx: rendert feed page met mocked data.

Anti-spam & privacy

  • IP’s worden nooit raw opgeslagen, alleen een salted SHA-256 hash (RATE_LIMIT_SALT).
  • Rate limit: max 3 inzendingen per 24 uur per IP-hash (DB + in-memory fallback).
  • Honeypot veld website op formulieren.
  • Keyword blocklist staat in lib/nominations.ts.
  • Signed URLs voor beelden; bucket is private.

Admin

  • Login via Supabase Auth (email/wachtwoord). Controle op e-mail in admins-tabel.
  • Dashboard: pending/approved/rejected, statuswissels, redactie, soft delete (ruimt storage op), report-queue open/closed, verwijderverzoeken open/closed.

Seeding

  • db/seed/seed.sql bevat 5 approved, 2 pending, 1 rejected nominatie + een report en verwijderverzoek.
  • Placeholderbeelden: public/placeholders/*.svg.

Deployment notities

  • Zet SITE_URL voor correcte sitemap/robots/share links.
  • Houd SUPABASE_SERVICE_ROLE_KEY server-side (env) en gebruik env-injectie bij deploy.
  • Verifieer dat bucket nominations bestaat (migration doet insert ... on conflict do nothing).

About

myfirstproject

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published