floord

Account & subscription setup

Production hosting is ready at app.floord.pro. Account access, email delivery, billing, and external connections still need production setup and verification. This release does not support live billing.

1. Cloudflare production

Production uses its own Worker, D1 database, and private R2 bucket. Apply every database migration before deploying the application.

  • Use the HTTPS production address shown in SITE_URL. Confirm that public signup, email links, proposal links, and provider callbacks reach the correct routes.
  • Keep GROUNDWORK_ACCOUNT_MODE=enabled. Standalone hosting rejects client-supplied Sites identity headers and legacy account-linking requests.
  • floord enforces verified login, company membership, and subscription access on protected routes. Customer proposal links use their existing token checks.
  • Workers Builds overwrites dashboard-only text variables. Both environments keep SUPABASE_PUBLISHABLE_KEY in tracked vars; production also tracks its public TURNSTILE_SITE_KEY. Do not create duplicate Secret bindings for tracked variable names. Keep SUPABASE_URL and GROUNDWORK_SESSION_KEY, plus staging TURNSTILE_SITE_KEY, as dashboard runtime bindings of type Secret. Build settings are separate from runtime bindings.

2. Supabase Auth and email

  1. Create a Supabase project. Enable email/password authentication and keep Confirm Email enabled. Set the minimum password length to 12 or more.
  2. Configure a transactional SMTP provider you control, such as Resend, Postmark, or Amazon SES. Verify its sending domain, SPF and DKIM. Supabase's default mail service is restricted and is unsuitable for customer onboarding.
  3. Set the Auth Site URL to https://app.floord.pro. Allow the exact floord confirmation URL below. In the confirmation email template, use https://app.floord.pro/auth/confirm?token_hash={{ .TokenHash }}&type=signup. In the recovery template use the same route with type=recovery. The landing page requires a button click before consuming a link.
  4. Configure SUPABASE_URL and GROUNDWORK_SESSION_KEY (32 random bytes, Base64 encoded) as runtime Secret bindings. Verify that the tracked SUPABASE_PUBLISHABLE_KEY is the correct project's sb_publishable_ key. All user authentication uses the publishable key; SUPABASE_SECRET_KEY is not needed and is never a fallback. Never put secrets into source files or chat.
  5. Create a Cloudflare Turnstile widget for the deployment domain. Keep Supabase CAPTCHA enabled with the matching widget secret, and set its public TURNSTILE_SITE_KEY in floord. When this site key is configured, signup, password login, recovery and resend require a challenge token; Supabase validates it. Refresh, confirmation and logout do not need a new challenge.
  6. Leave SUPABASE_FORWARD_IP unset or false; true causes a configuration error. Publishable-key authentication cannot send Supabase's privileged Sb-Forwarded-For header. floord retains its D1 limits by client IP and email. Supabase's IP limits see Worker egress shared by users; monitor those responses without restoring a privileged key.
  7. Before deploying this auth update to an existing environment, verify its respective publishable key in tracked vars and unset the old IP-forwarding setting or set it to false. Prepare staging and production separately, keep each domain's matching CAPTCHA configuration enabled, and verify staging before releasing to production. Existing unused Supabase secret bindings do not provide a fallback; removal or rotation is a separate operation.
  8. Verify missing and invalid CAPTCHA tokens fail signup, password login, recovery and resend; a fresh valid challenge should reach normal authentication. Check provider validation in Turnstile analytics. Also test confirmation, refresh, logout, password recovery, invalid credentials, expired links and repeated attempts. Finish signup in the same browser where it started; this protects the company selection from unverified signup attempts.

Password authentication · Email templates · SMTP · CAPTCHA · Rate limits

3. Production billing is not enabled

This release supports Stripe test billing only. Do not add Stripe test keys or live keys to the production Worker. Keep test billing on staging.

Live billing support must be implemented and validated before adding production Stripe credentials, prices, portal settings, or webhooks. Hosting the app does not enable real subscriptions.

Paid workspace access remains unavailable until production billing is ready. Complete that work and verify the production subscription flow before inviting paying customers.

4. Fresh production accounts

Production uses a clean database and file bucket; staging test data is not imported. Create new verified email accounts. Old company records, memberships, sessions, uploads, and provider connections are not imported. Required product defaults and the isolated sample demo remain available.

Keep staging data and provider credentials separate from production. Confirm two independently registered companies cannot access each other’s records or files.

Access policy

  • Paid access requires a matching Stripe subscription and verified paid service period. A previously paid subscription can qualify for the defined renewal grace period. Initial unpaid accounts and free trials do not unlock access.
  • For a confirmed failed automatic renewal after a paid subscription period, a seven-day grace period starts at the end of that paid period and ends exactly 168 hours later (UTC), or at an earlier effective cancellation. Retries do not extend it. After it expires, workspace access is suspended and company data is preserved. Initial unpaid subscriptions receive no access.
  • Cancellation at period end keeps access through the paid period. Trialing, paused, incomplete, canceled and expired subscriptions do not unlock access. A new subscription cannot inherit an old subscription’s grace period.
  • Successful payment or reactivation restores eligibility after server reconciliation. Billing status refreshes when needed and webhooks reconcile current Stripe state rather than applying old event snapshots.
  • Login, password reset and owner billing management remain available while access is suspended. Team members cannot manage billing.
  • Invitations expire in seven days. Regeneration or revocation invalidates pending uses. Membership is activated only after verified email, an eligible company subscription (paid or within verified renewal grace) and an atomic five-seat check. Job titles never grant owner permissions.
  • Removing a member revokes their managed sessions and blocks further company access. Their work remains in the company. Signup cannot create a replacement owner workspace for a removed member.
  • Homeowner proposal links retain their existing token-based access, signature and revision rules. No paid floord account is required by those application routes.

Commercial offer and support

$249 USD / month; 5 total seats, including the owner. Read the customer-facing cancellation, refund, access and support terms. Confirm that info@floord.pro receives mail and the published phone number reaches the support owner. Email is the primary support record; no guaranteed response time or 24/7 coverage is promised. Refund reviews are manual; never collect payment credentials in support email.

QuickBooks and Google Calendar connection code is implemented, but OAuth credentials and production validation remain outstanding. QuickBooks creates an unsent invoice from an approved proposal. The contractor reviews and sends it in QuickBooks; payment status is not synchronized.

Release checklist

Before inviting customers, complete and verify production account setup, SMTP delivery, signup confirmation, password recovery, team access, company isolation, and external connections. Implement and validate live billing, including payment failures, abandoned checkout, cancellation, and reactivation. Production hosting alone does not confirm that these services are ready.