diff --git a/.github/scripts/fop-local-ci.sh b/.github/scripts/fop-local-ci.sh
index f18e863d..73166652 100755
--- a/.github/scripts/fop-local-ci.sh
+++ b/.github/scripts/fop-local-ci.sh
@@ -520,6 +520,8 @@ post_commit_status "pending" "fop local ${profile} running"
run_direct "working tree whitespace" "git diff --check"
run_direct "ui polish contract" "scripts/tests/test-ui-polish-contract.sh"
+run_direct "legal-readiness wording contract" "scripts/tests/test-legal-readiness-wording.sh"
+run_direct "legal/module OpenAPI contract" "scripts/tests/test-legal-openapi-contract.sh"
# ---------------- Backend (PHP) ---------------------------------------------
if (( diff_touch_php )); then
diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml
index 501f87e2..c68e960a 100644
--- a/.github/workflows/security.yml
+++ b/.github/workflows/security.yml
@@ -165,6 +165,8 @@ jobs:
# Audit-mode: surface findings as informational; do NOT fail the gate yet.
# Promote findings to errors once the workflow inventory has been triaged.
continue-on-error: true
+ env:
+ ZIZMOR_VERSION: "1.24.1"
permissions:
contents: read # checkout source for the SAST scan
security-events: write # upload Zizmor SARIF results to GitHub Security tab
@@ -172,19 +174,50 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
+
+ - name: Install zizmor
+ run: |
+ set -euo pipefail
+ python3 -m pip install --user --break-system-packages "zizmor==${ZIZMOR_VERSION}"
+ echo "${HOME}/.local/bin" >> "${GITHUB_PATH}"
+ "${HOME}/.local/bin/zizmor" --version
+
- name: Run zizmor
continue-on-error: true
- uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3
+ run: |
+ set -euo pipefail
+ # Auditor persona surfaces useful hardening findings without making
+ # them release-gating while this job remains in audit mode.
+ zizmor \
+ --persona=auditor \
+ --min-severity=high \
+ --no-online-audits \
+ --no-progress \
+ --color=never \
+ --no-exit-codes \
+ .github/workflows .gitea/workflows
+
+ - name: Generate zizmor SARIF
+ continue-on-error: true
+ run: |
+ set -euo pipefail
+ zizmor \
+ --persona=auditor \
+ --min-severity=high \
+ --no-online-audits \
+ --no-progress \
+ --color=never \
+ --no-exit-codes \
+ --format=sarif \
+ .github/workflows .gitea/workflows > zizmor.sarif
+
+ - name: Upload Zizmor SARIF to GitHub Security tab
+ uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4
+ if: always() && hashFiles('zizmor.sarif') != ''
+ continue-on-error: true
with:
- # auditor persona surfaces low-severity findings useful for hardening
- # without flooding the PR with regular-user noise. Keep this aligned
- # with .github/scripts/fop-local-ci.sh: offline, high-severity-only,
- # and scoped to workflow manifests so PR audits cannot hang on live
- # GitHub API checks.
- inputs: .github/workflows .gitea/workflows
- persona: auditor
- online-audits: false
- min-severity: high
+ sarif_file: zizmor.sarif
+ category: zizmor
osv-scanner:
# Multi-ecosystem SCA via Google's osv-scanner against the OSV.dev DB.
diff --git a/README.md b/README.md
index b661715e..a6181cb2 100644
--- a/README.md
+++ b/README.md
@@ -14,8 +14,8 @@
-
-
+
+
Ihre Daten. Ihr Server. Ihre Kontrolle.
The on-premise parking management runtime for the canonical ParkHub product -- optimized for shared hosting, VPS, Docker, and Kubernetes.
- Built with Laravel 13, Astro 6, React 19, and Tailwind CSS 4. Zero cloud. Zero tracking. 100% GDPR compliant by design.
+ Built with Laravel 13, Astro 6, React 19, and Tailwind CSS 4. Zero cloud. Zero tracking. GDPR/DSGVO-ready architecture with deployment-dependent obligations.
@@ -103,7 +103,7 @@ Cross-runtime ownership and release discipline live in [docs/parity-governance.m Most parking management SaaS costs 200--2,000 EUR/month, stores your data on US cloud infrastructure, and requires a data processing agreement just to get started. -ParkHub is different. It runs on your server -- a shared hosting plan, a VPS, or your company network. Your data never leaves your premises, which means **no GDPR processor agreement needed**, no CLOUD Act exposure, and no monthly fees. The entire source code is MIT-licensed and auditable. +ParkHub is different. It runs on your server -- a shared hosting plan, a VPS, or your company network. For a purely self-hosted core deployment, data does not leave infrastructure you control; processor agreements, international-transfer analysis, and provider terms still depend on your hosting, SMTP, payment, analytics, AI, and backup choices. The entire source code is MIT-licensed and auditable. --- @@ -245,13 +245,16 @@ php artisan test # Run PHPUnit (1,320 feature + 434 unit) - **Advanced pass flow** -- digital passes, QR generation, visitor pre-registration, and check-in surfaces - **Runtime-sensitive surfaces** -- QR/check-in/public verification flows should be treated as advanced and runtime-sensitive, not as unconditional baseline behavior -### Legal Compliance +### Legal Readiness - **GDPR / DSGVO** -- Art. 15 data export, Art. 17 erasure, Art. 20 portability - **German law** -- DDG SS5 Impressum, TTDSG SS25 cookie policy, SS147 AO retention - **7 legal templates** -- Impressum, Datenschutz, AGB, Widerrufsbelehrung, AVV, VVT, Cookie Policy -- **International** -- UK GDPR, CCPA, nDSG (Switzerland), LGPD (Brazil) compatible -- See [GDPR Guide](docs/GDPR.md) | [Compliance Matrix](docs/COMPLIANCE.md) +- **International** -- UK GDPR, CCPA, nDSG (Switzerland), and LGPD mapping notes for operator review +- **Operator audit hub** -- [Legal Readiness Hub](docs/legal-readiness.md) ties templates, release checks, and deployment obligations together for review +- **Deployment signoff** -- [Deployment Readiness Record](docs/deployment-readiness-record.md) captures jurisdiction, module, processor, CI/CD evidence, and human go-live signoff per deployment +- **Cross-runtime parity** -- [Legal Readiness Parity](docs/legal-readiness-parity.md) keeps Rust/PHP legal-readiness gates, module/plugin review, and operator boundaries aligned +- See [Legal Readiness Hub](docs/legal-readiness.md) | [Deployment Readiness Record](docs/deployment-readiness-record.md) | [Legal Readiness Parity](docs/legal-readiness-parity.md) | [GDPR Guide](docs/GDPR.md) | [Compliance Matrix](docs/COMPLIANCE.md) --- @@ -261,7 +264,7 @@ ParkHub organizes functionality into **70 modules** across **11 categories** — Every module is exposed in the admin dashboard at `/admin/modules` with status pills, category grouping, search, dependency chain, and config-keys count. Shipped in **v4.13.0** (v1 + v2 + v3): -- **Runtime enable/disable** — 13 safe modules flip via `PATCH /api/v1/admin/modules/{name}` without a redeploy (widgets, themes, favorites, lobby-display, accessible, calendar-drag, ev-charging, maintenance, geofence, map, graphql, api-docs, setup-wizard). Security-sensitive modules (`auth`, `payments`, `rbac`, `webhooks`, `audit-export`, `multi-tenant`, `notifications`) stay env-flagged. +- **Runtime enable/disable** — 13 low-risk UI/operations modules flip via `PATCH /api/v1/admin/modules/{name}` without a redeploy (widgets, themes, favorites, lobby-display, accessible, calendar-drag, ev-charging, maintenance, geofence, map, graphql, api-docs, setup-wizard). Security-sensitive or legally sensitive modules (`auth`, `payments`, `rbac`, `webhooks`, `audit-export`, `multi-tenant`, `notifications`, and any AI/third-party integration) stay env-flagged or require operator review, audit logging, processor checks, and privacy-text updates before enablement. - **JSON Schema config editor** — 5 modules ship a `config_schema` (JSON Schema 2020-12) and surface a per-module config modal: `themes`, `announcements`, `notifications`, `email-templates`, `widgets`. Writes validate server-side via `opis/json-schema`; failures return `422 CONFIG_VALIDATION_FAILED` with a structured `details` array. - **Command Palette** — `Cmd+K` / `Ctrl+K` / `/` auto-seeds "Go to…" entries from every active module with a `ui_route`. - **Module Gate middleware** — `App\Http\Middleware\ModuleGate` returns `404 MODULE_DISABLED` for runtime-disabled routes (indistinguishable from an uninstalled feature). @@ -372,16 +375,29 @@ The complete OpenAPI 3.0 spec is snapshotted at [`docs/openapi/php.json`](docs/o --- -## Legal Compliance +## Legal Readiness -ParkHub PHP is designed for legal compliance across multiple jurisdictions. Audited against **9 regulatory frameworks**: +ParkHub PHP ships legal-readiness features and operator-customizable templates for deployments across multiple jurisdictions. Start with the [Operator Legal Readiness Hub](docs/legal-readiness.md) for the audit flow, evidence map, and release review boundary. A live deployment's legal posture depends on the operator's configuration, hosting model, enabled modules, processors, jurisdiction, and legal review. The docs map the product surface against **9 regulatory frameworks**: **GDPR** (EU) | **DSGVO** (DE) | **TTDSG** (DE) | **DDG** (DE) | **BDSG** (DE) | **NIS2** (EU) | **CCPA** (US) | **UK GDPR** | **nDSG** (CH) -All legal documents are provided as **operator-customizable templates** -- not binding legal texts. +All legal documents are provided as **operator-customizable templates** -- not binding legal texts and not legal advice. + +### Operator Go-Live Checklist + +- [ ] Complete or update the [Deployment Readiness Record](docs/deployment-readiness-record.md) for the exact deployment, enabled modules, processors, jurisdictions, CI/CD evidence, and final human signoff. +- [ ] Publish and verify Impressum, Datenschutzerklärung/privacy notice, AGB/terms if applicable, and withdrawal notice for B2C deployments. +- [ ] Complete AVV/DPA and sub-processor review for hosting, SMTP, payment, backups, support, analytics, AI, and any other external provider. +- [ ] Maintain a VVT/Record of Processing Activities and document legal bases, retention periods, recipients, and international transfers. +- [ ] Verify TTDSG/cookie/localStorage analysis after enabling optional modules; add consent flows if non-essential storage or tracking is introduced. +- [ ] Run BFSG/EAA accessibility review for consumer-facing deployments and keep the accessibility statement current. +- [ ] Add AI Act transparency notices and human-review procedures if AI/ML features are enabled. +- [ ] Configure retention, audit logging, backups, encryption, DSAR handling, breach response, and admin access controls for the actual deployment. +- [ ] Have the final deployment, legal texts, citations, and configuration reviewed by qualified counsel before production use. | Document | Purpose | Location | |----------|---------|----------| +| **Operator Legal Readiness Hub** | Audit index for legal-readiness evidence, review boundaries, and release checks | [docs/legal-readiness.md](docs/legal-readiness.md) | | **GDPR / DSGVO Guide** | Full DSGVO compliance documentation | [docs/GDPR.md](docs/GDPR.md) | | **Compliance Matrix** | German, EU, and international law mapping | [docs/COMPLIANCE.md](docs/COMPLIANCE.md) | | **Security Model** | Architecture, OWASP, encryption, disclosure | [docs/SECURITY.md](docs/SECURITY.md) | diff --git a/docs/COMPLIANCE.md b/docs/COMPLIANCE.md index 5a6a0c3a..dc7bc658 100644 --- a/docs/COMPLIANCE.md +++ b/docs/COMPLIANCE.md @@ -2,9 +2,10 @@ > **Version:** 3.3.0 | **Last updated:** 2026-04-12 -This document maps ParkHub PHP features to legal requirements across German, EU, and -international data protection regulations. It is intended for operators evaluating ParkHub -for deployment in regulated environments. +This document maps ParkHub PHP features and templates to legal requirements across German, +EU, and international data protection regulations. It is intended for operators evaluating +ParkHub for deployment in regulated environments; it is not a conclusion that any specific +deployment is compliant. **This document is informational and does not constitute legal advice.** @@ -18,7 +19,7 @@ for deployment in regulated environments. 4. [Data Processing Categories](#data-processing-categories) 5. [Data Retention Policies](#data-retention-policies) 6. [Sub-Processor List](#sub-processor-list) -7. [Compliance Checklist](#compliance-checklist) +7. [Legal Readiness Checklist](#legal-readiness-checklist) --- @@ -26,11 +27,12 @@ for deployment in regulated environments. ### DSGVO (Datenschutz-Grundverordnung) -The German implementation of the EU GDPR. ParkHub's self-hosted architecture means the -operator is the sole data controller with no mandatory data processor agreements for -core functionality. +The German implementation of the EU GDPR. ParkHub's self-hosted architecture can let the +operator act as the controller for the core system, but processor agreements and transfer +analysis depend on the chosen hosting, SMTP, payment, backup, support, AI, and integration +providers. -| Requirement | How ParkHub Complies | Module / Feature | +| Requirement | ParkHub Support | Module / Feature | |-------------|---------------------|------------------| | Art. 5 — Data processing principles | Data minimization (only required fields), purpose limitation (parking management), storage limitation (configurable retention) | Core | | Art. 6 — Legal basis | Documented per processing activity in [GDPR.md](GDPR.md) | Core | @@ -43,17 +45,17 @@ core functionality. | Art. 18 — Right to restriction | Admin can deactivate accounts | Admin module | | Art. 20 — Data portability | JSON export via `/api/v1/user/export`, CSV via admin reports | GDPR + Data Export modules | | Art. 21 — Right to object | Notification preferences toggle, contact form for objections | Notifications module | -| Art. 25 — Privacy by design | Self-hosted = no third-party processors; only required fields collected | Architecture | -| Art. 28 — Processor agreements | No DPA needed for core (on-premise); AVV template for SMTP | `legal/avv-template.md` | +| Art. 25 — Privacy by design | Self-hosted core architecture, data minimization, and no external analytics by default | Architecture | +| Art. 28 — Processor agreements | Core on-premise processing can avoid external processors; AVV/DPA review is required for configured providers | `legal/avv-template.md` | | Art. 30 — Records of processing | VVT template with all processing activities | `legal/vvt-template.md` | | Art. 32 — Security of processing | See [SECURITY.md](SECURITY.md) — encryption, access control, audit logging | Core | | Art. 33/34 — Breach notification | Breach notification template in [GDPR.md](GDPR.md); audit log for forensics | Core | -| Art. 35 — DPIA | Guidance in GDPR.md; not required for typical deployments | Documentation | +| Art. 35 — DPIA | Guidance in GDPR.md; operator assesses whether the concrete deployment requires a DPIA | Documentation | | Art. 37 — DPO appointment | Guidance provided; operator responsibility | Documentation | ### TTDSG (Telekommunikation-Telemedien-Datenschutz-Gesetz) -| Requirement | How ParkHub Complies | Module / Feature | +| Requirement | ParkHub Support | Module / Feature | |-------------|---------------------|------------------| | §25 Abs. 1 — Consent for non-essential storage | Not applicable — ParkHub uses no cookies and no non-essential localStorage | Core | | §25 Abs. 2 Nr. 2 — Technically necessary exemption | All localStorage entries (token, theme, features, language, hints) qualify as technically necessary | Core | @@ -63,7 +65,7 @@ core functionality. Replaced the TMG (Telemediengesetz) as of 2024. -| Requirement | How ParkHub Complies | Module / Feature | +| Requirement | ParkHub Support | Module / Feature | |-------------|---------------------|------------------| | §5 — Impressum (provider identification) | Admin panel for Impressum, public display at `/impressum`, API endpoint | Admin Settings | | §6 — Special Impressum requirements | Template covers all GmbH/AG fields, VAT ID, register court | `legal/impressum-template.md` | @@ -74,7 +76,7 @@ Superseded by DDG. ParkHub references DDG §5 (not TMG §5) in all templates. ### BDSG (Bundesdatenschutzgesetz) -| Requirement | How ParkHub Complies | Module / Feature | +| Requirement | ParkHub Support | Module / Feature | |-------------|---------------------|------------------| | §38 — DPO appointment threshold | Guidance in GDPR.md (20+ employees processing personal data) | Documentation | | §26 — Employee data processing | Applicable if ParkHub is used for employee parking; legal basis: Art. 6 lit. b (employment contract) | Core | @@ -83,7 +85,7 @@ Superseded by DDG. ParkHub references DDG §5 (not TMG §5) in all templates. Relevant for operators using ParkHub for commercial parking with revenue tracking. -| Requirement | How ParkHub Complies | Module / Feature | +| Requirement | ParkHub Support | Module / Feature | |-------------|---------------------|------------------| | Traceability | Audit log records all booking/payment operations with timestamps | Audit Log | | Immutability | Audit log has no delete endpoint; deletion requires direct DB access | Audit Log | @@ -98,12 +100,13 @@ Relevant for operators using ParkHub for commercial parking with revenue trackin ### GDPR (General Data Protection Regulation) -Identical to DSGVO coverage above. ParkHub complies with all GDPR requirements through -its self-hosted architecture and built-in privacy features. +Identical to DSGVO coverage above. ParkHub provides self-hosting, privacy features, and +operator templates that can support GDPR implementation; production compliance depends on +the live deployment, configuration, processors, jurisdiction, and legal review. ### ePrivacy Directive (2002/58/EC) -| Requirement | How ParkHub Complies | Module / Feature | +| Requirement | ParkHub Support | Module / Feature | |-------------|---------------------|------------------| | Art. 5(3) — Cookie consent | No cookies used; localStorage is technically necessary | Core | | Art. 13 — Unsolicited communications | Push notifications require explicit opt-in; email only for transactional messages | Web Push module | @@ -137,7 +140,7 @@ and ParkHub's accessibility features. The UK retained the GDPR post-Brexit as the UK GDPR, alongside the Data Protection Act 2018. -| Requirement | How ParkHub Complies | Notes | +| Requirement | ParkHub Support | Notes | |-------------|---------------------|-------| | UK GDPR — all articles | Substantively identical to EU GDPR | Same features apply | | UK DPA 2018 | No special category data processed | No additional requirements | @@ -152,7 +155,7 @@ websites must identify the operator under the Companies Act 2006 and the Electro The California Consumer Privacy Act (CCPA) and California Privacy Rights Act (CPRA). -| Requirement | How ParkHub Complies | Notes | +| Requirement | ParkHub Support | Notes | |-------------|---------------------|-------| | Right to know | `GET /api/v1/user/export` provides full data disclosure | Automated | | Right to delete | `POST /api/v1/users/me/anonymize` or `DELETE /api/v1/users/me/delete` | Automated | @@ -163,14 +166,14 @@ The California Consumer Privacy Act (CCPA) and California Privacy Rights Act (CP **Note**: For CCPA compliance, US operators should adapt the privacy notice template to include CCPA-specific language (categories of PI collected, business purpose, "Do Not Sell" -disclosure). ParkHub's self-hosted model means operators are sole data controllers with no -"sale" of personal information. +disclosure). ParkHub's self-hosted model can avoid a sale of personal information, but the +operator must verify all enabled integrations and business processes. ### nDSG (Switzerland — New Data Protection Act) The Swiss nDSG (in force since September 1, 2023) aligns closely with the GDPR. -| Requirement | How ParkHub Complies | Notes | +| Requirement | ParkHub Support | Notes | |-------------|---------------------|-------| | Art. 6 — Privacy by design | Self-hosted architecture, data minimization | Architecture | | Art. 7 — Privacy by default | Only essential fields required; modules opt-in | Module system | @@ -186,7 +189,7 @@ The Swiss nDSG (in force since September 1, 2023) aligns closely with the GDPR. The Brazilian LGPD closely mirrors the GDPR. -| Requirement | How ParkHub Complies | Notes | +| Requirement | ParkHub Support | Notes | |-------------|---------------------|-------| | Art. 7 — Legal basis | Mapped from GDPR Art. 6 — contract performance and legitimate interest | Core | | Art. 9 — Sensitive data | ParkHub does not process sensitive data (biometric, health, etc.) | Architecture | @@ -238,8 +241,10 @@ All retention periods are configurable by the operator. The following are recomm ### Self-Hosted Deployment (Default) -**No sub-processors.** All data is processed exclusively on the operator's infrastructure. -No Auftragsverarbeitungsvertrag (AVV / DPA) is required for the core system. +For a default self-hosted core deployment, data is processed on the operator's infrastructure. +An Auftragsverarbeitungsvertrag (AVV / DPA) may still be required for hosting, maintenance, +SMTP, payment, backup, support, AI, analytics, or other external providers used by the +operator. ### Optional Sub-Processors (if enabled by operator) @@ -263,12 +268,12 @@ a sub-processor: --- -## Compliance Checklist +## Legal Readiness Checklist ### Pre-Launch (All Deployments) -- [ ] Privacy notice published (adapted from template) -- [ ] Impressum published (German operators) +- [ ] Privacy notice published after adapting the template to actual data, recipients, retention, transfers, and contact details +- [ ] Impressum/provider identification published and publicly reachable where required - [ ] HTTPS configured with TLS 1.2+ - [ ] `APP_DEBUG=false` in production - [ ] `APP_ENV=production` in production @@ -277,6 +282,8 @@ a sub-processor: - [ ] Data export endpoint tested - [ ] Account deletion/anonymization tested - [ ] Backup strategy documented +- [ ] Processor list and AVV/DPA status documented for hosting, SMTP, payments, backups, support, analytics, AI, and integrations +- [ ] Final legal texts, citations, configuration, and launch process reviewed by qualified counsel ### German Law Specific @@ -286,6 +293,7 @@ a sub-processor: - [ ] Widerrufsbelehrung published (if B2C with consumers) - [ ] VVT (Art. 30 records) created and maintained - [ ] AVV signed with SMTP provider (if email enabled) +- [ ] AVV/DPA reviewed for hosting and any provider with system or data access - [ ] DSB appointment evaluated (§38 BDSG) - [ ] §147 AO retention configured for booking/payment records @@ -293,11 +301,13 @@ a sub-processor: - [ ] Data subject rights accessible (export, deletion, rectification) - [ ] Breach notification process documented -- [ ] Cookie/localStorage policy documented (even if no banner needed) +- [ ] Cookie/localStorage/TTDSG policy documented; consent added if optional modules introduce non-essential storage or tracking - [ ] Third-party sub-processors listed in privacy notice - [ ] International transfer safeguards (SCCs) for non-EU sub-processors - [ ] NIS2 self-assessment completed (if in scope) - [ ] BFSG/EAA accessibility assessment (if B2C with >10 employees) +- [ ] AI Act transparency notice and human-review process documented if AI/ML features are enabled +- [ ] Security-sensitive or legally sensitive modules enabled only after operator review, audit-log coverage, privacy-text updates, retention review, and rollback planning ### CCPA Specific (California) diff --git a/docs/FEATURES.md b/docs/FEATURES.md index f44a4c5f..9f313d3d 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -1,7 +1,7 @@ # ParkHub PHP Feature Notes > **Self-hosted parking management for enterprises, universities, and residential complexes.** -> Laravel 13 · Apache / shared hosting / Render · Zero cloud · Zero tracking · 100% GDPR compliant. +> Laravel 13 · Apache / shared hosting / Render · Zero cloud · Zero tracking · GDPR/DSGVO-ready architecture with deployment-dependent obligations. [Live Demo](https://parkhub-php-demo.onrender.com) · [API Docs](API.md) · [Installation](INSTALLATION.md) · [GDPR Guide](GDPR.md) @@ -48,11 +48,13 @@ The frontend is byte-identical with the parkhub-rust copy (verified via `diff -q ### Runtime Toggle -Thirteen safe modules can be flipped at runtime without redeploying: +Thirteen low-risk UI/operations modules can be flipped at runtime without redeploying: `widgets` · `themes` · `favorites` · `lobby-display` · `accessible` · `calendar-drag` · `ev-charging` · `maintenance` · `geofence` · `map` · `graphql` · `api-docs` · `setup-wizard` -Security-sensitive modules (`auth`, `payments`, `rbac`, `webhooks`, `audit-export`, `multi-tenant`, `notifications`) keep `runtime_toggleable = false` and are invariant at runtime. +Security-sensitive or legally sensitive modules keep `runtime_toggleable = false` and are invariant at runtime unless an operator deliberately enables them through configuration and release process. This group includes `auth`, `payments`, `rbac`, `webhooks`, `audit-export`, `multi-tenant`, `notifications`, AI/ML features, third-party integrations, and any module that changes personal-data recipients, retention, automated decisions, public exposure, or billing. + +Before enabling those modules in production, operators should document the purpose, legal basis, processor/DPA impact, privacy-notice changes, audit-log coverage, retention settings, rollback plan, and attorney review status. ### JSON Schema Config Editor diff --git a/docs/GDPR.md b/docs/GDPR.md index b0978e40..7b29c8e3 100644 --- a/docs/GDPR.md +++ b/docs/GDPR.md @@ -25,7 +25,7 @@ qualified data protection attorney (Datenschutzbeauftragter) for binding guidanc 10. [TTDSG §25 — Cookie / localStorage Policy](#cookie-policy-ttdsg-25) 11. [DDG §5 — Impressum Requirement](#ddg-5--impressum-requirement) 12. [Breach Notification (Art. 33/34)](#breach-notification-art-3334) -13. [DSGVO Compliance Checklist](#dsgvo-compliance-checklist) +13. [Legal Readiness Checklist](#legal-readiness-checklist) 14. [Responding to DSARs](#responding-to-data-subject-access-requests-dsar) 15. [Data Protection Impact Assessment (DPIA)](#data-protection-impact-assessment-dpia) 16. [Accessibility (BFSG / EU Accessibility Act)](#accessibility-bfsg--eu-accessibility-act) @@ -39,7 +39,7 @@ ParkHub PHP is designed for on-premise, self-hosted deployment. All data remains | Aspect | Benefit | |--------|---------| -| No cloud upload | No Auftragsverarbeitungsvertrag (AVV / Art. 28 DPA) needed for the core system | +| No cloud upload by the core app | AVV/DPA scope is usually narrower, but still depends on hosting, support, SMTP, backups, payments, AI, and other providers | | No third-party SaaS | No dependency on external privacy policies | | Full control | You control storage location, encryption, access, and retention | | No analytics | No tracking pixels, no CDN, no external JavaScript | @@ -210,7 +210,7 @@ Administrators can update any user field via `PUT /api/v1/admin/users/:id`. ParkHub implements two distinct deletion modes: -#### 1. Account anonymization — DSGVO-compliant approach (recommended) +#### 1. Account anonymization — DSGVO-oriented approach (recommended) **API endpoint**: `POST /api/v1/users/me/anonymize` @@ -349,7 +349,7 @@ phone. For GmbH/AG: register court, register number, VAT ID, managing directors. ### Datenschutzerklärung (Privacy Policy) -A DSGVO-compliant privacy policy is required. +A privacy notice tailored to the deployment is required for GDPR/DSGVO-covered services. **Templates**: [`legal/datenschutz-template.md`](/legal/datenschutz-template.md) | [`docs/PRIVACY-TEMPLATE.md`](PRIVACY-TEMPLATE.md) @@ -508,28 +508,37 @@ Datum der Kenntnisnahme: [Datum] --- -## DSGVO Compliance Checklist +## Legal Readiness Checklist -Before going live: +ParkHub ships technical controls and templates that can support a GDPR/DSGVO deployment, but the operator remains responsible for the live service, legal texts, processor contracts, configuration, citations, and jurisdiction-specific review. Before going live: -**Legal setup** -- [ ] Impressum fully filled in (Admin → Impressum). Verify `/impressum` is publicly accessible -- [ ] Datenschutzerklärung written and published (Admin → Privacy → Policy Text) -- [ ] AGB created and published (if commercial service) -- [ ] AVV signed with SMTP provider (e.g. Mailgun, SendGrid, Postmark) — `legal/avv-template.md` -- [ ] AVV signed with hosting provider if they can physically access your server -- [ ] Verzeichnis der Verarbeitungstätigkeiten (VVT) updated (Art. 30 DSGVO) -- [ ] DPA/DSB appointment evaluated (Art. 37 DSGVO) -- [ ] Widerrufsbelehrung published (if B2C commercial service) +**Shipped templates and features** +- [ ] Impressum template adapted, filled in, and verified at `/impressum` +- [ ] Datenschutzerklärung/privacy notice adapted and published +- [ ] AGB/terms and Widerrufsbelehrung adapted if the deployment is commercial or B2C +- [ ] AVV/DPA template reviewed before use with processors +- [ ] VVT/Record of Processing Activities template completed for the actual deployment +- [ ] Export, anonymization, hard-deletion, audit-export, and compliance-report features tested with production-like data + +**Operator legal obligations** +- [ ] Controller identity, legal bases, categories, recipients, retention periods, international transfers, and data-subject rights documented +- [ ] AVV/DPA signed with hosting, SMTP, backup, support, payment, analytics, AI, or other processors where applicable +- [ ] DPO/DSB appointment evaluated under Art. 37 DSGVO and §38 BDSG +- [ ] Cookie/localStorage/TTDSG analysis verified after enabling optional modules; consent implemented if non-essential storage or tracking is introduced +- [ ] BFSG/EAA accessibility assessment completed if the service is consumer-facing and in scope +- [ ] AI Act transparency notice, human-review process, and Datenschutz text updated if AI/ML features are enabled +- [ ] Final legal texts, citations, configuration, and operational processes reviewed by qualified counsel **Technical controls** - [ ] HTTPS enabled (TLS 1.2+ at reverse proxy) - [ ] `APP_DEBUG=false` and `APP_ENV=production` in `.env` - [ ] Disk encryption at the OS level for the data volume - [ ] GDPR enabled: `gdpr_enabled=true` in admin settings -- [ ] Data retention policy for audit logs implemented +- [ ] Retention settings configured for audit logs, bookings, payments, backups, sessions, and uploaded files - [ ] Backup encryption configured - [ ] Access logging at reverse proxy level +- [ ] Admin roles, 2FA, API tokens, and module enablement reviewed before launch +- [ ] Security-sensitive or legally sensitive modules enabled only after operator review, audit-log coverage, privacy-text updates, and rollback planning **Testing** - [ ] Export endpoint tested: `GET /api/v1/user/export` → verify JSON completeness @@ -567,7 +576,7 @@ When a user submits a DSAR: A DPIA (Art. 35 DSGVO) is required when data processing is "likely to result in a high risk to the rights and freedoms of natural persons." -**For most ParkHub deployments, a DPIA is NOT required** because: +**Many routine ParkHub deployments may not require a DPIA**, but the operator must assess this for the concrete deployment because: - No systematic monitoring of publicly accessible areas (unless combined with CCTV) - No large-scale processing of special category data (Art. 9) diff --git a/docs/deployment-readiness-record.md b/docs/deployment-readiness-record.md new file mode 100644 index 00000000..845075f5 --- /dev/null +++ b/docs/deployment-readiness-record.md @@ -0,0 +1,109 @@ +# Deployment Readiness Record + +Use this record before a ParkHub PHP deployment is opened for production, +business use, personal-data processing, or customer-facing evaluation. Keep one +completed copy per deployment or material configuration change. Do not store +secrets, access tokens, private keys, or raw personal data in this record. + +This record is an engineering and operator evidence artifact. It is not legal +advice, does not verify citations, and does not replace attorney review, +citation verification, deployment-specific configuration review, human signoff, +or final legal judgment for a specific operator. + +## Deployment Header + +| Field | Operator value | +| --- | --- | +| Deployment name and environment | | +| Deployment purpose | | +| Personal, business, or mixed use | | +| Public, internal, or private exposure | | +| Controller / operator entity | | +| Deployment owner | | +| Launch approver | | +| Target launch date | | +| ParkHub PHP commit / tag | | +| CI run / local fop attestation | | +| `fop legal catalog` generated_at / source_revision | | +| Review record owner | | + +## Jurisdiction And Business Context + +- [ ] Countries, states, and regions where the service is offered are listed. +- [ ] Germany-specific obligations are reviewed when the operator, customers, or + users are in Germany. +- [ ] EU/EEA GDPR obligations are reviewed when EU/EEA users or operators are in + scope. +- [ ] International overlays such as UK GDPR, Swiss nDSG, CCPA/CPRA, and LGPD are + reviewed where applicable. +- [ ] Consumer-facing, employee-facing, B2B, public-sector, and sector-specific + obligations are explicitly marked in or out of scope. +- [ ] Accessibility scope is reviewed for BFSG / EU Accessibility Act relevance. +- [ ] NIS2-style cybersecurity scope is assessed for the operator category. + +## Data And Processor Evidence + +- [ ] Actual personal-data categories are listed. +- [ ] Purposes and legal bases are mapped to the privacy notice and VVT. +- [ ] Retention periods are set for bookings, payments, audit logs, sessions, + uploads, backups, and exports. +- [ ] Export, deletion, anonymization, and data-subject request paths are tested + or explicitly deferred with owner and date. +- [ ] Hosting regions, backup regions, email providers, payment providers, + analytics providers, AI providers, monitoring providers, and support tools + are listed. +- [ ] AVV/DPA/sub-processor evidence is attached for every external processor. +- [ ] Cross-border transfer basis and sub-processor evidence are recorded where + data leaves the operator's primary jurisdiction. + +## Module And Plugin Review + +Security-sensitive or legally sensitive modules remain disabled until this table +has an owner, review state, rollback path, and launch decision. + +| Module / plugin | Purpose | Data categories | External recipients | Audit coverage | Rollback path | Review state | Launch decision | +| --- | --- | --- | --- | --- | --- | --- | --- | +| Auth / MFA / SSO | | | | | | | | +| RBAC / multi-tenant boundaries | | | | | | | | +| Payments / invoices / tax records | | | | | | | | +| Notifications / messaging | | | | | | | | +| Webhooks / third-party integrations | | | | | | | | +| Analytics / reporting | | | | | | | | +| AI/ML / recommendations | | | | | | | | +| Custom plugins | | | | | | | | + +## Security And CI/CD Evidence + +- [ ] Required GitHub checks are green for the release or PR. +- [ ] Local fop attestation is captured when required by the release process. +- [ ] `scripts/tests/test-legal-readiness-wording.sh` passes. +- [ ] `scripts/tests/test-legal-openapi-contract.sh` passes after legal, privacy, + module, plugin, export, erasure, or OpenAPI changes. +- [ ] Vulnerability scan, dependency review, secret scan, and workflow/static + analysis results are attached or linked. +- [ ] SBOM, provenance, image scan, and signature evidence are attached when a + container or downloadable artifact is released. +- [ ] Backup, restore, incident response, vulnerability disclosure, and audit-log + export paths are assigned to an operator owner. + +## Required Signoff + +| Review | Owner | Date | Decision | Notes | +| --- | --- | --- | --- | --- | +| Engineering readiness | | | | | +| Security review | | | | | +| Privacy / data-protection review | | | | | +| Attorney / qualified counsel review | | | | | +| Accessibility review | | | | | +| Business owner approval | | | | | +| Final human go-live signoff | | | | | + +## Go / No-Go Decision + +- [ ] All required review rows above are complete. +- [ ] No unresolved high-risk security, legal, privacy, accessibility, or data + transfer issue remains without a named owner and accepted risk decision. +- [ ] Release notes describe legal-readiness changes as deployment-dependent + support and operator obligations, not as final legal compliance. +- [ ] The launch owner has confirmed the exact configuration, modules, processors, + regions, and legal texts deployed. diff --git a/docs/legal-readiness-parity.md b/docs/legal-readiness-parity.md new file mode 100644 index 00000000..d53ea380 --- /dev/null +++ b/docs/legal-readiness-parity.md @@ -0,0 +1,55 @@ +# Legal Readiness Parity + +This report compares the Rust and PHP legal-readiness surfaces that operators +use before personal, business, German, EU, or international deployments. It is a +repo-local review aid, not legal advice and not a certification of any live +deployment. + +## Parity Baseline + +| Area | Rust surface | PHP surface | Required parity outcome | +| --- | --- | --- | --- | +| Operator hub | `docs/legal-readiness.md` | `docs/legal-readiness.md` | Both repos expose one audit entry point with German, EU, international, attorney-review, citation-verification, human-signoff, and deployment-specific configuration boundaries. | +| Deployment record | `docs/deployment-readiness-record.md` | `docs/deployment-readiness-record.md` | Both repos require one per-deployment record for jurisdiction, business context, modules/plugins, processors, CI/CD evidence, and final human go-live signoff. | +| Compliance matrix | `docs/COMPLIANCE.md` | `docs/COMPLIANCE.md` | Both repos keep operator obligations separate from shipped templates/features. | +| Data-protection guide | `docs/GDPR.md` | `docs/GDPR.md` | Both repos map data inventory, retention, data-subject rights, export, deletion, and processor evidence. | +| Legal templates | `legal/` and `docs/*-TEMPLATE.md` | `legal/` and `docs/*-TEMPLATE.md` | Templates remain operator-customizable starting points, not final legal texts. | +| Module/plugin review | `docs/COMPLIANCE.md`, `docs/legal-readiness.md`, deployment record | `docs/COMPLIANCE.md`, `docs/legal-readiness.md`, deployment record | Security-sensitive and legally sensitive modules/plugins require documented purpose, data categories, recipients, audit coverage, rollback path, review state, and launch decision. | +| AI/ML transparency | `legal/ai-act-transparency-template.md`, deployment record | `legal/ai-act-transparency-template.md`, deployment record | AI/ML, profiling, recommendation, and automated-support features require transparency and human-review evidence when enabled. | +| Release gate | `docs/release-checklist.md` | `docs/release-checklist.md` | Release checklists require legal wording and legal/module OpenAPI guards before tagging or deploying material legal/privacy changes. | +| Static wording guard | `scripts/tests/test-legal-readiness-wording.sh` | `scripts/tests/test-legal-readiness-wording.sh` | Absolute legal-status wording stays blocked; deployment-dependent review language remains required. | +| Legal/module OpenAPI guard | `scripts/tests/test-legal-openapi-contract.sh` | `scripts/tests/test-legal-openapi-contract.sh` | Legal, module, plugin, export, erasure, and privacy API surfaces remain explicitly reviewed. | +| Source of truth | GitHub `nash87/parkhub-rust` | GitHub `nash87/parkhub-php` | Review and release evidence comes from GitHub PRs/checks, not stale mirrors. | + +## Cross-Repo Review Rules + +- When one runtime changes legal, privacy, compliance, module, plugin, export, + erasure, or deployment-readiness wording, review whether the sibling runtime + needs the same operator-facing change. +- Keep runtime-specific implementation details separate, but keep operator + obligations, human signoff boundaries, and release-review language equivalent. +- Use deployment-dependent language. Do not describe either runtime or a live + deployment as having a final legal status. +- Treat `fop legal catalog` as reference-only. Attorney review, citation + verification, deployment-specific configuration review, human signoff, and + final legal judgment remain required. +- Record accepted parity gaps in the release notes or a follow-up issue before + tagging a release. + +## Current T-6382 Status + +- Rust and PHP both have a legal-readiness hub. +- Rust and PHP both have a deployment-readiness record. +- Rust and PHP both wire the legal-readiness wording guard into local PR CI. +- Rust and PHP both wire the legal/module OpenAPI guard into local PR CI. +- PHP PR evidence is published in GitHub PR #515. +- Rust branch evidence is local until the fop capacity guard allows the normal + pre-push path to run. + +## Operator Boundary + +This parity report compares engineering controls and review artifacts. It does +not decide whether any operator is in scope for GDPR, DSGVO, TTDSG, DDG, BDSG, +GoBD, BFSG/EAA, NIS2, EU AI Act, UK GDPR, Swiss nDSG, CCPA/CPRA, LGPD, or any +sector-specific rule. The operator and qualified counsel must make that decision +for the actual deployment. diff --git a/docs/legal-readiness.md b/docs/legal-readiness.md new file mode 100644 index 00000000..22198355 --- /dev/null +++ b/docs/legal-readiness.md @@ -0,0 +1,116 @@ +# Operator Legal Readiness Hub + +ParkHub PHP ships technical controls, templates, API surfaces, and release checks +that can support German, EU, and international legal-readiness work. This hub +organizes the evidence an operator should review before launch. It is not legal +advice and is not a legal conclusion for any specific deployment. + +Use this page as the audit index. The operator remains responsible for the live +service, enabled modules, processors, regions, legal texts, citations, retention +settings, launch approvals, and final human signoff. + +## Required External Review + +Before production use, the operator should have qualified counsel review: + +- final legal texts and citations; +- deployment-specific configuration, hosting regions, and processor contracts; +- enabled modules, third-party integrations, and AI/ML features; +- retention, deletion, export, audit-log, and backup settings; +- accessibility, consumer, and sector-specific obligations for the actual + business model and jurisdiction. + +`fop legal catalog` can be used as a reference-only catalog of obligations and +internal evidence pointers. It is not legal advice, does not verify citations, +and does not replace attorney review, citation verification, human signoff, +deployment-specific configuration review, or final legal judgment. + +## Evidence Map + +| Operator question | Primary evidence | +| --- | --- | +| What personal-data flows and legal bases are documented? | [GDPR guide](GDPR.md), [Compliance Matrix](COMPLIANCE.md), [VVT template](../legal/vvt-template.md) | +| What public legal texts are available as starting points? | [Privacy template](PRIVACY-TEMPLATE.md), [Impressum template](IMPRESSUM-TEMPLATE.md), [legal templates](../legal/) | +| What admin compliance APIs can be audited? | [API docs](API.md), `GET /v1/admin/compliance/report`, `GET /v1/admin/compliance/data-map`, `GET /v1/admin/compliance/audit-export` | +| What release checks protect the legal posture? | [Release checklist](release-checklist.md), `scripts/tests/test-legal-readiness-wording.sh`, `scripts/tests/test-legal-openapi-contract.sh` | +| What security controls should be reviewed with privacy obligations? | [Security model](SECURITY.md), audit log export, module review, processor list | +| What per-deployment record captures launch signoff? | [Deployment readiness record](deployment-readiness-record.md) for jurisdiction, business context, enabled modules, processors, CI/CD evidence, legal review, and final human go-live decision | +| How do Rust and PHP stay aligned? | [Legal readiness parity](legal-readiness-parity.md) compares hubs, release gates, module/plugin review policy, and operator boundaries across both runtimes | + +## German Readiness Review + +- **Provider identification:** adapt and publish the Impressum; verify the + public route and API route after deployment. +- **Privacy notice:** adapt the Datenschutz/privacy template to the actual + controller, processing purposes, recipients, retention periods, transfers, and + data-subject contact paths. +- **Processor agreements:** review AVV/DPA status for hosting, SMTP, payment, + backups, support, analytics, AI, and any integration with system or data + access. +- **Records of processing:** maintain the VVT/Record of Processing Activities + for the actual deployment. +- **TTDSG/local storage:** re-check cookie and localStorage analysis whenever + optional modules introduce non-essential storage or tracking. +- **Retention:** align booking, payment, audit-log, backup, session, and upload + retention with the operator's obligations and documented policy. +- **BDSG/DSB:** evaluate DSB appointment duties for the operator's staff count, + monitoring profile, and business context. +- **BFSG/EAA:** review accessibility scope for consumer-facing deployments and + keep the accessibility statement current. + +## EU And International Review + +- **GDPR / UK GDPR / nDSG / LGPD:** confirm data-subject rights, export, + deletion/anonymization, breach response, international transfers, and + controller contact details for the actual deployment. +- **CCPA / CPRA:** adapt the privacy notice for California-specific + disclosures where the operator is in scope. +- **NIS2:** complete a scope assessment for operators in essential or important + entity categories. +- **EU AI Act:** add transparency notices and human-review procedures if AI/ML + features, profiling, or third-party AI processors are enabled. +- **Cross-border processors:** document transfer mechanisms, regions, and + sub-processor evidence for every configured external provider. + +## Module And Plugin Review + +Security-sensitive or legally sensitive modules should remain disabled until an +operator records: + +- purpose and legal basis for the module; +- personal-data categories, recipients, retention, and transfer impact; +- AVV/DPA and sub-processor status; +- privacy notice and template updates; +- audit-log coverage and export path; +- rollback plan and launch owner; +- counsel review status; +- final human signoff status. + +This applies especially to authentication, payments, RBAC, webhooks, +audit-export, multi-tenant mode, notifications, AI/ML features, analytics, +third-party integrations, and any plugin that changes data recipients, +retention, public exposure, billing, or automated decisions. + +## Release Review Flow + +Before tagging or deploying a release that touches legal, privacy, module, +plugin, export, erasure, or audit surfaces: + +1. Update the affected legal templates, GDPR guide, Compliance Matrix, and API + docs. +2. Run `scripts/tests/test-legal-readiness-wording.sh`. +3. Run `scripts/tests/test-legal-openapi-contract.sh`. +4. Complete or update [deployment-readiness-record.md](deployment-readiness-record.md) + before production use, business use, or customer-facing evaluation. +5. Review [legal-readiness-parity.md](legal-readiness-parity.md) when a change + should stay aligned across Rust and PHP. +6. Review the legal-readiness section in [release-checklist.md](release-checklist.md). +7. Record unresolved deployment decisions in the release notes or operator + handoff. + +## Wording Guardrails + +Use readiness, support, obligation, and review language. Do not present ParkHub +or a live deployment as having a final legal status. Operator-facing copy should +state that legal texts, citations, configuration, providers, and launch process +still require qualified review and human signoff for the specific deployment. diff --git a/docs/release-checklist.md b/docs/release-checklist.md index 8b0026da..eb263511 100644 --- a/docs/release-checklist.md +++ b/docs/release-checklist.md @@ -13,9 +13,34 @@ Use this before tagging a ParkHub release from this repo. ## Contract and parity - Regenerate and commit the local OpenAPI snapshot when the contract changed. +- Run `scripts/tests/test-legal-openapi-contract.sh` after changes to legal, + compliance, module, plugin, export, erasure, or privacy surfaces. - Review any remaining runtime-sensitive gaps and make sure they are documented. - Do not silently introduce new shared-frontend branching requirements. +## Legal readiness + +- Start from `docs/legal-readiness.md`; it is the operator-facing hub for + legal-readiness evidence, review boundaries, and release checks. +- Complete or update `docs/deployment-readiness-record.md` for the target + deployment before production use, business use, or customer-facing evaluation. +- Review `docs/legal-readiness-parity.md` for Rust/PHP legal-readiness parity + when a change affects shared legal, privacy, module, plugin, or release policy. +- Run `scripts/tests/test-legal-readiness-wording.sh`; public docs must describe + deployment-dependent readiness and obligations, not absolute legal compliance. +- Confirm the operator checklist in `docs/GDPR.md` and `docs/COMPLIANCE.md` + reflects the enabled modules, integrations, processors, retention settings, + and jurisdictions. +- Confirm the evidence map in `docs/legal-readiness.md` still points to the + current templates, API surfaces, and release checks. +- Confirm privacy notice, Impressum, AVV/DPA, VVT, cookie/TTDSG, BFSG/EAA, and + AI Act transparency templates are still starting points, not legal advice. +- Confirm any security-sensitive or legally sensitive module/plugin change is + audit-logged and documented with a rollback path before release. +- Treat `fop legal catalog` as reference-only: attorney review, citation + verification, human signoff, deployment-specific configuration review, and + final legal judgment remain required. + ## Quality bar - Required CI is green. @@ -31,4 +56,5 @@ Use this before tagging a ParkHub release from this repo. - If this release changes a shared customer-visible feature, verify whether `parkhub-rust` needs a matching change. - If parity is not yet closed, record the gap explicitly in release notes. -- Push order remains `origin` first, then `github`. +- GitHub `nash87/parkhub-php` remains the CI/review source of truth. Do not + base releases on a stale Gitea mirror. diff --git a/scripts/tests/test-legal-openapi-contract.sh b/scripts/tests/test-legal-openapi-contract.sh new file mode 100755 index 00000000..0694a294 --- /dev/null +++ b/scripts/tests/test-legal-openapi-contract.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +# +# Static OpenAPI guard for legal-readiness and module/plugin surfaces. +# +# This checks the generated OpenAPI snapshot only; it does not start Laravel. +# Keep this guard cheap so docs/legal policy work can run it under pressure. +# +# Run: bash scripts/tests/test-legal-openapi-contract.sh + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +cd "$REPO_ROOT" + +node <<'NODE' +const fs = require('fs'); + +const specPath = 'docs/openapi/php.json'; +if (!fs.existsSync(specPath)) { + console.error(`ERROR: required OpenAPI snapshot not found: ${specPath}`); + console.error('Regenerate and commit the PHP OpenAPI snapshot before running this guard.'); + process.exit(1); +} + +let spec; +try { + spec = JSON.parse(fs.readFileSync(specPath, 'utf8')); +} catch (error) { + console.error(`ERROR: failed to read or parse ${specPath}: ${error.message}`); + console.error('Regenerate and commit a valid PHP OpenAPI snapshot before running this guard.'); + process.exit(1); +} + +const paths = spec.paths || {}; + +const required = [ + ['GET', '/api/v1/legal/impressum'], + ['GET', '/legal/privacy'], + ['GET', '/api/v1/admin/privacy'], + ['PUT', '/api/v1/admin/privacy'], + ['GET', '/api/v1/admin/impressum'], + ['PUT', '/api/v1/admin/impressum'], + ['GET', '/api/v1/users/me/export'], + ['POST', '/api/v1/users/me/anonymize'], + ['DELETE', '/api/v1/users/me/delete'], + ['GET', '/api/v1/admin/compliance/report'], + ['GET', '/api/v1/admin/compliance/data-map'], + ['GET', '/api/v1/admin/compliance/audit-export'], + ['GET', '/api/v1/modules'], + ['GET', '/api/v1/modules/{name}'], + ['PATCH', '/api/v1/admin/modules/{name}'], + ['GET', '/api/v1/admin/plugins'], + ['GET', '/api/v1/admin/plugins/{id}/config'], + ['PUT', '/api/v1/admin/plugins/{id}/config'], + ['PUT', '/api/v1/admin/plugins/{id}/toggle'], +]; + +function candidatePaths(path) { + if (path.startsWith('/api/v1/')) { + return [path, path.replace(/^\/api\/v1/, '/v1')]; + } + return [path]; +} + +let failed = false; + +for (const [method, path] of required) { + const entry = candidatePaths(path) + .map((candidate) => paths[candidate]) + .find((candidate) => candidate && candidate[method.toLowerCase()]); + if (!entry || !entry[method.toLowerCase()]) { + console.error(`ERROR: OpenAPI snapshot missing ${method} ${path}`); + failed = true; + } +} + +if (failed) { + process.exit(1); +} + +console.log('ParkHub PHP legal/module OpenAPI contract OK.'); +NODE diff --git a/scripts/tests/test-legal-readiness-wording.sh b/scripts/tests/test-legal-readiness-wording.sh new file mode 100755 index 00000000..c7b6ffa9 --- /dev/null +++ b/scripts/tests/test-legal-readiness-wording.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# +# Static guard for legal-readiness wording. +# +# ParkHub ships controls and templates that support legal-readiness work, but +# live legal posture depends on operator configuration, contracts, jurisdiction, +# and attorney review. Keep public docs from drifting back to absolute legal +# conclusions. +# +# Run: bash scripts/tests/test-legal-readiness-wording.sh + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +cd "$REPO_ROOT" + +scan_paths=( + README.md + docs + legal +) + +if ! command -v rg >/dev/null 2>&1; then + echo "ERROR: ripgrep (rg) is required for the legal-readiness wording guard." >&2 + echo "Install ripgrep or run this check in the project CI image." >&2 + exit 1 +fi + +pattern="100%[[:space:]-]+GDPR|GDPR[[:space:]-]+compliant|DSGVO[[:space:]-]+konform|Compliance[[:space:]-]+Audited|complies with all GDPR|No DPA needed|no GDPR processor agreement needed|no mandatory data processor agreements|DPIA is NOT required|not required for typical deployments|legally compliant|guarantees compliance|legal compliance is guaranteed|certifies compliance|(GDPR|DSGVO|compliance|legal)[^.\n]{0,40}(certified|guaranteed)|(certified|guaranteed)[^.\n]{0,40}(GDPR|DSGVO|compliance|legal)" + +if rg --pcre2 --ignore-case -n "$pattern" "${scan_paths[@]}"; then + echo "ERROR: legal-readiness docs contain absolute compliance wording." >&2 + echo "Use deployment-dependent wording and require operator/legal review." >&2 + exit 1 +fi + +require_text() { + local file="$1" + local text="$2" + + if [ ! -r "$file" ]; then + echo "ERROR: required file not found or unreadable: $file" >&2 + exit 1 + fi + + if ! grep -Fq "$text" "$file"; then + echo "ERROR: $file is missing required legal-readiness text: $text" >&2 + exit 1 + fi +} + +require_text docs/release-checklist.md "scripts/tests/test-legal-readiness-wording.sh" +require_text docs/release-checklist.md "scripts/tests/test-legal-openapi-contract.sh" +require_text docs/release-checklist.md "docs/legal-readiness.md" +require_text docs/release-checklist.md "docs/deployment-readiness-record.md" +require_text docs/release-checklist.md "docs/legal-readiness-parity.md" +require_text docs/release-checklist.md "legal-readiness evidence" +require_text docs/release-checklist.md "fop legal catalog" +require_text docs/release-checklist.md "reference-only" +require_text docs/release-checklist.md "attorney review" +require_text docs/release-checklist.md "citation" +require_text docs/release-checklist.md "human signoff" +require_text docs/release-checklist.md "deployment-specific configuration review" +require_text docs/release-checklist.md 'GitHub `nash87/parkhub-php` remains the CI/review source of truth' +require_text README.md "docs/legal-readiness.md" +require_text README.md "docs/deployment-readiness-record.md" +require_text README.md "docs/legal-readiness-parity.md" +require_text docs/legal-readiness.md "Operator Legal Readiness Hub" +require_text docs/legal-readiness.md "It is not legal advice" +require_text docs/legal-readiness.md "not a legal conclusion" +require_text docs/legal-readiness.md "qualified counsel" +require_text docs/legal-readiness.md "attorney review" +require_text docs/legal-readiness.md "citation verification" +require_text docs/legal-readiness.md "human signoff" +require_text docs/legal-readiness.md "deployment-specific configuration review" +require_text docs/legal-readiness.md "fop legal catalog" +require_text docs/legal-readiness.md "reference-only" +require_text docs/legal-readiness.md "scripts/tests/test-legal-openapi-contract.sh" +require_text docs/legal-readiness.md "deployment-readiness-record.md" +require_text docs/legal-readiness.md "legal-readiness-parity.md" +require_text docs/deployment-readiness-record.md "# Deployment Readiness Record" +require_text docs/deployment-readiness-record.md "Personal, business, or mixed use" +require_text docs/deployment-readiness-record.md "Germany-specific obligations" +require_text docs/deployment-readiness-record.md "Module And Plugin Review" +require_text docs/deployment-readiness-record.md "AI/ML / recommendations" +require_text docs/deployment-readiness-record.md "Required Signoff" +require_text docs/deployment-readiness-record.md "Final human go-live signoff" +require_text docs/legal-readiness-parity.md "# Legal Readiness Parity" +require_text docs/legal-readiness-parity.md "Rust and PHP" +require_text docs/legal-readiness-parity.md "Module/plugin review" +require_text docs/legal-readiness-parity.md "fop legal catalog" +require_text docs/legal-readiness-parity.md "qualified counsel" +require_text docs/GDPR.md "Legal Readiness Checklist" +require_text docs/COMPLIANCE.md "Legal Readiness Checklist" + +echo "ParkHub legal-readiness wording contract OK."