Skip to content

Commit 8c41919

Browse files
committed
chore: update setup instructions and configuration for public demo with pgflow integration
- Clarify goal to implement a minimal end-to-end flow without authentication - Fix Supabase init command to use npx for latest CLI version - Add schemas to supabase config for pgflow - Include detailed steps for copying core migrations and creating anon permissions - Update vendoring script paths and add Nx target for dependency syncing - Include instructions for building dependencies, creating test flow, and setting up worker - Add steps for testing locally with supabase start and serving functions - Revise UI setup to use Svelte 5 syntax and demonstrate flow start and status updates - Enhance troubleshooting section with relevant checks for vendoring, edge functions, auth, and real-time - Overall, improve clarity for public, unauthenticated demo setup and ensure all steps are aligned for end-to-end testing
1 parent 5270efa commit 8c41919

34 files changed

+4750
-102
lines changed

PHASE_1_VERTICAL_SLICE.md

Lines changed: 228 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,93 @@
22

33
**Branch:** `feat-demo-1-vertical-slice`
44

5-
**Goal:** Implement minimal end-to-end flow execution - from UI button click through Edge Function to real-time status updates. Validates entire integration stack with **client-side auth only**.
5+
**Goal:** Implement minimal end-to-end flow execution - from UI button click through Edge Function to real-time status updates. Validates entire integration stack with **no authentication required** - just public anon key access.
66

77
**Success Criteria:**
88
- ✅ Supabase initialized in demo app
9-
- ✅ Client-side anonymous auth working
109
- ✅ Edge Function with 1-step test flow executes
1110
- ✅ pgflow packages vendored correctly
12-
- ✅ pgflow client connects from UI
11+
- ✅ pgflow client connects from UI (anon key only)
1312
- ✅ Button click starts flow
1413
- ✅ Status updates in real-time
1514
- ✅ No console errors
1615

17-
**Philosophy:** Build the thinnest possible slice through the entire stack. UI will be ugly - that's fine. Goal is to prove integration works. **No server-side auth needed - demo is public!**
16+
**Philosophy:** Build the thinnest possible slice through the entire stack. UI will be ugly - that's fine. Goal is to prove integration works. **No authentication - just public demo with anon key!**
1817

1918
---
2019

2120
## Tasks
2221

2322
### 1. Add pgflow Client Dependency
2423

25-
Edit `apps/demo/package.json` - add `"@pgflow/client": "workspace:*"` to dependencies:
26-
2724
```bash
28-
pnpm install
25+
cd apps/demo
26+
pnpm add @pgflow/client
27+
cd ../..
2928
```
3029

30+
This will add `"@pgflow/client": "workspace:*"` to dependencies automatically.
31+
3132
### 2. Initialize Supabase
3233

3334
```bash
34-
cd apps/demo && supabase init && cd ../..
35+
cd apps/demo && npx -y supabase@latest init && cd ../..
3536
```
3637

3738
---
3839

39-
### 3. Configure Supabase for pgflow
40+
### 3. Install pgflow
4041

41-
Edit `apps/demo/supabase/config.toml` - add `"pgflow"` to `[api]` schemas:
42+
Run the pgflow installer:
4243

