feat(privacy): implement GDPR and global privacy compliance

- Add dismissable cookie notice banner to base template (essential
  cookies only, ePrivacy Directive compliant, localStorage persistence)
- Expand Privacy Notice to cover all target markets: EU/GDPR,
  UK GDPR, Switzerland nFADP, Ukraine, US CCPA/CPRA, Canada PIPEDA/
  Law 25, Brazil LGPD/Latin America, and Asia-Pacific & Japan (APPI,
  Australia Privacy Act, South Korea PIPA, Singapore PDPA, India DPDP)
- Add International Data Transfers section (SCCs, IDTAs, adequacy
  decisions) and Data Minimization & Purpose Limitation section
- Update Cookie Policy with precise cookie table, ePrivacy exemption
  rationale, and localStorage notice dismissal documentation
- Create docs/PrivacyCompliance.md: full multi-market compliance guide
  covering cookie strategy, data transfer mechanisms, data subject
  rights handling matrix with response timelines, and market-specific
  notes for all supported regions
- Add docs/PrivacyCompliance.md to mkdocs.yml Compliance nav section
- Add 10 new targeted tests to test_views_general.py validating all
  key compliance content areas

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-02-25 15:15:24 +00:00
parent 5eb6b794c4
commit 0821e2f989
6 changed files with 674 additions and 75 deletions
+41
View File
@@ -217,6 +217,47 @@
</div>
</footer>
<!-- Cookie Notice Banner -->
<!-- DocuElevate uses only strictly necessary session cookies (no tracking/analytics).
Under GDPR Art. 5(3) ePrivacy Directive, strictly necessary cookies do not require
prior consent, but transparency is required. This banner provides that notice. -->
<div id="cookieNotice"
class="fixed bottom-0 inset-x-0 z-50 bg-gray-800 text-white text-sm px-4 py-3 flex flex-col sm:flex-row items-center justify-between gap-2"
style="display:none!important"
aria-live="polite"
role="region"
aria-label="Cookie notice">
<p class="text-center sm:text-left">
DocuElevate uses only essential session cookies required for authentication and service operation.
No tracking or analytics cookies are used.
<a href="/cookies" class="underline hover:text-blue-300 ml-1">Cookie Policy</a> &middot;
<a href="/privacy" class="underline hover:text-blue-300 ml-1">Privacy Notice</a>
</p>
<button
id="cookieNoticeAccept"
type="button"
class="flex-shrink-0 bg-blue-600 hover:bg-blue-700 text-white font-semibold px-4 py-1.5 rounded focus:outline-none focus:ring-2 focus:ring-blue-400"
aria-label="Acknowledge cookie notice">
Got it
</button>
</div>
<script>
(function () {
var NOTICE_KEY = 'cookieNoticeDismissed';
var notice = document.getElementById('cookieNotice');
var btn = document.getElementById('cookieNoticeAccept');
if (!localStorage.getItem(NOTICE_KEY)) {
notice.style.removeProperty('display');
}
if (btn) {
btn.addEventListener('click', function () {
localStorage.setItem(NOTICE_KEY, '1');
notice.style.display = 'none';
});
}
})();
</script>
<!-- Common JS (shared) -->
<script src="/static/js/common.js"></script>