Files
smoothschedule/smoothschedule/DATA_EXPORT_API.md
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

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_data must 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): csv or json (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): csv or json (default: json)
  • status (optional): active or inactive

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): csv or json (default: json)
  • is_active (optional): true or false

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): csv or json (default: json)
  • is_active (optional): true or false

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:

  1. User is authenticated
  2. User has an associated tenant
  3. 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.csv
  • customers_20241202_103015.json
  • resources_20241202_103030.csv

Security Considerations

  1. Authentication Required: All endpoints require valid authentication
  2. Permission Gating: Only tenants with can_export_data can access
  3. Tenant Isolation: Data is automatically scoped to the tenant's schema
  4. Rate Limiting: Consider implementing rate limiting for production
  5. 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:

  1. Add pagination for large datasets
  2. Support for custom field selection
  3. Excel (.xlsx) format support
  4. Scheduled/automated exports
  5. Email delivery of export files
  6. Compressed exports (.zip) for large datasets
  7. Export templates/presets
  8. Async export jobs for very large datasets