veza/apps/web/src/components
senke c0e06e61b6 feat(legal): versioned terms acceptance ledger (CGU/CGV/mentions)
v1.0.10 légal item 3. RGPD requires explicit re-acceptance of any
terms-of-service-class document on material change. Adds a per-user,
per-document, per-version ledger so disputes can be answered with
evidence (timestamp + originating IP + user-agent).

Backend
  * migrations/991_terms_acceptance.sql — table terms_acceptances with
    UNIQUE (user_id, terms_type, version) so re-accepts are idempotent.
    inet column for IP, varchar(512) for UA, both nullable for the
    internal seed paths.
  * internal/services/terms_service.go — TermsService :
      - CurrentTerms map (ISO date version per class) is the single
        source of truth ; bump on text edit.
      - CurrentVersions(userID) returns versions + the user's
        unaccepted set ; userID==Nil ⇒ versions only (anonymous OK).
      - Accept(userID, []AcceptInput) : validates each (type, version)
        against CurrentTerms (ErrTermsVersionMismatch on stale POST),
        writes one row per accept in a single transaction, idempotent
        via FirstOrCreate against the unique index.
  * internal/handlers/terms_handler.go — REST surface :
      - GET  /api/v1/legal/terms/current  (public, OptionalAuth)
      - POST /api/v1/legal/terms/accept   (RequireAuth)
      - Captures IP via gin's ClientIP() (X-Forwarded-For-aware) and
        UA from the request, truncates UA to fit the column.
  * routes_legal.go — wires the two endpoints. `current` falls back
    to no-middleware when AuthMiddleware is nil so test rigs work.

Frontend
  * features/legal/pages/{CGUPage,CGVPage,MentionsPage}.tsx — initial
    drafts with version constants matching the backend's CurrentTerms.
    Counsel review required before v2.0.0 (text is honest baseline,
    not finalised legal copy).
  * services/api/legalTerms.ts — fetchCurrentTerms() / acceptTerms() ;
    hand-written to keep the consent-modal wiring readable.
  * components/TermsAcceptanceModal.tsx — non-dismissable modal that
    opens on every authenticated session when the unaccepted set is
    non-empty. Per-document checkboxes + single submit ; refusal keeps
    the modal open (no decline-and-continue path because the legal
    contract requires acceptance to use the platform).
  * Mounted in App.tsx alongside CookieBanner ; both must overlay
    every screen.
  * Lazy-component registry + routes for /legal/{cgu,cgv,mentions}.

Operator workflow when text changes :
  1. Edit the text in the relevant page component. Bump the
     `*_VERSION` const in that file.
  2. Bump CurrentTerms[*] in services/terms_service.go to the same
     value.
  3. Deploy. Every existing user gets force-prompted on their next
     session ; new users prompted at registration.

