Ship /terms, /privacy, and /waitlist as structure, not finished pages
SAAS_PLAN.md B5/B6, narrowed: no Stripe/pricing/tier work of any kind this pass (a mid-build correction from the business side landed while this was in progress - the commercial model, SAAS_PLAN.md section 6.1, is still undecided), so app/pricing and lib/billing.ts's PLANS are untouched here. What's left of B5/B6 without that - real legal pages and a working waitlist - still ships. app/terms/page.tsx and app/privacy/page.tsx are section scaffolding, not legal text. Every section is a TODO(legal) note describing what that section needs to cover, and the page leads with a "Draft - not yet in force" banner. This isn't caution for its own sake: DRB records, stores, and transcribes public-safety radio traffic, and recording/rebroadcast legality varies by state (SAAS_PLAN.md section 6.3) - an agent-generated draft here would be actively wrong to publish, not just unpolished. Both were pre-added to middleware.ts's PUBLIC_PATHS and ChromeSwitcher's MARKETING_PATHS two commits ago; MarketingFooter now links both. app/waitlist/page.tsx is a real, working form against the already-shipped POST /waitlist - email + optional org name/note, no plan or price mentioned anywhere on it, matching the backend route's own scope (rate limited by source IP, not coupled to any tier). Linked from MarketingFooter as "Request access," not from the pricing page - pricing CTAs stay exactly as they were. Typecheck: clean (tsc --noEmit via the WSL-native ~/drb-frontend copy). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
4842725a03
commit
1b4ed0d09c
@@ -0,0 +1,89 @@
|
||||
import Link from "next/link";
|
||||
|
||||
/**
|
||||
* SAAS_PLAN.md B5: page structure only. The agent building this is
|
||||
* explicitly instructed not to invent legal text — DRB records, stores, and
|
||||
* transcribes public-safety radio traffic, and recording/rebroadcast
|
||||
* legality varies by state (see SAAS_PLAN.md section 6.3), so this needs a
|
||||
* human, and probably a lawyer, not a generated draft. Every section below
|
||||
* is a placeholder marking what a real Terms of Service needs to cover, not
|
||||
* actual terms — see the banner and every TODO(legal) marker.
|
||||
*/
|
||||
|
||||
const SECTIONS: { heading: string; note: string }[] = [
|
||||
{
|
||||
heading: "1. Acceptance of terms",
|
||||
note: "TODO(legal): standard acceptance clause — using the service means agreeing to these terms.",
|
||||
},
|
||||
{
|
||||
heading: "2. What the service does and does not do",
|
||||
note: "TODO(legal): describe the product (SDR ingestion, transcription, AI correlation, Discord relay) and, importantly, disclaim accuracy — AI-generated transcripts and incident summaries are not guaranteed accurate and must not be relied on as the sole source for dispatch or safety decisions.",
|
||||
},
|
||||
{
|
||||
heading: "3. Radio recording and rebroadcast — the part that needs a lawyer",
|
||||
note: "TODO(legal): this is the section that actually matters. Recording, storing, and rebroadcasting monitored radio traffic (including public-safety frequencies) has different legal treatment by state and by traffic type (encrypted vs. clear, dispatch vs. tactical). Needs jurisdiction-aware legal review before this product can be sold across state lines — do not ship this page live without it.",
|
||||
},
|
||||
{
|
||||
heading: "4. Customer responsibilities and acceptable use",
|
||||
note: "TODO(legal): who owns the hardware, who's responsible for lawful operation of the field node, prohibited uses.",
|
||||
},
|
||||
{
|
||||
heading: "5. Data ownership and retention",
|
||||
note: "TODO(legal): who owns the recorded audio/transcripts/incidents, how long they're kept, what happens on cancellation or account deletion. Note: no retention enforcement exists in the product yet either (see DEFERRED.md) — this section can't promise a retention window the system doesn't yet enforce.",
|
||||
},
|
||||
{
|
||||
heading: "6. Payment, billing, and cancellation",
|
||||
note: "TODO(legal): once a billing model and pricing exist (SAAS_PLAN.md section 6, still undecided) — refunds, proration, what happens to data on non-payment.",
|
||||
},
|
||||
{
|
||||
heading: "7. Service availability and support",
|
||||
note: "TODO(legal): whether any uptime/SLA commitment is made (today: none).",
|
||||
},
|
||||
{
|
||||
heading: "8. Limitation of liability",
|
||||
note: "TODO(legal): standard limitation-of-liability language, reviewed against the fact that this product touches public-safety-adjacent data.",
|
||||
},
|
||||
{
|
||||
heading: "9. Changes to these terms",
|
||||
note: "TODO(legal): how customers are notified of material changes.",
|
||||
},
|
||||
{
|
||||
heading: "10. Governing law and contact",
|
||||
note: "TODO(legal): governing jurisdiction, and a real company legal identity and contact address (SAAS_PLAN.md section 6.6 — not yet decided).",
|
||||
},
|
||||
];
|
||||
|
||||
export default function TermsPage() {
|
||||
return (
|
||||
<div className="max-w-screen-md mx-auto px-4 md:px-6 py-16 md:py-20">
|
||||
<div className="bg-yellow-900/30 border border-yellow-700/50 rounded-lg px-4 py-3 mb-10">
|
||||
<p className="text-yellow-200 text-sm font-mono font-semibold">
|
||||
Draft — not yet in force
|
||||
</p>
|
||||
<p className="text-yellow-200/80 text-xs mt-1 leading-relaxed">
|
||||
This page is a structural placeholder, not a real Terms of Service. Every section below is a{" "}
|
||||
<code className="text-yellow-100">TODO(legal)</code> marker, not actual legal text. Nothing on this page is
|
||||
binding, and no self-serve signup should be considered subject to it until an actual attorney-reviewed
|
||||
version replaces this content.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h1 className="text-display-sm text-white">Terms of Service</h1>
|
||||
<p className="text-gray-500 text-sm mt-2 font-mono">Draft — last structured {new Date().getFullYear()}</p>
|
||||
|
||||
<div className="mt-10 space-y-8">
|
||||
{SECTIONS.map((s) => (
|
||||
<section key={s.heading}>
|
||||
<h2 className="text-white font-semibold">{s.heading}</h2>
|
||||
<p className="text-gray-500 text-sm mt-2 leading-relaxed italic">{s.note}</p>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="text-gray-600 text-xs font-mono mt-16">
|
||||
Questions in the meantime? <Link href="/faq" className="text-indigo-400 hover:text-indigo-300 transition-colors">Check the FAQ</Link> or{" "}
|
||||
<Link href="/login" className="text-indigo-400 hover:text-indigo-300 transition-colors">sign in to reach us directly</Link>.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user