Dynamically set robots meta tag to noindex/nofollow when on any
subdomain (platform.*, demo.*, etc.). Only the root domain
marketing pages should be indexed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Set robots meta tag to noindex, nofollow (site not live)
- Update robots.txt with instructions for going live
- Add sitemap.xml with all marketing pages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace "multi-tenant" wording with user-friendly alternatives
- Hero subheadline: "Secure" instead of "Multi-tenant"
- Feature title: "Enterprise Security" instead of "Multi-Tenant Architecture"
- Updated testimonials and FAQ to remove technical references
- Add comprehensive SEO meta tags to index.html:
- Meta description for search engines
- Open Graph tags for social sharing
- Twitter card meta tags
- Canonical URL and robots directives
- Update all language files (en, es, fr, de) with consistent changes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Simplified UI with Email, Business Name, and Subscription Tier fields
- Added collapsible "Override Tier Limits" section with sliding animation
- Permission options match platform settings structure (Payments, Communication, Customization, Plugins, Advanced, Enterprise)
- Permissions are loaded from subscription plans or fallback to static defaults
- Custom limits/permissions only sent to backend when override is checked
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- New TenantLandingPage component with 'Coming Soon' message
- Shows business name derived from subdomain
- Has 'Sign In' button that goes to /login
- 'Powered by SmoothSchedule' footer
- Will be customizable later for each tenant
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The button after tenant creation was misleading - users need to log in first.
Changed button text and URL to explicitly point to /login.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Wildcard subdomain routing is now working. Removed access logging
that was added for debugging.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
In YAML single-quoted strings, backslashes are literal characters.
'\\.' was being interpreted as two backslashes + dot, not as an
escaped dot in the regex.
Changed from '\\.smoothschedule\\.com' to '\.smoothschedule\.com'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The TCP router was intercepting wildcard subdomain traffic at the TCP layer
and sending it directly to nginx:80, bypassing HTTP routing entirely.
This caused 404 errors because nginx wasn't receiving proper HTTP routing.
Now relying on:
- TLS store's defaultGeneratedCert for wildcard certificate
- HTTP HostRegexp router for subdomain routing to nginx
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add support for specifying services to rebuild (e.g., ./deploy.sh traefik)
- Add --no-migrate flag to skip migrations for config-only changes
- Reduce wait time from 10s to 5s
Usage examples:
./deploy.sh # Build all, run migrations
./deploy.sh traefik --no-migrate # Only rebuild traefik, skip migrations
./deploy.sh django nginx # Build django and nginx, run migrations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add a TCP-level router using HostSNIRegexp to match unknown subdomains
at the TLS layer and terminate TLS with wildcard certificate.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add default TLS store with wildcard certificate for unknown SNIs
- Add priority=1 to subdomain-router for catch-all behavior
- Use proper Traefik v3 HostRegexp syntax with anchors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Separate acme.json storage for HTTP and DNS certificate resolvers
to prevent conflicts when requesting wildcard certificates.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Traefik v3 changed HostRegexp syntax from named capture groups to
standard regex. Added low priority to avoid matching specific routes.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
HostRegexp patterns don't work with HTTP challenge because Traefik
can't request certificates for dynamic subdomains. Switched to DNS
challenge using DigitalOcean provider for *.smoothschedule.com wildcard.
Requires DO_AUTH_TOKEN environment variable to be set.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The subdomain-router was incorrectly sending tenant subdomain requests
directly to Django (API server), causing 404 errors. Now routes to nginx
which serves the React SPA and proxies /api/ requests to Django.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add elapsed time counter (MM:SS)
- Spread animation steps over ~30 seconds before final step
- Final step stays spinning (doesn't complete early)
- Progress bar caps at 90% until actually done, pulses on final step
- Show "Finalizing..." and helpful message during long final step
- Clear "45-90 seconds" time estimate upfront
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add multi-step animated loading indicator during tenant creation
- Fix blank completion screen (was checking wrong step number)
- Auto-verify email for users accepting tenant invitations
- Show progress bar and step-by-step status during database setup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The post_save signal was trying to seed plugins before the tenant's
schema migrations had completed, causing a 500 error when accepting
tenant invitations. Using transaction.on_commit() ensures the schema
and tables exist before seeding.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Platform/tenant invitations should redirect to /tenant-onboard which has
the full onboarding wizard, not /accept-invite which is for staff invitations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update useInvitationDetails to try platform tenant invitation first,
then fall back to staff invitation
- Update useAcceptInvitation to handle both invitation types
- Update useDeclineInvitation to handle both invitation types
- Pass invitation type from AcceptInvitePage to mutations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Requires changes to be committed and pushed before deploying
- Clones repo on first deploy, then uses git fetch/reset
- Preserves .envs secrets which are not in git
- Better for multi-developer workflows
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Don't redirect unauthenticated users to login when accessing public paths
like /accept-invite, /verify-email, or /tenant-onboard on subdomains.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add SMTP email backend support to production settings (EMAIL_HOST, EMAIL_PORT, etc.)
- Falls back to console backend if SMTP not configured
- Fix AcceptInvitePage to support both path parameter (/accept-invite/:token) and
query parameter (?token=...) formats for invitation tokens
- Add route for /accept-invite/:token in App.tsx
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove volume mount for SSH keys and rely on Dockerfile COPY instruction
to bake SSH keys into the image during build. This ensures proper
permissions and ownership for the django user.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Mount SSH keys in Django container for mail server access
- Add mail server configuration environment variables
- Import mail server settings in production.py with env defaults
- Configure mail.talova.net SSH connection parameters
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major updates including:
- Customizable dashboard with drag-and-drop widget grid layout
- Plan-based feature locking for plugins and tasks
- Comprehensive help documentation updates across all pages
- Plugin seeding in deployment process for all tenants
- Permission synchronization system for subscription plans
- QuotaOverageModal component and enhanced UX flows
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed documentation that incorrectly stated the pending appointments
sidebar appears on the right side of the scheduler when it actually
appears on the left side.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Rewrote HelpScheduler.tsx to document actual scheduler features including:
- Drag-and-drop to reschedule, change resource, or delete appointments
- Resize appointments by dragging edges (start or end)
- Pending appointments sidebar with archive zone
- Undo/Redo with Ctrl+Z/Ctrl+Y (up to 50 actions)
- Zoom controls for timeline detail
- Status colors (blue/yellow/red/green/gray)
- Filtering by status, resource, and service
- Overlapping appointment lanes
- Real-time WebSocket updates
- Month view click-to-day and drag overlay features
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replaced inline HelpButton components with a global FloatingHelpButton
that appears fixed in the top-right corner of all pages. The button:
- Automatically detects the current route and links to the appropriate help page
- Uses a consistent position across all pages (fixed, top-right)
- Is hidden on help pages themselves
- Works on both business and platform layouts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add locked state to Plugins sidebar item with plan feature check
- Create Branding section in settings with Appearance, Email Templates, Custom Domains
- Split Domains page into Booking (URLs, redirects) and Custom Domains (BYOD, purchase)
- Add booking_return_url field to Tenant model for customer redirects
- Update SidebarItem component to support locked prop with lock icon
- Move Email Templates from main sidebar to Settings > Branding
- Add communication credits hooks and payment form updates
- Add timezone fields migration and various UI improvements
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix Stripe SDK v14 compatibility (bracket notation for subscription items)
- Fix subscription period dates from subscription items instead of subscription object
- Add tier-based permissions (can_accept_payments, etc.) on tenant signup
- Add stripe_customer_id field to Tenant model
- Add clickable logo on login page (navigates to /)
- Add database setup message during signup wizard
- Add dark mode support for payment settings and Connect onboarding
- Add subscription management endpoints (cancel, reactivate)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create reusable ConfirmationModal component with variants (info, warning, danger, success)
- Replace browser confirm() dialogs with styled modal for email verification
- Update PlatformBusinesses and PlatformUsers to use the new modal
- Add translation keys for verification messages
- Unverify test@example.com for testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>