Changelog · 264 updates

What's new

Every change we ship, in the order we shipped it — features, fixes and security work, written by the people who built them. Subscribe via RSS.

NewImprovedFixedSecurity
August 17, 20266 updates
New

Trust & self-serve (Tier B)

Public status page at /status: a new 10-minute cron (*/10 * *, separated from the daily 14:00 jobs in scheduled()) probes API, database, R2 storage, the public-forms API path and the website, stores results in status_checks (migration 0021, 90-day retention), and GET /api/public/status summarises current state, 90-day uptime %, average latency and 30-day daily bars. Public changelog at /changelog/ + /changelog/feed.xml (RSS): build-time SSG (generate-changelog-page.mjs) parses CHANGELOG.md — 263 entries grouped by day, type badges, internal "Ops to-do" notes scrubbed. API reference at /developers: every v1 endpoint with scopes, params, curl examples, response shapes, hook payload and limits (verified against v1.ts / form-integrations.ts). Accessibility statement at /accessibility (WCAG 2.1 AA target, known limitations, reporting path). Self-serve session management: logins now mint a sessions row and put its id (sid) in the JWT; requireAuth rejects revoked/expired sessions (older sid-less tokens keep working until expiry); GET/DELETE /api/auth/sessions, POST /api/auth/sessions/revoke-others; logout revokes its own row; Settings → "Active sessions" card (device/browser, IP, last active, sign out / sign out others). Migration 0020 adds last_seen_at/revoked_at. Owner-facing activity log: new activity_log table (migration 0022) + logActivity(); instrumented form created/published/unpublished/deleted, API key created/revoked, sessions revoked, password changed, Stripe connected/disconnected, subscription started/cancelled/retention-accepted; GET /api/auth/activity (paginated) and a Settings → "Recent activity" card. Footer links added (API, Changelog, Status, Accessibility); sitemap updated.

New

Billing & retention (Tier A)

Six standard-SaaS gaps closed in one pass. Annual billing: STRIPE_PRO_ANNUAL_PRICE_ID (Worker) + VITE_STRIPE_PRO_ANNUAL_PRICE_ID (frontend, passed through deploy.sh) enable a Monthly/Yearly toggle on Pricing ($390/yr = 2 months free); price validation, switch-plan and webhook plan-mapping accept the annual price. Promo codes: "Have a promo code?" in the payment modal → API resolves the customer-facing code via /promotion_codes and applies it as a subscription discount (clear error on invalid). Real free trial: first-ever subscriptions get trial_period_days: 14 (card required, charged after); modal and pricing card say so, and the "30-day"/"no card required" claims on Pricing FAQ, Security and HIPAA pages were corrected. Dunning: new invoice.payment_failed webhook case marks the subscription past_due and sends a "payment failed — update card" email (amount, next retry date, billing + invoice links); Billing page shows a red past-due banner linking to payment methods. Usage meter + warning: GET /api/billing now returns usage (published forms, monthly responses vs plan limits), rendered as meters on Billing with an inline upgrade prompt at ≥80%; a daily cron (sendUsageWarnings) emails free users once per calendar month when they cross 80% (the existing held-response email covers 100%). Win-back: if STRIPE_WINBACK_COUPON_ID is set, the cancel modal offers the coupon ("Apply discount and stay"); POST /api/billing/retention-offer applies it once per user and records cancellation_feedback.reason='winback_accepted'.

New

Real respondent payments via Stripe Connect

The May payment field charged FormBuilder's own platform Stripe account, so owners could never actually get paid. Now owners connect their own Stripe account (Standard/OAuth) in Settings → Payments (new PaymentsSettings card: connect / connected-account status / disconnect) and payment fields create Checkout Sessions on the connected account (Stripe-Account header) — money goes straight to the owner, no platform fee. Migration 0019 adds users.stripe_connect_account_id/status/connected_at. New API /api/stripe-connect (status, authorize with HMAC-signed state, callback, disconnect). Submissions to a form with a payment field are refused (422 PAYMENT_NOT_CONFIGURED) until the owner connects — never charged to the platform. New public POST /api/public/forms/:id/payment/confirm verifies the Checkout Session server-side (must be paid and carry this response's id) before the public form shows the thank-you screen; the webhook and the confirm endpoint share one idempotent finalizePaidResponse() (services/payments.ts) so a response is finalized exactly once. Webhook route accepts the Connect webhook signing secret (STRIPE_CONNECT_WEBHOOK_SECRET) as a fallback. Public form now handles ?payment=success|cancelled (verifying → paid / pending / error panels; cancelled shows an inline retry notice). Builder shows a Stripe-connection notice on payment fields.

New

Free plan: 5 forms + webhooks/Zapier/payments listed as included

PLAN_LIMITS.free.forms 3→5 (API create/publish caps) and plans.ts to match; webhooks were never plan-gated in the API, so the Free feature list now says so (Pro list de-duplicated). Copy fixed in pricing table, help center (3 places), templates page, integration pages' CTA fine-print (was claiming "Unlimited forms on the free plan"), and all comparison/alternatives pages (FormBuilder facts, competitor pricing analyses, FAQs).

New

Comparison-page accuracy

Feature matrix: Payments → Yes ("Stripe — paid to your own account, no platform fee"), Calculations & scoring → "Calculation field + auto-graded quizzes" (quiz grading shipped July 24), Webhooks → "All plans". Rewrote 12 competitor sentences that described FormBuilder payments as "Stripe/Zapier workflows".

New

Programmatic SEO: 26 static comparison + alternatives pages

Engineered-visibility play for AI assistants and search: new build-time mini-SSG (frontend/scripts/generate-compare-pages.mjs, runs after the integrations generator) renders /compare/ (hub), 12 /compare/formbuilder-vs-<competitor>/ head-to-head pages, /alternatives/ (hub), and 12 /alternatives/<competitor>/ ranked buyer's guides. Tier-1 competitors: Typeform, Jotform, Google Forms, Microsoft Forms, SurveyMonkey, Tally, Formstack, Wufoo, Cognito Forms, Paperform, Fillout, MightyForms (acquisition-flavored). Each competitor is one rich data file (compare-data/competitors/<slug>.mjs: 3-paragraph overview, best/not-ideal-for, vendor-terms pricing table checked live on Aug 17 2026, pricing analysis, 25-row feature matrix, strengths/weaknesses, verdict + choose-X-if lists, 4-step migration, why-people-switch, 6–8 chatbot-phrased FAQs); FormBuilder facts live once in compare-data/formbuilder.mjs. Design per guidelines: scorecard hero artifact, charcoal verdict panel, side-by-side pricing decision tables, grouped feature matrix, S/W cards, numbered migration steps, FAQ, related pills, CTA band; verified via headless-Chrome renders desktop + narrow. JSON-LD: BreadcrumbList, Article (dateModified), FAQPage, ItemList (alternatives). sitemap-compare.xml + robots.txt Allow/Sitemap lines; footer gained Compare/Alternatives links. Adding a competitor = one data file + one registry line + rebuild.

July 28, 20261 update
Fixed

Review-queue SLA alert false alarm on banned users' forms

The daily SLA email reported "5 form(s) waiting >24h" while the admin review queue was empty. Root cause: ban-takedown intentionally leaves requires_review = 1 on a banned user's forms, and the SLA queries in abuse-sweeps.ts counted forms.requires_review = 1 without checking owner status, while the admin queue filters on u.is_active = 1 — so already-handled phishing forms (all 5 belonged to banned accounts) re-alerted daily forever. Both SLA queries now join users and require is_active = 1, matching the queue's definition of pending. Verified against production D1: fixed count query returns 0. No data cleanup needed — the flag on banned users' forms is intentional.

July 25, 20265 updates
New

CTA realignment to draft-first across marketing surfaces

CTA audit found several pages still funneling visitors into signup/dashboard dead-ends instead of the draft-first builder. Fixed: all 138 static integration pages (nav "Get started free" + hero + closing-band CTAs went from /register to /form-builder), the Features page CTA band (was signup modal / dashboard, now "Create a form free" → builder), and all three blog CTAs (inline ---cta--- box, sidebar card, bottom band — all previously opened the signup modal). Every CTA now carries a ?src= param and fires create_intent_opened with a per-surface source; the builder additionally logs a new builder_opened event with the src param on arrival, so per-page draft-conversion can finally be measured (homepage vs features vs blog vs integrations). Verified in headless Chromium: features CTA lands on /form-builder?src=features, blog post renders both new CTA links, no console errors.

New

MightyForms banner shortened + dismissible

The acquisition banner dropped its redundant middle sentence ("Existing MightyForms customers can still sign in." — the login link already says that) and "Read the announcement" became "Announcement". Added an × dismiss button that persists via localStorage (mightyforms_notice_dismissed), so returning visitors get the row back after one acknowledgment. Verified in headless Chromium including dismissal surviving reload.

New

Form editor nav simplification + standout Share button

The editor header dropped from ~10 controls to 6. The red Unpublish button is gone from the action row: the Live status pill is now a small dropdown (Live ▾ → Unpublish form), so the destructive action no longer sits next to Share competing for attention. Settings and Integrations merged into one Settings ▾ dropdown. The email + Sign Out text became an avatar menu (initial circle → email, Sign Out). Preview is now icon-only. Share was redesigned as the single primary CTA when a form is live: charcoal fill per design guidelines, semibold, rounded-full, shadow + ring, emerald live dot, icon micro-scale on hover — the only filled button in the bar (Publish takes that role on drafts). Also fixed: header dropdowns previously rendered underneath the Field Properties panel (header lacked a z-index). Verified with headless-Chromium screenshots (desktop + menus open). Known pre-existing issue, not addressed: the header action row overflows off-screen at phone widths.

Fixed

Publish-gate AI review dedupe

The security gate re-ran a full AI review on every publish/save that carried publish state, even for identical content: one untrusted user's autosave burned 27 AI reviews in 2 minutes (41 total), and a blocked phisher's publish-hammering re-sent the review-queue email on every retry. The gate now hashes the scanned content (title, description, fields, thank-you/redirect/webhook) into KV (pubscan:<formId>, 7-day TTL) and reuses the prior verdict on a hash match — allowed verdicts skip the AI call entirely; blocked verdicts are honored only while the form is still requires_review so admin approvals always win. Pattern scans (cheap regex) still run every time.

Fixed

Review-queue SLA alert email actually useful now

The daily "Review queue SLA" email was a bare count with no links. It now lists each stuck form (up to 20, oldest first) with title, why it was flagged (latest scan risk level + top finding descriptions), owner (name linked to their admin detail page, email, plan), and exact wait time, plus an "Open the review queue" button to /admin/security and a pointer to the batch rescan. Also added GET /api/admin/security/sla-alert/resend (manage_security permission) to re-trigger the alert on demand by opening the URL in a logged-in admin browser.

July 24, 202617 updates
New

Integration pages redesign + main sitemap fix

The 138 /integrations pages got a full visual upgrade per DESIGN-GUIDELINES: hero product artifact (sample contact form → Zapier bolt → destination-app card with live-feed rows), subtle grid texture, stats strip, iconed workflow cards with a "Popular" flagship badge, a field-mapping panel artifact (form fields → app fields), numbered setup steps, animated-caret FAQ, app-monogram related pills, and a charcoal closing CTA band. Verified by actual headless-Chrome renders (desktop full-page + narrow), which caught unsized inline SVGs rendering giant. Sitemap fix: formbuilder.com/sitemap.xml was silently serving the SPA's index.html (Pages fallback shadowed the worker route — crawlers got HTML, not XML). The generator now writes a static sitemap.xml with 29 marketing/help URLs plus all 304 template pages (ids extracted from the same src/data/templates/*.js the template pages render from), 333 URLs total; static files always beat the SPA fallback.

New

Zapier integration: real REST-hooks app + public API expansion

FormBuilder now supports a genuine Zapier app (code in new zapier/ dir, Zapier Platform CLI) instead of the old paste-a-webhook-URL approach. New v1 API surface behind the existing developer tokens: GET /v1/me (auth test), GET /v1/forms/:id/fields (field schema → Zapier dynamic output fields), POST /v1/hooks + DELETE /v1/hooks/:id (REST hook subscribe/unsubscribe, new api_hooks table, migration 0018, per-user cap 100, https + anti-SSRF validation). Triggers: New Form Response (instant — dispatchApiHooks fires from the submission pipeline alongside existing integrations; held over-cap responses never fire; 410 Gone auto-deletes dead hooks; deliveries logged to integration_logs as zapier_hook) and New Form (polling). New hooks:manage token scope; revoking a token deletes its hooks. Settings gained an "API & Zapier" card (create/copy/revoke keys — first UI for the token system); the editor's webhook panel links to it. Free on all plans (matches Tally/Jotform/Typeform). Zapier app still needs zapier register/push from the Zapier account (see zapier/README.md).

New

Programmatic SEO: 138 static integration pages

New build-time mini-SSG (frontend/scripts/generate-integration-pages.mjs, runs after vite build) renders /integrations/ (hub), /integrations/zapier/ (pillar), and 136 /integrations/zapier/<app>/ landing pages ("Connect FormBuilder to Salesforce/Slack/Notion/…") from a single dataset (zapier-apps.mjs: unique per-app blurbs + category use-case templates + custom flagship use cases). Fully static HTML on Cloudflare Pages — crawlable without JS, editorial design system, FAQPage + BreadcrumbList JSON-LD, per-category internal linking, sitemap-integrations.xml, robots.txt updated (static + worker), footer "Integrations" link. Growing the page set = appending to the dataset and rebuilding.

New

Owner-facing form analytics page

New /forms/:id/analytics page (linked from the responses page header) finally surfaces the analytics the API was already collecting but never showing anyone: views/starts/submissions/completion-rate stat tiles, a 30-day daily views-vs-submissions trend chart (inline SVG with hover tooltips, colorblind-validated amber/emerald palette with dashed-vs-solid line encoding), a respondent funnel (viewed → started → submitted with rates), and top countries. The existing GET /api/forms/:id/analytics endpoint gained funnel, daily (30-day series merged from product_events views and form_responses submissions), and quiz fields. No schema changes.

New

Quiz performance aggregates for owners

The analytics page shows a quiz block when a form has graded responses: average score, average percent, graded-response count, and a score distribution (0–19% … 80–100% buckets). Computed by new summarizeQuizScores() in the scoring service (unit-tested, 3 new tests) over the most recent 1,000 responses' stored metadata.scoring.quiz.

New

Autosave + resume for respondents

On forms with "save progress" enabled, answers now autosave to the respondent's browser (localStorage, 800ms debounce, 7-day expiry) as they type; returning respondents get the restore prompt (the previously-orphaned ResumeFormModal, now wired in) offering to continue where they left off, including the right page on multi-page forms. Cleared on submit or discard; server-side resume links (the existing manual "save progress" flow) take precedence when present. Closes the gap where leaving without clicking save lost everything.

New

Quiz functionality: auto-graded questions with respondent scores

Radio, select, checkbox, and text fields can now be marked as quiz questions in the builder (correct answer + points, checkbox answers require the exact set, text matches case-insensitively). Grading runs server-side on submission via the existing scoring service and is stored in metadata.scoring.quiz on each response. Respondents see a score card on the thank-you screen ("7 / 10 — 7 of 10 questions correct") unless the owner turns off the new "Show Quiz Score" toggle (settings → General, appears once a field has a correct answer; stored in new forms.quiz_settings column, migration 0017). Owners see the score plus per-question Correct/Incorrect badges in the response detail modal. Security: answer keys live in field settings and are stripped from all public form payloads — respondents can never fetch the key, and grading happens server-side only.

New

47 new templates closing every AI-demand gap + new Logistics category

The July 24 template review cross-referenced ~120 production AI-generator prompts against the library and shipped templates for every recurring theme with no coverage: Education 4→16 (multiple-choice quiz, exam answer sheet, class test, student assessment, assignment submission, primary school enrollment, daycare registration, college application, attendance sheet, parent-teacher conference signup, field trip permission slip, mentorship matching); new Logistics category (delivery note, delivery order, proof of delivery, delivery incident report, delivery driver application, courier pickup request); audits & inspections (store audit, site survey, internal audit checklist, RCSA, workplace safety inspection, general inspection checklist); HR 6→13 (supervisor feedback — the demanded supervisor-selection variant, leave request, overtime request, shift swap, performance self-review, workplace incident report, onboarding checklist); Food & Beverage 3→9 (restaurant customer review with dine-in/takeaway/drive-through split, takeaway feedback, online food order, private event booking, menu item survey, delivery driver signup); plus refund request, roadside assistance, car rental booking, equipment rental, visitor sign-in sheet, group volunteer registration, dance workshop registration, early access signup, dormant account reactivation, and training feedback survey. Every template has a distinct theme (varied palettes and font pairings). Contract test extended with the full id list. Note: quiz/exam templates collect answers only — no grading engine yet (next conversation).

Fixed

Template search analytics never logged

logTemplateSearch existed and the /api/template-search endpoint worked, but no page ever called it, so the admin Template Searches dashboard has been empty since launch. The templates page now logs settled searches (800ms debounce) with result counts, so future template-gap decisions can run on real zero-result search data.

Fixed

Unsubscribe audit: every recurring email now has a logged-out opt-out

