Releases

This section documents every version of the SONAN DIGITAL CRM, from the foundation alpha through the current production release. It includes full release notes, known issues, changelogs, and the production release checklist.


Current Release

v1.0.0 โ€” Released 2026-06-30 โ€” Initial production release of the SONAN DIGITAL CRM platform.

View v1.0.0 Release Notes View Known Issues View Release Checklist


Version History

Version Release Date Type Summary
v1.0.0 2026-06-30 Major Initial production release. Full multi-tenant CRM platform including client portal, Stripe payments, e-signatures, notifications, reports, and in-app Wiki.
v0.9.0 2026-05-15 Beta Feature complete. Full client portal implementation, Stripe Checkout, MFA enforcement across all roles. Pre-UAT candidate.
v0.8.0 2026-04-01 Beta Core commercial modules complete. Proposals, Contracts, Invoices, Support Tickets.
v0.7.0 2026-02-15 Alpha Platform foundation. Authentication, tenant system, Leads, Clients, Projects, Tasks, Time Logs.

Release Documents

Document Description
v1.0 Release Notes Complete feature list, security fixes, and upgrade notes for v1.0.0
v1.0 Known Issues Accepted risks and deferred issues in the v1.0.0 release
v1.0 Release Checklist Pre-release and go-live verification checklist
Changelog Full inline changelog from v0.7.0 to v1.0.0
Release History Complete release history table with semantic versioning policy

Semantic Versioning

This project follows Semantic Versioning 2.0.0:

  • Major version (X.0.0) โ€” Significant platform milestone, new module suite, or breaking change to integrations.
  • Minor version (X.Y.0) โ€” New features added in a backward-compatible manner.
  • Patch version (X.Y.Z) โ€” Backward-compatible bug fixes, security patches, or minor improvements.

See Release History for the full versioning policy as applied to this project.


v1.0.0 Release Notes

Release Date: 2026-06-30 Type: Major โ€” Initial Production Release Commit: (set at deployment) Deployed to: Vercel (production) Database: Supabase (production project)


Overview

v1.0.0 is the first full production release of the SONAN DIGITAL CRM platform. This release delivers a complete multi-tenant agency CRM covering the entire client lifecycle: lead capture โ†’ client onboarding โ†’ proposals and contracts โ†’ invoicing and payment โ†’ project delivery โ†’ support.

The platform runs on Next.js 15 App Router with edge runtime, backed by Supabase (PostgreSQL + Auth + RLS + Storage), deployed on Vercel, with email via Resend and payments via Stripe.


What's New in v1.0.0

This is the initial release. All features listed below are new.

Platform & Infrastructure

  • Multi-tenant architecture โ€” Full tenant isolation at the database level via Supabase Row-Level Security (RLS). Every table is scoped by tenant_id. Tenants cannot access each other's data.
  • Edge Runtime โ€” All API routes and pages use export const runtime = 'edge' for Vercel edge network deployment. Cold start times are minimized.
  • TOTP Multi-Factor Authentication โ€” All user roles (Admin, Employee, Client) must enroll in TOTP MFA using an authenticator app. MFA is enforced at login.
  • Role-Based Access Control โ€” Three distinct roles with isolated portals:
  • Admin โ€” full CRM access, all modules
  • Employee โ€” task management, time logging, ticket handling, limited client visibility
  • Client โ€” self-service portal (proposals, contracts, invoices, documents, support)

Lead Management

  • Lead record creation with name, email, phone, source, and status fields
  • Pipeline status tracking: New โ†’ Contacted โ†’ Qualified โ†’ Proposal Sent โ†’ Converted / Lost
  • One-click lead-to-client conversion
  • In-app new_lead notification broadcast to all admins on new lead creation
  • Email notification to admin team on new lead (via Resend)

Client Management

  • Full client record with company name, website, industry, and notes
  • Contact management: multiple contacts per client, primary contact designation, per-contact email/phone/title
  • Assigned manager field (assigned_manager_id) for routing and reporting
  • Client portal access provisioning: admin invites client via email, client self-activates account with MFA
  • Client status tracking (Active / Inactive / Archived)

Proposal Builder

  • Line-item proposal creation: description, quantity, unit price, calculated subtotal
  • Subtotal stored as subtotal_cents in the database (integer cents, never floats)
  • Proposal statuses: Draft โ†’ Sent โ†’ Approved / Declined
  • Email delivery to client on proposal send (Resend)
  • Client portal e-approval: client reviews and clicks Approve or Decline
  • proposal_approved and proposal_declined in-app notifications to admin
  • One-click conversion from approved proposal to invoice (line items and amount pre-populated)
  • Optional notes and validity date fields

Contract Management

  • Contract creation with rich-text body (HTML content)
  • E-signature workflow: admin sends for signature โ†’ client reviews and signs via portal
  • Contract statuses: Draft โ†’ Pending Signature โ†’ Signed / Declined
  • contract_signed and contract_declined notifications to admin
  • Signed timestamp recorded on the contract record
  • Client portal contract list showing all contracts and their current status

