Skip to content

rubentalstra/WebshopCheck

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

WebshopCheck

Dutch consumer protection. Paste a webshop URL → get a verifiable, evidence-based report covering KVK identity, BW 6 disclosure obligations, BTW validity, withdrawal rights, and operator clustering. Facts, not verdicts. Public methodology. Open source.

The full specification lives under docs/. Start with docs/product-spec.md for the mission and docs/principles.md for the ten non-negotiable rules.

Status. Slice 1 (foundation) is complete: the end-to-end pipe works against a local Supabase stack, with one rule shipped (NL-IDENT-004 — KVK deregistered). Slice 2 expands to the full NL identity/contact/VAT ruleset. The roadmap lives in docs/phases/.


Local development workflow

Prerequisites: Node 24, pnpm 11, Docker Desktop (for Supabase local stack).

One-time setup

pnpm install
cp .env.example .env.local        # fill in the keys after `pnpm supabase status`

Four-terminal dev workflow

# Terminal 1 — local Supabase stack (Postgres, Realtime, Storage, Studio)
pnpm dev:db:start
pnpm dev:db:status                 # copy NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY +
                                   # SUPABASE_SECRET_KEY into .env.local

# Terminal 2 — apply migrations once
pnpm db:migrate

# Terminal 3 — scan worker poll loop (replaces cloud pg_cron for local dev)
pnpm dev:fn:loop

# Terminal 4 — Next.js dev server
pnpm dev                           # http://localhost:3000

Submit a webshop URL (or paste https://example-shop-a.test in NEXT_PUBLIC_DEMO_MODE=true) on the landing page. Live progress streams via Supabase Realtime; the report renders at /r/<scan-id> once the worker completes the pipeline.

Smoke test

End-to-end verification without the UI:

node --import tsx scripts/smoke-test.ts

Inserts a scan for the deregistered KVK fixture (12345671), enqueues it, runs the worker, and asserts the resulting traffic light is red with one NL-IDENT-004 critical finding.

Anonymous-read RLS check

Proves the public-read policies on scans and findings work for unauthenticated visitors (prerequisite: dev server running):

node scripts/anon-read-check.mjs

Common scripts

Script What it does
pnpm dev Next.js dev server with Turbopack
pnpm dev:db:start / dev:db:stop / dev:db:reset Manage the local Supabase Docker stack
pnpm dev:db:status Prints local URL + sb_publishable_* / sb_secret_* keys
pnpm dev:fn:loop Poll the scan worker every 5s (local pg_cron replacement)
pnpm dev:fn:tick Run the worker once and exit
pnpm db:generate Generate Drizzle SQL migration from lib/db/schema.ts
pnpm db:migrate Apply pending migrations
pnpm db:studio Open Drizzle Studio against the local DB
pnpm db:verify-rls Assert every table has RLS + ≥1 policy
pnpm typecheck tsc --noEmit strict
pnpm lint ESLint, includes banned-vocabulary plugin
pnpm test Vitest

Architecture in one diagram

User pastes URL
   → Server Action submitScan (app/actions/submit-scan.ts)
   → INSERT scans row, pgmq.send('scan_queue', { scanId })
   → /scan/[id] page (Realtime subscription)

Local worker loop (scripts/run-worker.ts, replaces cloud Edge Function):
   pgmq.read → runScan → write findings → update scans.status='complete'

/r/[id] page (Server Component):
   read scans + findings → render report → SEO meta + OG image

Tech stack: Next.js 16 (App Router, proxy.ts not middleware.ts) · React 19.2 · Drizzle 1.0-rc with defineRelations (RQB v2) · Supabase SSR 0.10 with new sb_publishable_* / sb_secret_* keys (legacy JWT anon / service_role keys are not used) · Tailwind v4 (CSS-first config) · next-intl 4 (defineRouting + createNavigation) · Vitest 4 + Vite 7.

Full version table and rationale: docs/architecture.md.


The ten non-negotiable principles (TL;DR)

  1. Facts, not verdicts.
  2. No confidence scores — count-based traffic light only.
  3. Severity is fixed per rule.
  4. Verification beats extraction. Never assume.
  5. Targeting determines applicable law.
  6. Layered presentation (glance / findings / raw evidence).
  7. Reproducibility — every scan stamps scanner-version + ruleset-version.
  8. Cluster awareness as a feature.
  9. Transparency over cleverness.
  10. Banned vocabulary (scam, fraud, fake, dodgy, dropshipper, …) — enforced by ESLint + runtime rule lint.

Full text: docs/principles.md.


License

Code: AGPL-3.0-or-later (LICENSE-AGPL). Rule definitions exported from lib/rules/: Apache-2.0 (LICENSE-APACHE). Documentation under docs/: CC-BY-4.0 (LICENSE-DOCS).

About

No description, website, or topics provided.

Resources

License

AGPL-3.0 and 3 other licenses found

Licenses found

AGPL-3.0
LICENSE
Unknown
LICENSE-AGPL
Unknown
LICENSE-APACHE
Unknown
LICENSE-DOCS

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors