Commit Graph

129 Commits

Author SHA1 Message Date
poduck
7b18637b1e feat(tenant): Add public-facing landing page for business subdomains
- 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>
2025-12-03 17:54:46 -05:00
poduck
3a1b2f2dd8 fix(onboarding): Change 'Go to Dashboard' to 'Go to Login'
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>
2025-12-03 17:47:59 -05:00
poduck
88b54ef9e4 chore(traefik): Remove debug logging, set production log level
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>
2025-12-03 17:39:39 -05:00
poduck
5cdbc19517 fix(traefik): Fix HostRegexp YAML escaping for subdomain routing
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>
2025-12-03 17:38:57 -05:00
poduck
f3a0f1f07a debug: Add access logging to Traefik
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 17:37:47 -05:00
poduck
f3951295ac fix(traefik): Remove conflicting TCP router for subdomain handling
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>
2025-12-03 17:34:41 -05:00
poduck
9cbf19ed1b fix(traefik): Simplify HTTP HostRegexp pattern
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 17:32:53 -05:00
poduck
88c74398e4 fix(traefik): Simplify HostSNIRegexp pattern for wildcard subdomains
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 17:29:17 -05:00
poduck
86947ab206 feat(deploy): Add selective service rebuild and --no-migrate option
- 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>
2025-12-03 17:27:17 -05:00
poduck
7cc013eaf2 fix(traefik): Add TCP router with HostSNIRegexp for wildcard subdomain TLS
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>
2025-12-03 17:19:21 -05:00
poduck
a723d784cd fix(traefik): Add TLS store for wildcard subdomain routing
- 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>
2025-12-03 17:14:36 -05:00
poduck
13441d88fc fix(traefik): Use separate storage files for certificate resolvers
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>
2025-12-03 17:08:34 -05:00
poduck
b20fa5cfd8 fix(traefik): Update HostRegexp syntax for Traefik v3
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>
2025-12-03 16:59:45 -05:00
poduck
093f6d9a62 fix(traefik): Add env_file to read Cloudflare token
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 16:53:33 -05:00
poduck
5bf2fc5319 fix(traefik): Use Cloudflare DNS provider instead of DigitalOcean
DNS is hosted on Cloudflare, not DigitalOcean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 16:50:21 -05:00
poduck
33e4b6b9b5 feat(traefik): Add DNS challenge for wildcard SSL certificates
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>
2025-12-03 16:48:50 -05:00
poduck
434f874963 fix(traefik): Route tenant subdomains to nginx instead of django
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>
2025-12-03 16:40:18 -05:00
poduck
0d3c97ea5f fix(onboarding): Improve loading indicator with elapsed time and better pacing
- 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>
2025-12-03 16:37:34 -05:00
poduck
567fe0604a feat(onboarding): Add animated loading indicator and fix completion
- 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>
2025-12-03 16:26:11 -05:00
poduck
5244e16279 fix(tenant): Defer plugin seeding until after transaction commits
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>
2025-12-03 16:11:51 -05:00
poduck
55cb97ca0d fix(deploy): Check if backup directory has content before restoring
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 16:05:04 -05:00
poduck
a170d6134b fix(invitations): Use tenant-onboard page for platform invitations
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>
2025-12-03 16:02:02 -05:00
poduck
d2c4cbe183 fix(deploy): Fix .envs and .ssh restore to copy contents not directory
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 15:57:34 -05:00
poduck
47f1a4d7b4 fix(deploy): Backup and restore .ssh keys during git-based deployments
SSH keys for mail server management are not in git, need to preserve
them like .envs secrets.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 15:51:08 -05:00
poduck
b455be0ac6 fix(docker): Update nginx context path for git-based deployments
Changed from ../smoothschedule-frontend to ../frontend to match
the git repository structure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 15:50:31 -05:00
poduck
abf67a36ed fix(invitations): Support both platform and staff invitation types
- 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>
2025-12-03 15:49:59 -05:00
poduck
4f515c3710 feat: Quota enforcement UI and various improvements
- Add quota limit warnings to Resources, Services, and OwnerScheduler pages
- Add quotaUtils.ts for checking quota limits
- Update BusinessLayout with quota context
- Improve email receiver logging
- Update serializers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 15:47:48 -05:00
poduck
fd751f02f8 refactor(deploy): Use git pull instead of rsync for deployments
- 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>
2025-12-03 15:46:01 -05:00
poduck
04bb9e3c14 fix(auth): Allow accept-invite on subdomains without redirect to login
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>
2025-12-03 15:28:17 -05:00
poduck
39a376b39b fix(email): Add SMTP configuration and fix invitation link routing
- 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>
2025-12-03 15:19:46 -05:00
poduck
85c4b835fd fix(mail): Copy SSH keys into Docker image instead of volume mount
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>
2025-12-03 13:40:57 -05:00
poduck
bed0ba9304 feat(mail): Add mail server SSH configuration
- 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>
2025-12-03 13:33:19 -05:00
poduck
dcb14503a2 feat: Dashboard redesign, plan permissions, and help docs improvements
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>
2025-12-03 13:02:44 -05:00
poduck
9444e26924 docs(help): Comprehensive rewrites for Resources, Services, Customers, Staff guides
HelpResources.tsx:
- Added resource types section with Staff/Room/Equipment
- Documented table columns and their meanings
- Added step-by-step resource creation guide
- Added staff autocomplete with keyboard navigation
- Detailed multilane mode for concurrent bookings
- Documented View Calendar and Edit features

HelpServices.tsx:
- Documented two-column layout with customer preview
- Added drag-and-drop reordering instructions
- Detailed service properties (name, duration, price, description)
- Added photo gallery section with upload, reorder, delete
- Documented customer preview mockup feature

HelpCustomers.tsx:
- Documented customer table columns
- Added search and sorting capabilities
- Step-by-step customer creation guide
- Documented customer statuses (Active, Inactive, Blocked)
- Added tags section for customer organization
- Documented masquerading feature for customer support

HelpStaff.tsx:
- Detailed staff roles (Owner, Manager, Staff) with badges
- Staff table columns documentation
- Step-by-step staff invitation workflow
- Pending invitations management (resend, cancel)
- Edit staff modal with permissions
- Make Bookable feature for linking to resources
- Inactive staff section with reactivation
- Masquerading as staff for training/troubleshooting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 02:44:02 -05:00
poduck
445b2bb3fc fix(help): Correct pending appointments sidebar position to left
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>
2025-12-03 02:35:06 -05:00
poduck
baffe7e577 docs(help): Comprehensive Scheduler documentation with all features
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>
2025-12-03 02:27:39 -05:00
poduck
5aa49399d0 feat(help): Add floating help button to all pages
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>
2025-12-03 02:23:28 -05:00
poduck
11bb83a85d feat: Add comprehensive help documentation system and plugin creation page
- Add CreatePlugin.tsx page for custom plugin creation with code editor
- Add HelpButton component for contextual help links
- Create 21 new help pages covering all dashboard features:
  - Core: Dashboard, Scheduler, Tasks
  - Manage: Customers, Services, Resources, Staff
  - Communicate: Messages (Ticketing already existed)
  - Money: Payments
  - Extend: Plugins overview and creation guide
  - Settings: General, Resource Types, Booking, Appearance, Email, Domains, API, Auth, Billing, Quota
- Update HelpGuide.tsx as main documentation hub with quick start guide
- Add routes for all help pages in App.tsx
- Add HelpButton to Dashboard, Customers, Services, and Tasks pages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 02:18:05 -05:00
poduck
5cef01ad0d feat: Reorganize settings sidebar and add plan-based feature locking
- 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>
2025-12-03 01:35:59 -05:00
poduck
ef58e9fc94 feat: Stripe subscriptions, tier-based permissions, dark mode, and UX improvements
- 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>
2025-12-02 20:50:18 -05:00
poduck
08b51d1a5f feat: Quota overage system, updated tier pricing, and communication addons
Quota Overage System:
- Add QuotaOverage model for tracking resource/user quota overages
- Implement 30-day grace period with email notifications (immediate, 7-day, 1-day)
- Add QuotaWarningBanner component in BusinessLayout
- Add QuotaSettings page for managing overages and archiving resources
- Add Celery tasks for automated quota checks and expiration handling
- Add quota management API endpoints

Updated Tier Pricing (Stripe: 2.9% + $0.30):
- Free: No payments (requires addon)
- Starter: 4% + $0.40
- Professional: 3.5% + $0.35
- Business: 3.25% + $0.32
- Enterprise: 3% + $0.30

New Subscription Addons:
- Online Payments ($5/mo + 5% + $0.50) - for Free tier
- SMS Notifications ($10/mo) - enables SMS reminders
- Masked Calling ($15/mo) - enables anonymous calling

BusinessEditModal Improvements:
- Increased width to match PlanModal (max-w-3xl)
- Added all tier options with auto-update on tier change
- Added limits configuration and permissions sections

Backend Fixes:
- Fixed SubscriptionPlan serializer to include all communication fields
- Allow blank business_tier for addon plans
- Added migration for business_tier field changes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 13:05:02 -05:00
poduck
dc3210927a feat(platform): Add confirmation modal for email verification
- 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>
2025-12-02 11:26:47 -05:00
poduck
42988c0f88 fix(platform): Allow POST method for verify_email action
The PlatformUserViewSet restricted HTTP methods to GET and PATCH,
but the verify_email action requires POST. Added POST to allowed
methods.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 11:22:13 -05:00
poduck
e4ad7fca87 feat: Plan-based feature permissions and quota enforcement
Backend:
- Add HasQuota() permission factory for quota limits (resources, users, services, appointments, email templates, automated tasks)
- Add HasFeaturePermission() factory for feature-based permissions (SMS, masked calling, custom domains, white label, plugins, webhooks, calendar sync, analytics)
- Add has_feature() method to Tenant model for flexible permission checking
- Add new tenant permission fields: can_create_plugins, can_use_webhooks, can_use_calendar_sync, can_export_data
- Create Data Export API with CSV/JSON support for appointments, customers, resources, services
- Create Analytics API with dashboard, appointments, revenue endpoints
- Add calendar sync views and URL configuration

Frontend:
- Add usePlanFeatures hook for checking feature availability
- Add UpgradePrompt components (inline, banner, overlay variants)
- Add LockedSection wrapper and LockedButton for feature gating
- Update settings pages with permission checks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 11:21:11 -05:00
poduck
05ebd0f2bb feat: Email templates, bulk delete, communication credits, plan features
- Add email template presets for Browse Templates tab (12 templates)
- Add bulk selection and deletion for My Templates tab
- Add communication credits system with Twilio integration
- Add payment views for credit purchases and auto-reload
- Add SMS reminder and masked calling plan permissions
- Fix appointment status mapping (frontend/backend mismatch)
- Clear masquerade stack on login/logout for session hygiene
- Update platform settings with credit configuration
- Add new migrations for Twilio and Stripe payment fields

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 01:42:38 -05:00
poduck
8038f67183 fix(frontend): Add missing RefreshCw import to PlatformSettings
The Tiers & Pricing tab was crashing with "RefreshCw is not defined"
because the icon was used but not imported from lucide-react.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 20:58:44 -05:00
poduck
ee6cf2b802 fix(tickets): Remove invalid source_email_address_id in PlatformEmailReceiver
PlatformEmailReceiver was setting source_email_address_id to a
PlatformEmailAddress ID, but the Ticket model expects a TicketEmailAddress
foreign key. This caused an integrity error that was rolling back the
entire transaction (due to ATOMIC_REQUESTS=True), preventing tickets
from being created.
2025-12-01 19:32:45 -05:00
poduck
c82c60a562 fix(traefik): Add host rewriting for email autoconfig endpoints
Django's multi-tenant middleware doesn't recognize autoconfig/autodiscover
subdomains. This middleware rewrites the Host header to api.smoothschedule.com
so Django routes the request to the public schema.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 19:14:25 -05:00
poduck
06e0ec3d01 fix: Add SSH client and autoconfig routes for production
- Install openssh-client in production Django container for mail server management
- Copy .ssh keys into container with proper permissions
- Add explicit Traefik routes for autoconfig/autodiscover subdomains

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 18:03:40 -05:00
poduck
ae74b4c2ed feat: Multi-email ticketing system with platform email addresses
- Add PlatformEmailAddress model for managing platform-level email addresses
- Add TicketEmailAddress model for tenant-level email addresses
- Create MailServerService for IMAP integration with mail.talova.net
- Implement PlatformEmailReceiver for processing incoming platform emails
- Add email autoconfiguration for Mozilla, Microsoft, and Apple clients
- Add configurable email polling interval in platform settings
- Add "Check Emails" button on support page for manual refresh
- Add ticket counts to status tabs on support page
- Add platform email addresses management page
- Add Privacy Policy and Terms of Service pages
- Add robots.txt for SEO
- Restrict email addresses to smoothschedule.com domain only

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 17:49:09 -05:00