Skip to content

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

Email

  • 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.