Invoice Management

  • Invoice creation with line items, due date, and optional notes
  • Invoice statuses: Draft โ†’ Sent โ†’ Paid / Overdue / Cancelled
  • Stripe Checkout integration: Pay Now button generates a Stripe Checkout session; client is redirected to hosted Stripe payment page
  • Stripe webhook handler: checkout.session.completed event auto-marks invoice as Paid and records payment date
  • invoice_paid in-app notification to admin on successful payment
  • Email delivery to client on invoice send (Resend)

Recurring Invoices

  • Recurring invoice configuration: frequency (weekly, monthly, quarterly, annual), start date, end date (optional)
  • Automated generation via Vercel Cron job (runs daily, protected by CRON_SECRET)
  • Generated invoices inherit line items and amounts from the recurring invoice template
  • Admin notification when a recurring invoice is generated

Overdue Invoice Detection

  • Daily cron job scans all Sent invoices with a past due date
  • Invoices past due date are automatically updated to Overdue status
  • Admin notification generated for each newly-overdue invoice

Project Management

  • Project records linked to clients
  • Project status: Active / On Hold / Completed
  • Task creation within projects: title, description, assigned employee, due date, status
  • Task status pipeline: To Do โ†’ In Progress โ†’ Review โ†’ Done
  • Employee portal task list scoped to the logged-in employee

Time Logging

  • Employees log time against specific tasks
  • Fields: task, hours, logged date, optional note
  • Time logs visible to admin in the Time Logs report
  • Employee portal shows personal time log history

Support Ticket System

  • Clients submit support tickets from the client portal: subject, message, priority
  • Ticket statuses: Open โ†’ In Progress โ†’ Closed
  • Thread-based reply system: employee/admin appends replies to the ticket thread
  • support_reply notification delivered to client on each reply (in-app + email)
  • Admin/employee can close tickets; closed tickets visible to client as read-only

Document Sharing

  • Admins upload files for specific clients (stored in Supabase Storage)
  • Signed URLs with 1-hour expiry delivered to clients on document download request
  • Client portal document list: view all documents shared by admin, download on demand
  • Document metadata: name, upload date, file size, file type

Deployment Artifact Tracking

  • Per-project deployment records: version, environment, deployment date, notes
  • Admin creates and tracks deployment events for each client project
  • Useful for audit trails and release coordination

Client Cost Ledger

  • Internal cost tracking per client: cost entries with description, amount, date, category
  • Separate from invoices โ€” this is the internal cost of delivery, not what the client pays
  • Admin-only view; not exposed in client portal
  • Supports profitability analysis per client

Reports

  • Revenue Report: aggregates paid invoice amounts by date range; filterable by client or all clients; CSV export
  • Time Log Report: aggregates hours by employee; filterable by employee, project, and date range

In-App Wiki

  • Contextual help articles authored by admin
  • Articles organized by category with icons and sort order
  • Published/unpublished toggle for draft management
  • Accessible via a help icon in the navigation; searchable
  • Content stored as content_html; rendered safely in the portal

Notification System

  • In-app notification bell in the admin and employee navigation header
  • Unread count badge on the bell icon
  • Notification types: new_lead, invoice_paid, contract_signed, contract_declined, proposal_approved, proposal_declined, support_reply
  • Broadcast notifications (user_id = NULL) sent to all admins in the tenant
  • Targeted notifications sent to a specific user (user_id set)
  • Mark-as-read on click; mark-all-read action
  • Email counterpart for select notification types (via Resend)

Employee Portal

  • Dedicated portal for employees (separate from admin)
  • Visible modules: My Tasks, Time Logs, Projects (read-only), Support Tickets (reply access)
  • Scoped to the employee's assigned records โ€” employees see only their own tasks and time logs

Client Portal

  • Self-service portal accessible via invitation
  • Visible modules: Dashboard, Proposals, Contracts, Invoices, Documents, Support
  • Dashboard shows outstanding proposals, unpaid invoices, and open support tickets at a glance
  • All interactions (approvals, signing, payments, ticket submission) performed within the portal

Security Fixes

The following security issues were identified during pre-release review and are fixed in v1.0.0:

CRIT-4 โ€” Tenant Isolation Enforcement on Admin API Routes

Issue: Several admin API route handlers were not calling requireAdminWithTenant() before accessing Supabase. A malicious authenticated user could construct requests to access or modify records belonging to a different tenant by manipulating request parameters.

Fix: All admin API routes now begin with:

const caller = await requireAdminWithTenant()
if (!caller) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })

The caller.tenantId is used for all Supabase queries, making it impossible to access cross-tenant data regardless of request parameters.

Verified in UAT: TC security check for CRIT-4.


CRIT-7 โ€” RLS Policy Gaps on Documents and Contracts Tables

Issue: Supabase Row-Level Security policies on the documents and contracts tables were missing a tenant_id equality check in the USING clause. This allowed a service-role query (or a misconfigured client-side query) to return records across tenants.

Fix: RLS policies updated to include tenant_id = auth.jwt() ->> 'tenant_id' in all SELECT, INSERT, UPDATE, and DELETE policies on both tables. Migration applied to production.

Verified in UAT: TC security check for CRIT-7.


