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>
9.4 KiB
9.4 KiB
Advanced Analytics Implementation - Change Summary
Overview
Successfully implemented the Advanced Analytics feature with permission-based access control in the Django backend. All analytics endpoints are gated behind the advanced_analytics permission from the subscription plan.
Files Created
Analytics App (/smoothschedule/analytics/)
__init__.py- Package initializationapps.py- Django app configurationadmin.py- Admin interface (read-only app, no models)views.py- AnalyticsViewSet with 3 endpoints:dashboard()- Summary statisticsappointments()- Detailed appointment analyticsrevenue()- Revenue analytics (dual-permission gated)
serializers.py- Response serializers for data validationurls.py- URL routingtests.py- Comprehensive pytest test suitemigrations/- Empty migrations directoryREADME.md- Full API documentationIMPLEMENTATION_GUIDE.md- Developer implementation guide
Files Modified
1. /smoothschedule/core/permissions.py
Changes:
- Added
advanced_analyticsandadvanced_reportingto theFEATURE_NAMESdictionary inHasFeaturePermission
Before:
FEATURE_NAMES = {
'can_use_sms_reminders': 'SMS Reminders',
...
'can_use_calendar_sync': 'Calendar Sync',
}
After:
FEATURE_NAMES = {
'can_use_sms_reminders': 'SMS Reminders',
...
'can_use_calendar_sync': 'Calendar Sync',
'advanced_analytics': 'Advanced Analytics',
'advanced_reporting': 'Advanced Reporting',
}
2. /smoothschedule/config/urls.py
Changes:
- Added analytics URL include in the API URL patterns
Before:
# Schedule API (internal)
path("", include("schedule.urls")),
# Payments API
path("payments/", include("payments.urls")),
After:
# Schedule API (internal)
path("", include("schedule.urls")),
# Analytics API
path("", include("analytics.urls")),
# Payments API
path("payments/", include("payments.urls")),
3. /smoothschedule/config/settings/base.py
Changes:
- Added
analyticsapp toLOCAL_APPS
Before:
LOCAL_APPS = [
"smoothschedule.users",
"core",
"schedule",
"payments",
...
]
After:
LOCAL_APPS = [
"smoothschedule.users",
"core",
"schedule",
"analytics",
"payments",
...
]
API Endpoints
All endpoints are located at /api/analytics/ and require:
- Authentication via token or session
advanced_analyticspermission in tenant's subscription plan
1. Dashboard Summary
GET /api/analytics/analytics/dashboard/
Returns:
- Total appointments (this month and all-time)
- Active resources and services count
- Upcoming appointments
- Average appointment duration
- Peak booking day and hour
2. Appointment Analytics
GET /api/analytics/analytics/appointments/
Query Parameters:
days(default: 30)status(optional: confirmed, cancelled, no_show)service_id(optional)resource_id(optional)
Returns:
- Total appointments
- Breakdown by status
- Breakdown by service and resource
- Daily breakdown
- Booking trends and rates
3. Revenue Analytics
GET /api/analytics/analytics/revenue/
Query Parameters:
days(default: 30)service_id(optional)
Returns:
- Total revenue in cents
- Transaction count
- Average transaction value
- Revenue by service
- Daily breakdown
Note: Requires both advanced_analytics AND can_accept_payments permissions
Permission Gating Implementation
How It Works
- Request arrives at endpoint
- IsAuthenticated check - Verifies user is logged in
- HasFeaturePermission('advanced_analytics') check:
- Gets tenant from request
- Calls
tenant.has_feature('advanced_analytics') - Checks both direct field and subscription plan JSON
- If permission exists - View logic executes
- If permission missing - 403 Forbidden returned with message
Permission Check Logic
# In core/models.py - Tenant.has_feature()
def has_feature(self, permission_key):
# Check direct field on Tenant model
if hasattr(self, permission_key):
return bool(getattr(self, permission_key))
# Check subscription plan permissions JSON
if self.subscription_plan:
plan_perms = self.subscription_plan.permissions or {}
return bool(plan_perms.get(permission_key, False))
return False
Enabling Analytics for a Plan
Via Django Admin
- Go to
/admin/platform_admin/subscriptionplan/ - Edit a plan
- Add to "Permissions" JSON field:
{
"advanced_analytics": true
}
Via Django Shell
docker compose -f docker-compose.local.yml exec django python manage.py shell
from platform_admin.models import SubscriptionPlan
plan = SubscriptionPlan.objects.get(name='Professional')
perms = plan.permissions or {}
perms['advanced_analytics'] = True
plan.permissions = perms
plan.save()
Testing
Permission Tests Included
The analytics/tests.py file includes comprehensive tests:
-
TestAnalyticsPermissions
test_analytics_requires_authentication- 401 without authtest_analytics_denied_without_permission- 403 without permissiontest_analytics_allowed_with_permission- 200 with permissiontest_dashboard_endpoint_structure- Verify response structuretest_appointments_endpoint_with_filters- Query parameters worktest_revenue_requires_payments_permission- Dual permission checktest_multiple_permission_check- Both checks enforced
-
TestAnalyticsData
test_dashboard_counts_appointments_correctly- Correct countstest_appointments_counts_by_status- Status breakdowntest_cancellation_rate_calculation- Rate calculation
Running Tests
# Run all analytics tests
docker compose -f docker-compose.local.yml exec django pytest analytics/tests.py -v
# Run specific test
docker compose -f docker-compose.local.yml exec django pytest analytics/tests.py::TestAnalyticsPermissions::test_analytics_denied_without_permission -v
# Run with coverage
docker compose -f docker-compose.local.yml exec django pytest analytics/tests.py --cov=analytics
Error Responses
401 Unauthorized (No Authentication)
{
"detail": "Authentication credentials were not provided."
}
403 Forbidden (No Permission)
{
"detail": "Your current plan does not include Advanced Analytics. Please upgrade your subscription to access this feature."
}
403 Forbidden (Revenue Endpoint - Missing Payments Permission)
{
"error": "Payment analytics not available",
"detail": "Your plan does not include payment processing."
}
Example Usage
Get Dashboard Stats (with cURL)
TOKEN="your_auth_token_here"
curl -H "Authorization: Token $TOKEN" \
http://lvh.me:8000/api/analytics/analytics/dashboard/ | jq
Get Appointment Analytics (with filters)
curl -H "Authorization: Token $TOKEN" \
"http://lvh.me:8000/api/analytics/analytics/appointments/?days=7&status=confirmed" | jq
Get Revenue Analytics
curl -H "Authorization: Token $TOKEN" \
http://lvh.me:8000/api/analytics/analytics/revenue/ | jq
Key Design Decisions
- ViewSet without models - Analytics is calculated on-the-fly, no database models
- Read-only endpoints - No POST/PUT/DELETE, only GET for querying
- Comprehensive permission naming - Both
advanced_analyticsandadvanced_reportingsupported for flexibility - Dual permission check - Revenue endpoint requires both analytics and payments permissions
- Query parameter filtering - Flexible filtering for reports
- Detailed error messages - User-friendly upgrade prompts
Documentation Provided
- README.md - Complete API documentation with examples
- IMPLEMENTATION_GUIDE.md - Developer guide for enabling and debugging
- Code comments - Detailed docstrings in views and serializers
- Test file - Comprehensive test suite with examples
Next Steps
- Migrate - No migrations needed (no database models)
- Configure Plans - Add
advanced_analyticspermission to desired subscription plans - Test - Run the test suite to verify functionality
- Deploy - Push to production
- Monitor - Check logs for any issues
Implementation Checklist
- Create analytics app with ViewSet
- Implement dashboard endpoint with summary statistics
- Implement appointments endpoint with filtering
- Implement revenue endpoint with dual permission check
- Add permission to FEATURE_NAMES in core/permissions.py
- Register app in INSTALLED_APPS
- Add URL routing
- Create serializers for response validation
- Write comprehensive test suite
- Document API endpoints
- Document implementation details
- Provide developer guide
Files Summary
Total Files Created: 11
- 10 Python files (app code + tests)
- 2 Documentation files
Total Files Modified: 3
- core/permissions.py
- config/urls.py
- config/settings/base.py
Lines of Code:
- views.py: ~350 lines
- tests.py: ~260 lines
- serializers.py: ~80 lines
- Documentation: ~1000 lines
Questions or Issues?
Refer to:
analytics/README.md- API usage and endpointsanalytics/IMPLEMENTATION_GUIDE.md- Setup and debugginganalytics/tests.py- Examples of correct usagecore/permissions.py- Permission checking logic