Files
opencode-mobile/website/app/privacy/page.tsx
Den 63f3ec3c7e docs+consent: disclose activation analytics honestly across consent modal, privacy policy, and store docs (#81)
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>
2026-07-17 03:28:00 -07:00

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>
)
}