Skip to content

Add DTC legal footer, legal pages, and analytics preferences #125

Description

@alexeygrigorev

Parent epic: #6

Normative process: _docs/PROCESS.md

Outcome

Add a consistent Legal section to the global DataTalks.Club footer with:

  • Terms of Service;
  • Privacy Policy;
  • Analytics preferences; and
  • Impressum.

Reuse the proven AI Shipping Labs structure and consent behavior, but write and verify the policies for the actual DataTalks.Club website, community, accounts/member profiles, courses/cohorts, events/registrations, GitHub content, Slack onboarding, Relay email, AWS/CloudFront country suggestion, and analytics boundary. Do not copy AI Shipping Labs memberships, Stripe, paid-plan, CRM, sprint, or product-specific statements into DTC.

Reference implementation

Reference the clean content of DataTalksClub/ai-shipping-labs@189708e06ca1e0519a7ad6abfe81fcf9c12b165d, especially:

  • templates/includes/footer.html;
  • templates/legal/{terms,privacy,impressum}.html;
  • content/views/legal.py and its URL routes;
  • content/tests/test_legal_pages.py;
  • playwright_tests/test_static_page_design_1229.py;
  • playwright_tests/test_analytics_consent_1164.py;
  • playwright_tests/test_public_mobile_tap_targets_1214.py; and
  • _docs/integrations/analytics.md.

Reuse its layout, accessibility, and consent invariants where applicable. DTC's existing design system, no-trailing-slash URL convention, shared services/settings/API rules, and readable non-minified templates remain authoritative.

Product and URL contract

  • Canonical public pages are /terms, /privacy, and /impressum with 200 OK and production self-canonicals.
  • /terms/, /privacy/, and /impressum/ permanently redirect in one hop to their no-slash canonical while preserving the raw query.
  • Footer links point directly to the canonical no-slash URLs; internal links must not rely on redirects.
  • The legal section appears on every public shell, including the main/content shell and copied course-platform shell. Use one shared footer/legal partial or another tested single source so the surfaces cannot drift.
  • Analytics preferences is a semantic button, not a fake link. It reopens the consent UI without navigation and works from keyboard and assistive technology.
  • Development remains globally noindex, nofollow; production legal-page robots/canonical/sitemap treatment is explicit and tested.

DTC-specific legal content

Before acceptance, inventory the actual deployed data flows and processors and reconcile the wording with _docs/specs/07-security-privacy-operations.md. At minimum:

Terms of Service

Cover the free DataTalks.Club community/site, accounts, member profiles, Slack access, events, courses/cohorts, submissions/contributions, acceptable use, account security, third-party destinations, intellectual property/licensing, availability/changes, disclaimers, liability, termination, governing law, operator/contact details, and an explicit last-updated date.

Privacy Policy

Cover the controller/contact, data categories, purpose and lawful basis, account/profile data, course/cohort and event registrations, learner work and certificates, GitHub-authored public content/people, Slack onboarding, Relay transactional email, necessary session/CSRF/security cookies, optional analytics, editable CloudFront country suggestion, logs/security data, subprocessors/regions/transfers, retention, consent withdrawal, access/export/correction/deletion/restriction/objection rights, complaint authority, minors policy, and an explicit last-updated date.

List only processors and data flows that current authoritative specs/code actually use. Do not mention AI Shipping Labs, Stripe, paid memberships, or direct website SES/Datamailer delivery. Relay is the website's transactional-email processor boundary; legacy Datamailer is migration/history/reconciliation-only.

Impressum

Publish the verified DataTalks.Club operator identity, address, authorized representative, contact, VAT/tax identifiers, and applicable German statutory/dispute-resolution wording. The owner/legal reviewer must confirm the exact public details; do not infer or silently copy an outdated contact from another product.

Legal copy must be versioned in source, readable HTML (not minified), escaped safely, and editable through the ordinary reviewed code/content workflow. It is not arbitrary database-authored HTML.

Analytics-consent contract

  • Optional analytics fails closed. Before an affirmative choice, and after rejection/withdrawal, the browser loads no analytics script, contacts no analytics endpoint, sets no optional analytics/attribution cookie, and emits no analytics event.
  • Necessary consent state is stored in a minimal secure cookie with an explicit version and documented lifetime; consent is not inferred from continued browsing.
  • The accessible preferences dialog offers equally clear allow/deny choices, preserves the current choice, returns focus to the opener, traps/follows focus correctly, closes predictably, and supports reduced motion and 200% zoom/reflow.
  • Withdrawal immediately prevents further optional events and expires every DTC-owned optional analytics/attribution cookie. Rejecting analytics never blocks content, signup, Slack, course, or event functionality.
  • Analytics configuration is off by default, blank in CI/local/development, and managed through the existing typed Studio settings plus admin-only API parity. A missing/invalid measurement ID emits no loader.
  • Development/previews never send production analytics. No email, profile value, country suggestion/header, raw IP, account/database ID, session/CSRF value, credential, Slack secret, or other PII is sent as an analytics field.
  • Content Security Policy and privacy documentation agree with the disabled/enabled analytics states.