H8 โ€” Client Portal Access Token Validation Strengthened

Issue: The client portal session validation was checking only that a valid Supabase session existed, but was not verifying that the session's user_id belonged to the correct tenant and had the client role. A valid session from a different role or tenant could access the client portal.

Fix: Client portal middleware now explicitly checks: 1. Session is valid and not expired 2. User has role client in the users table 3. User's tenant_id matches the portal's expected tenant context

Verified in UAT: TC security check for H8.


Known Issues

The following issues are accepted for v1.0.0 and are documented in Known Issues. They do not block go-live but are scheduled for v1.1 or v1.2.

See Known Issues for full details, workarounds, and target fix versions.

ID Severity Module Summary Target
HIGH-1 High API / Security No custom rate limiting on API routes v1.1
HIGH-2 High Invoices / Contracts PDF generation not implemented (browser print workaround) v1.1
HIGH-3 High Admin No audit log for admin actions v1.2
HIGH-4 High Email Silent email delivery failures, no retry queue v1.1
HIGH-5 High Recurring Invoices Recurring invoice generation does not email client v1.1
HIGH-6 High Documents Signed download URLs expire in 1 hour v1.1
HIGH-7 High Auth / MFA No TOTP recovery codes โ€” lost device requires admin reset v1.1

Upgrade Notes

v1.0.0 is the first production release. There is no prior production version to upgrade from. No migration path is required.

For initial deployment steps, see the Release Checklist.


v1.0.0 Known Issues

โš ๏ธ
Accepted Risks

The issues on this page are accepted risks for the v1.0.0 production release. They were reviewed by the Technical Lead and Business Owner during UAT sign-off and determined not to block go-live. Each issue has a documented workaround and a target fix version. They must be addressed before v1.1 or v1.2 as indicated.


Issue Index

ID Severity Module Summary Target Fix
HIGH-1 High API / Security No custom rate limiting on API routes v1.1
HIGH-2 High Invoices / Contracts PDF generation not implemented v1.1
HIGH-3 High Admin / Compliance No audit log for admin actions v1.2
HIGH-4 High Email / Resend Silent email delivery failures with no retry queue v1.1
HIGH-5 High Recurring Invoices Recurring invoice generation does not email the client v1.1
HIGH-6 High Documents / Storage Signed download URLs expire after 1 hour v1.1
HIGH-7 High Auth / MFA No TOTP recovery codes โ€” lost device requires admin reset v1.1

HIGH-1

Severity: High Module: API / Security Status: Accepted โ€” target fix v1.1

Description

No custom rate limiting has been implemented on the CRM API routes. Under normal operating conditions this presents no problem, but the absence of rate limiting creates a theoretical surface for brute-force attacks against the authentication endpoints and credential-stuffing against the login page.

Risk Assessment

The risk is partially mitigated by Supabase Auth's built-in rate limiting on the /auth/v1/token endpoint (default: 10 requests per hour per IP for password grants, configurable in the Supabase dashboard). However, application-level API routes (/api/**) do not have rate limiting and could be targeted.

For v1.0.0, the application operates in a controlled-access environment with a small number of known users. The likelihood of active brute-force targeting is low.

Workaround

  • Supabase Auth built-in rate limiting is active and covers login attempts.
  • Vercel's edge network provides DDoS protection at the infrastructure layer.
  • Monitor Sentry and Vercel function invocation logs for anomalous traffic patterns post-launch.

Target Fix: v1.1