Conditional-notification recipients (form-integration emails with no stored recipient row) previously had NO unsubscribe link; they now get an HMAC-signed /unsubscribe-notifications/:payload link (login-free, tamper-rejecting, warm-paper pages) with opt-outs persisted in KV and filtered before every send. Backfilled the one production recipient row missing an unsubscribe token. All three unsubscribe flows (marketing/lifecycle, per-form recipient, conditional) verified live and logged out end-to-end.

Fixed

Email round 2: full lifecycle coverage + deliverability hygiene

(1) Create nudge (code 100): signed up 24h+ ago with zero forms → starter ideas + template/AI links; completes the nudge ladder (signup→create was the funnel's biggest single drop at 47%). (2) Weekly digest (code 103, Mondays): owners whose forms had views/responses in the last 7 days get "Your week on FormBuilder: X views, Y responses" with a per-form table; quiet accounts get nothing. (3) Unsubscribe hygiene: all lifecycle sends now carry an unsubscribe footer to the (restyled, warm-paper) /marketing-unsubscribe page; List-Unsubscribe header not possible with the current EMAIL binding shape (no headers field) — revisit if the binding changes. (4) Bounce suppression: provider-reported permanent bounces are logged as bounced, and any recipient with a bounce or 3+ failures and no successes in 30d is skipped (suppressed log status) to protect sender reputation. (5) Deleted the never-wired welcomeSeries day-2/5 drip templates and sendWelcomeSeriesDay dead code. Admin preview endpoint now sends all five sample emails.

Fixed

Lifecycle activation emails

The product now follows up after the two moments where funnels die. Daily cron sends (once per user, future accounts only, marketing_emails_enabled respected): a draft nudge when a real draft (3+ fields) sits unpublished for 24h with nothing else live, and a share nudge when a published form still has zero views after a day — including the live link, a mailto share shortcut, and a deep link that reopens the share modal. The first response a form ever receives now sends a celebration variant ("🎉 Your first response") with momentum copy. All email templates restyled to the editorial design system (warm paper, charcoal CTAs — the retired blue chrome is gone from every email). Send history in welcome_series_emails (codes 101/102); admin preview endpoint POST /api/admin/lifecycle/preview-emails.

Fixed

Dashboard visibility for the zero-views problem

Published form cards now show view counts, and a live form with 0 views and 0 responses gets an amber "No views yet — share your link" callout that opens the share modal. Publishing from anywhere on the dashboard now opens the share modal immediately (the share moment), instead of just a toast.

Fixed

Persistent Share in the editor

A published form's editor nav now leads with a charcoal Share button (reopens the share modal any time); Unpublish is demoted to a quiet text action. Publish/Share buttons restyled from retired blue to charcoal.

Improved

Free plan form cap now binds at publish, not create

Drafts no longer count against the 3-form free cap (production data: 72 free users were locked out of creating anything, 49 of them without ever publishing; templates — the #1 creation method — hit an upsell wall). Creation is now effectively unlimited (anti-abuse ceiling of 100 total forms), and the cap is enforced when transitioning a form to published (402 PLAN_FORM_LIMIT_REACHED, counts other published forms only so republishing never trips it). Removed the client-side 3-form block on the templates page.

Fixed

Dashboard "Get your first response" alert could unpublish a live form

The alert targeted forms[0] blindly: its "Publish" button toggled publish state (silently unpublishing an already-live form) and "Copy link" could copy a draft's dead URL. It now spotlights a live form awaiting its first response (Copy link / Share / Send test) or the newest draft (Publish, which then opens the share modal), and never copies unpublished links.

Fixed

anonymous_publish_instant events were silently dropped

The instant-publish success event fired by the frontend was missing from the server's allowedEventNames whitelist, so the new flow's key metric never recorded. Also: template usage now fires template_selected and form_created product events (the #1 creation path was invisible in the create funnel).

July 23, 202618 updates
Fixed

Held responses: the free cap stops losing data and becomes the upgrade moment

The free plan's 100 responses/month cap previously rejected the respondent's submission with an error (data lost, form looked broken, upgrade prompt shown to the respondent instead of the owner). Now forms keep collecting: responses past the cap are stored with metadata.held = true, locked from viewing/export/API while the owner is on free, and unlock instantly on upgrade. Held responses skip webhooks/integrations and send a "New response waiting" teaser notification. Owners see a warm-paper banner on the responses page ("N responses are waiting — upgrade to unlock") and locked rows show a quiet lock chip.

Fixed

Visible usage meter

GET /api/forms now returns accurate monthly response_usage; the dashboard Plan card shows "34 of 100 responses this month" with a thin progress bar (charcoal, amber past 80%), and the near-limit alert uses real monthly usage instead of all-time counts. Response notification emails carry a quiet usage footer once past 50% of the cap. Pricing page and plan catalog updated to state real boundaries (held responses, badge removal, post-submit redirects on Pro).

Fixed

Publish-first anonymous flow

Clicking Publish as an anonymous builder now creates the account from the email alone, runs the full security pipeline, publishes instantly, and shows the live link + share panel on the spot; the emailed magic link became the account claim mechanism (7-day expiry, "Your form is live 🎉" template) instead of an inbox gate. Existing-account emails still fall back to the magic-link flow (we never start a session on an unproven email). Abuse valves: unclaimed accounts' forms pause at 10 responses and auto-unpublish after 7 unclaimed days (daily cron, with a fresh claim link emailed). Motivated by funnel data: 118 anonymous publish clicks → only 20 completions, with 92% of magic links clicked within 2 minutes or never.

Fixed

Iron-clad scanner upgrades

normalizeScanText now folds Unicode homoglyphs (Cyrillic/Greek "pаsswоrd"), NFKC-normalizes fullwidth/styled text, strips diacritics and zero-width chars; credential terms in 15 languages added to both the pattern scanner and the non-negotiable credential hard-block (previously "Contraseña"/"Пароль" fields sailed through untouched). New evasion-corpus test suite (scripts/security-scanner.test.ts). AI review now runs on EVERY publish by untrusted accounts (new/unverified/unclaimed), not just pattern-flagged ones — non-English or creatively-phrased harvesting can no longer skip Claude; AI outage on a pattern-clean publish fails open but flags the form and emails the alert list.

Fixed

Bait-and-switch defense

Field create/update/delete and version restore on a published form now re-run the full scan pipeline (previously never rescanned: publish benign, rename a field to "Password", stay live); suspicious verdicts auto-unpublish + flag + alert.

Fixed

Behavioral defenses

Trust tiers (api/src/services/trust.ts); post-submit redirect URLs restricted to established/paid accounts; disposable-email rejection on instant publish; auto-suspend + full takedown on a second suspicious form per account; "Report this form" link in the public-form branding bar (2 distinct-IP reports auto-pause + alert); credential-pair tripwire pauses any free-tier form whose responses start looking like email+password pairs (3 strikes); admin POST /users/:userId/ban-takedown one-click action; daily review-queue SLA re-alert for anything pending >24h.

New

YouTube tutorial video pipeline + "How To Create a Form" video

New promo/ toolkit: promo/record/record.mjs (Playwright, drives production formbuilder.com with an injected visible cursor, records 1920×1080 beats with a marker manifest) and promo/remotion/ (Remotion 4 composition: editorial intro/end card, macOS browser frame, step captions with serif-italic accents, Ken Burns zooms, cross-fade/slide transitions, Nihilore CC-BY music bed). Builder footage recorded on production; respondent clip recorded locally (prod Turnstile correctly blocks headless submits). Output: promo/dist/how-to-create-a-form.mp4. Demo account [email protected] (pro, verified) with one live "Customer Feedback Survey" form remains on production for the video.

Security

Credential-collecting fields always block publishing — hard rule, never AI-adjudicated

Per policy, any text-input field whose label captures a password/passcode/PIN/OTP/CVV/seed phrase (including leetspeak and asterisk-obfuscated variants) returns a suspicious verdict in aiReviewFlaggedForm before the model is consulted, and the review prompt no longer allows "internal IT password form" as a benign rationale. Motivated by the backfill: the AI cleared a "Change Password" form collecting Old/New Password.

Fixed

Verification emails actually send now

Registration fired sendWelcome without ctx.waitUntil, so Cloudflare Workers cancelled the promise when the response returned: production email_delivery_logs show zero welcome/verification emails across all 290 signups since logging began April 30 (magic-link emails, which are awaited, sent fine). 57% of all users (455/804) are unverified as a result. The send is now wrapped in c.executionCtx.waitUntil (api/src/routes/auth.ts).

Fixed

Unverified users no longer locked out of sharing

The share link was withheld from unverified users purely client-side (the server never enforced it; published forms were always publicly reachable): the legacy builder showed a "Published (Private) — verify to unlock the shareable link" banner instead of the share panel, the publish modal warned the link was "locked until email verified", and the dashboard publish toggle hard-blocked with a dead-end toast. Combined with verification emails never sending, this stranded publishers with no URL — the main cause of the create→publish collapse (only 75 of 428 form creators ever published; 215 users abandoned drafts with 6+ fields). All three blocks removed; unverified owners of a published form now see a dismissible verify-email nudge with a working "Resend verification email" button (frontend/src/legacy/pages/FormBuilderPage.jsx, frontend/src/pages/DashboardPage.tsx).

New

Admin backfill endpoint POST /api/admin/users/backfill-verification

Batched send of the standard verification email to unverified active users who never received one (skips anyone with a logged sent verification email, so runs resume cleanly). Supports { limit, dry_run } plus targeting filters { min_fields, days } (only users owning a form with >= min_fields fields touched in the last N days). Built for the 455 users stranded by the dropped-email bug. Targeting dry-runs on July 23 showed the intended segment (5+ fields, 14 days) contains zero real users — everyone stranded is 30+ days stale (127 all-time, 33 within 180 days, 5 within 90) because the magic-link flow auto-verifies all recent serious builders. No live send has been fired.

Fixed

Security scanner no longer scans random field IDs

evaluatePublicPublishSafety passed field.name ?? field.id into the content scanner, but form_fields has no name column, so every field's UUID was scanned as content; hex IDs containing "2fa"/"2f4" (leetspeak-normalized) flagged benign forms as high-risk phishing (~1.5% chance per field) and permanently blocked publishing. Confirmed in production: a school enrollment form was blocked because a field ID contained -2fa8-.

Fixed

AI form generator reliability

Turnstile tokens are single-use but the frontend reused a consumed token on retry (guaranteed 403); tokens now reset after every attempt. Rate limit raised 2/min → 6/min (iterating users hit 429 on their third prompt). Claude call now retries once on 403/429/5xx (production 403s from Anthropic proved sporadic, not a dead key — last success July 23; same retry added to the AI publish review), model updated claude-sonnet-4-5claude-sonnet-5, and failure events now capture the server error message. NOTE: the dominant production failure (97 occurrences through July 21) is the Anthropic API rejecting CLAUDE_API_KEY with 403 "Request not allowed" — the key itself needs attention in the Anthropic console.

Fixed

Anonymous publish flow survives cross-device magic links

The builder draft only lived in localStorage, so opening the magic-link email on a different device (build on desktop, tap link on phone) silently lost the form. Drafts now ride along with the magic-link request and are stored server-side in KV (24h TTL); login returns the draft and the existing client-side save/publish flow runs from it. localStorage remains as fallback for pre-change links.

New

AI second-opinion review for flagged publishes

Forms flagged above "low" risk by the pattern scanner are now adjudicated by Claude (api/src/services/ai-review.ts) before blocking: benign verdicts publish immediately (scan recorded as approved/ai); suspicious verdicts or AI errors block as before and email ALERT_EMAIL_RECIPIENTS — which was "" in production (review emails never sent to anyone, review queue sat at 66 pending / 0 ever approved); now set to [email protected].

New

Admin backfill endpoint POST /api/admin/security/rescan-blocked

Batched re-scan of forms stuck with requires_review = 1 using the fixed scanner + AI review; benign forms are unblocked (flags cleared, scans approved) and owners get a "your form is ready to publish" apology email; suspicious forms stay blocked and are listed in the response. Supports { limit, notify, dry_run }.

New

Post-publish share moment

Publishing from the editor now opens a share modal (link, QR, embed, social) instead of just a toast; ShareModal extracted from the dashboard into frontend/src/components/ShareModal.tsx and the previously-dead ?published=true redirect param from the anonymous flow now triggers it too. Motivated by production data: 58 of 115 published forms had zero views ever, while forms with 5+ views got responses 70% of the time.

New

Response notifications on by default for verified owners

New forms created by a verified user get email_notifications_enabled = 1 with the owner as a verified recipient; when a user verifies their email, notifications switch on for their existing forms that never had recipients configured (api/src/services/default-notifications.ts).

July 22, 202611 updates
Security

JWT session revocation

  • Tokens now carry a per-user sv (session version) claim checked on every authenticated request (migration 0015)
  • Password change, password reset, and admin suspend now invalidate all outstanding tokens; self password change re-issues a fresh session
Security

PBKDF2 iterations stay at 100k — Workers platform cap discovered

A 600k raise was attempted per OWASP but Cloudflare Workers WebCrypto hard-rejects PBKDF2 above 100,000 iterations at runtime; reverted after it briefly broke production registration (caught and hotfixed within minutes during post-deploy testing). Raising further requires moving off WebCrypto.

Security

Rate limiting keyed on IP only

Rotating the User-Agent no longer resets a client's quota; rate_limits table DDL moved from runtime to migration 0016

Security

IPv6 SSRF fix in isPrivateUrl

Bracketed IPv6 hostnames ([::1], link-local, ULA) and IPv4-mapped IPv6 addresses are now correctly blocked when vetting user-supplied webhook URLs

Improved

iPhone field app redesigned in the editorial design language

Warm paper surfaces, charcoal actions, white field cards, quiet status badges, and full adaptive dark mode across every screen, driven by a new shared DesignSystem.swift. The Form Runner got three design passes: star ratings, tactile choice rows, focus-ring inputs, animated progress, scroll-to-first-error with haptics, and a sticky action bar. 42 tests pass; light/dark verified in the simulator.

Fixed

iPhone field app hardening after full code review

Drafts are removed once their response is queued (with swipe-to-delete and orphaned-attachment cleanup) closing a duplicate-submission gap; expired sessions return to login while keeping offline work on-device; sign-out warns about unsynced responses; sync now respects the API's 10-submissions/minute rate limit (429 pauses the batch, items stay pending); forms list follows pagination beyond 50 forms; hidden-field answers are excluded from submissions; numeric min/max validation rules are enforced; and the Turnstile sheet fits expanded challenges. 41 unit tests pass.

Fixed

Deploy scripts no longer require ripgrep

check-secrets.sh false-negatived every secret and blocked deploys on machines without rg; all deploy/preflight/parity scripts now use grep

Improved

Split api/src/routes/admin.ts (4,919 lines) into api/src/routes/admin/ modules

Mechanical move, route inventory verified identical

Improved

Removed unused Drizzle ORM

All DB access is raw D1 SQL; hand-written migration workflow unchanged

Improved

Frontend cleanup

Pruned 121 unreachable files under frontend/src/legacy/ (2.9MB → 556K), removed unrouted DashboardPageOld/MagicLoginPage, consolidated duplicate billing/analytics service shims

New

Unit tests for pure API modules

57 cases across crypto, validation, conditional-logic, and scoring via npm run test:api-units; surfaced the IPv6 isPrivateUrl gap fixed above

May 7, 202611 updates
New

Phase 3 enterprise ecosystem features

  • Moved SSO/SAML, mobile/offline/kiosk, and translation/localization/custom-code marketplace work to Phase 4 in the product roadmap
  • Added form version snapshots with owner-accessible version listing, detail, restore, and audit export routes
  • Added scoped developer API tokens with forms:read and responses:read abilities
  • Added /api/v1/forms and /api/v1/forms/{form_id}/responses public API endpoints with bearer-token auth and audit logging for response reads
  • Added docs/public-api.md with token creation, scopes, endpoint examples, and revoke guidance
New

Phase 2 product gap features

  • Added response workflow metadata for statuses, assignee emails, approval state, and response activity history
  • Added save-progress partial submissions with respondent resume links for forms that enable save_progress
  • Added server-side response PDF generation with generated document records
  • Added matrix, ranking, NPS, and score field support with response scoring metadata
  • Added conditional notification and redirect rules using the existing conditional-rule shape
New

Google OAuth verification documents

  • Added an internal Google OAuth verification checklist with redirect URI, scope justifications, privacy coverage, and demo video script
  • Updated the Help Center Google Sheets article with Google data access, sync behavior, and disconnect guidance
New

Phase 1 product gap features

  • Added persisted conditional logic support from the active builder through public form rendering and backend required-field validation
  • Added fixed-amount respondent payment fields backed by Stripe Checkout, pending response records, and webhook-confirmed paid status
  • Added submission integration dispatch for Google Sheets, Slack, Teams, and Zapier/Make webhook payloads with delivery logging
  • Added API-backed response filters and saved response views for owners
  • Added compact builder controls for payment fields and Slack/Teams/Zapier/Make webhook settings
New

Tally template gap additions

  • Crawled Tally's public template gallery and compared 154 visible templates against FormBuilder's 491 local templates using normalized title matching
  • Added 15 focused missing templates across quizzes, product research, NPS/churn feedback, remote work requests, RSVP/order collection, address collection, and legal consent/release forms
  • Added template data contract coverage requiring the selected Tally gap template IDs to remain present locally
Fixed

Google Sheets OAuth editor return and spreadsheet listing

  • Returned Google Sheets OAuth success and error results to the originating form editor when the connection starts from an editor
  • Added Drive metadata OAuth scope for listing available spreadsheet files before selecting a sheet tab
  • Turned on the Google Sheets integration toggle after Google account connection while keeping response sync inactive until a spreadsheet is selected
Fixed

Google Sheets OAuth invalid state and callback 404

  • Fixed OAuth state expiry storage to use the same ISO timestamp format as cleanup and validation so fresh Google Sheets connection states are not deleted immediately
  • Added a protected /settings/integrations callback landing route with Google Sheets connection success and error messaging
Fixed

Google API privacy policy coverage

  • Updated Privacy Policy and Terms pages to describe Google Sheets integration data use, Google API Services User Data Policy Limited Use commitments, and third-party integration responsibilities
Fixed

Google Sheets OAuth callback auth

  • Made the Google OAuth callback bypass app auth middleware and rely on the signed OAuth state, so Google's redirect can complete token exchange after authorization
  • Added regression coverage for the callback route and Google provider OAuth path
Fixed

Google Sheets OAuth connect route

  • Fixed the builder Google Sheets connect button so it opens the Worker OAuth route instead of a frontend path that returned 404
  • Aligned Google Sheets status and disconnect calls with the stored google OAuth provider key
  • Normalized spreadsheet and sheet-list API response handling in both Google Sheets integration components
Fixed

Reliable submission PDF downloads

  • Bundled jsPDF with the frontend app so individual response PDF downloads and PDF response exports no longer depend on runtime CDN loading
  • Removed jsPDF window-global fallback handling from the owner responses page while preserving the existing PDF layouts and download buttons
May 6, 20266 updates
New

Help Center visual refresh

  • Added a richer Help Center hero with a product guide map artifact, visible article/category metrics, and improved search presentation
  • Added category quick navigation and more distinctive article cards with quiet category accents
  • Reworked Help Center article pages with an article brief, desktop table of contents, enhanced step checklist, richer section treatments, and polished related article cards
New

Current-product Help Center rebuild

  • Replaced the static Help Center FAQ with a searchable category/article index backed by typed help content data
  • Added dedicated /help/:slug article pages for builder, publishing, responses, notifications, integrations, teams, billing, security, compliance, and MightyForms login workflows
  • Updated Help Center copy to match current product behavior, including 16 field types, PDF/Jotform/Typeform imports, verified notification recipients, Google Sheets, webhooks, custom domains, and current plan limits
  • Listed the visible builder field set on the field-types help article so customers can confirm supported inputs without opening the builder
  • Added sitemap entries for key Help Center articles
New

MightyForms acquisition transition surfaces

  • Added a public acquisition notice linking existing MightyForms customers to the legacy MightyForms app login
  • Added a MightyForms login helper link to the FormBuilder sign-in modal
  • Added a FormBuilder acquisition announcement/news page plus careers pages for the Customer Success Manager role
  • Added JobPosting structured data for the Customer Success Manager opening
  • Expanded the acquisition announcement and Customer Success Manager job details, and removed fake social proof from the About page (May 6, 2026 @ 1:48 PM CDT)
  • Updated the public footer copyright year to 2026 (May 6, 2026 @ 1:51 PM CDT)
  • Added a dedicated /news link to the public footer Company column (May 6, 2026 @ 1:53 PM CDT)
  • Collapsed public footer link groups into mobile accordions while preserving the desktop columns (May 6, 2026 @ 1:59 PM CDT)
Fixed

Template and public-form activation links

  • Made the top template workbench rows real links so Client intake, Patient intake, and Lead capture open representative templates instead of looking inert
  • Switched editor and legacy dashboard public links to the canonical forms.formbuilder.com helper for direct links, embeds, QR codes, and social sharing
  • Changed public Open form / View actions to deterministic same-tab navigation so users can reliably reach the live form
Fixed

Public form captcha and branding bar polish

  • Moved the Cloudflare Turnstile captcha below public form content so the form title and fields stay at the top of the page
  • Restyled the free-plan bottom branding bar with the warm FormBuilder surface, charcoal primary CTA, and quieter remove-branding action
Fixed

Help Center hero cleanup

  • Removed the horizontal category-navigation scrollbar from the middle of the Help Center page
  • Replaced the non-functional product-guide-map search-looking row with static recommended-path context
  • Made the product-guide-map workflow rows link to their primary help articles
May 5, 202621 updates
New

Anonymous builder publish polish

  • Tightened the anonymous publish ribbon height and changed the save reassurance to automatic-save language
  • Made the draft-state Publish button the strongest logged-in editor CTA while making Save a quieter operational action
New

First-time publish activation panel

  • Expanded the post-publish editor panel into a lightweight activation checklist that confirms form creation and publishing, then points new publishers toward sharing and receiving the first response
  • Added the public form URL inline with copy/open actions, kept Copy public link as the primary CTA, and left Send test response and View responses as secondary actions
  • Added post-publish responses-view tracking so activation analytics can distinguish link copy, test email, and response-review intent
New

Admin product analytics command center

  • Added a first-party admin command-center endpoint with benchmarked scorecards, previous-period deltas, alerts, funnels, segments, top lists, PQLs, security summary, and recent product events
  • Rebuilt the Admin Analytics page into tabbed operational views for Executive, Activation, Forms & Responses, Revenue, Acquisition, Security & Quality, Users / PQLs, and Events
  • Added directional industry-guide status bands so key metrics show whether they are below target, watch-worthy, healthy, or above target
  • Surfaced action lists for hot PQLs, stalled publish flows, forms with traffic but no submissions, high-abandonment forms, and the security queue
New

Anonymous publish funnel analytics

  • Added first-party product events for anonymous publish clicks, publish modal opens/closes, email submission/sent/failure, and post-auth publish completion/failure
  • Added anonymous publish readiness metadata using safe counts/booleans/source labels without storing emails, field answers, prompts, or form content
  • Added an admin anonymous publish funnel endpoint with journey-scoped counts, drop-offs, and rates for publish click, modal submit, email completion, publish success, and post-publish activation
  • Added an Admin Analytics panel for the anonymous publish funnel so activation drop-off can be reviewed from the admin UI
New

Daily activity email summary

  • Added a daily Cloudflare Worker scheduled email summary for [email protected] covering the previous 24 hours of signups, forms created, publish/share activity, public form activity, and responses collected
  • Added privacy-safe summary queries that omit submitted response answer payloads while reporting owners, form titles, field counts, response counts, and activation signals
  • Added an admin-only manual test-send endpoint for sending the same past-24-hours report on demand
Fixed

Anonymous template magic-link duplicate and publish-state handoff

  • Prevented existing form edit routes from loading anonymous/template draft state while the nested legacy auth provider is still catching up
  • Made anonymous publish-after-auth an explicit modal intent and cleared stale publish intent before plain save/signup magic-link requests
Fixed

Self-serve Pro upgrade checkout paths

  • Wired authenticated Billing and Subscription upgrade CTAs into the shared Stripe checkout modal so Free users can start payment from account settings
  • Fixed Pricing page direct billing/auth API calls to use active /api/* routes
  • Aligned subscription checkout payment-intent confirmation between the Worker billing route and frontend payment modal
  • Reconciled Stripe subscription webhooks using the configured Pro price ID instead of inferring plans from price ID text
Fixed

Anonymous template signup duplicate saves

  • Added a shared anonymous-draft save claim so magic-link signup and legacy builder save paths cannot create multiple owned forms from the same local draft
  • Kept the magic-link callback as the primary owner of post-auth anonymous draft persistence and guarded the legacy template/post-auth fallback paths
Fixed

Anonymous publish ribbon hierarchy

  • Simplified the anonymous builder ribbon into a cleaner left message and right-side Ready badge plus Publish form CTA
  • Removed the duplicate anonymous publish CTA from the top editor navigation so the eye has one primary pre-modal action
  • Removed the smaller Draft complete pill from the publish modal and kept the stronger readiness card as the single success signal
  • Refined reassurance copy to Everything will stay exactly as you built it
Fixed

Anonymous publish modal launch polish

  • Added a subtle launch/success treatment to the anonymous publish gate with a draft-complete badge, checkmark accent, and readiness signal
  • Widened the publish-gate modal so the launch copy has more room and reads less like an administrative form
  • Removed the duplicate publish button from the anonymous builder ribbon, leaving the editor navigation as the single primary publish action before the modal
  • Replaced Your draft stays exactly as it is with the smoother reassurance We’ll save everything exactly as it is
Fixed

Anonymous builder publish gate conversion copy

  • Reframed the anonymous publish/auth modal around the user's outcome with Your form is ready to go live
  • Changed publish-gate benefits to emphasize keeping work safe, getting a shareable link, and tracking responses
  • Changed the publish-gate CTA from magic-link language to Create free account & publish
  • Updated the anonymous builder ribbon to say progress is saved locally while building, without making the draft feel temporary or fragile
  • Reduced visual weight on the secondary anonymous Sign in link so Publish form remains the primary activation action
Fixed

Anonymous builder activation ribbon

  • Replaced inert Save account, Publish, and Share link ribbon labels with passive activation copy so they no longer look clickable
  • Kept Publish form as the only interactive ribbon action for anonymous builder sessions
Fixed

Anonymous builder publish modal cleanup

  • Aligned the anonymous builder publish/auth modal styling with the current warm-paper and charcoal product chrome
  • Changed the anonymous editor primary CTA to Publish form and kept the publish-gate copy focused on launch progress
  • Added visible copy feedback for share-link and embed-code actions in the share modal
  • Fixed legacy builder fallback paths that referenced undefined setForm and setAuthMode state setters
Fixed

AI Turnstile verification UX

  • Hid the homepage AI generator Turnstile widget until a visitor clicks Generate with a valid prompt
  • Automatically continues AI form generation after Turnstile returns a token, while preserving the existing verification requirement
  • Clears pending verification state when a token expires or verification is rejected so visitors can retry cleanly
Fixed

Security review hardening

  • Tightened import URL validation to use parsed supported hosts and paths, and to reject redirects to unsupported hosts before AI ingestion
  • Rejected unconfigured Stripe price IDs server-side for subscribe, plan preview, and switch-plan billing flows
  • Added the missing ownership check before returning prefill test mappings
  • Added baseline security headers for the Worker API and Cloudflare Pages, while keeping public embed routes out of the admin frame-blocking rule
  • Enabled production Turnstile enforcement in Worker config and made the deploy secret check require TURNSTILE_SECRET_KEY
  • Updated the deploy helper to pass TURNSTILE_SITE_KEY from .env into the frontend build as VITE_TURNSTILE_SITE_KEY
Fixed

Admin security suspension pending-review cleanup

  • Fixed user suspension so pending security scans for that user's forms are closed as flagged and no longer remain in Pending Reviews
  • Tightened the Pending Reviews dashboard count/list to only include scans for active-owner, non-deleted forms
Fixed

Admin security in-page form review

  • Replaced the owner-only Preview/Edit security review link with an in-page read-only admin form review modal for unpublished and under-review forms
  • Kept public form links available only when the reviewed form is actually public
Fixed

Admin security review workflow usability

  • Improved admin security review workflow with public-form and editor links, visible scan findings, direct form deactivation, and owner suspension actions
  • Updated admin user suspension so suspended users are not notified and their active public forms are unpublished/deactivated automatically
Fixed

Admin security review data

  • Fixed admin security review data so the overview Pending Reviews and Recently Flagged Forms lists include real rows instead of only counts
  • Normalized security scan rows with nested form/user/reviewer data and scan timestamps so the Security Scans tab can show form titles, owner emails, and valid scanned dates
Fixed

Admin security blank-page crash

  • Fixed the /admin/security blank-page crash caused by the security dashboard API returning top-level numeric flagged_forms; the overview now receives array list fields for rendering and separate count fields for summary values
Fixed

Template search analytics and admin security dashboard access

  • Fixed template search analytics logging so the legacy frontend /api/template-search payload using search_term is accepted and records the supplied result count
  • Fixed the admin template search analytics API response to expose totals, zero-result metrics, search-term aliases, filters, and pagination fields used by /admin/template-searches
  • Fixed the initial /admin/security dashboard API so admins who can access the admin security route can load the overview without needing an extra manage_security permission
May 4, 202613 updates
Fixed

Production Pages branch deploy targeting

  • Updated the deployment script so production frontend deploys explicitly publish the Cloudflare Pages main branch instead of inheriting the local checkout branch
  • Redeployed the paid conversion frontend bundle to https://formbuilder.com and verified the live asset manifest contains the new HIPAA coming-soon and payment configuration copy
Fixed

Paid conversion entitlements and funnel analytics

  • Added a shared frontend plan catalog so Pricing, Billing, Subscription, Payment, Dashboard, and AI form-limit surfaces use the same Free/Pro/HIPAA prices and limits
  • Kept Pro as the self-serve paid plan using configured Stripe price IDs, and changed HIPAA to a coming-soon/contact-led plan instead of self-serve checkout
  • Added backend plan-limit helpers and enforced Free/Pro form creation limits across form, template, import, and duplicate creation paths
  • Added monthly public response-limit enforcement for form owners and records limit_hit events when limits block usage
  • Added paid conversion funnel analytics from existing product_events and surfaced it in the admin analytics page
Fixed

Anonymous signup flow entry points

  • Added app-level compatibility for older public CTAs that call window.showAuthModal, so active public routes open the current auth modal instead of silently doing nothing
  • Routed anonymous Free, Pro, and final pricing CTAs into the draft-first create-form flow at /?createForm=true
  • Made pricing BAA, compliance, and enterprise CTAs use deterministic in-app contact routes
  • Passed URL/PDF intent from the create-form modal into the import wizard so each import button opens the expected starting point
  • Aligned BAA page pricing copy with current Pro $39/month and HIPAA $99/month plans
Fixed

Magic link production domain routing

  • Changed production Worker FRONTEND_URL ordering so emailed auth links use https://formbuilder.com as the primary frontend origin instead of the Cloudflare Pages develop hostname
  • Removed the registration verification email fallback that pointed to https://develop.formbuilder-3n1.pages.dev
  • Updated frontend parity coverage to prevent production emailed auth links from using the develop Pages hostname as the primary origin
  • Deployed Worker version 8f32992e-7cd5-4f81-a86d-26ba541efa84 with the corrected production frontend URL ordering
New

Public trust page Cloudflare copy alignment

  • Added public trust/legal contract coverage so active pages do not advertise retired Google Cloud infrastructure
  • Updated BAA, DPA, HIPAA, Security, and Subprocessors public-page copy to refer to the current Cloudflare platform and infrastructure wording
  • Preserved historical migration references in changelog and project planning history
New

Marketing page distinctiveness and template fixes

  • Refreshed DESIGN-GUIDELINES.md to document the current warm-paper, charcoal, slate/stone, Lucide-icon, product-artifact public page direction instead of the retired blue/purple SaaS style
  • Added distinct product artifact previews to the Templates, Pricing, and Features heroes so those core marketing pages feel less templated and more specific to their job
  • Added template data contract coverage requiring unique template IDs across all category source files
  • Fixed duplicate Real Estate template IDs that caused React duplicate-key warnings on the Templates page
  • Removed the stale Built on Google Cloud item from the footer compliance bar
New

Non-admin product chrome final alignment audit

  • Extended non-admin style contract coverage across response manager, public form utility states, renderer controls, import wizard, payment modals, Google Sheets integration, prefill configuration, cookie consent, reset password, and active legacy editor subcomponents
  • Replaced remaining blue/purple/pink product chrome in those surfaces with charcoal, slate, stone, warm paper, and restrained semantic status colors
  • Preserved admin pages and customer-controlled form theme/color palette values as explicitly out of scope
New

Form editor command-center redesign

  • Restyled the active /forms/:id/edit builder route with warm-paper side rails, charcoal action chrome, stronger central canvas hierarchy, and homepage-aligned slate/stone surfaces
  • Replaced visible editor emoji controls with Lucide icon tooling across the editor navigation, field palette, AI suggestions, field actions, publish/share controls, and key editor modals
  • Removed remaining blue/purple product chrome from the active form editor and share modal while preserving form editing, publishing, preview, AI generation, and settings behavior
  • Added focused contract coverage for the active form editor so old blue/purple treatments and missing command-center copy do not return
New

Shared product chrome purple cleanup

  • Removed remaining purple/blue-gradient product chrome from the AI form generator used inside the create-form modal
  • Restyled the floating support widget, support modal, sales bar, and resume-progress modal to use charcoal, warm paper, slate, stone, and restrained semantic status colors
  • Updated AI-generated default form theme colors away from purple toward the current charcoal/warm-paper brand direction
  • Added focused contract coverage for active shared product chrome so purple/violet/indigo/blue-gradient treatments do not return to these shared surfaces
New

Remaining logged-in product page style rollout

  • Restyled the non-admin logged-in product pages outside the form editor: settings, profile, billing, subscription, subscription success, teams, team workspace/folders/templates, custom domains, and recycling bin
  • Updated the shared settings shell with the authenticated warm-paper command-center treatment, grid/noise texture, slate typography, and charcoal active navigation
  • Replaced old blue/purple buttons, badges, focus rings, gradient panels, and modal surfaces with slate, stone, warm paper, charcoal CTAs, and restrained semantic status colors
  • Added focused logged-in page style contract coverage to prevent the retired blue/purple product-page treatment from returning
New

Dashboard command-center redesign

  • Rebuilt /dashboard around a warm-paper command-center shell with homepage-style grid/noise texture, charcoal primary actions, and operational summary cards
  • Added a momentum-oriented next-best-action treatment for limit, first-response, empty, and unread-response states while preserving existing dashboard actions
  • Restyled dashboard form cards, segmented controls, share modal, test-email modal, empty state, skeletons, and account-limit meters away from retired blue/purple gradient treatments
  • Added focused contract coverage to keep the authenticated dashboard aligned with the new command-center direction
New

Auth and form-creation modals editorial rebuild

  • AuthModal: removed the blue→purple gradient header and wand icon entirely; rebuilt as an editorial invitation card on warm paper (#FBF9F4) with serif italic accent ("Sign in. / Pick up where you left off.") and charcoal slate-950 primary CTA
  • AuthModal: switched terminology from "magic link" to "secure sign-in link" in body copy and CTA; removed double-period awkwardness
  • AuthModal: added body scroll lock, Esc-to-close, autofocus email input, accessibility roles
  • FormCreationModal: replaced blue-600 primary button with charcoal slate-950 card containing warm amber spotlight on hover and italic serif "most popular" tag (replacing the green floating "Recommended" badge)
  • FormCreationModal: rebuilt the AI sub-modal — was a purple→indigo gradient header, now matches the editorial paper card
  • FormCreationModal: import options consolidated into a single grouped card with two underline buttons; "or start blank" demoted to a quiet italic serif link in the footer
  • Added shared modal entrance animation (backdrop fade, card scale-up) and warm shadow-editorial shadow used by both
  • Backdrop changed from cool gray-900/75 to warm rgba(14,10,6,0.62) with grain overlay and backdrop-blur
New

Nav and footer editorial repalette

  • Nav primary CTA changed from bg-blue-600 to bg-slate-950 to match homepage
  • Avatar circle moved from blue-600 to slate-950
  • Solutions dropdown hover states moved from blue tint to warm stone
  • Logo wordmark now uses serif italic accent ("Form" + italic "builder") to match homepage typography
  • Nav background now translucent white with backdrop blur and slate-tinted hairline border
  • Footer compliance bar moved from cool gray-50 to warm paper #FBF9F4 with emerald compliance dots
  • Main footer now charcoal #0E0E0E with grain overlay and warm amber spotlight, matching the homepage final CTA
  • Footer uppercase column headings styled with editorial tracking and white/50 secondary tone
  • Removed cool blue/gray-900 holdovers across both components
May 3, 202617 updates
New

Public frontend homepage-style rollout foundation

  • Added homepage editorial public-page guidance to DESIGN-GUIDELINES.md for warm paper surfaces, slate/stone typography, ink CTAs, Lucide icons, and draft-first conversion framing
  • Added shared public-page primitives for heroes, section headers, cards, CTA bands, and trust lists under frontend/src/components/public/
  • Added focused public-style contract coverage to keep the rollout guidance and primitives in place before page-by-page restyling begins
  • Updated the frontend parity contract to protect the current editorial auth modal styling instead of the retired blue-to-purple gradient treatment
New

Core public conversion page editorial hero pass

  • Applied the shared public-page hero primitive to Features, Pricing, Templates, Template detail, and AI Form Generator pages
  • Replaced the old blue/purple public hero and CTA gradient treatment on the core conversion pages with the homepage warm-paper and charcoal editorial surfaces
  • Added contract coverage requiring these core public pages to use the shared homepage editorial primitives before broader page-by-page restyling continues
New

Core public conversion page internal element style pass

  • Extended the public style contract to scan core public page internals for retired blue/purple treatments, gradient utilities, emoji visual treatments, and template/category emoji icon render paths
  • Reworked Pricing page cards, enterprise panel, comparison table values, final CTA, and billing/downgrade modal treatments to use slate, stone, warm paper, and text/icon primitives
  • Reworked Templates page welcome modal, search panel, AI panel, popular template cards, category cards, feature blocks, and upgrade modal to remove emoji-led visuals and old focus/gradient colors
  • Reworked Template detail stat strip, HIPAA panels, related-template cards, and HIPAA conversion banner to match the homepage editorial palette while preserving existing content and actions
New

Public solutions pages editorial internal style pass

  • Added public-style contract coverage for the Solutions overview and seven individual solution pages
  • Reworked solution heroes, industry cards, template cards, stats/testimonial bands, feature grids, use-case cards, compliance blocks, and final CTAs away from blue/purple gradients and emoji-led visuals
  • Preserved all existing solution copy, template links, start-building actions, and industry-specific sections while aligning surfaces to warm paper, charcoal, slate, stone, and neutral badge treatments
New

Public trust and legal pages editorial internal style pass

  • Added public-style contract coverage for Security, HIPAA, BAA, DPA, GDPR, Privacy, Terms, and Subprocessors pages
  • Reworked trust/legal heroes, evidence panels, compliance cards, pricing/BAA blocks, legal callouts, subprocessors sections, contact panels, and final CTAs away from blue/purple gradients and emoji-led visuals
  • Preserved compliance/legal copy, links, contact paths, and route behavior while aligning the visual language to warm paper, charcoal, slate, stone, and restrained proof blocks
New

Remaining public frontend pages editorial internal style pass

  • Added public-style contract coverage for About, Contact, Help, Blog index/post, blog components, category template pages, magic-link login, email verification, test embed, and the secondary /new homepage route
  • Reworked company/support/blog/category-template internal elements, cards, forms, category badges, newsletter CTAs, placeholders, utility buttons, and modal panels away from blue/purple gradients and emoji-led visuals
  • Replaced the old standalone /new homepage implementation with the current homepage component so the public site has one homepage style source
  • Preserved public content, contact form behavior, FAQ/search behavior, blog API loading, category template preview/use behavior, magic-link handling, and verification/test utility route behavior
New

Homepage editorial color repalette

  • Stripped every blue→purple/indigo/violet gradient and aurora orb that read as "generic AI app"
  • Replaced cool slate hero with warm paper (#FBF9F4) and a single warm-haze + ink-haze atmospheric layer
  • Headline italic accents now use serif Georgia in stone-600 instead of animated blue→purple gradient text
  • Use-case and trust cards use cream icon plates (#FBF9F4) with neutral ink rings instead of blue-50→indigo-50 gradient plates
  • Confidence cards swapped blue gradient bg-clip numerals for sepia serif italic numerals (01/02/03)
  • Final CTA rebuilt as true charcoal (#0E0E0E) with warm amber radial spotlights instead of navy→blue with cool aurora; primary CTA is now solid white-on-black instead of multi-color gradient
  • Pulse-ring badge dot moved from blue to emerald to break the monochrome blue accent cliché
  • Section transitions use restrained ink hairlines instead of colored divider gradients
  • Shimmer placeholder bars desaturated from blue tint to neutral slate
New

Homepage cinematic visual pass

  • Replaced flat hero gradient with layered aurora orbs, soft grid, and film-grain overlay to remove the "AI slop" gradient look
  • Added animated cinematic gradient on key headline phrases ("60 seconds", "workflow", "matter", "Decide later")
  • Rebuilt the draft preview card with window chrome, traffic-light dots, floating "AI drafted" chip, sweep highlight, shimmering field placeholders, animated typing caret, and gradient step badges
  • Introduced staggered fade-up entrance animations on hero copy and IntersectionObserver scroll-reveal across all sections
  • Upgraded use-case and trust cards with hover lift, glow shadow, gradient icon plates, and rotating icon affordance
  • Added numbered (01/02/03) confidence cards with hover glow rather than flat bordered boxes
  • Rebuilt final CTA as a dark cinematic stage with radial spotlights, grid mask, gradient-bordered glow CTA button, and grain texture
  • Added gradient divider-fade lines between sections and respected prefers-reduced-motion for accessibility
  • All copy, layout, and section structure preserved per request — visual treatment only
New

Homepage confidence sections

  • Added a compact "What you can build" section for common form workflows without pushing visitors away from the creation path
  • Added a compact business-ready trust section for secure responses, HIPAA-ready plans, branding, teams, and response management
  • Added contract coverage to keep pricing off the homepage during this activation-first pass
New

Homepage activation redesign

  • Rebuilt the homepage around an inline AI form prompt so visitors can create a draft before signup
  • Added fast-start form chips for client intake, lead capture, event registration, and HIPAA patient workflows
  • Added a persistent public navigation Create form action that opens the existing creation flow
  • Added focused contract coverage for homepage activation copy, modest trust proof, and create-modal hierarchy
Improved

Anonymous activation and post-publish conversion UI

  • Added a guest-builder activation path that shows draft progress and changes the primary CTA to save and publish the form
  • Preserved the anonymous draft through magic-link signup while setting the post-auth action to publish
  • Added a post-publish editor panel with copy-link, send-test, and view-responses actions to help users collect their first response faster
  • Added focused growth-event contract coverage for the anonymous activation and post-publish UI
Improved

Create form modal hierarchy

  • Simplified the create modal around AI as the recommended path, templates as the secondary path, imports as utility actions, and blank creation as a low-emphasis option
  • Added explicit AI generator event source support so homepage prompt events can be measured separately from other AI entry points
Fixed

Fast Cloudflare deploy targets

  • Added API-only, frontend-only, and full-stack deploy commands so simple backend changes do not rebuild or redeploy the frontend
  • Updated the deploy helper to default to Pages project formbuilder, use the repo Wrangler binary for Pages deploys, and set sandbox-safe Wrangler/npm cache paths
  • Documented when to use each deploy target
Fixed

Admin AI Logs data display

  • Normalized /api/admin/ai-logs list and detail responses so the active admin page receives valid generated dates, prompts, generated form titles, field counts, user info, and generated form JSON from the stored D1 log rows
  • Added AI log chart data and root pagination fields to match the frontend contract
  • Added focused admin contract coverage to prevent regressing back to raw ai_form_logs storage fields
Fixed

GA4 manual page-view collection

  • Verified against official Google Analytics documentation that manual SPA page views should disable automatic send_page_view and send gtag('event', 'page_view', ...)
  • Updated route-driven page-view tracking to send explicit GA4 page_view events with page_location, page_path, and page_title
  • Matched the standard Google tag queue by pushing the JavaScript arguments object into dataLayer instead of a rest-parameter array
  • Deferred route page-view dispatch until the downloaded Google tag script has loaded, retaining the current route as a pending page view during startup
  • Updated frontend parity coverage to prevent regressing back to a metadata-only gtag('config', ...) call that does not emit a page-view collection request
Fixed

Ignored local Claude worktrees

  • Added .claude/worktrees/ to .gitignore so assistant-created nested worktree checkouts do not appear as untracked project files or get included in commits
New

Conversion funnel and product event instrumentation

  • Added first-party product_events storage for owner activation, public respondent, and monetization funnel events with indexed user, anonymous, journey, form, event, and timestamp fields
  • Added a validated /api/events endpoint with optional auth, rate limiting, server-derived request context, and sensitive metadata filtering
  • Added server-side events for form creation, publish success, publish review blocks, public submissions, and first response received
  • Added a consent-aware frontend product event client that records durable API events and forwards eligible GA4 events
  • Instrumented create intent, create method selection, AI generation, magic-link auth completion, anonymous draft save, dashboard publish/share/test/response/limit actions, and public form start/progress/validation/abandon/submit events
  • Added an admin growth-funnel API for activation step counts and conversion rates
  • Added focused growth event contract coverage for the durable event spine and critical funnel instrumentation
May 2, 20266 updates
New

Published blog content refresh

  • Refreshed all 49 published blog posts in production Cloudflare D1 with integrated 2026 guidance, current source links, updated titles, SEO metadata, excerpts, and read times
  • Added a repeatable blog refresh script and audit inventory under migration-reports/blog-refresh-20260502/
  • Preserved existing slugs and article bodies while adding fact-check context for comparison posts, Google Forms tutorials, WordPress form posts, payments posts, Wix/Shopify/Microsoft Forms coverage, and evergreen form-building guidance
  • Removed standalone update-note language so refreshed posts read as current 2026 articles rather than old articles with appended update sections
  • Completed a final body QA pass to remove remaining stale 2020-2024 references, outdated exact-price claims, old launch-year language, and visible source-note sections from the published article bodies
New

MightyForms template migration mapping and templates

  • Added a MightyForms-to-FormBuilder template mapping report under migration-reports/mightyforms-template-comparison/
  • Added 216 generated MightyForms-derived templates and mapped 27 MightyForms template detail URLs to existing FormBuilder templates
  • Imported the updated template library into production D1 and deployed the updated frontend bundle to Cloudflare Pages
New

Full MightyForms blog import

  • Imported all 49 collected MightyForms blog posts into production D1 under their mapped FormBuilder /blog/... URLs
  • Uploaded and verified 567 referenced article image URLs on the owned files.formbuilder.com R2-backed domain
  • Added direct R2 S3-compatible uploads and existing-object checks to make the blog import resumable without repeatedly reuploading already-copied images
  • Expanded importer validation across all posts to prevent duplicate leading H1s, repeated cover images, crawler audit sections, stale previously MightyForms copy, and old MightyForms URLs in article bodies
Fixed

Google Analytics page-view tracking

  • Updated GA4 SPA page-view tracking to use gtag('config', measurementId, ...) with page_location, page_path, and page_title
  • Kept the initial GA4 load from sending an automatic page view so route-driven tracking remains the single source of page-view events
  • Added frontend parity coverage to prevent regressing back to bare page_view events without full GA4 page metadata
  • Deployed Worker version beeec811-483f-4d2e-af2e-63962c9a41a9 and Pages build https://c4369ba5.formbuilder-3n1.pages.dev
Fixed

Public template auth redirect loop

  • Fixed public template pages redirecting to the homepage sign-in modal after the logged-out /api/auth/me probe returned 401
  • Added template routes to the public auth-redirect suppressor and prevented auth probe failures from triggering global login redirects
  • Added regression coverage so public template pages stay public when a visitor is logged out
Fixed

MightyForms blog pilot article rendering cleanup

  • Removed imported source H1 headings from the beginning of blog post bodies so titles do not render twice beneath the blog page title
  • Removed the repeated leading body image when it matches the post cover image, keeping the featured image in the page hero only
  • Added a D1-only reimport mode to skip R2 image uploads when reprocessing already-uploaded pilot images
  • Reimported the 3-post pilot with cleaned body content while preserving existing owned R2 image URLs
May 1, 202619 updates
New

MightyForms blog pilot import

  • Added a repeatable MightyForms blog import script with validate/import modes, 3-post pilot limiting, D1 upserts, seeded-post removal, and Cloudflare R2 image uploads
  • Imported the first 3 MightyForms blog posts into production and removed the two seeded FormBuilder example posts
  • Uploaded 22 referenced pilot images to the owned Cloudflare R2-backed files.formbuilder.com domain under blog/mightyforms/
New

Blog redesign for signup conversion

  • Redesigned /blog index with featured-post hero, category pills, post cards with covers and read time, newsletter banner, and end-of-page signup CTA
  • Redesigned /blog/:slug post page with markdown rendering, sticky table of contents, author bio, share buttons, inline CTA, sidebar newsletter capture, and related posts
  • Added react-markdown, remark-gfm, and @tailwindcss/typography for editorial post styling
  • Added Article JSON-LD structured data on post pages
  • Added migration 0009 for blog cover image, category, tags, read time, and newsletter subscriber storage
  • Added POST /api/public/newsletter/subscribe with optional Beehiiv sync when secrets are configured
  • Updated the admin blog editor with cover image, category, tags, read time, markdown, and CTA marker support
  • Applied production D1 migration 0009_add_blog_extras_and_newsletter.sql, deployed Worker version a726592e-ff63-48a5-8dca-1fce1f0374ae, and deployed Pages build https://22bf0edc.formbuilder-3n1.pages.dev
New

MightyForms blog content capture archive

  • Captured the MightyForms KEEP blog mapping locally under migration-reports/mightyforms-blog-content/
  • Stored raw HTML, extracted content HTML, markdown-like text, metadata, manifests, and in-post image assets for migration review
  • Downloaded 593 images from the mapped blog URLs and 31 images from recovered live variants for two mapped URLs that now return 404
New

Blog and admin post management

  • Added a public /blog index and /blog/:slug post route without adding public navigation or footer links yet
  • Added D1-backed blog post storage with two seeded example posts
  • Added public published-post read endpoints and admin CRUD endpoints for blog post management
  • Added an admin Blog console for creating, editing, publishing, and deleting posts
New

Confirmed signup admin email notification

  • Added an admin email to [email protected] when a user confirms signup by verifying through a magic link or verification link
  • Guarded magic-link notifications so repeat logins by already verified users do not count as new confirmed signups
  • Added focused auth and email-service contract coverage for confirmed signup notifications
New

Google production backup for post-cutover decommission

  • Backed up the retired Google Cloud project formbuilder-464015 after production traffic moved to Cloudflare
  • Exported the old production and development Cloud SQL PostgreSQL databases to restorable SQL dumps
  • Captured Cloud Run, Cloud SQL, Secret Manager, IAM, Artifact Registry, Cloud Build, bucket, domain mapping, and recent log metadata
  • Archived the backup locally under backups/google-cutover-20260501-1117/ and uploaded a verified copy to Cloudflare R2 bucket formbuilder
  • Deleted the old Google Cloud Run services/jobs, Cloud SQL instances, Artifact Registry repository, Storage buckets, and captured Secret Manager secrets after verifying the R2 backup and Cloudflare production health
  • Added a Google decommission checklist and ignored local backups/ artifacts so secret-containing backups are not committed
New

Cloudflare D1 backup retention worker

  • Added a separate scheduled Cloudflare backup Worker for production D1 SQL exports
  • Added daily R2 backup storage with adjacent JSON manifests containing bookmark, source database, size, and checksum metadata
  • Added retention planning for 30 daily backups, then one weekly backup through day 365
  • Documented backup bucket setup, required D1 export API token secret, deployment approval, and restore rules
  • Created R2 bucket formbuilder-backups, set the production D1_EXPORT_API_TOKEN secret, and deployed backup Worker version b04a6a91-ef1a-40cc-a181-812f8d589cce with cron schedule 0 8 *
  • Ran a live production D1 backup and verified the remote R2 SQL export and manifest by downloading both objects and matching checksums
Improved

Cloudflare root migration cleanup

  • Promoted the active Cloudflare app from cloudflare/ to root-level frontend/, api, scripts, backup-worker, parity, and migration-reports folders
  • Removed retired Laravel/PHP, Google Cloud, AWS/Elastic Beanstalk, Docker/PHP, and Laravel Mix deployment artifacts from the root workspace
  • Replaced root development and deployment docs with the active Cloudflare workflow while preserving the old Google deployment notes under docs/legacy-google-deployment.md
  • Updated root package scripts, env examples, script paths, and ignore rules for the Cloudflare root layout
Improved

Cloudflare production DNS cutover

  • Cut formbuilder.com and www.formbuilder.com over from Google Frontend/Laravel to Cloudflare Pages project formbuilder
  • Added api.formbuilder.com as the production Worker API hostname and routed it to Worker formbuilder-api
  • Updated the Cloudflare Worker production APP_URL and Cloudflare frontend production VITE_API_URL to use https://api.formbuilder.com
  • Deployed Worker version 5f43c81a-aef9-474a-bfc9-3458919a81bc and Pages build https://97eb745e.formbuilder-3n1.pages.dev
  • Recorded rollback DNS details in cloudflare/cutover-rollback-20260501-1030.md
Fixed

MightyForms blog pilot cleanup

  • Removed crawler-generated Downloaded Images audit sections from imported blog content
  • Removed stale previously MightyForms asides before rebranding so imported posts do not render confusing previously FormBuilder text
  • Reimported the 3-post pilot with cleaned content while keeping images on the owned files.formbuilder.com R2 domain
Fixed

Blog anonymous auth redirect

  • Fixed /blog and /blog/:slug for anonymous visitors by treating blog pages as public paths in the global auth redirect guard
  • Added regression coverage so blog routes do not redirect to the homepage sign-in modal after /api/auth/me returns 401 for anonymous sessions
Fixed

Homepage magic-link signup redirect

  • New users signing up from the homepage now return to the homepage with the create form modal open
  • Existing users signing in from the homepage now land on the dashboard
  • Anonymous form-builder drafts still save and reopen after magic-link login when the user was actively editing a form
Fixed

Cloudflare root follow-up cleanup

  • Removed the vulnerable expr-eval frontend dependency from the legacy form renderer calculation path
  • Replaced formula evaluation with a local arithmetic-only parser for numbers, field variables, braces, parentheses, and basic operators
  • Retired the old Laravel parity audit script now that the Laravel source tree has been removed
  • Updated historical parity docs to use root-level Cloudflare paths instead of the retired cloudflare/ folder layout
Fixed

Cloudflare public form hardening

  • Confirmed the Cloudflare stack sends app emails through the centralized Cloudflare Email Sending service
  • Added per-recipient unsubscribe links to form response notification emails using existing notification recipient unsubscribe tokens
  • Exposed public form owner plan metadata so the frontend can decide whether branding should be shown
  • Redirected main-domain public form and embed routes from formbuilder.com / www.formbuilder.com to forms.formbuilder.com
  • Added a Cloudflare zone redirect rule so main-domain /f/* and /embed/* requests redirect at the edge before the SPA loads
  • Added a bottom FormBuilder branding bar on free/non-paid public forms with create-account and remove-branding CTAs
  • Deployed Worker version 2a21c73b-2204-491a-b428-1647ae765a1d and Pages build https://6c7f1a8b.formbuilder-3n1.pages.dev
Fixed

Cloudflare search traffic page routes

  • Fixed legacy category template URLs from Search Console traffic, including /financial-templates and related category pages, so they render the intended Cloudflare category content instead of redirecting back to /templates
  • Added Cloudflare frontend redirects for legacy /hipaa/baa and /download traffic URLs to real marketing pages
  • Added regression coverage for the search-traffic route aliases
Fixed

Cloudflare public forms subdomain CORS

  • Added https://forms.formbuilder.com to the production Worker frontend origin configuration and explicit CORS allowlist
  • Added regression coverage so the public forms host remains allowed by Worker CORS/frontend configuration
  • Deployed Worker version 6bad0dcd-36f8-4c38-a89b-688108a07229
  • Verified forms.formbuilder.com public form loading and browser response submission against the live production API
Fixed

Cloudflare production data import repair

  • Added final production import repair tooling for PostgreSQL-to-D1 cutover, including exact production user ID preservation, duplicate D1 email archiving, user foreign-key remapping, and deterministic form slug collision handling
  • Repaired remote D1 production data from Google Cloud SQL and imported 8,306 production-source rows with zero final repair errors
  • Archived 8 duplicate same-email D1 user records to formbuilder.local placeholder emails so the production user IDs own the real account emails
  • Updated the logged-in smoke test default user ID to the restored production [email protected] user ID
  • Final production reconciliation reported no missing source records and no form field, response, notification, or zero-field production-form mismatches
Fixed

Cloudflare cookie consent and analytics loading

  • Scoped the active Cloudflare cookie banner to GDPR-required regions using Worker cf-ipcountry geo metadata
  • Replaced passive continued-use copy with explicit Accept All and Necessary Only choices
  • Added consent-aware GA4 loading for the Cloudflare frontend using the migrated G-3CJVHVS4EG measurement ID
  • Removed the third-party client IP geo fallback so region detection stays on the Cloudflare Worker before consent
  • Deployed Worker version 8063d6df-6994-449e-b83e-7107a88f1213 and Pages build https://4243cb62.formbuilder-3n1.pages.dev
Fixed

Cloudflare public form QA fixes

  • Added static Cloudflare Pages robots.txt and _headers files so public form and embed routes get crawler noindex/disallow safeguards on the Pages/public-form hosts
  • Fixed deterministic scan false positives where compact text matching could treat legitimate words across boundaries, such as Platform Preference plus FaceTime, as mfa
  • Added a featured-template fallback so featured=1 requests return popular/recent public templates when no rows are explicitly flagged featured
  • Deployed Worker version fec2381e-5f18-496e-abf5-af270395b771 and Pages build https://a8ce61d5.formbuilder-3n1.pages.dev
April 30, 202613 updates
New

Cloudflare public form anti-phishing deploy

  • Ported public form anti-phishing protections into the Cloudflare Worker/Pages stack
  • Added fail-closed publish blocking for risky public forms, backed by persisted form_security_scans
  • Added D1-backed public form abuse reports and admin review email hooks
  • Added public form noindex,nofollow behavior and removed broad public form allowance from Worker robots.txt
  • Added Cloudflare public form share/embed URL generation for https://forms.formbuilder.com
  • Deployed D1 migration 0007_add_form_abuse_reports.sql, Worker version a880080b-fe7e-4f5d-848e-edeb8d6f1cc8, and Pages build https://69bd4b04.formbuilder-3n1.pages.dev
  • Verified the deployed Worker with functional smoke tests and a live 423 FORM_REQUIRES_REVIEW publish-block test
  • Added forms.formbuilder.com as a Cloudflare Pages custom domain and DNS CNAME to the Pages project
New

Public form anti-phishing protections

  • Added forms.formbuilder.com public form URL configuration and updated share/embed URL generation to use the protected forms subdomain
  • Added legacy /f/{slug} and /embed/{slug} redirects from the main domain to the public forms subdomain
  • Added fail-closed publish review behavior so risky or uncertain forms stay unpublished and email the configured admin for review
  • Added public abuse reports for hosted forms, including storage, admin review flags, and admin review email notifications
  • Added noindex defaults for hosted public form pages and removed broad /f/* allowance from production robots output
  • Expanded deterministic phishing scans to include field names/options and catch simple obfuscated password-style fields
  • Added optional Claude review for ambiguous phishing scans with strict JSON output, conservative allow rules, and fail-closed manual review fallback
New

Cloudflare production readiness features

  • Split the Cloudflare frontend into route-level lazy chunks for admin, builder, templates, marketing, billing, settings, and team surfaces; the main JS entry dropped from about 1.99 MB minified to about 74 KB minified
  • Added D1-backed alert events with alert evaluation for failed logins, failed submissions, failed email sends, failed webhooks, Stripe webhook failures, API/D1 errors, AI errors, and import errors
  • Added admin alert summary/list and delivery retry/replay endpoints, plus Operations page panels for open alerts, critical alerts, and pending delivery retries
  • Added configurable Cloudflare Turnstile verification for public form submissions, anonymous/authenticated imports, contact/support submissions, and AI form generation
  • Added D1-backed email/webhook retry queue support with dead-letter status and admin-triggered replay
  • Added a Cloudflare cleanup inventory for legacy frontend and generated migration/parity artifacts so destructive cleanup waits for migration validation sign-off
  • Deployed production D1 migration 0006_add_production_readiness.sql, Worker version 2d2047eb-2db9-46a3-9434-2b91ca07dea0, and Pages build https://b501d0e7.formbuilder-3n1.pages.dev for https://formbuilder-3n1.pages.dev (April 30, 2026 @ 10:13 AM CDT)
Improved

Merged develop into main

  • Promoted the current develop branch changes into main with a Git merge commit
  • Rebuilt localhost assets after the merge for testing
  • Deployed Cloudflare Worker version fd1e8901-7303-410b-a093-0651832dd773 and Pages develop build https://da04f92d.formbuilder-3n1.pages.dev behind https://develop.formbuilder-3n1.pages.dev for full Cloudflare testing
Fixed

Cloudflare browser CSRF for authenticated POST flows

  • Fixed authenticated browser POSTs from the Pages frontend to the Worker API failing CSRF after magic-link login because the frontend cannot read the API host's CSRF cookie across domains
  • Auth and /api/auth/me responses now return the issued CSRF token for frontend storage, and the API client sends that token as the X-CSRF-Token fallback when the cookie is unreadable
  • Allowed the X-CSRF-Token header in Cloudflare API CORS preflight responses
Fixed

Cloudflare security hardening

  • Removed the stale SES/SNS webhook receiver from the Cloudflare Worker and parity docs now that email sends use Cloudflare Email Sending
  • Bound Google OAuth callbacks to short-lived server-side state nonces and encrypted stored OAuth access/refresh tokens with a required Worker secret
  • Rechecked current user active/admin/permission state from D1 instead of relying only on long-lived JWT claims
  • Added double-submit CSRF protection for cookie-authenticated unsafe API requests and frontend CSRF header support
  • Added public file upload size/type/count and storage quota checks plus webhook URL SSRF validation
  • Removed unused risky frontend/API dev dependencies and brought Cloudflare package audits to zero moderate-or-higher vulnerabilities
Fixed

Cloudflare magic-link stale redirect

  • Fixed homepage magic-link sign-ins reusing an older stored form/editor redirect from a previous auth attempt
  • Homepage magic-link requests now send a fresh / redirect and clear stale stored redirect state before saving the new intent
  • Deployed Worker version d5523ab4-657e-4024-8dbd-0be4e3c968e0 and Pages develop build https://9298daac.formbuilder-3n1.pages.dev behind https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare magic-link callback state

  • Fixed magic-link callbacks being interrupted by the global unauthenticated redirect before the callback could update React auth state
  • Added frontend parity coverage so /magic-login remains exempt from the global 401 sign-in redirect
  • Rebuilt the Cloudflare frontend bundle for localhost testing
  • Deployed Worker version eab09cb6-93dc-4f54-a437-e75041eb0e44 and Pages develop build https://210733bc.formbuilder-3n1.pages.dev behind https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare magic-link API host

  • Fixed the Cloudflare deploy script so the develop frontend builds against https://formbuilder-api.me-493.workers.dev instead of unresolved https://api.formbuilder.com
  • Added frontend parity coverage to prevent redeploying the testing frontend with the unresolved API hostname
  • Deployed Pages build https://abf19e0d.formbuilder-3n1.pages.dev behind https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin organization console

  • Added a read-only admin organization console for platform-wide folder usage, team vs personal folder mix, explicit form shares, owner plan mix, share permissions, expiring shares, and one-time shares
  • Added admin organization overview and unified organization item endpoints with type, search, owner plan, page, per-page, and limit support
  • Added /admin/organization to the shared Cloudflare admin sidebar and routed the page behind admin protection
  • Added admin contract coverage for the organization API/page, source table coverage, filters, pagination, and read-only constraints
  • Deployed Worker version 834f7d69-9f55-4ffa-ad17-0f1d3341dcac and Cloudflare Pages build https://e689ee5d.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin notifications console

  • Added a read-only admin notifications console for form notification recipient coverage, verified/pending recipient state, owner plan mix, and marketing email preference counts
  • Added admin notification overview and recipient list endpoints with search, verification status, owner plan, page, per-page, and limit support
  • Added /admin/notifications to the shared Cloudflare admin sidebar and routed the page behind admin protection
  • Added admin contract coverage for the notifications API/page, source table coverage, filters, pagination, and read-only constraints
  • Deployed Worker version 3910be80-f1b7-4adb-ae6f-ac9561e39dd7 and Cloudflare Pages build https://79465e75.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin auth console

  • Added a read-only admin authentication console for active sessions, failed logins, pending/used magic links, unverified users, locked users, and account risk signals
  • Added admin auth overview and unified auth event endpoints with event type, search, page, per-page, and limit support
  • Added /admin/auth to the shared Cloudflare admin sidebar and routed the page behind admin protection
  • Added admin contract coverage for the auth API/page, source table coverage, filters, pagination, and read-only constraints
  • Deployed Worker version acd23791-7f59-422b-9f90-d1da2ad8c322 and Cloudflare Pages build https://89b43ad1.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin storage console

  • Added a read-only admin storage console for uploaded file volume, total stored bytes, file type distribution, quota pressure, largest files, owner context, and form/response context
  • Added admin storage overview and file list endpoints with search, file type, owner plan, page, per-page, and limit support
  • Added /admin/storage to the shared Cloudflare admin sidebar and routed the page behind admin protection
  • Added admin contract coverage for the storage API/page, source table coverage, filters, pagination, and read-only constraints
  • Deployed Worker version 1edaa033-1aa9-4cbf-8d3c-9c5f17e73663 and Cloudflare Pages build https://b531cd60.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
April 29, 202633 updates
Fixed

Cloudflare admin imports console

  • Added a read-only admin imports console for platform import activity, source mix, status mix, owner context, result form context, and failure diagnostics
  • Added admin import overview and import list endpoints with search, status, source type, page, per-page, and limit support
  • Added /admin/imports to the shared Cloudflare admin sidebar and routed the page behind admin protection
  • Added admin contract coverage for the imports API/page, source table coverage, filters, pagination, and read-only constraints
  • Deployed Worker version a009eee1-a45e-41fb-a374-d2cd164c87a5 and Cloudflare Pages build https://2661a816.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin domains console

  • Added a read-only admin custom domains console for verification status, certificate readiness, owner context, and plan distribution
  • Added admin domain overview and domain list endpoints with search, status, plan, page, per-page, and limit support
  • Added /admin/domains to the shared Cloudflare admin sidebar and routed the page behind admin protection
  • Added admin contract coverage for the domains API/page, source table coverage, filters, pagination, and read-only constraints
  • Deployed Worker version f0ee0edf-2e1d-4704-ae1c-28434cfeba4a and Cloudflare Pages build https://73935275.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin teams console

  • Replaced the stale legacy admin teams wrapper with an active read-only Cloudflare admin Teams page
  • Added admin team overview and team list endpoints with team counts, member counts, pending invitations, plan/role summaries, owner context, forms count, filters, and pagination aliases
  • Added /admin/teams to the shared Cloudflare admin sidebar and routed the page behind admin protection
  • Removed destructive legacy team delete behavior from the active admin teams surface
  • Added admin contract coverage for the teams API/page, source table coverage, filters, pagination, and read-only constraints
  • Deployed Worker version 8c6a414b-2941-4caa-b974-45780b77b2a5 and Cloudflare Pages build https://2cd173bd.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin deliverability console

  • Added read-only admin deliverability overview and event endpoints for email delivery, outbound form webhook delivery, and Stripe webhook outcomes
  • Added type, status, search, page, per-page, and limit support for unified delivery event investigation
  • Added /admin/deliverability with delivery health cards, recent per-channel delivery panels, searchable delivery event table, and recent failure list
  • Added Deliverability to the shared Cloudflare admin sidebar and routed the page behind admin protection
  • Added admin contract coverage for deliverability API/page, source table coverage, filters, pagination, and read-only constraints
  • Deployed Worker version 512173c3-4edc-481a-9f33-b8c89e0be9af and Cloudflare Pages build https://5dba63dc.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare magic-link deployed domain

  • Fixed Worker deployment so emailed magic links use the deployed Cloudflare Pages domain instead of localhost
  • Added frontend parity coverage to prevent deploying the Worker with localhost FRONTEND_URL vars for emailed links
  • Deployed Worker version c5336d44-8612-4022-911b-98728fa056a5 with FRONTEND_URL pointing at https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin delivery observability

  • Added D1 delivery log tables for email sends, outbound form webhooks, and Stripe webhook validation/processing outcomes
  • Added best-effort delivery logging helpers so observability failures do not block user-facing email, form submission, or webhook flows
  • Logged Cloudflare email send successes/failures, outbound form webhook statuses, and Stripe missing signature, invalid signature, invalid JSON, processed, unhandled, and failed processing outcomes
  • Updated Operations overview and event APIs to expose delivery health cards, recent delivery lists, and normalized email_delivery, webhook_delivery, and stripe_webhook event types
  • Updated /admin/operations with delivery panels and live delivery log status instead of stale logging gap callouts
  • Deployed remote D1 migration, Worker version 33bed0d7-63a7-48e6-98c5-1af56a5da9c1, and Cloudflare Pages build https://678b0558.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin operations dashboard

  • Added read-only admin operations overview endpoints for failed imports, failed logins, pending security scans, flagged forms, AI usage, recent admin activity, billing attention, and logging gaps
  • Added a normalized operations event list with type/search filters and pagination aliases
  • Added the /admin/operations page with health cards, recent failure panels, logging gap callouts, and a filterable event table
  • Added Operations to the shared Cloudflare admin sidebar and routed the page behind admin protection
  • Added admin contract coverage for the operations API/page, read-only constraints, filters, pagination, and source table coverage
  • Deployed Worker version f9749194-d9fc-4fee-8e74-825d3db36d6c and Cloudflare Pages build https://c4d441c2.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin billing console

  • Added read-only admin billing overview endpoints for plan counts, subscription status counts, estimated MRR, recent subscriptions, cancellation feedback, and Stripe customers without active subscriptions
  • Added paginated admin subscription listing with search, plan/status filters, pagination aliases, user context, Stripe IDs, and Stripe dashboard links
  • Added the /admin/billing page with stats cards, plan/status summaries, filters, subscription table, recent feedback, and customer review list
  • Added Billing to the shared Cloudflare admin sidebar and routed the page behind admin protection
  • Added admin contract coverage for the billing API/page, read-only constraints, filters, pagination, and Stripe link fields
  • Deployed Worker version 72058c59-5923-4add-a629-8377c6b2167b and Cloudflare Pages build https://2771054b.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin audit logs

  • Updated the active admin audit API to combine admin_activity_logs and phi_audit_logs into one normalized audit feed
  • Added audit filters for action, resource type, actor, search, date range, suspicious-only, auth-only, page, per-page, and limit
  • Added audit stats for total logs, suspicious events, failed logins today, PHI access today, and action counts
  • Logged sensitive admin response detail views and bulk response exports into admin activity logs
  • Updated the audit logs page to consume normalized actor/source fields and export CSV details without assuming valid JSON
  • Deployed Worker version 54fec3b7-881e-440d-850b-eda6435e239b and Cloudflare Pages build https://c9bbb9b2.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin shared shell

  • Added a shared admin layout so active Cloudflare admin pages use one sidebar, content container, and active-route behavior
  • Wrapped Dashboard, Users, User Detail, Forms, Responses, Analytics, Security, Audit Logs, AI Logs, and Template Searches routes in the shared admin shell
  • Simplified the admin dashboard page to only render the dashboard overview content and removed stale nested placeholder admin pages
  • Added contract coverage for the shared admin shell, sidebar entries, route wrapping, and dashboard placeholder cleanup
  • Deployed Cloudflare Pages build https://498bbc67.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin responses management

  • Added an active /admin/responses page with stats, form/search/date filters, pagination, redacted response previews, and an explicit detail modal for full payload review
  • Added the Responses route to the Cloudflare admin app and sidebar, plus response-focused links from dashboard recent activity and admin form response counts
  • Updated /api/admin/responses to support search, form, date, page, and limit filters with Laravel-compatible pagination aliases
  • Changed admin response list rows to return metadata, owner/form context, field_count, and preview_fields without exposing full response payloads in list results
  • Kept /api/admin/responses/:response as the full-detail endpoint and added contract coverage for route/nav, redaction, filters, and on-demand detail loading
  • Deployed Worker version 449e535c-517c-46a7-bbe6-8572f7c8f900 and Cloudflare Pages build https://7778a40e.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare admin stabilization

  • Added focused admin contract coverage for dashboard, users, user detail, forms, security, and passwordless admin account actions
  • Expanded the Worker admin dashboard response with operational stats, recent users/forms/responses, growth data, response activity, and top forms
  • Fixed admin users list filters, pagination shape, stats, and user-detail data sections so active admin pages can consume Worker data reliably
  • Replaced active admin password create/reset UI with magic-link invite/access actions backed by a new admin-triggered magic-link endpoint
  • Updated admin forms and security pages to consume Worker-compatible stats, response counts, pagination, and scan review notes
  • Deployed Worker version 5572f230-3004-468b-9fb9-11e66b1aa7f7 and Cloudflare Pages build https://2c757562.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare magic-link anonymous draft handoff

  • Moved anonymous draft save/publish handoff into the magic-link callback so it runs immediately after token login succeeds
  • Prevented single-use magic-link tokens from being submitted twice by duplicate callback effects
  • Preserved post-auth publish intent even if the emailed link falls back to a non-editor route
  • Added frontend parity coverage for callback-side anonymous draft save/publish behavior
  • Deployed Cloudflare Pages build https://96c32aaf.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare anonymous publish progress copy

  • Strengthened anonymous editor progress copy to “Your form is almost ready to launch.”
  • Added ownership copy that the form is saved in the browser and can be accessed anywhere after account creation
  • Updated the publish-gate modal to “Launch your form” with outcome bullets for share link, responses dashboard, and account save
  • Added frontend parity coverage for the progress and outcome copy
  • Deployed Cloudflare Pages build https://8c0df6f4.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare anonymous editor banner cleanup

  • Hid the older onboarding progress tracker and AI Generated Draft banner for anonymous template editor sessions
  • Kept the simplified anonymous editor focused on Publish form, quiet Sign in, and the value-oriented publish banner
  • Added frontend parity coverage so those older banners do not reappear in anonymous editor sessions
  • Deployed Cloudflare Pages build https://59b350a9.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare anonymous template publish gate

  • Removed early anonymous editor conversion CTAs like Save & sign up from template/blank builder sessions
  • Made Publish form the primary anonymous conversion action with quiet Sign in as the only secondary auth option
  • Replaced temporary preview-mode messaging with progress copy: “Your form is ready. Customize it and publish in seconds.”
  • Added a post-auth publish intent so magic-link signup can save and publish the anonymous draft after return
  • Updated the publish-gate auth modal to tie signup to collecting responses instead of saving a draft
  • Added frontend parity coverage for the simplified anonymous editor conversion path
  • Deployed Cloudflare Pages build https://02c33ca6.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare gradient auth modal styling

  • Updated the active homepage sign-in/sign-up modal to match the established blue-to-purple gradient auth styling
  • Kept the email-only magic-link auth flow unchanged
  • Added frontend parity coverage for the modern auth modal gradient header and primary action
  • Deployed Cloudflare Pages build https://b56ac8e2.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare magic-link editor return path

  • Persisted the intended editor return path locally before sending magic links from homepage and builder auth entry points
  • Updated magic-link login to use that persisted editor redirect when emailed links do not include a redirect parameter
  • Closed stale homepage auth modals automatically once the user is authenticated
  • Added frontend parity coverage for persisted magic-link redirects and authenticated modal cleanup
  • Deployed Cloudflare Pages build https://77643aa1.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare passwordless auth frontend

  • Switched the modern homepage auth modal and active legacy builder auth modal to email-only magic-link sign in/sign up
  • Removed frontend password, confirm-password, forgot-password, and password-reset entry points from active auth modals while leaving backend password endpoints intact
  • Updated magic-link requests to create a new user when the email does not exist, enabling passwordless signup
  • Preserved safe magic-link redirects so anonymous builder saves can return to the editor after email verification
  • Removed user-facing account password update/reset surfaces from active Settings, Profile, and routing
  • Fixed magic-link returns from anonymous template/editor signup so persisted anonymous form data is saved before template reload logic can clear it, and added a local anonymous-draft redirect fallback when emailed links lack a redirect
  • Extended auth JWT and cookie defaults to 30 days
  • Deployed Worker version 7917aa4e-1d80-44f6-88e1-1fea7f5fecff and Cloudflare Pages build https://57a92dda.formbuilder-3n1.pages.dev to the develop alias
Fixed

Cloudflare homepage signup name field

  • Removed the required name field from the modern homepage signup modal
  • Updated modern registration to derive the required backend display name from the email address instead of asking users for it
  • Added frontend parity coverage so homepage signup does not reintroduce a name field
  • Deployed Cloudflare Pages build https://d62e7438.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare anonymous AI form signup save

  • Fixed homepage AI-generated anonymous forms so they are stored in the draft shape expected by the post-signup save handoff
  • Added normalization for existing raw anonymous draft data already in localStorage so affected sessions can still save after signup
  • Extended the active legacy builder bridge to render nested form_structure anonymous drafts, covering AI, import, and future anonymous draft entry points that use the wrapped shape
  • Synced the auth modal to updated login/register requests so ?auth=register reliably opens the signup view
  • Suppressed global auth redirects on anonymous builder routes so /api/auth/me 401 responses do not bounce guest-created forms back to the homepage login modal
  • Refreshed the modern app auth context after legacy-builder signup/sign-in so saved anonymous forms can stay on the protected edit route with logged-in UI
  • Added frontend parity coverage for the anonymous AI draft signup-save path
  • Deployed Cloudflare Pages build https://a64200e7.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev and verified in the browser that AI-generated and blank anonymous forms open signup/sign-in directly from the editor without losing the draft
Fixed

Cloudflare public form optional-field label zeros

  • Fixed optional public form fields rendering numeric 0 after labels when D1 returned required: 0
  • Added focused coverage for numeric required flags so optional fields do not leak falsey values into labels
  • Extended the same numeric flag normalization to the responses table test badge and template/editor field required markers
Fixed

Cloudflare incognito public form redirects

  • Fixed anonymous /f/:slug public form visits being redirected to the homepage/login flow after the unauthenticated /api/auth/me bootstrap request returned 401
  • Added a tested public-route auth redirect guard for /f/:slug, /form/:slug, /embed/:slug, /preview/:id, and /forms/:id/preview
  • Deployed Cloudflare Pages build https://37705e5a.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare Help page popular-topic links

  • Fixed /help popular-topic cards on the develop frontend by replacing unsupported :contains() section lookups with stable FAQ section anchors
  • Converted popular-topic cards into explicit non-submit buttons so card clicks do not bubble into unrelated navigation/auth handlers
  • Added frontend parity coverage so Help page topic clicks keep using supported section anchors
Fixed

Cloudflare homepage create-form options

  • Fixed anonymous Create Your First Form blank-form starts so they open the anonymous builder instead of calling the authenticated form-create API
  • Fixed the import wizard blank page by normalizing supported platform API objects before rendering import source buttons
  • Fixed homepage AI form generation by accepting the current Worker form_structure response shape as well as the legacy { success, form } shape
  • Added anonymous URL and PDF import paths so homepage imports can finish into the anonymous builder without requiring a saved account first
  • Fixed import completion handling so immediate completed responses navigate to the created/imported form instead of staying on the progress screen
  • Added frontend parity coverage for the anonymous blank-form route, import platform normalization, AI response normalization, and anonymous import endpoints
  • Deployed Worker version 22118a18-bcac-49ff-9262-dc1d028ca19b and Pages build https://11eff222.formbuilder-3n1.pages.dev to the develop alias for end-to-end testing
Fixed

Cloudflare anonymous builder header parity

  • Hid the app-level marketing navigation on /form-builder, /form-builder/:id, and /forms/new so anonymous builder pages match production
  • Added frontend parity coverage that guards builder routes from rendering the extra app nav above the builder toolbar
Fixed

Cloudflare homepage nav and template preview parity

  • Restored the high-level public navigation links for Solutions, Templates, Pricing, and HIPAA
  • Added the legacy Solutions dropdown links for healthcare, real estate, digital agency, legal, professional services, financial services, and education pages
  • Mirrored those public navigation links in the mobile menu
  • Fixed /templates preview by passing a normalized form object to the current Cloudflare FormRenderer API instead of legacy preview props
  • Expanded npm run test:frontend-parity coverage for public nav links and template preview renderer usage
Fixed

Cloudflare frontend page parity cleanup

  • Added AdminTeamsPage.tsx and DashboardPageOld.tsx compatibility page filenames so the component parity inventory has no missing legacy page filenames
  • Replaced remaining admin “coming soon” page copy with functional analytics/security summary panels backed by existing page data
  • Renamed the scheduled public-form heading from “Coming Soon” to “Opens Soon” so placeholder scans only target unfinished parity UI
  • Added npm run test:frontend-parity to guard against missing legacy page filenames and visible frontend parity placeholders
Fixed

Removed Mailgun and SendGrid provider remnants

  • Removed the remaining Mailgun webhook route from the Worker
  • Deleted the unused SendGrid service and removed SendGrid secret requirements from setup/check/push scripts
  • Removed Mailgun and SendGrid binding/types/config dependencies from the Cloudflare app source
  • Added provider-cleanup coverage to npm run test:email so Worker source/config stays Cloudflare Email Sending only
  • Deployed Worker version a37bcedf-134b-437d-b0b1-52979d69aa19 and verified form test sends still return sent: 1, total: 1
Fixed

Cloudflare-only transactional email sending

  • Removed Mailgun fallback delivery from the Worker email service so transactional email sends only through Cloudflare Email Sending
  • Removed Mailgun API/domain from Worker secret setup/check scripts
  • Added npm run test:email coverage proving Cloudflare send failures do not call Mailgun fallback even if legacy Mailgun env values exist
  • Deployed Worker version ef887aa2-1e10-4ce2-a397-a50c0b9f0848 and verified test sends for the two browser-created advanced forms
Fixed

Cloudflare advanced public form submissions from browser controls

  • Fixed deployed public form rendering so date inputs and other browser form controls are included reliably in the submitted payload
  • Added field-id name attributes to public renderer controls and merged browser FormData values into React state before validation/submission
  • Added a date onInput handler so date controls update state when browser automation or native date controls change the value
  • Verified through the Codex in-app browser with two advanced forms, including create/edit/publish/public-submit/logged-in-response readback
  • Deployed Cloudflare Pages build https://5c2ab19b.formbuilder-3n1.pages.dev to https://develop.formbuilder-3n1.pages.dev
Fixed

Cloudflare editor field publish and advanced option persistence

  • Fixed top-level advanced editor updates such as rating maxRating, slider bounds/defaults, file limits, and calculation formulas by normalizing them into field options
  • Fixed legacy editor publish payloads using is_public and is_active so forms become public published forms instead of draft-only records
  • Added deployed functional smoke coverage for editor advanced option updates and boolean publish payloads
Fixed

Cloudflare logged-in form editor browser flow

  • Fixed new-form field creation in the deployed editor by preventing the first draft-create navigation from remounting the editor before the field insert completes
  • Reused the in-flight draft form creation request so rapid field clicks do not trigger duplicate create requests
  • Preserved the created form ID in editor state after adding the first field, which allows Settings tabs like Notifications to load immediately
  • Routed notification recipient and verification resend actions through the configured Cloudflare Worker API client instead of same-origin Pages /api fetches
  • Verified in the Codex in-app browser on https://develop.formbuilder-3n1.pages.dev: new form creation, all 16 field buttons, Notifications settings, and no console errors
April 28, 202625 updates
Improved

Homepage Preview Redesign — Editorial / Cinematic Pass

  • Backed up original to homepage-preview.backup.html before rewriting
  • Removed AI-slop signals: blue→purple gradients applied to everything, fabricated stats (50k forms, 2M responses), made-up testimonials with picsum avatars, fake customer logos, picsum placeholder images, floating fake-metric cards, cliché copy ("loved by teams everywhere", "actually convert")
  • New editorial palette: warm paper neutrals, deep indigo accent used sparingly, gold/serif italic flourishes for drama
  • Typography: Instrument Serif italic accents over Inter, oversized hero, tighter letter-spacing
  • New structure: Hero with live typewriter prompt cycling through real form ideas → marquee of who actually uses it → "Three principles" dark section → three numbered chapters (AI, Analytics, HIPAA) with HTML/CSS-built product visuals (no picsum) → designed template cards built from primitives → single restrained pull-quote → three pricing tiers with featured ink-black middle → FAQ with serif "+" markers → cinematic dark final CTA
  • Cinematic details: subtle SVG film-grain overlay, fixed left-side roman-numeral chapter rail with active-section tracking, hero parallax on scroll, animated analytics chart bars, security checklist styled like terminal output
New

Cloudflare Data Reconciliation Report

  • Added npm run reconcile:data to compare Google PostgreSQL source counts against Cloudflare D1 counts and count exact missing/extra IDs for tables within the safe scan limit
  • Added per-form reconciliation checks for migrated fields, responses, and notification recipients under [email protected]
  • Added RECONCILE_TOP_ACCOUNTS support to run the same per-form checks against the most active source accounts
  • Wrote cloudflare/data-reconciliation-report.json with the latest reconciliation output
  • Wrote cloudflare/data-reconciliation-active-accounts-report.json for the top 8 accounts by source response/form activity
  • Confirmed Conference Registration has zero fields and zero responses in both PostgreSQL and D1, so it is not a migration-loss case
  • Confirmed [email protected] has zero field-count, response-count, and notification-count mismatches between source and D1
  • Confirmed the top 8 active source accounts have zero field-count, response-count, and notification-count mismatches
New

Cloudflare Public SEO + Visual Parity Harness

  • Restored legacy app-shell SEO metadata, social sharing tags, canonical URL defaults, and SoftwareApplication JSON-LD in the Cloudflare frontend
  • Added runtime canonical, Open Graph URL, and Twitter URL updates for routed Cloudflare pages
  • Added npm run parity:public to verify deployed public-page metadata and run desktop/mobile screenshot diffs against formbuilder.com when headless Chrome is available
  • Wrote cloudflare/public-page-parity-report.json; local screenshot capture is currently recorded as skipped because Chrome headless aborts on this host
New

Cloudflare Public Route Parity Cleanup

  • Restored the legacy /test-embed page and route on the Cloudflare frontend
  • Aligned /preview/:id with the legacy route shape while preserving public form identifier lookup
  • Restored the global public footer behavior so normal public pages have one footer, DPA/GDPR have the same double-footer behavior as production, and public form pages have none
  • Fixed Cloudflare GDPR geo-detection to call the deployed Worker API instead of the Pages SPA fallback
  • Regenerated frontend route parity inventory and verified the missing /test-embed and /preview/:id route gaps are closed
New

Cloudflare Public Frontend Legacy Page Port

  • Ported the first public frontend parity batch directly from the legacy React pages: home, new home, templates, template detail/category pages, pricing, features, solutions, industry landing pages, help, security, legal/privacy pages, subprocessors, and AI form generator
  • Added Cloudflare compatibility shims for legacy page imports: data/formTemplates, services/forms, services/billing, and services/analytics
  • Added named component exports needed by legacy pages while preserving existing default imports
  • Browser-swept the main public routes on the deployed develop site with no runtime error logs
New

Cloudflare Form Creation/Edit Hardening Tests

  • Expanded deployed functional smoke coverage for multi-page form settings, themes, webhook settings, access control, password protection, all core field types, field deletion, multipart file upload, public submission, and owner response readback
  • Verified /forms/new?blank=true in the in-app browser creates a real form, opens the edit page, adds a field, and reloads with fields still present
  • Added slider coverage so the deployed smoke now creates, persists, submits, and reads back every legacy field-palette type: text, textarea, email, number, phone, date, file, select, radio, checkbox, calculation, signature, rating, slider, address, and name (April 28, 2026 @ 11:57 PM CDT)
  • Added settings coverage for notification recipient add/resend/delete, verified-recipient test email, prefill create/list/test/public-prefill/delete, scheduled form gate, and max-response gate (April 29, 2026 @ 12:00 AM CDT)
New

Cloudflare Dashboard Exact-Parity Pass

  • Replaced the simplified Cloudflare dashboard with a TypeScript port of the legacy dashboard flow
  • Restored dynamic onboarding/usage/new-response alerts, richer form cards, publish/share/preview/response actions, grid/list toggle, share modal, test-email modal, sales bar, recycling bin count, account limits, and support widget
  • Added /f/:slug and /preview/:slug frontend aliases so dashboard links match legacy public-form behavior
  • Added deployed smoke assertions for dashboard form-list compatibility fields
New

Cloudflare One-to-One Parity Inventories

  • Added npm run parity:audit to regenerate frontend route, API route, component, and data migration parity inventories
  • Generated cloudflare/parity/frontend-route-parity.md, cloudflare/parity/api-route-parity.md, cloudflare/parity/component-parity.md, and cloudflare/parity/data-parity.md
  • Added prefix-aware Laravel route parsing, Cloudflare Worker route extraction, nested frontend wildcard detection, and API parameter-shape matching for actionable parity review
New

Cloudflare Migration Test Import + Email Service Sending

  • Extracted PostgreSQL → D1 migration mapping and serialization behavior into tested helper logic
  • Added automated migration tests for legacy column mappings, derived fields, timestamp fallbacks, and D1 value serialization
  • Added MIGRATE_LIMIT_PER_TABLE support for guarded test imports into D1
  • Ran validation against the current Google PostgreSQL source and D1 target with zero reported migration errors
  • Ran guarded representative D1 test import with 8 attempted rows, 8 migrated rows, and zero errors
  • Added Cloudflare Email Service binding support for transactional app email, with Mailgun fallback for provider outages
  • Added an admin-only deployed email test endpoint and onboarded formbuilder.com to Cloudflare Email Sending
New

Cloudflare Functional Smoke Coverage

  • Added deployed smoke coverage for create/reuse form, edit form settings, update theme, add/update fields, publish, public response submission, owner response readback, and owner notification recipient setup
  • Uses a named smoke form under [email protected] so repeated runs do not create duplicate audit forms
  • Documented that destructive field/form removal is excluded from automated cloud smoke tests until explicitly approved
Improved

Cloudflare API Compatibility Alias Parity

  • Added legacy-compatible Worker aliases for auth plan switching, development email verification, template form creation, form-to-template creation, Google integration testing, and /api/webhooks/*
  • Regenerated API route parity after the alias pass; remaining API review items are parameter-name-compatible routes and web/SPA fallback routes that need manual cutover decisions
  • Deployed Worker version d51ef56d-91a5-4756-bd93-c059fb861043 to the Cloudflare development API
  • Verified deployed logged-in smoke, functional smoke, migration tests, and public parity checks after the Worker deployment
Improved

Cloudflare Admin/Dashboard/Team Route Parity

  • Added explicit Cloudflare routes for legacy admin pages, dashboard, teams, and team workspace URLs
  • Routed admin user detail, forms, analytics, security, audit logs, AI logs, and template searches to their full page components
  • Regenerated route parity inventory; all legacy production frontend routes now report exact route/component matches
  • Deployed the updated frontend to the Cloudflare Pages develop alias
Improved

Cloudflare Editor Route Exact Parity

  • Updated the route parity audit to unwrap ProtectedRoute and report the underlying page component
  • Switched /forms/:id/edit to render the legacy FormBuilderPage bridge instead of the simplified Cloudflare editor page
  • Regenerated route parity inventory; /forms/:id/edit now reports an exact route/component match
  • Deployed the updated frontend to the Cloudflare Pages develop alias
Improved

Cloudflare Public Runtime Route Parity

  • Aligned /embed/:slug, /preview/:id, and /forms/:id/preview to render PublicFormPage like the legacy production app
  • Fixed preview mode so PublicFormPage loads authenticated preview data from /api/forms/:id/preview
  • Regenerated route parity inventory; embed and preview routes now report exact route/component matches
  • Deployed the updated frontend to the Cloudflare Pages develop alias
Improved

Cloudflare Responses UI + API Parity

  • Switched FormResponsesPage to render the legacy production responses UI through the Cloudflare legacy bridge
  • Expanded /api/forms/:formId/responses to return legacy-compatible form, fields, responses, file aliases, and read-state updates
  • Added deployed functional smoke assertions for the legacy response payload shape and uploaded file aliases
  • Deployed the updated Worker and frontend to the Cloudflare develop environment
Improved

Cloudflare Magic Login Route Parity

  • Restored /magic-login to use a MagicLinkLoginPage component name matching the legacy app
  • Added Cloudflare magicLinkLogin support in AuthContext while preserving the Worker magic-link endpoint
  • Kept the older MagicLoginPage filename as a compatibility re-export and added the missing legacy AuthPage.tsx filename
  • Deployed the updated frontend to the Cloudflare Pages develop alias
Improved

Cloudflare Builder/Responses Route Name Parity

  • Added FormBuilderPage.tsx and FormResponsesPage.tsx compatibility page names for legacy route/component inventory parity
  • Routed /form-builder, /form-builder/:id, and /forms/new through FormBuilderPage
  • Routed response aliases through FormResponsesPage while keeping the existing Cloudflare responses implementation as the underlying component
  • Deployed the updated frontend to the Cloudflare Pages develop alias
Improved

Cloudflare Legacy Builder Save Fix

  • Fixed the legacy /forms/new builder bridge so saves call Cloudflare Worker /api/... routes instead of the old Laravel /api.php?route=... proxy
  • Normalized legacy form, field, and auth service responses so Worker { form }, { field }, and { user } payloads match the shapes expected by the legacy builder
  • Verified the deployed /forms/new?blank=true flow creates a form and lands on the new edit URL without the previous “failed to save form after authentication” error
Improved

Cloudflare Editor + Frontend Route Parity Pass

  • Added D1/API support for legacy form submit button text, thank-you type/title/message, redirect URL, and response summary settings
  • Backfilled 110 existing D1 forms with legacy thank-you settings from the PostgreSQL source
  • Restored editor controls for notification recipients, test notification email, custom thank-you/redirect settings, signature/calculation fields, duplicate field, default values, field page assignment, and richer number/file/rating field options
  • Updated public form rendering/submission to honor custom submit button text, thank-you copy, redirect responses, response summaries, signature fields, accepted file types, and numeric constraints
  • Restored legacy frontend aliases and template category routes including /new, /forms/new, /form-builder/:id, /forms/:id/preview, /form-responses/:id, /ai-form-generator, /custom-domain, /folders, /team-templates, and dynamic *-templates category pages
  • Added deployed functional smoke assertions for submit-button text, thank-you metadata, signature/calculation fields, and rating option persistence
Improved

Cloudflare Form Publish State + Response Count Parity

  • Restored legacy is_active as a Cloudflare form field and migration target
  • Derive migrated form status from legacy is_public + is_active so published/draft state matches production
  • Calculate dashboard response totals from actual D1 response rows instead of stale denormalized counts
  • Repaired remote dev D1 form publish flags/counts from the PostgreSQL source and reran targeted form_responses migration to fill missing response rows
  • Updated dashboard/editor publish actions to write status, is_public, and is_active together
  • Fixed editor settings and field-property panels so they remain reachable in the in-app browser/narrow viewports
Improved

Cloudflare Password Update Flow

  • Removed the current-password requirement from Settings and Profile password-change forms
  • Updated the Worker password update endpoint to accept a new password with an 8-character minimum
  • Added explicit session-expired handling for password updates so authenticated failures redirect to login instead of showing a generic failure
  • Fixed deployed password updates failing with Internal Server Error by lowering PBKDF2 hashing to Cloudflare Workers' supported 100,000-iteration limit
  • Disabled login request throttling and failed-attempt lockouts in the Cloudflare development environment so migrated-account testing is not blocked
  • Deployed the updated Worker and Pages develop build for testing
Improved

Cloudflare Form List Dashboard Contract

  • Added legacy-compatible form-list aliases from the Worker API: is_active, responses_count, unread_responses_count, last_response_at, and share_url
Fixed

Cloudflare Protected Public Form Submission

  • Enforced password checks on POST /api/public/forms/:identifier/submit so direct API submissions cannot bypass password-protected forms
  • Updated the public form page to include the verified password when submitting protected forms, including file-upload submissions
  • Hash form passwords when saving authenticated form settings so password-protected forms verify consistently
  • Prevented transient anonymous-builder state from trying to auto-save an empty form after authentication
Fixed

Cloudflare Existing Form Editor Fields + Settings Load

  • Parsed authenticated form detail settings/theme JSON so migrated theme, notification, webhook, scheduling, access, and integration values are returned as usable objects instead of raw JSON strings
  • Wired the Cloudflare editor Settings dropdown to visible settings panels for general form settings, theme, notifications, webhooks, scheduling, and access controls
  • Added migrated field types like name and address to the editor field type list so existing legacy fields do not appear blank in the field type selector
  • Deployed the updated Worker and Pages develop build for testing
Fixed

Cloudflare Logged-In Dashboard Forms Load

  • Fixed /api/folders returning 500 for authenticated users by quoting the D1 order column in folder queries
  • Added deployed logged-in smoke coverage for [email protected] across forms, folders, billing, teams, domains, imports, templates, responses, analytics, previews, notification recipients, and prefill configs
  • Confirmed the dashboard data was present in D1 and the empty dashboard was caused by the folder request failure rejecting the combined dashboard load
February 16, 20262 updates
Fixed

Cloudflare Frontend: All 15 Missing Pages

  • Admin Pages (8): AdminUsersPage, AdminUserDetailPage, AdminFormsPage, AdminAnalyticsPage, AdminSecurityPage, AdminAuditLogsPage, AdminAiLogsPage, AdminTemplateSearchesPage
  • Team Pages (3): TeamWorkspacePage, TeamFoldersPage, TeamTemplatesPage
  • User Pages (4): ProfilePage, SubscriptionPage, NewHomePage, FormPreviewPage
  • All pages converted from original JS to TypeScript (.tsx) with full implementations (not stubs)
  • Replaced all emoji with lucide-react icon components across all pages
  • Uses design system: blue-600 primary, Tailwind CSS, max-w-7xl containers
  • Proper service integration (adminService, teamService, billingService)
  • Admin pages include security dashboard, HIPAA audit logs, AI generation logs, template search analytics
  • Team pages include workspace management, folder organization, template gallery
  • Subscription page includes plan management, payment methods, cancel/downgrade flows
  • Profile page includes password change, timezone settings, email preferences
Fixed

Complete Cloudflare Ecosystem Rewrite

  • Full rewrite of FormBuilder from Laravel/PHP/Google Cloud to Cloudflare Workers/D1/R2/KV
  • New codebase in cloudflare/ folder with TypeScript + Hono framework
  • API: 22 route files, 150+ endpoints, 5 middleware, 5 services, 4 utilities (9,297 lines)
  • Frontend: 14 pages, 7 components, 2 hooks, 6 services, App.tsx routing (10,093 lines)
  • Database: Drizzle ORM schemas for all ~30 tables, D1 migration SQL
  • Auth: JWT-based auth using Web Crypto API (PBKDF2 + HMAC-SHA256)
  • Email: Direct Mailgun HTTP API with 11 HTML email templates
  • Billing: Direct Stripe HTTP API (no Laravel Cashier dependency)
  • Geo: Native cf-ipcountry header (no external API)
  • Scripts: Data migration (PostgreSQL → D1) and setup script
  • Both API and frontend build successfully with zero errors
December 3, 20252 updates
Fixed

Homepage Create Form UX

  • Updated "Create Your First Form" and "Get Started Free" buttons on homepage to open FormCreationModal
  • Users can now start creating forms (AI, templates, import, blank) without signing up first
  • Matches the same experience as the dashboard "Create New Form" button
Security

Bug Fixes

  • Replaced mathjs (2MB) with expr-eval (30KB) for formula evaluation - fixes React render crash
  • Fixed AuthContext loading state initialization to prevent homepage crash on load
  • Bundle size reduced by 600KB
December 2, 20252 updates
Security

Authentication Security Hardening

  • Fixed SQL logic bug in FailedLoginAttempt::isLocked() where lockout conditions weren't applied to email checks
  • Implemented secure magic link token storage using selector+hash pattern (tokens now hashed with bcrypt)
  • Removed access tokens from API response bodies (now only in httpOnly cookies)
  • Added SameSite=Lax attribute to all auth cookies for CSRF protection
  • Optimized refresh token lookup from O(n) to O(1) using indexed token selectors
  • Lowered login rate limit from 20/min to 10/min to reduce brute force window
Security

Code Security & Performance Fixes

  • Replaced unsafe eval() with expr-eval library for form calculations (prevents code injection)
  • Removed localStorage token storage from AuthContext (XSS protection - now uses httpOnly cookies only)
  • Added SSRF protection for webhook URLs (blocks private/internal IP ranges)
  • Whitelisted prefill user fields to prevent sensitive data exposure
  • Added rate limiting to send-test-email (5/min) and import validate-url (10/min) endpoints
  • Moved hardcoded admin email to config/mail.php
  • Fixed N+1 query in FormController::index() using withCount()
  • Added pagination to form list endpoints (default 50 per page)
  • Added database index on form_responses.country_code for analytics queries
  • Guarded console.log statements with development environment check
October 3, 20251 update
Removed

CAPTCHA System

- Removed Cloudflare Turnstile CAPTCHA from application (October 3, 2025)

  • Deleted TurnstileCaptcha.js React component
  • Removed all CAPTCHA validation logic from form submissions (PublicController)
  • Removed all CAPTCHA validation logic from authentication (AuthController login)
  • Removed TurnstileService.php backend service
  • Cleaned up commented CAPTCHA code from AuthModal.js
  • API keys remain in config/services.php for reference
  • Form submissions and user authentication now work without CAPTCHA verification in all environments
September 14, 20254 updates
New

Admin User Plan Management

- Added account type editing to admin users page (September 14, 2025)

  • Added plan selection dropdown to Quick Edit modal in admin users page
  • Supports all plan types: Free, Pro, HIPAA, Enterprise
  • Backend validation ensures only valid plans can be selected
  • Automatic plan_expires_at handling (free = null, others = +1 year)
  • Full admin activity logging for plan changes
  • Maintains consistency with existing changePlan functionality
New

Unread Form Responses Tracking

- Implemented functional unread response system (September 14, 2025)

  • Added read_at timestamp column to form_responses table with database index for performance
  • Dashboard now shows accurate unread counts for each form with blue badges
  • Forms automatically sorted by unread responses priority
  • Auto-mark as read when users visit form responses page
  • "New responses" summary counts unread responses across all forms
  • Existing responses marked as unread until first visit to responses page
  • Simple and intuitive workflow: visit responses → mark as read automatically
  • Added subtle pulse animation to unread badges to draw user attention
Improved

Enhanced Admin Users Table UI

- Improved table layout and usability (September 14, 2025)

  • Added Account Plan column showing user's current plan with color-coded badges
  • Converted Actions column from text buttons to intuitive icons with tooltips
  • Icons: 👁️ (View Details), ✏️ (Quick Edit), ✅ (Unsuspend), ⛔ (Suspend)
  • Added hover effects and consistent spacing for better user experience
  • Color-coded plan badges: Gray (Free), Blue (Pro), Green (HIPAA), Purple (Enterprise)
Fixed

Fixed Checkbox Options in PDF Export

- Restored proper checkbox display behavior (September 14, 2025)

  • Root cause identified: Form responses API was not including the options field from form_fields table
  • Added options column to the API query in FormController responses method
  • Removed logic that automatically added hardcoded dietary restriction options to PDF exports
  • Fixed issue where PDF only showed selected checkbox options instead of complete list
  • Added proper JSON parsing for checkbox field options stored as strings
  • PDF exports now show complete checkbox lists with [X] for selected and [ ] for unselected options
  • Previously: PDF showed 9 dietary options (4 real + 5 hardcoded extras) or only selected options
  • Now: PDF shows exactly the configured options with proper checked/unchecked states
  • Ensures user control and data integrity in form exports
September 12, 20257 updates
Security

Comprehensive Form Submission Protection

- Multi-layer bot and abuse prevention (September 12, 2025)

  • Turnstile CAPTCHA: Extended existing Turnstile integration to all form submissions
  • Multi-tier Rate Limiting: Implemented sophisticated throttling system
  • Global: 20 submissions per IP per 5 minutes
  • Per-form: 5 submissions per form per IP per 5 minutes
  • Rapid-fire: 1 submission per IP per 10 seconds
  • Suspicious activity: Enhanced monitoring at 50+ submissions per hour
  • Progressive Responses: User-friendly error messages with retry times
  • Cache-based Tracking: Efficient rate limiting using Laravel cache
  • Works seamlessly with existing Cloudflare protection
Security

Restricted Debug Logging to Localhost

- Debug logs now only appear in development (September 12, 2025)

  • Wrapped all debug logging with app()->environment('local') checks
  • Fixed debug logs in PublicController, MagicLinkMail, SendGridEventService, and SendGridMetricsRefreshJob
  • Prevents sensitive debug information from appearing in production logs
  • Maintains full debug capabilities for local development while securing production
Security

Enhanced File Upload Security

- Comprehensive server-side validation (September 12, 2025)

  • Added real file content validation using PHP's finfo instead of trusting client data
  • Expanded dangerous file type blacklist to 40+ malicious extensions and MIME types
  • Validates actual file headers against expected types to prevent disguised files
  • Detects MIME type spoofing attempts and logs suspicious activity
  • Prevents upload of executables, scripts, system files, and potentially dangerous archives
Security

CRITICAL - Removed Password Logging

- Fixed plain text password exposure in logs (September 12, 2025)

  • Removed debug logging that was recording form passwords in plain text
  • Fixed PublicController::verifyPassword method lines 598 and 608
  • URGENT: Review and purge existing log files for exposed passwords
Security

Enhanced Admin Account Security

- Block password login for [email protected] in production (September 12, 2025)

  • Admin account now requires magic link authentication only
  • Password login attempts automatically fail and are logged as suspicious activity
  • Maintains existing brute force protection while adding extra admin security layer
Improved

Dashboard Share Modal Enhancement

- Compact two-column design with modern gradient interface (September 12, 2025)

  • Redesigned with FormCreationModal-inspired styling and space-efficient two-column layout
  • Left Column: Direct Link (blue-to-purple gradient) and Embed Code (orange-to-red gradient) cards
  • Right Column: QR Code (green-to-teal gradient) and Social Sharing (clean white card) sections
  • Compacted Design: Reduced padding, smaller text sizes, and condensed spacing for better screen utilization
  • Enhanced UX: Smaller QR code with inline display, condensed embed textarea, and tighter social buttons
  • Maintained visual hierarchy with medium-sized emojis and descriptive text while significantly reducing modal height
  • Responsive design that stacks to single column on mobile devices
Improved

Dashboard Form Cards UI Improvements

- Enhanced user experience with clearer form actions (September 12, 2025)

  • Button Text Logic: Published forms show "View" button, draft forms show "Preview" button
  • Share Button Enhancement: Added visual indicators and tooltips for disabled share buttons
  • Disabled share buttons have reduced opacity and "cursor-not-allowed" styling
  • Orange warning badge (!) appears on disabled share buttons for unpublished forms
  • Informative tooltips: "Share this form" vs "Publish your form first to share it"
  • Clear visual feedback helps users understand form publication requirements
September 9, 20252 updates
Security

CRITICAL: Comprehensive Security Hardening

- Major security vulnerability fixes (September 9, 2025 5:30 PM)

  • Fixed API Key Exposure - Claude API keys were being exposed in error messages when API calls failed
  • Removed Debug Routes - Removed multiple debug endpoints that exposed sensitive system information:
  • /debug-admin was exposing user passwords and admin credentials
  • /force-create-admin had hardcoded admin credentials
  • /debug-templates was exposing file system paths
  • /react-debug was exposing system internals
  • /debug route now restricted to local environment only
  • Fixed Stack Trace Exposure - Removed stack traces from error responses that could reveal database credentials and file structures
  • Sanitized Exception Messages - Fixed 20+ controllers exposing raw exception messages to users
  • Removed Environment Variable Logging - Fixed logging of sensitive environment variables including API endpoints and bucket names
  • Added Security Infrastructure - Created centralized SecurityHelper class for safe error handling
  • Protected Error Responses - All API errors now return safe, generic messages while logging details internally
New

Form Import Wizard

- Complete form import system supporting external platforms (September 9, 2025 4:30 PM)

  • NEW: Import from Popular Platforms - Import forms from Jotform, 123FormBuilder, Typeform, and Google Forms
  • Multi-step wizard interface with platform selection, URL validation, and import progress tracking
  • Intelligent field mapping with automatic type detection and transformation rules
  • Async processing via Laravel queues for handling complex forms without timeout
  • Comprehensive scraping engine with robust error handling and retry logic
  • Added import option to form creation modal alongside existing blank/AI/template options
  • Real-time import status updates with detailed progress indicators
  • Field mapping confidence scoring and transformation recommendations
  • Support for conditional logic, multi-page forms, and complex field types
  • Database migrations: form_imports and import_field_mappings tables
  • New API endpoints: /api/import/* for wizard functionality
  • Full form conversion pipeline: Scrape → Intermediate Representation → FormBuilder Format
July 4, 20256 updates
New

Pre-Submission Review Page

- Revolutionary form review functionality for better user experience (July 4, 2025 9:30 PM)

  • NEW: Review Before Submit - When "Response Summary" is enabled, users see a review page before actual submission
  • Moved "Show response summary" toggle to be a standalone setting under Notifications tab
  • Uses modern toggle switch interface consistent with other notification settings
  • Complete Pre-Submission Flow: Fill Form → Review Responses → Confirm & Submit → Thank You Page
  • Shows "Review Your Responses" page with all form data clearly displayed
  • Smart field formatting (files show with 📎 icon, addresses/names are formatted properly)
  • "Back to Edit" button to return to form for corrections
  • "Confirm & Submit" button to proceed with actual submission
  • Works with all form types (single-page, multi-page) and thank you page types
  • Prevents accidental submissions and reduces form errors
  • Removed redundant post-submission summary (no longer needed since users review before submitting)
  • Clean, simplified thank you pages without duplicate response display
New

Production Deployment

- Successfully deployed application to production at formbuilder.com (July 4, 2025 8:34 PM)

  • Deployed latest codebase including soft neobrutalism homepage design and all recent features
  • Service running on Cloud Run with revision formbuilder-prod-00046-6bd
  • Production environment configured with live Stripe integration and production secrets
  • Build completed successfully with production optimizations (2GB memory, 300s timeout)
  • All production environment variables and secrets properly configured for live operation
  • Live site accessible at https://formbuilder.com with full feature set
New

Development Environment Deployment

- Successfully deployed application to dev environment on dev.formbuilder.com (July 4, 2025 8:28 PM)

  • Deployed latest codebase including soft neobrutalism homepage design and all recent features
  • Service running on Cloud Run with revision formbuilder-00063-5s5
  • Environment configured for staging with proper database connections and secret management
  • Build completed successfully with expected 5-6 minute build time
  • All environment variables and secrets properly configured for development testing
New

Soft Neobrutalism Homepage Design

- Created experimental new homepage with soft neobrutalism design principles at /new (July 4, 2025 3:30 PM)

  • Bold, chunky typography with playful personality and expressive language
  • Vibrant color gradients with thick rounded borders and soft shadows
  • Asymmetrical layout with floating geometric shapes and organic elements
  • Playful hover effects with scale, rotation, and shadow animations
  • High contrast design with generous spacing and breathing room
  • Reimagined content sections with fun, engaging copy and visual elements
  • Interactive CTA buttons with gradient backgrounds and transform effects
  • Enhanced industry solution cards with emoji pairs and benefit badges
  • Pricing cards with popular plan highlighting and animated interactions
  • Maintained full functionality while dramatically improving visual appeal and user engagement
New

Fixed Template Links in Industry Solution Pages

- Updated template showcase sections to link directly to specific templates (July 4, 2025 2:00 PM)

  • Updated LegalServicesSolutionsPage.js with correct template IDs and field counts
  • Updated FinancialServicesSolutionsPage.js with proper template mappings
  • Updated EducationSolutionsPage.js with available education templates
  • Updated ProfessionalServicesSolutionsPage.js with business template links
  • Changed link text from "View →" to "Use Template →" for better user guidance
  • Fixed template links to point to /templates/{templateId} instead of category pages
  • Corrected field counts to match actual template structures
New

Enhanced Dashboard Form Management

- Redesigned form cards with improved functionality and user experience (July 4, 2025 11:30 AM)

  • Implemented Option 6 card design with toggle switches for published/draft status
  • Added dropdown menu with comprehensive form management actions (duplicate, export, copy link, delete)
  • Enhanced form duplication that automatically opens new form in editor as draft status
  • Implemented form sorting: published forms first, then by response count descending
  • Added copy link functionality for published forms with visual feedback
  • Integrated icon-enhanced action buttons (edit, share, responses with count in parentheses)
  • Removed large response count display in favor of cleaner card design with larger form titles
  • Added click-outside detection for dropdown menus with proper event handling
  • Enhanced form title prominence and improved overall visual hierarchy
July 3, 20251 update
New

Marketing Email Preference System

- Complete user control over marketing communications (July 3, 2025 6:45 PM)

  • Marketing email unsubscribe system with secure token-based links
  • User profile toggle for marketing email preferences with default opt-in
  • Professional unsubscribe pages with clear messaging about what emails are affected
  • Separate system from form notification preferences for better granular control
  • Marketing email preferences persist across unsubscribe link and profile settings
  • Enhanced email button styling consistency across all email templates for better client compatibility
  • API endpoint for updating marketing preferences with proper validation
  • Email layout automatically includes unsubscribe links for marketing emails
  • Note: Users still receive important account emails (security, password resets) regardless of marketing preference
July 2, 20253 updates
New

Magic Link Authentication System

- Passwordless login system for secure, convenient access (July 2, 2025 7:30 PM)

  • Magic link request functionality from login modal with dedicated UI
  • Secure token generation using 64-character random strings
  • 15-minute token expiry for enhanced security
  • Single-use tokens that automatically invalidate after successful login
  • Rate limiting: 3 magic link requests per email per hour
  • Professional magic link email template with security information and expiry details
  • Magic link landing page with real-time login processing and user feedback
  • Automatic cleanup of expired and used tokens
  • Full integration with existing authentication system and session management
  • Magic link option prominently displayed in login modal for easy access
  • Comprehensive error handling for expired, invalid, or used tokens
New

Secure Email Notification System

- Comprehensive email verification system for form notifications (July 2, 2025 6:45 PM)

  • Pro-only email notifications with 3 email recipient limit
  • Email verification system with secure token-based verification
  • Owner email auto-verification (no verification required for form owner)
  • Verification email with 24-hour token expiry and rate limiting
  • Professional verification UI with status indicators (Owner, Verified, Pending, Expired)
  • Backend API for managing notification recipients with full CRUD operations
  • Only verified emails receive notifications for enhanced security
  • Resend verification functionality with rate limiting (3 attempts/day, 5min between)
  • Pro plan upsell messaging for free users
  • Environment-based email queueing (immediate for dev, queued for production)
  • Improved verification email styling and copy
  • Enhanced "send copy to respondent" functionality with better error handling
  • Fixed share modal to use form slugs instead of IDs for consistent URLs
  • Fixed notification emails not being sent - Added exception handling around FormAnalytic tracking to prevent it from blocking notification sending (July 2, 2025 6:19 PM)
Fixed

SEO Structured Data Issue

- Completely removed review ratings from all pages (July 2, 2025 7:15 PM)

  • Fixed Google search results showing "4.8 stars and 150 reviews" on all pages where ratings don't make sense
  • Removed aggregateRating structured data entirely from all pages
  • All pages now show clean search results without misleading rating information
  • Maintained proper SEO structured data for the software application while removing all rating display
January 18, 20251 update
New

Database Prefill System (Phase 2)

- Advanced form prefilling from multiple data sources (January 18, 2025)

  • Created DatabasePrefillService for backend data fetching
  • Added prefill_configurations and prefill_audit_log database tables
  • Implemented user session prefill (auto-fill from logged-in user data)
  • Added previous submission prefill (reuse data from past form submissions)
  • Created PrefillConfiguration API with full CRUD operations
  • Built React component for managing prefill configurations
  • Integrated database prefill with existing URL parameter prefill
  • Added security validation and permission checks
  • Implemented caching for improved performance
  • Extended PrefillManager service to support database sources
  • Priority system: URL params > Database/Session data
  • Audit logging for all prefill operations
Earlier11 updates
New

File Upload Storage Management System

- Complete file upload functionality with storage tracking and user limits

  • File type dropdown with common file type combinations (Documents & Images, Images Only, PDF Only, etc.)
  • User plan-based storage limits: Free users (10MB per file, 100MB total), Paid users (100MB per file, 1GB total)
  • Real-time storage usage calculation and validation
  • Storage usage display on dashboard with visual progress bar and color coding
  • Cloudflare R2 integration for secure file storage
  • File size and type validation with security measures
  • Storage quota enforcement before file upload
  • Automatic storage usage updates after file uploads
Improved

File Upload Field Configuration

- Improved UX for configuring file upload fields

  • Replaced text input with user-friendly dropdown for accepted file types
  • Updated default maximum file size from 10MB to 5MB
  • Added dynamic file size limits based on user's subscription plan
  • Enhanced field options persistence and loading
Fixed

Form Submission Issues

- Resolved critical form submission problems

  • Fixed storage calculation database relationship query (response.formform)
  • Fixed field options access in frontend (selectedFieldData.acceptedTypesselectedFieldData.options?.acceptedTypes)
  • Fixed field options merging in updateField function to properly handle nested options object
  • Fixed file upload data format handling between frontend FormData and backend validation
  • Enhanced form submission to support both regular forms and file uploads with proper data parsing
Fixed

Dashboard Storage Display

- Fixed storage usage showing "0 B" instead of actual usage

  • Added refreshUser() call on dashboard load to fetch up-to-date storage information
  • Dashboard now displays accurate storage usage after file uploads
Fixed

Form Responses Display

- Fixed form responses page not showing field data properly

  • Fixed backend API to include field id in responses endpoint
  • Updated frontend to access response data using field.name instead of field.id
  • Responses page now correctly displays all submitted form data
Improved

Database Changes

: Added storage_used_bytes, storage_limit_bytes, storage_last_calculated_at to users table

Improved

Models Updated

: User model with storage tracking methods, FormFile model relationships

Improved

API Updates

: AuthController includes storage information in user data, PublicController handles file uploads

Improved

Frontend Updates

: Dashboard storage card, improved form builder field configuration, file upload processing

Improved

Security

: File type validation, storage quota enforcement, dangerous file type filtering

Improved

Historical changes to be documented as needed

Historical changes to be documented as needed

Something you'd like to see next? Tell us.