baseline checks : tsc 0 errors, eslint 754, go build clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:47:07 +02:00
..
admin refactor(web): zero out react-hooks/exhaustive-deps (49 → 0) 2026-05-01 04:00:46 +02:00
analytics refactor(web): migrate components from hardcoded pigment hex to SUMI tokens 2026-04-27 05:07:24 +02:00
auth refactor(web): zero out @typescript-eslint/no-unused-vars (134 → 0) 2026-04-30 23:05:32 +02:00
base refactor: Phase 1 — SUMI token foundation 2026-02-12 01:48:01 +01:00
branding feat(branding): scaffold Logo component + Sumi icons + brand assets pipeline (Sprint 3) 2026-04-27 17:08:17 +02:00
charts refactor(design-system): finish Sprint 2 — light theme + 3 viz pigments canonized 2026-04-27 16:57:12 +02:00
commerce fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
dashboard refactor(web): zero out @typescript-eslint/no-unused-vars (134 → 0) 2026-04-30 23:05:32 +02:00
data fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
demo feat(ui): add SUMI design system components, seasonal hooks, and i18n updates 2026-03-31 19:15:54 +02:00
developer refactor(web): zero out react-hooks/exhaustive-deps (49 → 0) 2026-05-01 04:00:46 +02:00
feedback refactor(web): zero out @typescript-eslint/no-explicit-any (115 → 0) 2026-05-01 03:23:27 +02:00
filters refactor(web): zero out @typescript-eslint/no-explicit-any (115 → 0) 2026-05-01 03:23:27 +02:00
forms fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
icons feat(branding): scaffold Logo component + Sumi icons + brand assets pipeline (Sprint 3) 2026-04-27 17:08:17 +02:00
inventory fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
keyboard refactor: Phase 3a — Global color class migration to SUMI semantics 2026-02-12 01:51:49 +01:00
layout fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
library refactor(web): zero out @typescript-eslint/no-explicit-any (115 → 0) 2026-05-01 03:23:27 +02:00
live fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
marketplace refactor(web): zero out 3 ESLint warning buckets (storybook + react-refresh + non-null-assertion) 2026-04-30 23:30:22 +02:00
modals fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
monitoring fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
navigation refactor(web): zero out 3 ESLint warning buckets (storybook + react-refresh + non-null-assertion) 2026-04-30 23:30:22 +02:00
notifications fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
player refactor(web): zero out @typescript-eslint/no-explicit-any (115 → 0) 2026-05-01 03:23:27 +02:00
pwa refactor(web): zero out @typescript-eslint/no-explicit-any (115 → 0) 2026-05-01 03:23:27 +02:00
search refactor(web): zero out @typescript-eslint/no-explicit-any (115 → 0) 2026-05-01 03:23:27 +02:00
seller refactor(web): zero out @typescript-eslint/no-explicit-any (115 → 0) 2026-05-01 03:23:27 +02:00
settings refactor(web): zero out @typescript-eslint/no-explicit-any (115 → 0) 2026-05-01 03:23:27 +02:00
share fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
social refactor(web): zero out react-hooks/exhaustive-deps (49 → 0) 2026-05-01 04:00:46 +02:00
sumi fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
theme refactor(web): zero out @typescript-eslint/no-explicit-any (115 → 0) 2026-05-01 03:23:27 +02:00
ui feat(legal): versioned terms acceptance ledger (CGU/CGV/mentions) 2026-05-01 20:47:07 +02:00
upload refactor(web): zero out react-hooks/exhaustive-deps (49 → 0) 2026-05-01 04:00:46 +02:00
user fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
AdvancedFilters.tsx fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
BulkModeBanner.tsx fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
COMPONENT_USAGE.md docs: update Welcome.mdx and deprecate Kodo references in docs 2026-02-17 17:05:33 +01:00
CookieBanner.tsx feat(legal): cookie banner + privacy page (ePrivacy/RGPD consent gate) 2026-05-01 17:33:19 +02:00
ErrorBoundary.stories.tsx fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
ErrorBoundary.test.tsx fix(a11y): fix heading hierarchy h1→h3 gaps on 8 pages 2026-03-25 10:14:18 +01:00
ErrorBoundary.tsx improving UI: adding API doc to Developer Page 2026-01-26 14:12:17 +01:00
index.ts incus deployement fully implemented, Makefile updated and make fmt ran 2026-01-13 19:47:57 +01:00
OfflineIndicator.stories.tsx fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
OfflineIndicator.tsx fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
OfflineQueueManager.tsx fix: stabilize builds, tests, and lint across all stacks 2026-04-05 16:48:07 +02:00
Onboarding.tsx chore: enable noUncheckedIndexedAccess, isolate ghost MSW handlers, document go-clamd tech debt 2026-02-12 23:12:35 +01:00
RateLimitIndicator.tsx refactor(tokens): complete design token migration to semantic system 2026-02-09 23:05:09 +01:00
TermsAcceptanceModal.tsx feat(legal): versioned terms acceptance ledger (CGU/CGV/mentions) 2026-05-01 20:47:07 +02:00
types.ts incus deployement fully implemented, Makefile updated and make fmt ran 2026-01-13 19:47:57 +01:00