43-
```toml
44-
schemas = ["public", "pgflow"]
44+
```bash
45+
npx pgflow@latest install
46+
```
47+
48+
This will:
49+
- Update `supabase/config.toml` (adds pgflow schema, connection pooling)
50+
- Copy pgflow migrations to `supabase/migrations/`
51+
52+
### 4. Create Anon Permissions Migration
53+
54+
Create `apps/demo/supabase/migrations/<timestamp>_demo_anon_permissions.sql`:
55+
56+
```sql
57+
-- Grant anon role access to start flows
58+
GRANT USAGE ON SCHEMA pgflow TO anon;
59+
GRANT EXECUTE ON FUNCTION pgflow.start_flow TO anon;
60+
61+
-- Grant anon role read access to pgflow tables for real-time updates
62+
GRANT SELECT ON pgflow.flows TO anon;
63+
GRANT SELECT ON pgflow.runs TO anon;
64+
GRANT SELECT ON pgflow.steps TO anon;
65+
GRANT SELECT ON pgflow.step_states TO anon;
66+
GRANT SELECT ON pgflow.deps TO anon;
67+
68+
-- Enable real-time for anon role
69+
ALTER PUBLICATION supabase_realtime ADD TABLE pgflow.runs;
70+
ALTER PUBLICATION supabase_realtime ADD TABLE pgflow.step_states;
71+
```
72+
73+
### 5. Restart Supabase and Apply Migrations
74+
75+
```bash
76+
npx -y supabase@latest stop
77+
npx -y supabase@latest start
78+
npx -y supabase@latest migrations up
4579
```
4680

4781
---
4882

49-
### 4. Copy Vendoring Script
83+
### 6. Copy Vendoring Script
5084

5185
```bash
5286
mkdir -p apps/demo/scripts
5387
cp examples/playground/scripts/sync-edge-deps.sh apps/demo/scripts/
5488
chmod +x apps/demo/scripts/sync-edge-deps.sh
5589
```
5690

57-
### 5. Update Vendoring Script Paths
91+
### 7. Update Vendoring Script Paths
5892

5993
Edit `apps/demo/scripts/sync-edge-deps.sh` - replace `PLAYGROUND_DIR` with `DEMO_DIR`:
6094

@@ -65,7 +99,7 @@ VENDOR_DIR="$DEMO_DIR/supabase/functions/_vendor"
6599

66100
---
67101

68-
### 6. Add Nx Target for Vendoring
102+
### 8. Add Nx Target for Vendoring
69103

70104
Edit `apps/demo/project.json` - add `sync-edge-deps` target:
71105

@@ -77,7 +111,7 @@ Edit `apps/demo/project.json` - add `sync-edge-deps` target:
77111
}
78112
```
79113

80-
### 7. Build Dependencies and Vendor
114+
### 9. Build Dependencies and Vendor
81115

82116
```bash
83117
pnpm nx build core dsl
@@ -86,93 +120,233 @@ pnpm nx sync-edge-deps demo # Verify: ls apps/demo/supabase/functions/_vendor/@
86120

87121
---
88122

89-
### 8. Create Test Flow Definition
123+
### 10. Create Test Flow Worker Directory
124+
125+
Create worker directory with flow definition inside:
126+
127+
```bash
128+
mkdir -p apps/demo/supabase/functions/test_flow_worker
129+
```
90130

91-
Create `apps/demo/supabase/functions/_flows/test-flow.ts`:
92-
- Import Flow from `@pgflow/dsl`
93-
- Create simple 1-step flow with slug 'test-flow'
94-
- Handler returns: `Hello, ${input.run.message}!`
95-
- Note: Access run input via `input.run.*` pattern
131+
### 11. Create Test Flow Definition
96132

97-
### 9. Create Edge Function Worker
133+
Create `apps/demo/supabase/functions/test_flow_worker/test_flow.ts`:
134+
135+
```typescript
136+
import { Flow } from '@pgflow/dsl';
137+
138+
export default new Flow<{ message: string }>({ slug: 'test_flow' }).step(
139+
{ slug: 'greet' },
140+
(input) => `Hello, ${input.run.message}!`
141+
);
142+
```
143+
144+
**Note:** Flow slug is `test_flow` (with underscore), matching the worker directory name.
145+
146+
### 12. Create Edge Function Worker
147+
148+
Create `apps/demo/supabase/functions/test_flow_worker/index.ts`:
98149

99-
Create `apps/demo/supabase/functions/demo-worker/index.ts`:
100150
```typescript
101151
import { EdgeWorker } from '@pgflow/edge-worker';
102-
import TestFlow from '../_flows/test-flow.ts';
152+
import TestFlow from './test_flow.ts';
103153