Footer design and accessibility

  • Follow the existing DTC/CMP design system rather than introducing a separate visual language.
  • Legal links and the preferences button have visible focus, sufficient contrast, semantic labels, and at least 44×44 CSS-pixel mobile targets without causing horizontal overflow at 320/390 px or 200% zoom.
  • The existing GitHub footer icon remains a clearly labelled external link and must not be underlined in default, hover, focus, active, or visited states. Remove text decoration from the icon control itself without weakening its visible focus indicator or the styling of ordinary text links.
  • External-link semantics, icon placement, wrapping, and footer alignment remain stable on desktop and mobile.

Studio/admin API boundary

If analytics configuration is introduced or changed, declare it in the existing typed settings registry and expose the same validation, permissions, audit redaction, defaults, and result through Studio and the admin-only API. Never return secrets or accept arbitrary executable analytics markup. Legal copy itself remains source-reviewed; Studio may link to its source/preview but does not become a second mutable policy store in this slice.

Acceptance criteria

  • The global footer exposes the four requested legal controls on every public/main/course shell with no duplicate or divergent implementation.
  • /terms, /privacy, and /impressum are public, readable, DTC-specific, self-canonical 200 pages; slash aliases redirect one hop and all internal links use canonical no-slash paths.
  • DTC legal copy matches the actual architecture/data inventory and contains no stale AI Shipping Labs, Stripe, paid-membership, direct-SES, or new-Datamailer statements.
  • Exact operator/contact/tax details and last-updated dates receive an explicit owner/legal HUMAN review before production acceptance.
  • Analytics sends nothing and sets no optional cookie before opt-in or after reject/withdraw; preferences can be reopened from every footer and withdrawal clears optional DTC cookies.
  • Analytics is disabled by default and in development/CI, invalid configuration fails closed, CSP remains correct, and no prohibited identifier/PII is emitted.
  • Typed Studio/admin API settings parity, permission, validation, audit-redaction, and negative tests pass if analytics settings are in scope.
  • The GitHub footer icon is never underlined, retains an accessible name and visible focus, and ordinary legal text links keep their expected link styling.
  • Desktop/mobile keyboard, focus, 200% zoom/reflow, target-size, contrast, reduced-motion, and no-horizontal-overflow checks pass.
  • Legal routes have tested sitemap/robots/canonical behavior and development stays noindex/nofollow.
  • Templates remain human-readable and non-minified.

Verification

Add focused Django tests for public access, canonical/slash behavior, exact template use, DTC content canaries, forbidden copied-product canaries, footer coverage across both shells, sitemap/robots/canonical behavior, settings/API parity, and analytics fail-closed behavior.

Add Playwright coverage at approximately 1440×900 and 390×844 for:

  1. each legal page and footer navigation;
  2. keyboard-open/allow/reject/reopen/withdraw/focus-return consent behavior;
  3. network/cookie proof that no optional analytics request or cookie exists before opt-in or after withdrawal;
  4. public functionality with analytics rejected;
  5. 200% zoom/reflow and mobile tap targets; and
  6. the GitHub icon's computed text-decoration-line: none, focus visibility, accessible name, and no overflow.

Capture and inspect desktop/mobile screenshots below .tmp/screenshots/ only. Screenshots and artifacts contain no real identity, consent value, credential, or PII.

Run the repository's applicable uv/Make lint, format, Django, contract, accessibility, and core Playwright targets. The tester must record exact commands, results, candidate fingerprint, and screenshot paths.

Dependencies and sequencing

Non-goals

  • No marketing/newsletter consent changes.
  • No analytics event taxonomy, CRM attribution, advertising, profiling, fingerprinting, cross-site tracking, or consent wall.
  • No arbitrary script/tag-manager editor.
  • No legal guarantee generated by engineering; the owner/legal reviewer accepts the final public wording.
  • No production analytics property/configuration mutation during implementation tests.

Process handoff

Implement from current main in an isolated issue worktree. Follow _docs/PROCESS.md: engineer implements and tests without committing; a separate tester verifies functionality, responsive/accessibility behavior, network/cookie invariants, and screenshots; a product manager accepts the complete result; only then commit locally with Closes #N, merge without a pull request, deploy, and run exact-SHA on-call checks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0Must-have or release-blockingaccessibilityArea: accessibilitydocumentationImprovements or additions to documentationenhancementNew feature or requestfrontendArea: frontendhumanCode complete; manual verification requiredsecurityArea: securityseoArea: seotestingArea: testing

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions