Developer Guide
Technical Reference
Architecture, database schema, step type reference, and API documentation.
Architecture
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Customer │ │ Admin │ │ Public │
│ Form View │ │ Editor │ │ API │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└────────────────────┼────────────────────┘
│
┌───────▼───────┐
│ Supabase │
│ (PostgreSQL) │
└───────┬───────┘
│
┌─────────────┼──────────────┐
│ │ │
┌─────▼───┐ ┌──────▼─────┐ ┌────▼────┐
│ Stripe │ │ Resend │ │ PDF │
│(Payments)│ │ (Email) │ │ Gen │
└─────────┘ └────────────┘ └─────────┘
Tech Stack
- Frontend: Svelte 5, SvelteKit
- Database: Supabase (PostgreSQL with RLS)
- Styling: Tailwind CSS v4
- Security: Cloudflare Turnstile
- Email: Resend
- PDF: Custom PDF generation with
pdfmake - Deployment: Cloudflare Pages + Workers
Database Schema
FlowForms uses only 2 tables in the database:
forms
| Column | Type | Description |
|---|---|---|
form_id |
UUID | Primary key |
user_id |
UUID | Owner (references auth.users) |
step_number |
integer | Step order |
step_type |
text | welcome, multi_select, single_select, rush_fee, form, actions |
step_data |
JSONB | Full step configuration |
slug |
text | Custom URL slug (deprecated — use step_data.slug) |
created_at |
timestamptz | Creation timestamp |
updated_at |
timestamptz | Last update timestamp |
form_submissions
| Column | Type | Description |
|---|---|---|
form_id |
UUID | References forms.form_id |
submission_data |
JSONB | Complete submission payload |
created_at |
timestamptz | Submission timestamp |
Step Type Reference
Welcome Step step_data
{
"title": "Get Your Quote",
"description": "Tell us about your project",
"slug": "custom-url-slug",
"startDate": "2025-01-01",
"endDate": "2025-12-31",
"initialMonths": 3
}
Multi Select Options
Uses discriminated unions for product linking:
Product-linked: { "value": "opt_1", "product_id": "uuid" }
Custom inline: { "value": "opt_1", "label": "Service A", "description": "Full description", "price": 500 }
Rush Fee Options
{
"value": "rush_express",
"label": "Express (2 weeks)",
"description": "Fast-track processing",
"rushFee": {
"multiplier": 1.5,
"title": "Express Service",
"description": "50% surcharge for express processing"
}
}
Key Routes
| Route | Purpose |
|---|---|
/ |
Marketing homepage |
/login |
OTP authentication |
/form/[id] |
Public form submission |
/edit/forms |
Form list (auth required) |
/edit/forms/[formId] |
Form editor (auth required) |
/api/form-expiry |
Credit deduction for form expiry |
/api/create-customer |
Wave Accounting customer creation |
/api/send-quotation |
Email quotation delivery |
Integrations
Wave Accounting
- API token + Business ID stored in actions step
step_data - Flow: Search → PATCH if exists → CREATE if new
Telegram
- Bot token + chat ID in actions configuration
- Formatted notification on submission
- WYSIWYG template editor with merge fields
- Supports
{{ fieldName }}and ternary syntax - Custom To/CC/BCC per form
Custom Webhooks
- POST submission data to any URL
- Configurable per form in actions step
Deployment
# Development
npm run dev
# Build
npm run build
# Deploy to Cloudflare
npx wrangler deploy
Deployed to Cloudflare Workers via @sveltejs/adapter-cloudflare.