page.tsx122 lines · main
| 1 | import { DocsShell } from '../../components/shell'; |
| 2 | |
| 3 | export const metadata = { title: 'roadmap' }; |
| 4 | |
| 5 | export default function RoadmapPage() { |
| 6 | return ( |
| 7 | <DocsShell> |
| 8 | <h1 className="font-mono text-2xl tracking-tight">roadmap</h1> |
| 9 | <p className="mt-2 font-mono text-sm text-[var(--color-text-muted)]"> |
| 10 | what we're building, in rough order of priority. dates are intent, not commitment — |
| 11 | anything ships when it's ready and not before. the changelog is what actually |
| 12 | landed; this page is what we're working towards. |
| 13 | </p> |
| 14 | |
| 15 | <Phase label="now" body="dogfooding briven on a single VPS, hardening the operator surface, public alpha behind invite codes."> |
| 16 | <Bullet status="done">phase 0 — foundations: api, runtime, realtime, dashboard, docs all live</Bullet> |
| 17 | <Bullet status="done">phase 1 — reactive queries via LISTEN/NOTIFY across all client SDKs</Bullet> |
| 18 | <Bullet status="done">phase 2 — per-tier rate limits, abuse pipeline, audit log, encryption-at-rest for env vars</Bullet> |
| 19 | <Bullet status="done">phase 3 — usage metering, beta invite UX, studio CRUD UI, admin triage</Bullet> |
| 20 | <Bullet status="done">phase 4 — self-host templates, observability stack, public docs polish, status page</Bullet> |
| 21 | <Bullet status="active">deploy on briven's own VPS, run alpha invitees through the cli + dashboard</Bullet> |
| 22 | </Phase> |
| 23 | |
| 24 | <Phase label="next" body="closing the gaps that turn alpha into a product anyone can adopt without hand-holding."> |
| 25 | <Bullet status="planned">point-in-time recovery (replace nightly pg_dump with WAL streaming + 7-day window)</Bullet> |
| 26 | <Bullet status="planned">multi-region read replicas (eu-west + us-east, opt-in per project)</Bullet> |
| 27 | <Bullet status="planned">team auth: SSO via SAML/OIDC, per-project member roles beyond owner/admin/developer</Bullet> |
| 28 | <Bullet status="planned">payments live: Polar + invoice PDFs + dunning + tax handling for EU/UK</Bullet> |
| 29 | <Bullet status="planned">function logs: full-text search across the last 7 days (today is tail-only)</Bullet> |
| 30 | <Bullet status="planned">scheduled functions: cron expressions in code, observable in the dashboard</Bullet> |
| 31 | <Bullet status="planned">file uploads: presigned-URL flow + per-project minio bucket + image transforms</Bullet> |
| 32 | </Phase> |
| 33 | |
| 34 | <Phase label="later" body="quality-of-life and breadth. nothing here blocks GA but we know we'll want them."> |
| 35 | <Bullet status="planned">first-class python + go SDKs (parity with TS/JS clients)</Bullet> |
| 36 | <Bullet status="planned">vector search beyond pgvector — first-party embedding generation via the platform</Bullet> |
| 37 | <Bullet status="planned">k8s helm chart for self-hosters past ~100 projects per host</Bullet> |
| 38 | <Bullet status="planned">desktop dashboard (electron) for offline-edit + git-based workflows</Bullet> |
| 39 | <Bullet status="planned">briven AI: schema-aware function generator, doc-aware chatbot for self-host operators</Bullet> |
| 40 | </Phase> |
| 41 | |
| 42 | <Phase label="not on the roadmap" body="things people ask about that we don't plan to build, with the why."> |
| 43 | <Bullet status="rejected"> |
| 44 | <strong>swappable storage backend (mongo, planetscale, etc.)</strong> — the bet is on |
| 45 | postgres. multi-backend is a lot of code for very little user benefit. |
| 46 | </Bullet> |
| 47 | <Bullet status="rejected"> |
| 48 | <strong>edge runtime</strong> — deno + cloudflare workers conflict on the network |
| 49 | surface; we'd rather invest in regional hosting on real VPSes. |
| 50 | </Bullet> |
| 51 | <Bullet status="rejected"> |
| 52 | <strong>proprietary closed-source plugins</strong> — anything we ship lives in the |
| 53 | public repo, even if AGPL is incompatible with your use case (we sell exemptions). |
| 54 | </Bullet> |
| 55 | </Phase> |
| 56 | |
| 57 | <p className="mt-12 font-mono text-xs text-[var(--color-text-subtle)]"> |
| 58 | miss something? open an issue on{' '} |
| 59 | <a href="https://codeberg.org/flndrn/briven" className="underline"> |
| 60 | codeberg.org/flndrn/briven |
| 61 | </a> |
| 62 | . |
| 63 | </p> |
| 64 | </DocsShell> |
| 65 | ); |
| 66 | } |
| 67 | |
| 68 | function Phase({ |
| 69 | label, |
| 70 | body, |
| 71 | children, |
| 72 | }: { |
| 73 | label: string; |
| 74 | body: string; |
| 75 | children: React.ReactNode; |
| 76 | }) { |
| 77 | return ( |
| 78 | <section className="mt-10"> |
| 79 | <h2 className="font-mono text-lg uppercase tracking-[0.12em] text-[var(--color-primary)]"> |
| 80 | {label} |
| 81 | </h2> |
| 82 | <p className="mt-1 font-mono text-sm text-[var(--color-text-muted)]">{body}</p> |
| 83 | <ul className="mt-4 space-y-2 font-mono text-sm">{children}</ul> |
| 84 | </section> |
| 85 | ); |
| 86 | } |
| 87 | |
| 88 | function Bullet({ |
| 89 | status, |
| 90 | children, |
| 91 | }: { |
| 92 | status: 'done' | 'active' | 'planned' | 'rejected'; |
| 93 | children: React.ReactNode; |
| 94 | }) { |
| 95 | const tag = |
| 96 | status === 'done' |
| 97 | ? 'done' |
| 98 | : status === 'active' |
| 99 | ? 'now ' |
| 100 | : status === 'planned' |
| 101 | ? 'next' |
| 102 | : 'no '; |
| 103 | const colour = |
| 104 | status === 'done' |
| 105 | ? 'var(--color-text-subtle)' |
| 106 | : status === 'active' |
| 107 | ? 'var(--color-primary)' |
| 108 | : status === 'planned' |
| 109 | ? 'var(--color-text-muted)' |
| 110 | : 'var(--color-text-subtle)'; |
| 111 | return ( |
| 112 | <li className="flex items-start gap-3"> |
| 113 | <span |
| 114 | className="font-mono text-[10px] uppercase tracking-[0.12em]" |
| 115 | style={{ color: colour, paddingTop: 2 }} |
| 116 | > |
| 117 | [{tag}] |
| 118 | </span> |
| 119 | <span className="text-[var(--color-text-muted)]">{children}</span> |
| 120 | </li> |
| 121 | ); |
| 122 | } |