104154
EdgeWorker.start(TestFlow);
105155
```
156+
106157
**This 3-line pattern is critical - it's how all pgflow workers are set up!**
107158

108-
### 10. Test Edge Function Locally
159+
### 13. Create Deno Import Map
160+
161+
Create `apps/demo/supabase/functions/test_flow_worker/deno.json`:
162+
163+
```json
164+
{
165+
"imports": {
166+
"@pgflow/core": "../_vendor/@pgflow/core/index.ts",
167+
"@pgflow/core/": "../_vendor/@pgflow/core/",
168+
"@pgflow/dsl": "../_vendor/@pgflow/dsl/index.ts",
169+
"@pgflow/dsl/": "../_vendor/@pgflow/dsl/",
170+
"@pgflow/dsl/supabase": "../_vendor/@pgflow/dsl/src/supabase.ts",
171+
"@pgflow/edge-worker": "../_vendor/@pgflow/edge-worker/index.ts",
172+
"@pgflow/edge-worker/": "../_vendor/@pgflow/edge-worker/",
173+
"@pgflow/edge-worker/_internal": "../_vendor/@pgflow/edge-worker/_internal.ts",
174+
"postgres": "npm:postgres@3.4.5",
175+
"@henrygd/queue": "jsr:@henrygd/queue@^1.0.7",
176+
"@supabase/supabase-js": "jsr:@supabase/supabase-js@^2.49.4"
177+
}
178+
}
179+
```
180+
181+
**Critical:** This maps all `@pgflow/*` imports to the vendored packages (one level up), including subpaths and required dependencies!
182+
183+
---
184+
185+
### 14. Configure Edge Function in config.toml
186+
187+
Edit `apps/demo/supabase/config.toml`, add at the end:
188+
189+
```toml
190+
[functions.test_flow_worker]
191+
enabled = true
192+
verify_jwt = false
193+
import_map = "./functions/test_flow_worker/deno.json"
194+
entrypoint = "./functions/test_flow_worker/index.ts"
195+
```
196+
197+
**Critical:** `verify_jwt = false` allows public demo access without authentication.
198+
199+
---
200+
201+
### 15. Build Client Package
202+
203+
```bash
204+
pnpm nx build client
205+
```
206+
207+
### 16. Test Edge Function Locally
109208

110209
```bash
111210
cd apps/demo
112-
supabase start # Then in another terminal:
113-
supabase functions serve demo-worker
211+
npx -y supabase@latest start # Then in another terminal:
212+
npx -y supabase@latest functions serve test_flow_worker
114213
```
115214

116-
### 11. Create Client-Side Supabase Configuration
215+
### 17. Create Client-Side Supabase Configuration
117216

118217
Create `apps/demo/src/lib/supabase.ts`:
119-
- Create Supabase client with URL and anon key (use env vars or local defaults)
120-
- Create PgflowClient wrapping the Supabase client
121-
- Export both for use in components
122-
- **Key point:** Pure client-side - no server hooks, no cookies!
123218

124-
---
219+
```typescript
220+
import { createClient } from '@supabase/supabase-js';
221+
import { PgflowClient } from '@pgflow/client';
125222

126-
### 12. Create Minimal Test UI
223+
// Hardcoded local Supabase defaults (Phase 1 - production config in Phase 6)
224+
const SUPABASE_URL = 'http://127.0.0.1:54321';
225+
const SUPABASE_ANON_KEY = 'sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH';
127226

128-
Replace `apps/demo/src/routes/+page.svelte` with basic test interface.
227+
export const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
228+
export const pgflow = new PgflowClient(supabase);
229+
```
129230

130-
**Key patterns to implement:**
131-
- Anonymous auth: `await supabase.auth.signInAnonymously()` in onMount
132-
- Start flow: `pgflow.startFlow('test-flow', { message: 'World' })`
133-
- Listen to events: `run.on('*', (event) => { ... })`
134-
- Svelte 5 state: `let status = $state<string>('idle')`
135-
- Display status updates and output
231+
**Note:** Get the anon key from `npx -y supabase@latest status`. Environment variables for production will be added in Phase 6 (Deploy).
232+
233+
---
136234

137-
**Remember:** Use `onclick={handler}` not `on:click` (Svelte 5 syntax)
235+
### 18. Create Minimal Test UI
236+
237+
Replace `apps/demo/src/routes/+page.svelte` with basic test interface:
238+
239+
```svelte
240+
<script lang="ts">
241+
import { pgflow } from '$lib/supabase';
242+
243+
let status = $state<string>('idle');
244+
let output = $state<string>('');
245+
let events = $state<string[]>([]);
246+
247+
async function startTestFlow() {
248+
status = 'starting...';
249+
events = [];
250+
output = '';
251+
252+
try {
253+
const run = await pgflow.startFlow('test_flow', { message: 'World' });
254+
255+
run.on('*', (event) => {
256+
events = [...events, JSON.stringify(event, null, 2)];
257+
status = event.status || status;
258+
259+
if (event.status === 'completed' && event.output) {
260+
output = JSON.stringify(event.output, null, 2);
261+
}
262+
});
263+
} catch (error) {
264+
status = 'error';
265+
output = error instanceof Error ? error.message : String(error);
266+
}
267+
}
268+
</script>
269+
270+
<div class="container">
271+
<h1>pgflow Demo - Phase 1 Vertical Slice</h1>
272+
273+
<div class="controls">
274+
<button onclick={startTestFlow}>Start Test Flow</button>
275+
</div>
276+
277+
<div class="status">
278+
<h2>Status</h2>
279+
<p>{status}</p>
280+
</div>
281+
282+
{#if output}
283+
<div class="output">
284+
<h2>Output</h2>
285+
<pre>{output}</pre>
286+
</div>
287+
{/if}
288+
289+
{#if events.length > 0}
290+
<div class="events">
291+
<h2>Events</h2>
292+
{#each events as event}
293+
<pre>{event}</pre>
294+
{/each}
295+
</div>
296+
{/if}
297+
</div>
298+
299+
<style>
300+
/* Add basic styling for layout */
301+
</style>
302+
```
303+
304+
**Key patterns:**
305+
- Use `onclick={handler}` not `on:click` (Svelte 5 syntax)
306+
- Svelte 5 state: `let status = $state<string>('idle')`
307+
- Start flow: `pgflow.startFlow('test_flow', { message: 'World' })`
308+
- Listen to events: `run.on('*', (event) => { ... })`
138309

139310
---
140311

141-
### 13. Start Dev Server
312+
### 19. Start Dev Server
142313

143314
```bash
144-
pnpm nx dev demo # Ensure supabase start running
315+
pnpm nx dev demo # Ensure npx -y supabase@latest start running
145316
```
146317

147-
### 14. Test End-to-End
318+
### 20. Test End-to-End
148319

149320
Open http://localhost:5173/, click button, verify:
150321
- Status: `idle``starting...``running``completed`
151322
- Output shows `"Hello, World!"`
152-
- Console shows event stream
323+
- Events section shows real-time event stream
153324

154325
---
155326

156327
## Validation Checklist
157328

158329
- [ ] Supabase initialized, pgflow packages vendored
159-
- [ ] Test flow + worker created
160-
- [ ] Anonymous auth working (check Network tab for auth.signInAnonymously)
161-
- [ ] `supabase start` and `functions serve demo-worker` running
330+
- [ ] Test flow + worker created in `test_flow_worker/` directory
331+
- [ ] Worker configured in `config.toml` with `verify_jwt = false`
332+
- [ ] Deno import map created with all dependencies
333+
- [ ] `npx -y supabase@latest start` and `functions serve test_flow_worker` running
162334
- [ ] Dev server starts, button click starts flow
163-
- [ ] Status updates real-time, output appears, no console errors
335+
- [ ] Status updates real-time, output appears, events stream visible
336+
- [ ] No authentication needed - works immediately on page load
337+
- [ ] Flow slug is `test_flow` (with underscore)
338+
- [ ] No console errors
164339

165340
---
166341

167342
## Troubleshooting
168343

169344
- **Vendoring fails:** Check `ls pkgs/core/dist`, rebuild with `pnpm nx build core dsl`
170-
- **Edge Function won't start:** Check `supabase status`, verify vendored files exist
171-
- **Anonymous auth fails:** Check browser console, ensure Supabase anon key is valid
345+
- **Edge Function won't start:** Check `npx -y supabase@latest status`, verify vendored files exist
172346
- **Flow doesn't start:** Check browser console - Supabase connection, pgflow schema in config.toml, flow slug matches
173347
- **No real-time updates:** Check Realtime enabled, Edge Function logs, Svelte `$state` reactivity
174348
- **TypeScript errors:** Verify Svelte 5 syntax (`$state`, `onclick`)
175-
- **Auth issues:** Remember - this is all client-side! No server hooks needed
349+
- **Anon key issues:** Get correct key from `npx -y supabase@latest status`, ensure hardcoded in `lib/supabase.ts`
176350

177351
**Rollback:** Mock pgflow client to debug Edge Function separately
178352

0 commit comments

Comments
 (0)