Implement rate limiting using an edge-compatible solution (e.g., Upstash Redis + @upstash/ratelimit) on critical API routes, particularly /api/auth/** and any unauthenticated endpoints.


HIGH-2

Severity: High Module: Invoices / Contracts / Proposals Status: Accepted โ€” target fix v1.1

Description

PDF generation for invoices, contracts, and proposals has not been implemented. When a user clicks a download or print action, the raw HTML view is presented rather than a properly formatted PDF document. Sending professional-looking PDF invoices or contracts to clients via email is not possible in v1.0.0.

Risk Assessment

This is a significant UX gap for a professional services CRM. Clients expect to receive PDF invoices and be able to sign or file them. The workaround is sufficient for v1.0 given the controlled client base, but must be prioritized for v1.1.

Workaround

Admins can print invoices and contracts to PDF directly from the browser:

  1. Open the invoice or contract detail page in Chrome or Firefox.
  2. Press Cmd+P (Mac) or Ctrl+P (Windows) to open the print dialog.
  3. Change the destination to "Save as PDF".
  4. Click Save and download the PDF.
  5. Send the PDF to the client manually via email.

This workaround is functional but adds manual steps to the admin workflow.

Target Fix: v1.1

Integrate a server-side PDF generation library compatible with the edge runtime (e.g., Puppeteer via a dedicated Node.js serverless function, or a third-party PDF API such as PDFShift or Gotenberg). Generate PDFs on demand and store in Supabase Storage for download.


HIGH-3

Severity: High Module: Admin / Compliance Status: Accepted โ€” target fix v1.2

Description

No audit log records admin actions. When an admin modifies a client record, changes an invoice status, deletes a document, or any other write action, no record is kept of who performed the action and when. This makes it impossible to answer "who changed this and when?" after the fact.

Risk Assessment

For a client-facing CRM managing financial data, audit logging is a compliance and accountability requirement. However, because v1.0.0 operates with a small team of trusted admins in a controlled environment, the immediate risk is low. This is a v1.2 priority, not v1.1, because it requires a more significant architectural addition (trigger-based audit tables or application-level middleware).

Workaround

  • Supabase's built-in PostgreSQL logs capture low-level database writes and are accessible via the Supabase dashboard under Database โ†’ Logs.
  • All Vercel function invocations are logged and include the caller's user ID for authenticated routes (via the requireAdminWithTenant() pattern which logs the userId).
  • In the event of a disputed change, the Technical Lead can cross-reference Supabase DB logs with Vercel function invocation logs to reconstruct the timeline.

Target Fix: v1.2

Implement an audit_log table with tenant_id, user_id, action, resource_type, resource_id, old_value (JSONB), new_value (JSONB), and created_at. Populate via Supabase database triggers on key tables or via application-level logging middleware.


HIGH-4

Severity: High Module: Email / Resend Status: Accepted โ€” target fix v1.1

Description

Email delivery failures from Resend are silent. When a transactional email fails to send (e.g., due to a Resend API error, invalid email address, or temporary outage), the failure is logged in Vercel function logs but there is no retry mechanism, no in-app alert to the admin, and no visibility from the CRM interface into whether an email was delivered.

In practical terms: if an invoice email or proposal email fails to send, the admin has no indication that the client did not receive it, and there is no automatic retry.

Workaround

  • Admins should verify critical emails (proposals, invoices, contracts) were received by checking with the client directly or checking the Resend dashboard (https://resend.com โ†’ Emails) after sending.
  • The Resend dashboard shows delivery status for all outbound emails. Failed deliveries appear with an error reason.
  • If an email failed, admins can resend manually by using the Send action again in the CRM (this creates a new send attempt, not a retry of the failed one).

Target Fix: v1.1

Implement a lightweight email queue or use Resend's webhook callbacks (email.bounced, email.failed) to capture delivery failures and surface them to the admin as in-app notifications or alerts on the relevant record.


HIGH-5

Severity: High Module: Recurring Invoices Status: Accepted โ€” target fix v1.1

Description

When the daily cron job automatically generates a recurring invoice, no notification email is sent to the client. The invoice is created with status Draft or Sent (depending on configuration), but the client receives no notification that a new invoice is available in their portal.

Admins receive an in-app notification that a recurring invoice was generated, but must manually trigger the email delivery to the client.

Workaround

After a recurring invoice is generated (visible in the admin Invoices list with a "Recurring" tag):

  1. Open the generated invoice.
  2. Review line items and amounts.
  3. Click Send Invoice to trigger the email delivery to the client.

This manual step should be done within 1 business day of the invoice generation date.

Target Fix: v1.1

Update the recurring invoice generation cron job to automatically mark the generated invoice as Sent and trigger the Resend email delivery in the same cron execution.


HIGH-6

Severity: High Module: Documents / Supabase Storage Status: Accepted โ€” target fix v1.1

Description

Document download URLs are generated as Supabase Storage signed URLs with a 1-hour expiry. If a client opens the Documents page and does not click the download link within 60 minutes, the link will have expired and the download will fail with a 403 or 400 error from Supabase Storage.

This is particularly problematic for clients who open the portal, get distracted, and return later to download โ€” they will see an error with no clear explanation.

Workaround

  • If a download fails, instruct the client to refresh the Documents page. A fresh signed URL is generated on each page load.
  • Document page refresh resolves the issue immediately in all tested cases.

Target Fix: v1.1

Generate signed URLs on demand (on each download click via an API route) rather than embedding them in the page HTML at render time. This ensures the URL is always fresh at the moment of the download request, regardless of how long the client has had the page open. Alternatively, increase the signed URL expiry to 24 hours.


HIGH-7

Severity: High Module: Auth / MFA Status: Accepted โ€” target fix v1.1

Description

TOTP multi-factor authentication does not generate recovery codes at enrollment time. If a user loses access to their authenticator app (phone lost, app deleted, new device without backup), they have no recovery codes to bypass MFA.

The only recovery path is for an admin to disable the user's MFA via the Supabase Auth dashboard and issue a new invitation, which forces the user to re-enroll. This is a manual process that requires admin intervention and causes downtime for the affected user.

This issue affects all roles: Admin, Employee, and Client.

Workaround

For affected users (Admin or Employee):

  1. User contacts the Technical Lead or Admin.
  2. Admin logs into the Supabase dashboard โ†’ Authentication โ†’ Users.
  3. Locate the affected user account.
  4. Disable or remove the MFA factor from the user's record.
  5. User logs in with email/password only.
  6. User is prompted to re-enroll MFA.
  7. User scans new QR code and completes enrollment.

For affected Client users:

  1. Client contacts their admin contact.
  2. Admin deactivates the client's portal account in the CRM.
  3. Admin re-invites the client via the portal invite flow.
  4. Client re-activates their account and re-enrolls MFA.

Prevention:

Advise all users at enrollment time to back up their TOTP secret key (most authenticator apps โ€” Authy, 1Password โ€” offer cloud backup). Store the seed key in a secure password manager.

Target Fix: v1.1

Generate and display one-time recovery codes at MFA enrollment time. Store hashed recovery codes in the database (mfa_recovery_codes table or in the Supabase Auth user metadata). Allow users to consume a recovery code once to bypass TOTP if their device is unavailable.


v1.0.0 Release Checklist

This checklist must be completed in full before the v1.0.0 production deployment is initiated. Each item must be verified by the Technical Lead.

๐Ÿšจ
Sequential Order Required

Complete this checklist in order. Do not begin go-live steps until all pre-release items are confirmed. Do not deploy to production before receiving UAT sign-off.


Pre-Release Verification

Quality & Testing

  • [ ] All UAT test cases executed and passed โ€” All Phase 1โ€“5 test cases in UAT Execution Guide show PASS status in the test record.

  • [ ] UAT sign-off received from Technical Lead โ€” Signed UAT sign-off form from Technical Lead is on file (see UAT Sign-Off).

  • [ ] UAT sign-off received from Business Owner โ€” Signed UAT sign-off form from Business Owner is on file.

  • [ ] All Critical (P1) defects resolved โ€” Defect log shows zero open Critical defects. All resolved Critical defects have been retested and confirmed fixed.

  • [ ] All High (P2) defects resolved or formally accepted โ€” Each open High defect in the defect log has either been resolved+retested, or formally accepted as a known issue with documented rationale (see Known Issues).

  • [ ] Staging environment stable for 48 hours pre-release โ€” No Sentry errors, no function failures, no database errors in the 48 hours prior to release. Verify in Vercel logs and Sentry dashboard.


Environment & Configuration

  • [ ] All environment variables set in Vercel production environment โ€” Verify in Vercel Dashboard โ†’ Project โ†’ Settings โ†’ Environment Variables. Required variables:
Variable Notes
NEXT_PUBLIC_SUPABASE_URL Production Supabase project URL
NEXT_PUBLIC_SUPABASE_ANON_KEY Production Supabase anon key
SUPABASE_SERVICE_ROLE_KEY Production Supabase service role key โ€” mark as Secret
RESEND_API_KEY Production Resend API key
STRIPE_SECRET_KEY Production Stripe secret key (must start with sk_live_)
STRIPE_WEBHOOK_SECRET Production Stripe webhook signing secret
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY Production Stripe publishable key (must start with pk_live_)
CRON_SECRET Secret token protecting cron job endpoints
NEXT_PUBLIC_SENTRY_DSN Sentry DSN for production error tracking
SENTRY_AUTH_TOKEN Sentry auth token with org:ci scope for source map uploads
โš ๏ธ
Live vs. Test Stripe Keys

Confirm STRIPE_SECRET_KEY starts with sk_live_ in production. A sk_test_ key in production means payments will appear to succeed in Stripe test mode but no real money will be charged.

  • [ ] Stripe webhook registered for production domain โ€” In the Stripe Dashboard โ†’ Developers โ†’ Webhooks:
  • Endpoint URL: https://[production-domain]/api/webhooks/stripe
  • Events: checkout.session.completed
  • Copy the signing secret into STRIPE_WEBHOOK_SECRET in Vercel production env vars.

  • [ ] Resend domain DNS verified for production domain โ€” In the Resend dashboard, confirm the production domain's DNS records (MX, SPF, DKIM, DMARC) are verified. Emails sent from an unverified domain will be rejected or land in spam.

  • [ ] Cron jobs configured in vercel.json โ€” Confirm vercel.json contains cron job definitions for:

  • Recurring invoice generation (daily)
  • Overdue invoice detection (daily) Both cron routes must validate the CRON_SECRET header before executing.

json { "crons": [ { "path": "/api/admin/invoices/recurring/generate", "schedule": "0 9 * * *" }, { "path": "/api/admin/invoices/overdue", "schedule": "0 10 * * *" } ] }


Database

  • [ ] All database migrations applied to production Supabase project โ€” Run any pending migrations via Supabase CLI or SQL editor: bash supabase db push --linked Verify no errors. Confirm all tables exist in the production database schema.

  • [ ] RLS policies active on all tables โ€” In Supabase Dashboard โ†’ Database โ†’ Tables, confirm "Row Level Security" is enabled on every tenant-scoped table. Specifically verify:

  • documents โ€” RLS enabled, tenant_id check in all policies (CRIT-7 fix)
  • contracts โ€” RLS enabled, tenant_id check in all policies (CRIT-7 fix)
  • notifications โ€” RLS enabled
  • clients, leads, proposals, invoices, projects, tasks โ€” RLS enabled

  • [ ] Supabase Auth redirect URLs updated to production domain โ€” In Supabase Dashboard โ†’ Authentication โ†’ URL Configuration:

  • Site URL: https://[production-domain]
  • Redirect URLs (allowed list): https://[production-domain]/auth/callback, https://[production-domain]/portal/auth/callback
  • Remove any staging or localhost URLs from the allowed list.

Go-Live Steps

Execute these steps on release day, in order:

  • [ ] Deploy to production โ€” Push the release commit to the production Vercel deployment: bash git push origin <release-sha>:refs/heads/main Or promote the staging preview deployment to production in the Vercel dashboard.

  • [ ] Verify production homepage loads โ€” Open https://[production-domain] in a fresh private browser window. Confirm the page loads without errors. Check browser console for any JavaScript errors.

  • [ ] Verify admin login in production โ€” Log in with a dedicated production admin account (not the UAT test account โ€” create a real admin account for the production tenant). Confirm MFA prompt appears. Confirm dashboard loads after MFA.

๐Ÿ’ก
Production Test Account

Create a separate admin@[yourdomain].com production admin account before go-live. Do not use UAT credentials on production. UAT credentials use @sonandigital.test addresses which are not real email accounts.

  • [ ] Verify Stripe webhook receives a test event โ€” In the Stripe Dashboard โ†’ Webhooks โ†’ select the production webhook endpoint โ†’ click Send test webhook โ†’ select checkout.session.completed โ†’ Send. Confirm the webhook delivers with status 200 in the Stripe dashboard attempt log.

  • [ ] Monitor Sentry for 30 minutes post-deployment โ€” Open the Sentry dashboard for the production project. Watch for any new error events in the first 30 minutes after deployment. Investigate and fix any Critical errors before notifying stakeholders.

  • [ ] Notify stakeholders of successful go-live โ€” Once all go-live checks pass, send go-live notification to:

  • Business Owner
  • Any clients who were waiting for portal access
  • Internal team members

Post-Release โ€” First 24 Hours

The following checks should be performed in the 24 hours after go-live:

  • [ ] Confirm the first cron job execution succeeds (check Vercel Cron logs the following day).
  • [ ] Confirm at least one test notification is delivered correctly (create a test lead and verify the in-app notification appears).
  • [ ] Confirm Resend email delivery is working (invite a test user and verify the invitation email is received).
  • [ ] Review Sentry for any new errors that appeared post-launch.
  • [ ] Confirm Supabase database connection pool is healthy (Supabase Dashboard โ†’ Database โ†’ Reports).

Rollback Plan

If a Critical issue is found within 2 hours of go-live:

  1. Revert Vercel deployment to the previous build: Vercel Dashboard โ†’ Deployments โ†’ select the prior deployment โ†’ Promote to Production.
  2. Notify stakeholders of the rollback and expected resolution timeline.
  3. Fix the issue in staging, re-run affected UAT test cases, and re-deploy when resolved.
  4. Database rollback: if a migration is involved, run the rollback SQL script prepared by the Technical Lead before the migration was applied.

Changelog

All notable changes to the SONAN DIGITAL CRM are documented here. The format follows Keep a Changelog conventions. Versions follow Semantic Versioning.

Entries are listed in reverse chronological order (newest first).


[1.0.0] โ€” 2026-06-30

The first full production release of the SONAN DIGITAL CRM platform. This release delivers a complete multi-tenant agency CRM ready for live client use.

Added

Platform & Infrastructure - Multi-tenant architecture with full RLS-based tenant isolation (every table scoped by tenant_id) - Edge runtime deployment on Vercel (export const runtime = 'edge' on all routes) - TOTP multi-factor authentication for all user roles (Admin, Employee, Client) - Role-based access control with three isolated portals: Admin, Employee, Client

Lead Management - Lead record creation with name, email, phone, source, and pipeline status - Status pipeline: New โ†’ Contacted โ†’ Qualified โ†’ Proposal Sent โ†’ Converted / Lost - One-click lead-to-client conversion - new_lead in-app notification broadcast to all admins on new lead

Client Management - Client records with company name, website, industry, assigned manager, and notes - Multi-contact management per client with primary contact designation - Client portal access provisioning via email invitation - Client status tracking (Active / Inactive / Archived)

Proposal Builder - Line-item proposals with description, quantity, unit price, and calculated subtotal - Subtotal stored as integer cents (subtotal_cents) to avoid floating-point errors - Full proposal status workflow: Draft โ†’ Sent โ†’ Approved / Declined - Email delivery on send via Resend - Client portal e-approval (Approve or Decline actions) - proposal_approved and proposal_declined admin notifications - One-click conversion from approved proposal to invoice

Contract Management - Contract creation with HTML rich-text body - E-signature workflow: Draft โ†’ Pending Signature โ†’ Signed / Declined - contract_signed and contract_declined admin notifications - Signed timestamp recorded on contract record

Invoice Management - Invoice creation with line items, due date, and notes - Stripe Checkout integration for client payment (hosted payment page) - Stripe webhook handler: checkout.session.completed auto-marks invoice as Paid - invoice_paid admin notification on payment - Invoice status: Draft โ†’ Sent โ†’ Paid / Overdue / Cancelled

Recurring Invoices - Recurring invoice configuration (weekly, monthly, quarterly, annual) - Daily Vercel Cron job for automated invoice generation (protected by CRON_SECRET)

Overdue Invoice Detection - Daily cron job to detect and update overdue invoices - Admin notification for each newly overdue invoice

Project Management - Project records linked to clients with status tracking (Active / On Hold / Completed) - Task creation within projects: title, description, assigned employee, due date, status - Task status pipeline: To Do โ†’ In Progress โ†’ Review โ†’ Done

Time Logging - Employee time log entries against tasks (hours, date, note) - Employee portal personal time log history

Support Tickets - Client ticket submission from client portal (subject, message, priority) - Thread-based reply system for employee/admin responses - support_reply in-app and email notification to client on each reply - Ticket status: Open โ†’ In Progress โ†’ Closed

Document Sharing - Admin file upload to Supabase Storage, associated with client - Signed download URLs (1-hour expiry) for client portal downloads - Client portal document list with download action

Deployment Artifact Tracking - Per-project deployment records (version, environment, date, notes)

Client Cost Ledger - Internal cost tracking per client (admin-only; not visible in client portal)

Reports - Revenue report with date range filter and CSV export - Time log report filterable by employee, project, and date range

In-App Wiki - Help articles organized by category with icons and sort order - Published/unpublished toggle; content stored as HTML

Notification System - In-app notification bell with unread count badge - Supported types: new_lead, invoice_paid, contract_signed, contract_declined, proposal_approved, proposal_declined, support_reply - Broadcast (all admins) and targeted (specific user) notification modes - Email counterpart for select notification types via Resend

Employee Portal - Scoped portal: My Tasks, Time Logs, Projects (read-only), Support Tickets

Client Portal - Dashboard: outstanding proposals, unpaid invoices, open tickets - Full self-service: Proposals, Contracts, Invoices, Documents, Support

Fixed

  • CRIT-4 โ€” Tenant isolation enforcement: all admin API routes now call requireAdminWithTenant() and use caller.tenantId for all Supabase queries; cross-tenant data access via parameter manipulation is no longer possible.
  • CRIT-7 โ€” RLS policy gaps: documents and contracts tables now have correct tenant_id = auth.jwt() ->> 'tenant_id' equality checks in all USING clauses on SELECT, INSERT, UPDATE, DELETE policies.

Security

  • H8 โ€” Client portal middleware now validates that the session user has the client role and the correct tenant_id in addition to checking session validity. Sessions from other roles or tenants cannot access the client portal.
  • TOTP MFA enforced at login for all user roles; unenrolled users are redirected to MFA setup before accessing any portal.

[0.9.0] โ€” 2026-05-15

Feature-complete beta release. All modules implemented. Pre-UAT candidate.

Added

  • Client Portal โ€” Full client self-service portal: proposals, contracts, invoices, documents, support tickets, dashboard
  • Stripe Checkout โ€” Hosted payment page integration; Pay Now button on invoice detail
  • Stripe Webhook Handler โ€” checkout.session.completed event handler; auto-marks invoice paid
  • MFA Enforcement โ€” TOTP MFA mandatory for all roles; enrollment gate at first login
  • Client Portal Invitation Flow โ€” Admin sends invite; client receives email and self-activates with MFA
  • Employee Portal โ€” Scoped portal for employees: tasks, time logs, tickets

Fixed

  • RLS policy gaps on documents table: policies were missing tenant_id check, allowing cross-tenant reads in certain configurations
  • Supabase FK array typing: corrected TypeScript interfaces throughout the codebase to use array syntax ([0] indexing) for nested Supabase joins, resolving widespread TypeScript build errors

[0.8.0] โ€” 2026-04-01

Core commercial modules complete. First testable version of the revenue cycle.

Added

  • Proposals โ€” Full proposal builder with line items, subtotal calculation, status workflow, and email delivery
  • Contracts โ€” Contract creation, e-signature workflow, signing portal (placeholder โ€” full portal in 0.9.0)
  • Invoices โ€” Invoice creation, manual status management (Stripe integration in 0.9.0)
  • Support Ticket System โ€” Client ticket creation and employee reply thread (portal access in 0.9.0)
  • Document Sharing โ€” Admin upload and Supabase Storage integration; download link generation
  • Notification System โ€” In-app bell, notification types defined, createNotification helper
  • Reports โ€” Revenue report (basic) and time log report (basic)
  • In-App Wiki โ€” Article CRUD, category management, published/unpublished toggle

Fixed

  • Multiple TypeScript compilation errors caused by Supabase nested join return types being incorrectly typed as single objects rather than arrays
  • amount_cents column reference replaced with subtotal_cents throughout proposals and invoices codebase after DB schema clarification

[0.7.0] โ€” 2026-02-15

Platform foundation. First functional alpha.

Added

  • Authentication โ€” Supabase Auth integration, email/password login, session management
  • Tenant System โ€” Multi-tenant data model; tenant_id on all tables; RLS policies (initial implementation)
  • Lead Management โ€” Lead record CRUD, pipeline status field
  • Client Management โ€” Client record CRUD, contact management (single contact per client in this version)
  • Project Management โ€” Project CRUD linked to clients
  • Task Management โ€” Task CRUD linked to projects, employee assignment
  • Time Logging โ€” Basic time log entry and list
  • Admin Dashboard โ€” Summary statistics panel (counts of leads, clients, projects, invoices)
  • Next.js 15 App Router โ€” Full migration to App Router with edge runtime; all routes use export const runtime = 'edge'
  • Supabase Integration โ€” createClient() for user-scoped queries, createServiceClient() for admin/service-role queries
  • requireAdminWithTenant() Auth Guard โ€” Reusable admin API route protection helper

Release History

This page is the authoritative version history for the SONAN DIGITAL CRM platform, from the first alpha through the current production release.


Semantic Versioning Policy

This project follows Semantic Versioning 2.0.0. The version format is MAJOR.MINOR.PATCH.

Part When to Increment Examples
MAJOR Significant platform milestone, a new suite of modules, or a breaking change to an external integration (Stripe, Supabase schema, API contract) v0.x โ†’ v1.0.0 (production launch); future: v1 โ†’ v2 if multi-org or white-label added
MINOR New features added in a backward-compatible manner; new modules, pages, or API endpoints that do not break existing functionality v1.0 โ†’ v1.1 (PDF generation, rate limiting, recovery codes)
PATCH Backward-compatible bug fixes, security patches, dependency updates, or minor UI improvements with no functional change v1.0.0 โ†’ v1.0.1 (fix webhook edge case); v1.1.0 โ†’ v1.1.1 (fix decimal qty bug)

Release Type Definitions Used in This Project

Type Description
Alpha Internal development build. Core foundation only. Not suitable for external users or demos. May have known data integrity issues.
Beta Feature-implemented but not fully tested. Suitable for internal UAT and stakeholder previews. Not for production client use.
RC (Release Candidate) Feature-frozen, UAT passed on all critical paths. Minor polish remaining. Ready for production pending sign-off. (Not used in v1.0 cycle โ€” went directly from Beta to Release after UAT.)
Major Release UAT signed off, all Critical and High defects resolved or accepted. Deployed to production. Suitable for live client use.
Hotfix Emergency patch to a production release. Follows expedited testing (targeted retest only) and fast-track deployment. Versioned as a PATCH increment.

Full Release History

Version Release Date Type Key Changes Defects Fixed
v1.0.0 2026-06-30 Major Release Initial production release. Full multi-tenant CRM: Leads, Clients, Proposals, Contracts, Invoices (Stripe Checkout), Recurring Invoices, Projects, Tasks, Time Logs, Support Tickets, Documents, Reports, Wiki, Notifications, Employee Portal, Client Portal. TOTP MFA for all roles. CRIT-4, CRIT-7, H8
v0.9.0 2026-05-15 Beta Feature complete. Full client portal, Stripe Checkout integration, MFA enforcement, employee portal, client invitation flow. Pre-UAT candidate. RLS gap on documents table; Supabase FK array typing errors throughout codebase
v0.8.0 2026-04-01 Beta Core commercial modules: Proposals, Contracts, Invoices (manual), Support Tickets, Documents, Notifications, Reports (basic), Wiki. subtotal_cents vs amount_cents column naming fix; multiple TypeScript build errors
v0.7.0 2026-02-15 Alpha Platform foundation: Auth, multi-tenant model, RLS policies, Leads, Clients, Projects, Tasks, Time Logs, Admin Dashboard. Next.js 15 App Router + edge runtime migration. โ€” (initial build)

Upcoming Releases

The following releases are planned. Scope is subject to change based on UAT findings and prioritization.

Version Target Date Type Planned Scope
v1.0.1 TBD Patch Emergency bug fixes identified post-launch (if any). Stripe webhook edge cases.
v1.1.0 2026-Q3 Minor PDF generation (invoices/contracts), rate limiting on API routes, TOTP recovery codes, email delivery failure visibility, recurring invoice auto-email to client, signed URL on-demand generation
v1.2.0 2026-Q4 Minor Audit log for admin actions, multi-currency support, proposal templates, invoice payment reminders, bulk client import
v2.0.0 2027 Major (Tentative) White-label multi-organization support, custom domain per tenant, reseller billing model

Version Support Policy

Version Status Support Until
v1.0.x Active โ€” Current production version Until v1.1.0 is released (all critical fixes backported)
v0.9.x Retired โ€” Replaced by v1.0.0 No further support
v0.8.x Retired No further support
v0.7.x Retired No further support

Once a new MINOR version is released, the previous MINOR version receives critical security patches only for 30 days, then is retired. PATCH versions within the same MINOR are always cumulative โ€” apply the latest patch, never an intermediate one.


How Releases Are Made

  1. Development occurs on feature branches (or directly on main for small fixes, per team convention).
  2. Staging deployment is triggered automatically via Vercel preview on new commits to main (or a staging branch).
  3. UAT is run against the staging deployment per the UAT Execution Guide.
  4. Sign-off is obtained per UAT Sign-Off.
  5. Production deployment is performed by pushing the release commit SHA directly to main: bash git push origin <sha>:refs/heads/main (Per the FUSE-safe git workflow documented in CLAUDE.md, the push is always done from the Windows terminal, not the sandbox.)
  6. Post-release verification follows the Release Checklist.
  7. Release notes and this page are updated to reflect the new version.