legal: add imprint page, upgrade privacy policy to GDPR-proper

- Add /imprint route and template (§5 DDG compliant, Hendrik's details)
- Rewrite privacy.html: data controller, legal basis per GDPR Art. 6,
  sub-processors (Paddle/Resend/Umami/Hetzner), retention periods,
  GDPR rights with article references, BfDI supervisory authority link
- Add /imprint to sitemap.xml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Deeman
2026-02-22 15:54:26 +01:00
parent 9a67617f6a
commit 1814a76e74
3 changed files with 134 additions and 54 deletions

View File

@@ -46,6 +46,12 @@ async def about():
return await render_template("about.html")
@bp.route("/imprint")
async def imprint():
"""Legal imprint (Impressum) — required by §5 DDG."""
return await render_template("imprint.html")
@bp.route("/methodology")
async def methodology():
"""Data methodology page — explains all data sources."""
@@ -119,6 +125,7 @@ async def sitemap_xml():
xml += url_entry(f"{base}/pricing", priority="0.8")
xml += url_entry(f"{base}/terms", priority="0.3", changefreq="yearly")
xml += url_entry(f"{base}/privacy", priority="0.3", changefreq="yearly")
xml += url_entry(f"{base}/imprint", priority="0.2", changefreq="yearly")
# Add dynamic BeanFlows entries here (e.g. public commodity pages)
xml += "</urlset>"

View File

@@ -0,0 +1,56 @@
{% extends "base.html" %}
{% block title %}Imprint — {{ config.APP_NAME }}{% endblock %}
{% block head %}
<meta name="description" content="Legal imprint for BeanFlows — company information and contact details as required by §5 DDG.">
<meta name="robots" content="noindex">
{% endblock %}
{% block content %}
<main class="container-page py-12">
<div class="card max-w-3xl mx-auto">
<h1 class="text-2xl mb-1">Imprint</h1>
<p class="text-sm text-stone mb-8">Legal disclosure pursuant to §5 DDG (Digitale-Dienste-Gesetz)</p>
<div class="space-y-6 text-stone leading-relaxed">
<section>
<h2 class="text-lg mb-2">Service Provider</h2>
<p>
Hendrik Dreesmann<br>
c/o COCENTER<br>
Koppoldstr. 1<br>
86551 Aichach<br>
Germany
</p>
</section>
<section>
<h2 class="text-lg mb-2">Contact</h2>
<p>Email: <a href="mailto:{{ config.EMAIL_FROM }}" class="underline">{{ config.EMAIL_FROM }}</a></p>
</section>
<section>
<h2 class="text-lg mb-2">VAT</h2>
<p>Small business owner pursuant to §19 UStG (Umsatzsteuergesetz). VAT is not charged and no VAT identification number is issued.</p>
</section>
<section>
<h2 class="text-lg mb-2">Responsible for Content</h2>
<p>
Hendrik Dreesmann<br>
c/o COCENTER, Koppoldstr. 1, 86551 Aichach
</p>
<p class="mt-1 text-sm text-stone">(pursuant to §18 Abs. 2 MStV)</p>
</section>
<section>
<h2 class="text-lg mb-2">Disclaimer</h2>
<p>Despite careful content control we assume no liability for the content of external links. The operators of linked pages are solely responsible for their content.</p>
</section>
</div>
</div>
</main>
{% endblock %}

View File

@@ -7,87 +7,104 @@
<div class="max-w-3xl mx-auto">
<div class="page-header">
<h1>Privacy Policy</h1>
<p class="text-sm text-stone">Last updated: January 2024</p>
<p class="text-sm text-stone">Last updated: February 2025</p>
</div>
<div class="card">
<section class="mb-8">
<h2 class="text-xl mb-3">1. Information We Collect</h2>
<p class="text-stone mb-2">We collect information you provide directly:</p>
<ul class="list-disc pl-5 space-y-1 text-sm text-stone mb-3">
<li>Email address (required for account creation)</li>
<li>Name (optional)</li>
<li>Payment information (processed by Paddle)</li>
<div class="card space-y-8">
<section>
<h2 class="text-xl mb-3">1. Data Controller</h2>
<p class="text-stone">
Hendrik Dreesmann<br>
c/o COCENTER, Koppoldstr. 1, 86551 Aichach, Germany<br>
Email: <a href="mailto:{{ config.EMAIL_FROM }}" class="underline">{{ config.EMAIL_FROM }}</a>
</p>
</section>
<section>
<h2 class="text-xl mb-3">2. Data We Collect</h2>
<p class="text-stone mb-2"><strong>Data you provide directly:</strong></p>
<ul class="list-disc pl-5 space-y-1 text-sm text-stone mb-4">
<li>Email address — required to create an account and deliver the service</li>
<li>Payment information — collected and processed by Paddle (we never see your card details)</li>
</ul>
<p class="text-stone mb-2">We automatically collect:</p>
<p class="text-stone mb-2"><strong>Data collected automatically:</strong></p>
<ul class="list-disc pl-5 space-y-1 text-sm text-stone">
<li>IP address</li>
<li>Browser type</li>
<li>Usage data</li>
<li>IP address and browser type — used for security and abuse prevention</li>
<li>Session data — stored in a server-side cookie to keep you logged in</li>
<li>Usage data — anonymised page views collected by Umami Analytics (no cookies, no cross-site tracking)</li>
</ul>
</section>
<section class="mb-8">
<h2 class="text-xl mb-3">2. How We Use Information</h2>
<p class="text-stone mb-2">We use your information to:</p>
<section>
<h2 class="text-xl mb-3">3. Legal Basis (GDPR Art. 6)</h2>
<ul class="list-disc pl-5 space-y-1 text-sm text-stone">
<li>Provide and maintain the service</li>
<li>Process payments</li>
<li>Send transactional emails</li>
<li>Improve the service</li>
<li>Respond to support requests</li>
<li><strong>Art. 6(1)(b) — Contract:</strong> email address and payment data, to provide and bill the service</li>
<li><strong>Art. 6(1)(f) — Legitimate interest:</strong> security logs, anonymised analytics, fraud prevention</li>
<li><strong>Art. 6(1)(c) — Legal obligation:</strong> invoicing records retained for 10 years as required by German tax law</li>
</ul>
</section>
<section class="mb-8">
<h2 class="text-xl mb-3">3. Information Sharing</h2>
<p class="text-stone mb-2">We do not sell your personal information. We may share information with:</p>
<section>
<h2 class="text-xl mb-3">4. Sub-processors</h2>
<div class="text-sm text-stone space-y-2">
<p><strong>Paddle</strong> (payments) — processes payment data on our behalf. <a href="https://www.paddle.com/legal/privacy" class="underline" target="_blank" rel="noopener">Paddle Privacy Policy</a></p>
<p><strong>Resend</strong> (transactional email) — sends magic-link and notification emails. <a href="https://resend.com/privacy" class="underline" target="_blank" rel="noopener">Resend Privacy Policy</a></p>
<p><strong>Umami</strong> (analytics) — self-hosted, anonymised page-view analytics. No cookies, no cross-site tracking, no personal data transferred to third parties.</p>
<p><strong>Hetzner</strong> (hosting) — servers located in Germany (EU). <a href="https://www.hetzner.com/legal/privacy-policy" class="underline" target="_blank" rel="noopener">Hetzner Privacy Policy</a></p>
</div>
</section>
<section>
<h2 class="text-xl mb-3">5. Cookies</h2>
<p class="text-stone mb-2">We use only essential cookies:</p>
<ul class="list-disc pl-5 space-y-1 text-sm text-stone">
<li>Service providers (Paddle for payments, Resend for email)</li>
<li>Law enforcement when required by law</li>
<li><strong>Session cookie</strong> — keeps you logged in; expires when your session ends or after 30 days</li>
<li><strong>CSRF token</strong> — protects form submissions; session-scoped</li>
</ul>
<p class="text-stone mt-2">We do not use advertising, tracking, or third-party cookies. Umami Analytics is cookieless.</p>
</section>
<section class="mb-8">
<h2 class="text-xl mb-3">4. Data Retention</h2>
<p class="text-stone">We retain your data as long as your account is active. Upon deletion, we remove your data within 30 days.</p>
</section>
<section class="mb-8">
<h2 class="text-xl mb-3">5. Security</h2>
<p class="text-stone">We implement industry-standard security measures including encryption, secure sessions, and regular backups.</p>
</section>
<section class="mb-8">
<h2 class="text-xl mb-3">6. Cookies</h2>
<p class="text-stone">We use essential cookies for session management. We do not use tracking or advertising cookies.</p>
</section>
<section class="mb-8">
<h2 class="text-xl mb-3">7. Your Rights</h2>
<p class="text-stone mb-2">You have the right to:</p>
<section>
<h2 class="text-xl mb-3">6. Data Retention</h2>
<ul class="list-disc pl-5 space-y-1 text-sm text-stone">
<li>Access your data</li>
<li>Correct inaccurate data</li>
<li>Delete your account and data</li>
<li>Export your data</li>
<li>Account data — retained while your account is active; deleted within 30 days of account deletion</li>
<li>Invoicing records — retained for 10 years as required by German tax law (§147 AO)</li>
<li>Security logs — retained for 30 days</li>
<li>Anonymised analytics — retained indefinitely (no personal data)</li>
</ul>
</section>
<section class="mb-8">
<h2 class="text-xl mb-3">8. GDPR Compliance</h2>
<p class="text-stone">For EU users: We process data based on consent and legitimate interest. You may contact us to exercise your GDPR rights.</p>
<section>
<h2 class="text-xl mb-3">7. International Transfers</h2>
<p class="text-stone">All servers are located in Germany (EU). Paddle and Resend may process data outside the EU; both maintain EU Standard Contractual Clauses (SCCs) to ensure adequate protection.</p>
</section>
<section class="mb-8">
<section>
<h2 class="text-xl mb-3">8. Your Rights (GDPR)</h2>
<p class="text-stone mb-2">As an EU resident you have the right to:</p>
<ul class="list-disc pl-5 space-y-1 text-sm text-stone">
<li><strong>Access</strong> (Art. 15) — obtain a copy of your personal data</li>
<li><strong>Rectification</strong> (Art. 16) — correct inaccurate data</li>
<li><strong>Erasure</strong> (Art. 17) — delete your account and personal data</li>
<li><strong>Restriction</strong> (Art. 18) — restrict how we process your data</li>
<li><strong>Portability</strong> (Art. 20) — receive your data in a machine-readable format</li>
<li><strong>Object</strong> (Art. 21) — object to processing based on legitimate interest</li>
</ul>
<p class="text-stone mt-3">To exercise any of these rights, email <a href="mailto:{{ config.EMAIL_FROM }}" class="underline">{{ config.EMAIL_FROM }}</a>. We respond within 30 days.</p>
<p class="text-stone mt-2">You also have the right to lodge a complaint with your national data protection authority. In Germany: <a href="https://www.bfdi.bund.de" class="underline" target="_blank" rel="noopener">BfDI</a>.</p>
</section>
<section>
<h2 class="text-xl mb-3">9. Changes</h2>
<p class="text-stone">We may update this policy. We will notify you of significant changes via email.</p>
<p class="text-stone">We may update this policy. For significant changes we will notify you by email at least 14 days in advance.</p>
</section>
<section>
<h2 class="text-xl mb-3">10. Contact</h2>
<p class="text-stone">For privacy inquiries: {{ config.EMAIL_FROM }}</p>
<p class="text-stone">Privacy enquiries: <a href="mailto:{{ config.EMAIL_FROM }}" class="underline">{{ config.EMAIL_FROM }}</a></p>
</section>
</div>
</div>
</main>