The app ships PostHog activation-funnel analytics gated behind the same consent flag as Sentry, but the consent modal, Settings toggle, privacy policy, and Play Data safety draft only mentioned crash reporting. Fix the disclosure everywhere: - TelemetryConsentModal: body + bullets + a11y labels now cover anonymous usage analytics (PostHog EU) alongside crash reports - Settings: toggle renamed 'Crash Reports & Usage Analytics', description names both Sentry and PostHog - Privacy policy (md + html + live gh-pages mirror): new section 3a with the full event/property table, PostHog EU destination, anonymous-ID statement, decline/revoke (drop-on-revoke) semantics; sections 4-7, 9 and the Apple nutrition-label addendum updated for analytics - play-listing.md: Data safety draft declares App interactions + Device or other IDs (opt-in, default OFF, shared with PostHog/Sentry) - docs/playstore.md: Data safety row flipped to re-verify with pointer to the new design record - docs/analytics.md: new design record — event schema, consent gating incl. buffered-event drop on revoke, disclosure surfaces to keep in sync, verification checklist (all TODO) - website privacy page metadata mentions analytics opt-in Closes #63 Claude-Session: https://claude.ai/code/session_01NJKAQ6HAikWGQK7PGZ5Y4E Co-authored-by: engineer <engineer@gray-knight-m1.local> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
62 lines
2.8 KiB
TypeScript
62 lines
2.8 KiB
TypeScript
import type { Metadata } from 'next'
|
|
import { readFileSync } from 'fs'
|
|
import path from 'path'
|
|
|
|
export const metadata: Metadata = {
|
|
title: 'Privacy Policy',
|
|
description:
|
|
'OpenCode Mobile privacy policy. We do not collect your code, prompts, or AI responses. Crash diagnostics (Sentry), usage analytics (PostHog), and shared support reports (Chatwoot) are opt-in only.',
|
|
alternates: { canonical: 'https://opencode.agentlabs.cc/privacy' },
|
|
openGraph: {
|
|
title: 'Privacy Policy | OpenCode Mobile',
|
|
description: 'OpenCode Mobile privacy policy — minimal data collection, opt-in crash reporting and analytics.',
|
|
url: 'https://opencode.agentlabs.cc/privacy',
|
|
},
|
|
}
|
|
|
|
export default function PrivacyPage() {
|
|
// Read the canonical privacy policy HTML generated by the Android distribution workflow.
|
|
// This ensures the policy shown on the site is always in sync with app store submissions.
|
|
const policyPath = path.join(
|
|
process.cwd(),
|
|
'../../../opencode-mobile/distribution/privacy-policy.html',
|
|
)
|
|
|
|
let policyHtml = ''
|
|
try {
|
|
const raw = readFileSync(policyPath, 'utf8')
|
|
// Extract just the <body> content so we can render it inside our layout
|
|
const bodyMatch = raw.match(/<body[^>]*>([\s\S]*?)<\/body>/i)
|
|
policyHtml = bodyMatch ? bodyMatch[1] : raw
|
|
} catch {
|
|
policyHtml = `<p style="color:#94A3B8">Privacy policy document not found. Please contact
|
|
<a href="mailto:support@agentlabs.cc" style="color:#3B82F6">support@agentlabs.cc</a>.</p>`
|
|
}
|
|
|
|
return (
|
|
<div className="max-w-3xl mx-auto px-4 sm:px-6 py-16">
|
|
{/* Override the inline HTML colors from the standalone file with dark theme */}
|
|
<style>{`
|
|
.privacy-content body { color: inherit; background: transparent; }
|
|
.privacy-content header { border-bottom-color: #3B82F6; }
|
|
.privacy-content header h1 { color: #F1F5F9; }
|
|
.privacy-content .meta { color: #94A3B8; }
|
|
.privacy-content h2 { color: #F1F5F9; border-left-color: #3B82F6; }
|
|
.privacy-content p, .privacy-content li { color: #CBD5E1; }
|
|
.privacy-content a { color: #3B82F6; }
|
|
.privacy-content .highlight-box { background: rgba(59,130,246,0.1); border-color: rgba(59,130,246,0.4); }
|
|
.privacy-content .highlight-box strong { color: #93C5FD; }
|
|
.privacy-content th { background: #1E293B; border-color: #334155; color: #F1F5F9; }
|
|
.privacy-content td { border-color: #334155; color: #CBD5E1; }
|
|
.privacy-content tr:nth-child(even) td { background: rgba(30,41,59,0.5); }
|
|
.privacy-content footer { border-top-color: #334155; color: #64748B; }
|
|
.privacy-content code { color: #94A3B8; font-size: 0.85em; }
|
|
`}</style>
|
|
<div
|
|
className="privacy-content"
|
|
dangerouslySetInnerHTML={{ __html: policyHtml }}
|
|
/>
|
|
</div>
|
|
)
|
|
}
|