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>
8.7 KiB
Data Export API Documentation
Overview
The Data Export API allows businesses to export their data in CSV or JSON formats. This feature is gated by the can_export_data permission from the subscription plan.
Authentication & Permissions
- Authentication: Required (Bearer token or session authentication)
- Permission:
can_export_datamust be enabled on the tenant's subscription plan - Access Control: Only business users can export (platform users without tenants are denied)
Base URL
/api/export/
Endpoints
1. Export Appointments
Export appointment/event data with optional date range filtering.
Endpoint: GET /api/export/appointments/
Query Parameters:
format(optional):csvorjson(default:json)start_date(optional): ISO 8601 datetime (e.g.,2024-01-01T00:00:00Z)end_date(optional): ISO 8601 datetime (e.g.,2024-12-31T23:59:59Z)status(optional): Filter by status (SCHEDULED,CANCELED,COMPLETED,PAID,NOSHOW)
CSV Headers:
id, title, start_time, end_time, status, notes, customer_name,
customer_email, resource_names, created_at, created_by
JSON Response Format:
{
"count": 150,
"exported_at": "2024-12-02T10:30:00Z",
"filters": {
"start_date": "2024-01-01T00:00:00Z",
"end_date": "2024-12-31T23:59:59Z",
"status": null
},
"data": [
{
"id": 1,
"title": "John Doe - Haircut",
"start_time": "2024-03-15T14:00:00Z",
"end_time": "2024-03-15T15:00:00Z",
"status": "SCHEDULED",
"notes": "First time customer",
"customer_name": "John Doe",
"customer_email": "john@example.com",
"resource_names": ["Stylist Chair 1", "Sarah Smith"],
"created_at": "2024-03-10T09:20:00Z",
"created_by": "owner@business.com"
}
]
}
Example Requests:
# Export as JSON
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://lvh.me:8000/api/export/appointments/?format=json"
# Export as CSV with date range
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://lvh.me:8000/api/export/appointments/?format=csv&start_date=2024-01-01T00:00:00Z&end_date=2024-12-31T23:59:59Z"
# Export only completed appointments
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://lvh.me:8000/api/export/appointments/?format=json&status=COMPLETED"
2. Export Customers
Export customer/client data.
Endpoint: GET /api/export/customers/
Query Parameters:
format(optional):csvorjson(default:json)status(optional):activeorinactive
CSV Headers:
id, email, first_name, last_name, full_name, phone,
is_active, created_at, last_login
JSON Response Format:
{
"count": 250,
"exported_at": "2024-12-02T10:30:00Z",
"filters": {
"status": "active"
},
"data": [
{
"id": 42,
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Smith",
"full_name": "Jane Smith",
"phone": "+1-555-0123",
"is_active": true,
"created_at": "2024-01-15T08:30:00Z",
"last_login": "2024-12-01T14:20:00Z"
}
]
}
Example Requests:
# Export all customers as JSON
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://lvh.me:8000/api/export/customers/?format=json"
# Export active customers as CSV
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://lvh.me:8000/api/export/customers/?format=csv&status=active"
3. Export Resources
Export resource data (staff, rooms, equipment).
Endpoint: GET /api/export/resources/
Query Parameters:
format(optional):csvorjson(default:json)is_active(optional):trueorfalse
CSV Headers:
id, name, type, description, max_concurrent_events,
buffer_duration, is_active, user_email, created_at
JSON Response Format:
{
"count": 15,
"exported_at": "2024-12-02T10:30:00Z",
"filters": {
"is_active": "true"
},
"data": [
{
"id": 5,
"name": "Treatment Room 1",
"type": "ROOM",
"description": "Massage therapy room",
"max_concurrent_events": 1,
"buffer_duration": "0:15:00",
"is_active": true,
"user_email": "",
"created_at": "2024-01-05T10:00:00Z"
}
]
}
Example Requests:
# Export all resources as JSON
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://lvh.me:8000/api/export/resources/?format=json"
# Export active resources as CSV
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://lvh.me:8000/api/export/resources/?format=csv&is_active=true"
4. Export Services
Export service catalog data.
Endpoint: GET /api/export/services/
Query Parameters:
format(optional):csvorjson(default:json)is_active(optional):trueorfalse
CSV Headers:
id, name, description, duration, price, display_order,
is_active, created_at
JSON Response Format:
{
"count": 8,
"exported_at": "2024-12-02T10:30:00Z",
"filters": {
"is_active": "true"
},
"data": [
{
"id": 3,
"name": "Haircut",
"description": "Standard haircut service",
"duration": 60,
"price": "45.00",
"display_order": 1,
"is_active": true,
"created_at": "2024-01-01T12:00:00Z"
}
]
}
Example Requests:
# Export all services as JSON
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://lvh.me:8000/api/export/services/?format=json"
# Export active services as CSV
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://lvh.me:8000/api/export/services/?format=csv&is_active=true"
Error Responses
403 Forbidden - No Permission
When the tenant doesn't have can_export_data permission:
{
"detail": "Data export is not available on your current subscription plan. Please upgrade to access this feature."
}
403 Forbidden - No Tenant
When the user doesn't belong to a business:
{
"detail": "Data export is only available for business accounts."
}
400 Bad Request - Invalid Date
When date format is invalid:
{
"error": "Invalid start_date format: 2024-13-45"
}
401 Unauthorized
When authentication is missing or invalid:
{
"detail": "Authentication credentials were not provided."
}
File Download Behavior
CSV Format
- Content-Type:
text/csv - Content-Disposition:
attachment; filename="appointments_20241202_103000.csv" - Browser will automatically download the file
JSON Format
- Content-Type:
application/json - Content-Disposition:
attachment; filename="appointments_20241202_103000.json" - Response includes metadata (count, filters, exported_at) along with data
Implementation Details
File Location
- View:
/home/poduck/Desktop/smoothschedule2/smoothschedule/schedule/export_views.py - URLs: Registered in
/home/poduck/Desktop/smoothschedule2/smoothschedule/schedule/urls.py
Permission Check
The HasExportDataPermission class checks:
- User is authenticated
- User has an associated tenant
- Tenant has
can_export_data = True
Data Scoping
- All queries are automatically scoped to the tenant's schema via django-tenants
- No cross-tenant data leakage is possible
- Users only see data belonging to their business
Filename Format
Files are named with timestamps for unique identification:
{data_type}_{YYYYMMDD}_{HHMMSS}.{format}
Examples:
appointments_20241202_103000.csvcustomers_20241202_103015.jsonresources_20241202_103030.csv
Security Considerations
- Authentication Required: All endpoints require valid authentication
- Permission Gating: Only tenants with
can_export_datacan access - Tenant Isolation: Data is automatically scoped to the tenant's schema
- Rate Limiting: Consider implementing rate limiting for production
- Audit Logging: Consider logging all export operations for compliance
Subscription Plan Configuration
To enable data export for a tenant, set:
# In Django shell or admin
tenant.can_export_data = True
tenant.save()
Or via subscription plan:
# In subscription plan permissions
plan.permissions = {
'can_export_data': True,
# ... other permissions
}
plan.save()
Testing
Use the test script:
python /home/poduck/Desktop/smoothschedule2/test_export_api.py
Or test manually with curl/Postman using the example requests above.
Future Enhancements
Potential improvements:
- Add pagination for large datasets
- Support for custom field selection
- Excel (.xlsx) format support
- Scheduled/automated exports
- Email delivery of export files
- Compressed exports (.zip) for large datasets
- Export templates/presets
- Async export jobs for very large datasets