floord

Account & subscription setup

This staging deployment runs in your Cloudflare account with a clean database. Email login and integrations require the configuration below. Stripe live keys are rejected by this release.

1. Cloudflare staging

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

  • Use the HTTPS staging 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.
  • Store credentials as Cloudflare runtime secrets. Build settings are separate from the secrets used by the running application.

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://staging.floord.pro. Allow the exact floord confirmation URL below. In the confirmation email template, use https://staging.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. Add server secrets SUPABASE_URL, SUPABASE_SECRET_KEY (a new sb_secret_ key), and GROUNDWORK_SESSION_KEY (32 random bytes, Base64 encoded). Never put secrets into source files or chat.
  5. Create a Cloudflare Turnstile widget for the deployment domain. Set its secret in Supabase's CAPTCHA settings and TURNSTILE_SITE_KEY in floord. floord forwards the token to Supabase for validation. For provider rate limits using real client IPs, enable Supabase's IP-forwarding feature and set SUPABASE_FORWARD_IP=true only after confirming the host forwards a trusted cf-connecting-ip header.
  6. Test confirmation, resend, 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

3. Stripe test subscriptions

  1. Create a Stripe test account or sandbox. Create one product named floord and one active flat recurring Price: $249.00 USD, every month, amount 24900 cents, licensed per-unit billing, quantity one. Do not configure a trial, usage billing, quantity transforms, discounts, tiers, or annual prices. Supply its test Price ID as STRIPE_PRICE_ID. The server checks the amount, currency, interval and quantity against the advertised offer before checkout or workspace access.
  2. Set STRIPE_SECRET_KEY to the test secret key. This release rejects live keys, live prices, and live webhook events.
  3. Keep GROUNDWORK_INCLUDED_SEATS=5 (or omit it). Any other setting disables billing. Five seats total includes the owner; there are no seat add-ons. Checkout quantity is always one company subscription. Before enabling managed accounts for existing companies, review any company with more than five active members; do not delete their data.
  4. Enable the Stripe customer portal for payment methods, invoice history, and cancellation at period end. Keep plan and quantity changes disabled. Set STRIPE_PORTAL_CONFIGURATION_ID to this test configuration. The server verifies that payment updates and invoice history are enabled, cancellation mode is at_period_end, and subscription changes are disabled. It refuses checkout and portal sessions with incompatible settings.
  5. Configure automatic collection and renewal retries in Stripe Billing. Keep failed subscriptions past due (or unpaid); do not configure automatic cancellation before the seven-day floord grace deadline. Test retry timing with a Stripe test clock. Stripe may delay the first automatic invoice attempt; verify collection timing as part of the hosted test.
  6. Register a test webhook at https://staging.floord.pro/api/webhooks/stripe. Use API version 2025-03-31.basil. Subscribe to checkout.session.completed, checkout.session.expired, checkout.session.async_payment_succeeded, checkout.session.async_payment_failed, customer.subscription.created, customer.subscription.updated, customer.subscription.deleted, customer.subscription.paused, customer.subscription.resumed, invoice.paid, and invoice.payment_failed. Store the signing secret as STRIPE_WEBHOOK_SECRET.
  7. For local tests, use Stripe CLI forwarding. For hosted staging tests, verify that the HTTPS webhook endpoint receives signed Stripe test events.
  8. Test successful payment, declined payment, abandoned checkout and resume, duplicate webhooks, delayed events, cancellation, renewal failure, and reactivation. Use Stripe test cards and test clocks. A success URL never unlocks the workspace by itself.

Checkout subscriptions · Webhooks · Subscription testing

4. Fresh staging accounts

The old site contains test data, so this deployment starts with a clean database and file bucket. 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 testers, verify anonymous hosting, SMTP delivery, both authentication callbacks, successful and failed Stripe test payments, abandoned-checkout recovery, team seat limits, invalid and revoked codes, member removal, company isolation, password reset, cancellation and reactivation. Provider credentials are not configured yet, so actual email delivery and Stripe test-mode transactions remain pending.