page.tsx147 lines · main
1import { DocsShell } from '../../components/shell';
2
3export const metadata = { title: 'cli templates' };
4
5interface Template {
6 name: string;
7 pitch: string;
8 description: string;
9 schema: string;
10 highlights: readonly string[];
11}
12
13const TEMPLATES: readonly Template[] = [
14 {
15 name: 'blank',
16 pitch: 'kick the tyres',
17 description:
18 'one table (notes), one reactive query. the smallest valid briven project — useful when you just want to see the deploy / invoke loop work end-to-end before you commit to a real model.',
19 schema: `briven/
20├── schema.ts # 1 table: notes
21└── functions/
22 └── listNotes.ts # 1 reactive query`,
23 highlights: ['1 table', '1 reactive query', '0 mutations'],
24 },
25 {
26 name: 'todo-app',
27 pitch: 'canonical hello-world',
28 description:
29 'classic todo list. 4 mutations covering create / toggle / rename / delete, 1 reactive query with a filter argument (open / done / all). matches the live demo at briven.tech/demo (when phase 4 lands).',
30 schema: `briven/
31├── schema.ts # 1 table: todos
32└── functions/
33 ├── listTodos.ts # reactive query with ?filter=open|done|all
34 ├── createTodo.ts # mutation: validates body length, ulid id
35 ├── toggleTodo.ts # mutation: flips done + sets completedAt
36 ├── renameTodo.ts # mutation: body replace
37 └── deleteTodo.ts # mutation: hard delete by id`,
38 highlights: ['1 table', '1 query (with args)', '4 mutations', 'input validation'],
39 },
40 {
41 name: 'chat',
42 pitch: 'real-time multi-room',
43 description:
44 'rooms + messages with a per-room reactive query. shows how to use a foreign key + leading-column index to scope realtime fan-out to one room per subscriber. ulid ids, server-side timestamps.',
45 schema: `briven/
46├── schema.ts # 2 tables: rooms, messages (FK)
47└── functions/
48 ├── listRooms.ts # reactive query
49 ├── createRoom.ts # mutation
50 ├── listMessages.ts # reactive query, args: { roomId }
51 └── postMessage.ts # mutation, args: { roomId, body }`,
52 highlights: ['2 tables with FK', 'per-room realtime', '2 queries', '2 mutations'],
53 },
54 {
55 name: 'convex-notes',
56 pitch: 'familiar to convex users',
57 description:
58 'multi-user notes with per-owner reactive listing + optional tag filter — mirrors the canonical convex notes-app shape. ownership is enforced inside each mutation as an explicit guard, not via row-level policy. comes pre-wired so a convex user sees their mental model land 1:1.',
59 schema: `briven/
60├── schema.ts # 1 table: notes (owner-scoped)
61└── functions/
62 ├── listNotes.ts # reactive query, args: { ownerId, tag? }
63 ├── createNote.ts # mutation
64 ├── updateNote.ts # mutation with ownership guard
65 └── deleteNote.ts # mutation with ownership guard`,
66 highlights: ['multi-user', 'per-owner realtime', 'ownership guards', 'tag filter'],
67 },
68 {
69 name: 'supabase-auth-todos',
70 pitch: 'familiar to supabase users',
71 description:
72 "auth-scoped todo list. every function reads ctx.session.userId and applies the same scoping supabase would do via row-level security — except the predicate lives in code, where you can read it and debug it. paste this to translate `auth.uid() = user_id` into briven's model.",
73 schema: `briven/
74├── schema.ts # 1 table: todos (user_id-scoped)
75└── functions/
76 ├── myTodos.ts # reactive query, uses ctx.session.userId
77 ├── createTodo.ts # mutation, inserts with userId
78 ├── toggleTodo.ts # mutation with ownership guard
79 └── deleteTodo.ts # mutation with ownership guard`,
80 highlights: ['auth-aware', 'RLS → guards', '1 query', '3 mutations'],
81 },
82];
83
84export default function TemplatesPage() {
85 return (
86 <DocsShell>
87 <h1 className="font-mono text-2xl tracking-tight">cli templates</h1>
88 <p className="mt-2 font-mono text-sm text-[var(--color-text-muted)]">
89 optional starter files only — not the core product. the product path is{' '}
90 <code>briven setup</code> for a <strong>new</strong> cloud project, or{' '}
91 <code>briven connect p_…</code> for an <strong>existing</strong> one. pass{' '}
92 <code>--template</code> on setup when you want a sample schema/functions layout.
93 </p>
94
95 <pre className="mt-4 overflow-x-auto rounded-md border border-[var(--color-border-subtle)] bg-[var(--color-code-bg)] p-3 font-mono text-xs text-[var(--color-code-text)]">
96 <code>{`# new cloud project + sample files
97briven setup --name my-app --template=todo-app
98briven deploy
99
100# existing project — attach first, templates are optional later
101briven connect p_…
102# or local files only: briven init --template=todo-app`}</code>
103 </pre>
104
105 <p className="mt-2 font-mono text-xs text-[var(--color-text-subtle)]">
106 pass <code>briven init --list-templates</code> to print available names without
107 scaffolding. full connect flow:{' '}
108 <a className="underline" href="/connect">
109 connect
110 </a>
111 .
112 </p>
113
114 {TEMPLATES.map((t) => (
115 <section
116 key={t.name}
117 id={t.name}
118 className="mt-10 scroll-mt-20 border-t border-[var(--color-border-subtle)] pt-8"
119 >
120 <div className="flex items-baseline justify-between gap-3">
121 <h2 className="font-mono text-lg tracking-tight">
122 <code>{t.name}</code>
123 </h2>
124 <span className="font-mono text-xs text-[var(--color-text-subtle)]">{t.pitch}</span>
125 </div>
126 <p className="mt-2 font-mono text-sm text-[var(--color-text-muted)]">{t.description}</p>
127 <ul className="mt-3 flex flex-wrap gap-2 font-mono text-[10px]">
128 {t.highlights.map((h) => (
129 <li
130 key={h}
131 className="rounded-md border border-[var(--color-border)] px-2 py-0.5 text-[var(--color-text-muted)]"
132 >
133 {h}
134 </li>
135 ))}
136 </ul>
137 <pre className="mt-4 overflow-x-auto rounded-md border border-[var(--color-border-subtle)] bg-[var(--color-code-bg)] p-3 font-mono text-xs text-[var(--color-code-text)]">
138 <code>{t.schema}</code>
139 </pre>
140 <pre className="mt-3 overflow-x-auto rounded-md border border-[var(--color-border-subtle)] bg-[var(--color-code-bg)] p-3 font-mono text-xs text-[var(--color-code-text)]">
141 <code>{`mkdir my-app && cd my-app\nbriven setup --name my-app --template=${t.name}\nbriven deploy`}</code>
142 </pre>
143 </section>
144 ))}
145 </DocsShell>
146 );
147}