Skip to content

Release Candidate RC1 — Production Readiness

FieldValue
Recommended tagv1.2.0-rc.1 (never tagged — ship GA as v1.1.0)
Release date2026-07-14
StatusRelease Candidate — absorbed into v1.1.0
BasePlatform foundation + CRM Sprint 2
ScopeHardening only — no new business modules

Summary

RC1 closes Critical and High severity production blockers discovered during the production readiness audit across Backend, Frontend, and ops docs. The platform remains under the architecture freeze; this release is security, resilience, and operator readiness.


Release Notes

Security

  • Suspended users: Sanctum tokens revoked on suspend; not.suspended middleware rejects remaining sessions
  • Workspace self-registration defaults to off
  • Branding uploads reject SVG (stored XSS); privileged user fields stay non-fillable
  • CORS origins pinned via FRONTEND_URL / CORS_ALLOWED_ORIGINS
  • Impersonation targets workspace owner (superadmin) only
  • Password-reset emails include workspace query param for tenant SPA routing
  • SPA: Safe post-login redirects; email-verify redirect allowlisted to API origin
  • SPA: React Query cache cleared on login, impersonation, logout, and 401 handling
  • Payment API / webhook logs redact raw gateway bodies
  • Protected role assignment: cannot assign superadmin via tenant user APIs

Billing & webhooks

  • Webhook logs store safe summaries only (never full Stripe payloads)
  • Unique (payment_gateway_id, provider_event_id) prevents double processing
  • Cashier /stripe/webhook and /webhooks/gateways/stripe share the same idempotency store
  • Stripe driver requires signature unless preVerified: true (Cashier path only)

Ops & observability

  • Health /up checks DB; also Redis when cache/queue drivers use Redis
  • Queued notifications; scheduler uses withoutOverlapping
  • Production runbook updated

Frontend UX / a11y

  • Lead / Task detail sheets sync to ?lead= / ?task= (Back closes the drawer)
  • Billing pages surface ErrorState on query failure
  • Skip-to-content link; Kanban keyboard sensor
  • Remember-me defaults off
  • Email verified gate treats missing email_verified_at as unverified

Performance

  • Kanban board APIs cap cards per column (per_column, default 50, max 100) while returning accurate counts

Upgrade Notes

  1. Pull RC1; run composer install --no-dev / npm ci && npm run build as applicable.
  2. Set production env (see Production Checklist). Especially:
    • APP_DEBUG=false
    • CACHE_STORE=redis (required for Stancl tenant cache tags)
    • QUEUE_CONNECTION=redis (recommended)
    • STRIPE_WEBHOOK_SECRET non-empty when Stripe is live
    • Pin FRONTEND_URL / CORS_ALLOWED_ORIGINS
  3. Run migrations:
    bash
    php artisan migrate --force
    Includes webhook_logs unique index (duplicates are pruned to the earliest row).
  4. Warm caches: config:cache, route:cache, event:cache, view:cache
  5. Restart queue workers: php artisan queue:restart
  6. If using open registration, explicitly set registration_enabled to true in Central system settings (seeded default is now false).
  7. Point Stripe to one primary business webhook preferred: /webhooks/gateways/stripe. Keep /stripe/webhook for Cashier subscription mirroring if needed — both are idempotent for BillingEngine side effects.

Production Checklist

  • [ ] APP_ENV=production, APP_DEBUG=false, APP_KEY backed up
  • [ ] TLS terminated; SESSION_SECURE_COOKIE=true
  • [ ] CACHE_STORE=redis + Redis reachable
  • [ ] Emails queue worker running (queue:work --queue=emails); scheduler every minute
  • [ ] STRIPE_WEBHOOK_SECRET set; gateway sandbox/live mode correct
  • [ ] CORS / FRONTEND_URL exact SPA origins
  • [ ] registration_enabled intentional
  • [ ] FILESYSTEM_DISK=s3 + AWS_* configured; storage:migrate-to-s3 if migrating local branding; bucket backups (object-storage.md)
  • [ ] Log rotation configured; Nightwatch/Telescope policy decided
  • [ ] Database + Redis backups scheduled
  • [ ] GET /up returns 200
  • [ ] Smoke: central login, tenant login, lead create, task create, test webhook, forgot-password queued

Deployment Checklist

bash
php artisan down --retry=60   # optional
git checkout v1.2.0-rc.1      # or deploy artifact
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan event:cache
php artisan view:cache
php artisan queue:restart
php artisan up

Frontend: build SPA and publish static assets behind HTTPS.


Rollback Checklist

  1. Redeploy previous release artifact / prior tag
  2. Rollback migrations only if safe for this release (webhook_logs unique index is reversible; data loss risk is low)
  3. php artisan queue:restart
  4. Verify /up, login, and Stripe webhook reachability
  5. If registration was relied upon while default was on, re-enable via Central settings after rollback if needed

Known Issues / Limitations

ItemSeverityNotes
Assignee pickers load first 100 usersMediumSearchable async select deferred; use list filters for large orgs
Bearer tokens in web storageMediumSPA/Sanctum Bearer design; XSS surface locked down; remember defaults off
Spatie teams falseLowRoles scoped by tenant_id column; avoid Role::findByName without tenant
Dual Stripe ingressInfoShared idempotency; prefer documenting one ops webhook URL

Verification (RC1)

SuiteResult
New/updated Pest (suspend, webhook idempotency, impersonation owner, related auth/settings)Passed in hardening runs
Full Pest / PlaywrightRe-run before GA tag

Recommended GA tag: v1.1.0 (RC1 never received a git tag; GA uses clean SemVer).


Official documentation for the SaleOS SaaS Platform.