Skip to content

Update to privacy policy and related fixes - #304

Merged
malteos merged 11 commits into
mainfrom
feat/focused-darwin-rrnazo
Oct 10, 2026
Merged

malteos merged 11 commits into
mainfrom
feat/focused-darwin-rrnazo

Conversation

@malteos

@malteos malteos commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Generated by Claude Code

claude added 6 commits October 5, 2026 21:48
Reading screen resolution and plugin support via JavaScript is an access
to the end user's terminal equipment under § 25 TDDDG (DSK guidance on
digital services, Rn. 24), which disableCookies alone does not avoid. With
disableBrowserFeatureDetection the tracker only sends what the browser
transmits anyway (URL, referrer, user agent, language) and Matomo builds
its 24-hour config_id without device features, so the analytics stay
outside § 25 TDDDG. The privacy policy in the deployment repo describes
this configuration.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfK4DpRZBeer3JMt6Br9yw
Unsubscribing used to wipe the opt-in timestamps immediately, so consent
for mailings already sent could not be proven later, and the wording the
user accepted was never recorded. Legal review of the privacy policy
asked for the end of sending and the retention of proof to be separated.

- New append-only NewsletterConsentLog: one row per opt-in, double-opt-in
  confirmation and revocation with e-mail, source, consent text and text
  version; user FK is SET_NULL so rows survive account deletion.
- Logged from signup, on-login prompt, dashboard, DOI confirmation,
  inactivity anonymisation and account deletion.
- Consent wording centralised in newsletter.CONSENT_TEXT (+ version) and
  made explicit (sender, content, withdrawal); German translation added.
- purge_newsletter_consent_logs deletes a chain three years after the end
  of the revocation year (§§ 195, 199 BGB); read-only admin; rows included
  in the GDPR data export. Documented in docs/newsletter-consent.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfK4DpRZBeer3JMt6Br9yw
The privacy policy promises that passages removed after a privacy report
stay removed when a decision is crawled again. The ingestor only creates
cases and the (court, file_number) key rejects re-submissions with 409,
so the only way a removed decision can return is by deleting its row.

- Case.moderated_at / moderation_note (staff-only, deferred, never
  serialized) record the takedown or redaction.
- Case.apply_takedown() hides the case (rejected) and purges content, raw
  and abstract while keeping the dedupe key; Case.mark_redacted() blanks
  the unredacted raw HTML after a content edit.
- Admin actions "Takedown" and "Clear moderation record".
- While moderated_at is set, re-acceptance is refused by the
  set_review_accepted processing step, the REST PATCH serializer and
  bulk_approve_cases.
- Procedure documented in docs/content-moderation.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfK4DpRZBeer3JMt6Br9yw
Reverts the Matomo tracker change, the newsletter consent log and the
case moderation record so each can be discussed and re-done one by one.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfK4DpRZBeer3JMt6Br9yw
Add Case.review_date (stamped on save whenever review_status or
review_note changes, and on creation) and Case.review_note (staff-only,
deferred, never serialized) to record review decisions such as a
takedown or redaction after a privacy report. Case.apply_takedown()
hides a case (rejected) and purges content/raw/abstract while keeping
the (court, file_number) key so the ingestor cannot re-create it;
Case.mark_redacted() blanks the unredacted raw HTML. Admin action
"Takedown" applies it.

Guard: bulk review never touches already accepted or rejected items.
The set_review_accepted / set_review_rejected processing steps for
cases, courts, laws and law books now act on pending items only, the
set_review_pending steps reset accepted items only (never rejected),
the law-book cascade follows the same rules per law, bulk_approve_cases
stays pending-only and stamps review_date, and the staff REST PATCH
refuses to accept a rejected case that carries a review note.

Procedure documented in docs/content-moderation.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfK4DpRZBeer3JMt6Br9yw
…xisting docs

Drop the "Takedown" admin action and the apply_takedown/mark_redacted
helpers: rejections are done by hand in the admin change form (status +
review note). Keep review_date/review_note, the bulk-review guards and
the API guard. Replace docs/content-moderation.md with a short section
in docs/api/case-creation.md and a note in docs/processing.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfK4DpRZBeer3JMt6Br9yw
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Deploying oldp-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: e25f764
Status: ✅  Deploy successful!
Preview URL: https://a08111a9.oldp-docs.pages.dev
Branch Preview URL: https://feat-focused-darwin-rrnazo.oldp-docs.pages.dev

View logs

claude added 5 commits October 8, 2026 08:31
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfK4DpRZBeer3JMt6Br9yw
Reading screen resolution and plugin support via JavaScript is an access
to the user's terminal equipment under § 25 TDDDG (DSK guidance Rn. 24)
that analytics cannot justify without consent; disableCookies alone does
not avoid it. With disableBrowserFeatureDetection the tracker only sends
what the browser transmits anyway and Matomo builds its config_id without
device features. The resolution and plugin reports are dropped.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfK4DpRZBeer3JMt6Br9yw
Unsubscribing used to wipe the opt-in and confirmation timestamps, so
consent for mailings already sent could not be demonstrated (Art. 7 Abs. 1
DSGVO, § 7 UWG), and the wording the user agreed to was never recorded.

- New NewsletterConsentText (version, language, text): rows are created
  only by data migrations, save() refuses updates, delete() raises, the
  admin is read-only, and the profile FK is PROTECT.
- UserProfile.newsletter_consent_text stores the exact row shown at
  opt-in; newsletter_unsubscribed_at records the withdrawal. revoke_
  newsletter() now clears only the live flag; the proof lives and dies
  with the account (deletion, anonymisation). A new opt-in resets
  confirmation and withdrawal so a fresh double opt-in is required.
- Signup form, on-login prompt, dashboard and the double-opt-in e-mail
  render the current wording from the table, so what is shown and what
  is recorded are the same row. With no row migrated, no opt-in is
  offered.
- Seed migration adds the original 2026-06 English wording (all users
  saw it: the German translation was missing) and the 2026-10 wording in
  English and German, and backfills existing opt-ins to 2026-06.
- Export includes the consent text; docs/newsletter-consent.md added.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfK4DpRZBeer3JMt6Br9yw
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfK4DpRZBeer3JMt6Br9yw
@malteos malteos changed the title privacy dev Update to privacy policy and related fixes Oct 10, 2026
@malteos
malteos merged commit a1e9780 into main Oct 10, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants