Commit Graph

128 Commits

Author SHA1 Message Date
poduck
5147101c7c remove: Django Debug Toolbar from development setup
Removed django-debug-toolbar as it's unnecessary for API-only setup:
- Removed from INSTALLED_APPS and MIDDLEWARE in local.py
- Removed from dev dependencies in pyproject.toml
- Updated uv.lock after package removal

The debug toolbar was interfering with API documentation pages
and provides minimal value for a primarily API-based application.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 04:01:51 -05:00
poduck
10afe61bb8 fix(debug-toolbar): Hide debug toolbar on API documentation pages
Added SHOW_TOOLBAR_CALLBACK to exclude the debug toolbar from
displaying on /v1/* paths (Swagger UI and ReDoc documentation).

This prevents the large debug toolbar logo from interfering with
the API documentation interface.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 03:59:40 -05:00
poduck
f16ccf76a8 fix(csp): Add cdn.jsdelivr.net to local CSP policy for Swagger UI
Updated local.py CSP directives to match multitenancy.py changes.
This allows Swagger UI assets to load in local development.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 03:58:09 -05:00
poduck
86cde135a9 fix(csp): Allow cdn.jsdelivr.net for Swagger UI assets
Added cdn.jsdelivr.net to Content Security Policy directives to allow
Swagger UI assets (JavaScript, CSS, and images) to load properly.

Updated CSP directives:
- CSP_SCRIPT_SRC: Added cdn.jsdelivr.net for swagger-ui-bundle.js
- CSP_STYLE_SRC: Added cdn.jsdelivr.net for swagger-ui.css
- CSP_IMG_SRC: Added cdn.jsdelivr.net for favicon

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 03:56:05 -05:00
poduck
7e151a23cc fix(api-docs): Use absolute API URL for Interactive Explorer link
The Interactive Explorer link was using a relative URL (/v1/docs/), which caused it to open on the current subdomain instead of the API subdomain. This resulted in users being redirected to the dashboard.

Changed to use API_BASE_URL to construct the absolute URL, which will correctly point to:
- Local: http://lvh.me:8000/v1/docs/
- Production: https://api.smoothschedule.com/v1/docs/

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 03:50:55 -05:00
poduck
63723906d0 fix(production): Configure frontend build for api.smoothschedule.com subdomain
- Update nginx build context to ../smoothschedule-frontend (matches deployment structure)
- Add VITE_API_URL build arg to pass API URL during frontend build
- Fixes login issues caused by incorrect API endpoint configuration

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 03:03:48 -05:00
poduck
99adeda83c feat(production): Configure WebSocket auth and multi-tenant cookies for production
- Add TokenAuthMiddleware to WebSocket connections for authenticated access
- Configure SESSION_COOKIE_DOMAIN and CSRF_COOKIE_DOMAIN for subdomain sharing (.smoothschedule.com)
- Remove '/api' prefix from URL routes to align frontend/backend conventions
- Fix imports in asgi.py (tickets instead of smoothschedule.tickets)
- Update dependencies (pyproject.toml, uv.lock)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 02:54:03 -05:00
poduck
2b4104a819 chore(deploy): Update production configuration for ASGI and new URL structure
- Switched production start script from Gunicorn to Daphne to support WebSockets.
- Updated VITE_API_URL in frontend production env to 'https://api.smoothschedule.com', removing the '/api' prefix to align with the backend URL refactor.
2025-12-01 02:44:51 -05:00
poduck
fa3195b3b3 feat(multitenancy): Add TenantHeaderMiddleware to support centralized API with tenant switching
- Implemented TenantHeaderMiddleware to switch the database tenant schema based on the 'X-Business-Subdomain' request header.
- This allows API requests directed to the centralized 'api' subdomain (e.g., api.lvh.me) to correctly access tenant-specific data when the header is present.
- Registered the middleware in multitenancy settings after TenantMainMiddleware.
2025-12-01 02:41:25 -05:00
poduck
980b5d36aa fix(scheduler): Update Timeline to use apiClient for authenticated resource fetching
The Timeline component was using a raw axios instance with hardcoded URLs, causing it to bypass authentication and tenant context headers. This resulted in empty or failed data fetches. Updated it to use the configured 'apiClient', ensuring that the authentication token and 'X-Business-Subdomain' headers are correctly sent, allowing the backend to return the appropriate tenant-specific resources and appointments.
2025-12-01 02:32:48 -05:00
poduck
5cd689af0a fix(auth): Remove hash from email verification URL to support BrowserRouter
The email verification link was incorrectly including a hash fragment (/#/), which caused the React Router (using BrowserRouter) to misinterpret the path as the root path, leading to a redirect to the default 'email-verification-required' page instead of the 'verify-email' page. This commit removes the hash, ensuring the link correctly points to /verify-email.
2025-12-01 02:20:03 -05:00
poduck
b3e2c1f324 refactor(frontend): Remove '/api' prefix from all API calls to align with backend URL convention
- Updated all API endpoint strings in 'frontend/src' (via sed and manual fixes) to remove the '/api/' prefix.
- Manually fixed 'Timeline.tsx' absolute URLs to use the 'api' subdomain and correct path.
- Manually fixed 'useAuth.ts' logout fetch URLs.
- Updated 'HelpApiDocs.tsx' sandbox URL.
- This change, combined with the backend URL update, fully transitions the application to use subdomain-based routing (e.g., 'http://api.lvh.me:8000/resource/') instead of path-prefix routing (e.g., 'http://api.lvh.me:8000/api/resource/').
2025-12-01 02:14:17 -05:00
poduck
92724d03b6 refactor(api): Remove '/api' prefix from frontend API calls and config
- Removed '/api/' prefix from endpoint paths in auth.ts, notifications.ts, oauth.ts, and platform.ts to align with the backend URL reconfiguration.
- Updated 'API_BASE_URL' in config.ts to remove the '/api' suffix, ensuring that API requests are correctly routed to the root of the 'api' subdomain (e.g., http://api.lvh.me:8000/).
- Included improvements to login redirect logic in client.ts.
2025-12-01 01:48:22 -05:00
poduck
2ec78a5237 fix(urls): Remove 'api/' prefix from tickets endpoint to match frontend expectation 2025-12-01 01:45:22 -05:00
poduck
a274d70cec feat(websocket): Resolve ticket WebSocket disconnection/reconnection issue
This commit addresses the persistent WebSocket disconnection and reconnection
problem experienced with ticket updates. The root cause was identified as the
Django backend not running as an ASGI server, which is essential for WebSocket
functionality, and incorrect WebSocket routing.

The following changes were made:

- **Frontend ():**
  - Updated to append the  from cookies to the WebSocket URL's
    query parameter for authentication, ensuring the token is sent with the
    WebSocket connection request.

- **Backend Configuration:**
  - **:** Modified to explicitly
    start the Daphne ASGI server using  instead
    of . This ensures the backend runs in ASGI
    mode, capable of handling WebSocket connections.
  - **:** Removed 'daphne' from
    . Daphne is an ASGI server, not a traditional Django
    application, and its presence in  was causing application
    startup failures.
  - **:**
    - Removed  from  as it
      conflicts with Channels' ASGI server takeover.
    - Explicitly set  to ensure
      the ASGI entry point is correctly referenced.
  - **:** Added 'channels'
    to , ensuring the Channels application is correctly loaded
    within the multi-tenant setup, enabling ASGI functionality.

- **Backend Middleware & Routing:**
  - **:** Implemented a custom
     to authenticate WebSocket connections using an
     from either a query parameter or cookies. This middleware
    ensures proper user authentication for WebSocket sessions. Debugging
    prints with  were added for better visibility.
  - **:** Adjusted WebSocket URL regexes
    to  for robustness, ensuring correct matching
    regardless of leading/trailing slashes in the path.

These changes collectively ensure that WebSocket connections are properly
initiated by the frontend, authenticated by the backend, and served by
an ASGI-compliant server, resolving the frequent disconnection/reconnection
issue.
2025-12-01 01:40:45 -05:00
poduck
be3b5b2d08 Fix: Resolve production CORS issues by moving CorsMiddleware before TenantMainMiddleware
Root cause: CorsMiddleware was positioned after TenantMainMiddleware, which
prevented CORS headers from being set. The tenant middleware processes requests
before CORS middleware could add the necessary headers.

Changes:
- Moved CorsMiddleware to first position in MIDDLEWARE stack
- Added CORS_ALLOW_ALL_ORIGINS configuration (for testing only)
- Updated production CORS regex to match both base and subdomains
- Created public tenant and registered production domains
- Re-enabled CORS_URLS_REGEX for API security

This fix ensures proper CORS headers are sent for cross-origin requests from
smoothschedule.com domains to api.smoothschedule.com.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 21:29:00 -05:00
poduck
89f2b570b3 Fix: Move notifications to SHARED_APPS for platform-to-tenant notifications
Platform users need to send notifications to business tenants, so the
notifications app must be in SHARED_APPS (public schema) rather than
TENANT_APPS (tenant-specific schemas).

Changes:
- Moved notifications from TENANT_APPS to SHARED_APPS in multitenancy.py
- Run migrations on public schema to create notifications tables

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 21:15:03 -05:00
poduck
885d8bbba2 Fix: Add lvh.me to CORS allowed origins for development
- Added http://lvh.me:5173 and http://lvh.me:5174 to CORS_ALLOWED_ORIGINS
- Added regex pattern to allow all *.lvh.me subdomains in CORS_ALLOWED_ORIGIN_REGEXES
- This allows frontend at lvh.me:5173 to make requests to API at api.lvh.me:8000
- CORS preflight requests now return proper Access-Control-Allow-Origin headers
- Quick login and all API calls from frontend now work without CORS errors

Testing confirmed:
✓ OPTIONS request to /api/auth-token/ returns 200 OK with CORS headers
✓ Access-Control-Allow-Origin: http://lvh.me:5173
✓ Access-Control-Allow-Methods: DELETE, GET, OPTIONS, PATCH, POST, PUT

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 21:06:46 -05:00
poduck
c0c037e3b9 Fix: Use api.lvh.me:8000 consistently for development API access
- Changed VITE_API_URL from localhost:8000 to api.lvh.me:8000
- Registered api.lvh.me domain in database pointing to public schema
- This maintains consistency between development and production where
  api subdomain is used for API access
- All test users can now authenticate via quick login

The development setup now mirrors production:
- Production: api.smoothschedule.com → Django API
- Development: api.lvh.me:8000 → Django API (via docker container)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 21:05:40 -05:00
poduck
52dde7c95b Fix: Resolve Django settings import error and fix quick login API endpoint
Settings Refactoring Fixes:
- Add minimal LOGGING structure to base.py for multitenancy.py to extend
- Restore LOGGING import in multitenancy.py
- Add development LOGGING configuration to local.py
- This allows multitenancy.py to extend LOGGING configuration properly

Quick Login Fix:
- Update frontend .env.development to use VITE_API_URL=http://localhost:8000
- Previous configuration tried to access api.lvh.me which failed due to
  django-tenants not recognizing that hostname
- Using localhost:8000 directly bypasses subdomain routing and accesses
  the public schema where auth endpoints are available

Both fixes restore full functionality:
- Django now starts without import errors in local development
- Quick login API calls now succeed and return authentication tokens
- Frontend can authenticate users for development/testing

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 21:02:24 -05:00
poduck
af92a5ebf4 Refactor: Clean up settings files to eliminate duplication
- Remove duplicate FRONTEND_URL from base.py (was defined twice)
- Move LOGGING configuration from base.py to production.py (production-specific)
- Keep base.py minimal with only universal settings
- Verify EMAIL and AWS/STORAGES are production-only
- Update multitenancy.py import to not reference LOGGING from base.py

This ensures proper separation of concerns:
- base.py: Universal settings (DATABASES, CORS, CSRF, SECURITY basics)
- local.py: Development-specific (CSP, debug tools, console email, eager celery)
- production.py: Production-specific (LOGGING, EMAIL, AWS/S3, SECURITY headers, Sentry)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 20:47:48 -05:00
poduck
3ea71408db Refactor: Move CORS and CSRF to base.py with environment variable configuration
- Move CORS_ALLOWED_ORIGINS to base.py, configurable via DJANGO_CORS_ALLOWED_ORIGINS env var
- Move CORS_ALLOWED_ORIGIN_REGEXES to base.py, configurable via DJANGO_CORS_ALLOWED_ORIGIN_REGEXES
- Move CSRF_TRUSTED_ORIGINS to base.py, configurable via DJANGO_CSRF_TRUSTED_ORIGINS
- Remove duplicate CORS/CSRF config from local.py (now inherits from base)
- Remove production-specific CORS config (now uses env vars from base)
- Allows development and production to use same settings with different .env variables
2025-11-30 20:38:00 -05:00
poduck
60708a6417 Add CORS and CSRF configuration to production settings
- Add CORS_ALLOWED_ORIGINS configurable via DJANGO_CORS_ALLOWED_ORIGINS env var
- Add CORS_ALLOWED_ORIGIN_REGEXES for wildcard subdomains
- Add CSRF_TRUSTED_ORIGINS for production domain
- Support custom domains via DJANGO_DOMAIN_NAME env var
- Use corsheaders.defaults for standard CORS headers
- Add custom headers: x-business-subdomain, x-sandbox-mode
2025-11-30 20:37:11 -05:00
poduck
349a54e264 Fix: Remove duplicate middlewares key in Traefik configuration 2025-11-30 20:28:27 -05:00
poduck
c8c0669801 Fix: Correct frontend build context path in production docker-compose 2025-11-30 20:14:32 -05:00
poduck
fa68b4a869 Update README with production deployment guide reference 2025-11-30 20:13:33 -05:00
poduck
b958f9368b Add comprehensive production deployment manual guide 2025-11-30 20:13:19 -05:00
poduck
2b321aef57 Add missing frontend platform components and update production deployment
This commit adds all previously untracked files and modifications needed for production deployment:
- New marketing components (BenefitsSection, CodeBlock, PluginShowcase, PricingTable)
- Platform admin components (EditPlatformEntityModal, PlatformListRow, PlatformListing, PlatformTable)
- Updated deployment configuration and scripts
- Various frontend API and component improvements

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 19:49:06 -05:00
poduck
0d1a3045fb Feat: Add marketing site and switch to git-based deployment 2025-11-30 16:18:11 -05:00
poduck
2b28fc49c9 fix: Remove /api/ prefix from all API endpoints
- Fixed double /api/api/ issue in production
- Updated all API files to remove /api/ prefix since baseURL already includes it
- Files fixed: platform.ts, oauth.ts, customDomains.ts, domains.ts, business.ts, sandbox.ts
- Production build will need to be rebuilt after pulling these changes
2025-11-30 16:04:20 -05:00
poduck
4cd6610f2a Fix double /api/ prefix in API endpoint calls
When VITE_API_URL=/api, axios baseURL is already set to /api. However, all endpoint calls included the /api/ prefix, creating double paths like /api/api/auth/login/.

Removed /api/ prefix from 81 API endpoint calls across 22 files:
- src/api/auth.ts - Fixed login, logout, me, refresh, hijack endpoints
- src/api/client.ts - Fixed token refresh endpoint
- src/api/profile.ts - Fixed all profile, email, password, MFA, sessions endpoints
- src/hooks/*.ts - Fixed all remaining API calls (users, appointments, resources, etc)
- src/pages/*.tsx - Fixed signup and email verification endpoints

This ensures API requests use the correct path: /api/auth/login/ instead of /api/api/auth/login/

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 15:27:57 -05:00
poduck
f1d4dac9d2 Fix deployment: Inject DATABASE_URL in deploy script 2025-11-30 02:08:36 -05:00
poduck
25db8dd35a Fix API URL duplication: Remove /api suffix from VITE_API_URL 2025-11-30 02:04:43 -05:00
poduck
9eb07a87e6 Fix hardcoded domain redirect: Set FRONTEND_URL in production 2025-11-30 01:59:29 -05:00
poduck
613acf17c1 Fix production 404 errors: Add missing OAuth endpoints and domain script 2025-11-30 01:37:19 -05:00
poduck
3ddd762d74 fix: Add missing Django core apps and DigitalOcean Spaces support
- Add django.contrib.auth, contenttypes, sessions, sites, messages,
  staticfiles, and admin to INSTALLED_APPS
- Add DigitalOcean Spaces (S3-compatible) storage configuration
- Add AWS_S3_ENDPOINT_URL setting for custom S3 endpoints

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 21:32:29 -05:00
poduck
7b0cf62019 feat: Add OAuth email integration and production deployment config
- Add OAuthCredential model for storing Google/Microsoft OAuth tokens
- Add email provider auto-detection endpoint (Gmail, Outlook, Yahoo, etc.)
- Add EmailConfigWizard frontend component with step-by-step setup
- Add OAuth flow endpoints for Google and Microsoft XOAUTH2
- Update production settings to make AWS, Sentry, Mailgun optional
- Update Traefik config for wildcard subdomain routing
- Add logo resize utility script

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 21:26:17 -05:00
poduck
cfc1b36ada feat: Add SMTP settings and collapsible email configuration UI
- Add SMTP fields to TicketEmailSettings model (host, port, TLS/SSL, credentials, from email/name)
- Update serializers with SMTP fields and is_smtp_configured flag
- Add TicketEmailTestSmtpView for testing SMTP connections
- Update frontend API types and hooks for SMTP settings
- Add collapsible IMAP and SMTP configuration sections with "Configured" badges
- Fix TypeScript errors in mockData.ts (missing required fields, type mismatches)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 18:28:29 -05:00
poduck
0c7d76e264 feat: Add event automation system for plugins attached to appointments
- Add GlobalEventPlugin model for auto-attaching plugins to all events
- Create signals for auto-attachment on new events and rescheduling
- Add API endpoints for global event plugins (CRUD, toggle, reapply)
- Update CreateTaskModal with "Scheduled Task" vs "Event Automation" choice
- Add option to apply to all events or future events only
- Display event automations in Tasks page alongside scheduled tasks
- Add EditEventAutomationModal for editing trigger and timing
- Handle event reschedule - update Celery task timing on time/duration changes
- Add Marketplace to Plugins menu in sidebar

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:17:28 -05:00
poduck
9b106bf129 feat: Add plugin configuration editing with template variable parsing
## Backend Changes:
- Enhanced PluginTemplate.save() to auto-parse template variables from plugin code
- Updated PluginInstallationSerializer to expose template metadata (description, category, version, author, logo, template_variables)
- Fixed template variable parser to handle nested {{ }} braces in default values
- Added brace-counting algorithm to properly extract variables with insertion codes
- Fixed explicit type parameter detection (textarea, text, email, etc.)
- Made scheduled_task optional on PluginInstallation model
- Added EventPlugin through model for event-plugin relationships
- Added Event.execute_plugins() method for plugin automation

## Frontend Changes:
- Created Tasks.tsx page for managing scheduled tasks
- Enhanced MyPlugins page with clickable plugin cards
- Added edit configuration modal with dynamic form generation
- Implemented escape sequence handling (convert \n, \', etc. for display)
- Added plugin logos to My Plugins page
- Updated type definitions for PluginInstallation interface
- Added insertion code documentation to Plugin Docs

## Plugin System:
- All platform plugins now have editable email templates with textarea support
- Template variables properly parsed with full default values
- Insertion codes ({{CUSTOMER_NAME}}, {{BUSINESS_NAME}}, etc.) documented
- Plugin logos displayed in marketplace and My Plugins

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 23:45:55 -05:00
poduck
0f46862125 fix: Change Install to View button and fix author display in marketplace
Changes:
1. Changed "Install" button to "View" button with Eye icon
   - Removed separate "Details" button
   - Single "View" button now opens the details modal
2. Fixed author mapping to use author_name from API
3. Fixed rating field to use rating_average from API
4. Set isVerified based on visibility === 'PLATFORM'

The modal now correctly displays:
- Plugin name with verified badge for platform plugins
- Author name (e.g., "Smooth Schedule")
- Version number
- Full description with formatting
- Category, ratings, and install count

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 22:01:05 -05:00
poduck
c36025f018 feat: Add description field to PluginTemplateListSerializer
The description field is now included in marketplace listing responses,
allowing the frontend to display full plugin descriptions with formatting,
bullet points, and detailed benefits.

All 6 platform plugins now return complete information:
- Name, author (Smooth Schedule), version (1.0.0)
- Short description (one-line summary)
- Full description (multi-paragraph with bullets)
- Category, ratings, install count

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:58:57 -05:00
poduck
64ab9ea23c feat: Add version field and enhanced descriptions to platform plugins
Changes:
1. Added version field to PluginTemplate model (default: 1.0.0)
2. Updated platform plugins with detailed descriptions
3. Changed author_name from "SmoothSchedule Platform" to "Smooth Schedule"
4. Enhanced seed_platform_plugins command with comprehensive descriptions

Plugin descriptions now include:
- Detailed explanations of functionality
- Benefits and use cases
- Key features in bullet points

All 6 platform plugins now have:
- Version: 1.0.0
- Author: Smooth Schedule
- Rich, marketing-friendly descriptions

Migration: 0016_plugintemplate_version

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:56:59 -05:00
poduck
200b7f7930 fix: Include platform plugins in marketplace and fix serializer
Changes:
1. Updated PluginTemplateViewSet.get_queryset() to include PLATFORM
   visibility plugins in marketplace view alongside approved PUBLIC plugins
2. Fixed PluginTemplateListSerializer read_only_fields from string '__all__'
   to proper list reference

Platform plugins are now visible in the marketplace API:
- 6 platform-created plugins seeded via seed_platform_plugins command
- Categories: EMAIL, REPORTS, CUSTOMER, BOOKING
- All marked as visibility=PLATFORM, is_approved=True

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:50:22 -05:00
poduck
61f43375b9 refactor: Remove Marketplace link from Plugins dropdown
Users can access the marketplace via the "Browse Marketplace" button
on the My Plugins page, so the redundant sidebar link has been removed.

The Plugins dropdown now contains:
- My Plugins
- Plugin Docs

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:46:28 -05:00
poduck
141eadca8d feat: Add Plugin Marketplace and My Plugins management pages
This commit completes the plugin system UI by adding two key pages:

1. Plugin Marketplace (/plugins/marketplace):
   - Browse and search platform-provided plugins
   - Filter by category (EMAIL, REPORTS, CUSTOMER, BOOKING, etc.)
   - View plugin details including ratings, install count, description
   - Install plugins with one click
   - Modal view for detailed plugin information

2. My Plugins (/plugins/my-plugins):
   - View all installed plugins
   - Manage plugin activation status
   - Update plugins when new versions available
   - Rate and review installed plugins
   - Uninstall plugins with confirmation
   - Links to create custom plugins and browse marketplace

Additional changes:
- Added plugin routes to App.tsx with owner/manager access control
- Updated HelpPluginDocs.tsx with navigation callout boxes
- Added TypeScript interfaces for PluginTemplate and PluginInstallation
- Both pages feature full dark mode support
- Professional UI with Tailwind CSS styling
- React Query integration for data fetching

The pages are accessible from the Plugins dropdown menu in the sidebar.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:36:50 -05:00
poduck
e234d5fd9c feat: Add Plugins dropdown menu to Business sidebar
- Added Plugins collapsible menu with 3 items:
  - Plugin Marketplace (/plugins/marketplace)
  - My Plugins (/plugins/my-plugins)
  - Plugin Docs (/help/plugins)
- Moved Plugin Docs from Help dropdown to Plugins dropdown
- Added Plug, ShoppingBag, Package icons from lucide-react
- Added translations for plugin navigation items
- Auto-opens dropdown when on /plugins/* routes

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:29:02 -05:00
poduck
ea6b8fdadd feat: Add plugin marketplace backend infrastructure
Backend Features:
- Created PluginTemplate and PluginInstallation models
- Built complete REST API with marketplace, my plugins, install/uninstall endpoints
- Platform plugins supported (PLATFORM visibility, no whitelisting required)
- Template variable extraction and compilation
- Plugin approval workflow for marketplace publishing
- Rating and review system
- Update detection and version management
- Install count tracking

API Endpoints:
- GET /api/plugin-templates/ - Browse marketplace (view=marketplace/my_plugins/platform)
- POST /api/plugin-templates/ - Create new plugin
- POST /api/plugin-templates/{id}/install/ - Install plugin as ScheduledTask
- POST /api/plugin-templates/{id}/publish/ - Publish to marketplace
- POST /api/plugin-templates/{id}/approve/ - Approve for marketplace (admins)
- POST /api/plugin-installations/{id}/rate/ - Rate and review
- POST /api/plugin-installations/{id}/update_to_latest/ - Update plugin
- DELETE /api/plugin-installations/{id}/ - Uninstall plugin

Platform Plugins:
- Created seed_platform_plugins management command
- 6 starter plugins ready: daily summary, no-show tracker, birthdays, revenue reports, reminders, re-engagement
- Platform plugins bypass whitelist validation
- Pre-approved and available to all businesses

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:24:27 -05:00
poduck
3723b33cad feat: Add plugin code analysis and HTTP whitelist validation
Implemented static code analysis to detect and validate HTTP calls in plugins
before they are uploaded or approved for the marketplace.

**New Functions:**

1. **analyze_plugin_http_calls(script):**
   - Parses plugin code using Python AST
   - Detects all api.http_* method calls (GET, POST, PUT, PATCH, DELETE)
   - Extracts URL from first argument if it's a string literal
   - Handles dynamic URLs (f-strings, variables) with appropriate warnings
   - Returns list of HTTP calls with method, URL, and line number

2. **validate_plugin_whitelist(script, scheduled_task):**
   - Analyzes plugin code for HTTP calls
   - Validates each detected URL against WhitelistedURL model
   - Checks both platform-wide and plugin-specific whitelists
   - Returns validation results with errors, warnings, and detected calls
   - Provides clear error messages with line numbers

**Validation Logic:**
- **Static URLs** (string literals): Validated against whitelist, error if not found
- **Dynamic URLs** (f-strings, variables): Warning issued, runtime validation required
- **Syntax Errors**: Caught and reported as validation errors
- **Line Numbers**: All errors/warnings include line number for debugging

**Use Cases:**
1. Pre-upload validation: Check plugin before saving to database
2. Approval workflow: Platform staff can see which URLs need whitelisting
3. Marketplace submission: Reject plugins with non-whitelisted URLs
4. Security audit: Analyze existing plugins for HTTP call patterns

**Error Messages:**
- Clear, actionable messages with line numbers
- Direct users to pluginaccess@smoothschedule.com for whitelisting
- Warns about dynamic URLs that can't be statically validated

This enables proactive security enforcement before plugins are executed,
preventing runtime failures and improving user experience.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:11:26 -05:00
poduck
ecfdbdefe0 refactor: Replace "Platform" with "SmoothSchedule" in licensing section
Updated all references to "Platform" in the licensing documentation to use
"SmoothSchedule" for better branding consistency:

- Changed "Platform Rights" to "SmoothSchedule Rights"
- Changed "Platform Service Rights" to "SmoothSchedule Service Rights"
- Changed "Platform Use" table header to "SmoothSchedule Use"
- Updated all inline references from "Platform" to "SmoothSchedule"

This makes the licensing terms more specific and branded while maintaining
the same legal structure and protections.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:07:09 -05:00