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>
71 lines
2.2 KiB
Python
71 lines
2.2 KiB
Python
#!/usr/bin/env python
|
|
"""
|
|
Test script for Data Export API
|
|
"""
|
|
import requests
|
|
import json
|
|
|
|
# Base URL for API
|
|
BASE_URL = "http://lvh.me:8000"
|
|
|
|
def test_export_endpoints():
|
|
"""Test all export endpoints"""
|
|
|
|
print("Testing Data Export API Endpoints")
|
|
print("=" * 60)
|
|
|
|
# Test endpoints
|
|
endpoints = [
|
|
('appointments', 'format=json'),
|
|
('appointments', 'format=csv'),
|
|
('appointments', 'format=json&start_date=2024-01-01T00:00:00Z&end_date=2024-12-31T23:59:59Z'),
|
|
('customers', 'format=json'),
|
|
('customers', 'format=csv'),
|
|
('resources', 'format=json'),
|
|
('resources', 'format=csv'),
|
|
('services', 'format=json'),
|
|
('services', 'format=csv'),
|
|
]
|
|
|
|
for endpoint, params in endpoints:
|
|
url = f"{BASE_URL}/export/{endpoint}/?{params}"
|
|
print(f"\nTesting: GET {url}")
|
|
|
|
try:
|
|
response = requests.get(url)
|
|
print(f"Status Code: {response.status_code}")
|
|
|
|
if response.status_code == 200:
|
|
# Check Content-Type
|
|
content_type = response.headers.get('Content-Type', '')
|
|
print(f"Content-Type: {content_type}")
|
|
|
|
# Check Content-Disposition
|
|
content_disp = response.headers.get('Content-Disposition', '')
|
|
print(f"Content-Disposition: {content_disp}")
|
|
|
|
# Show response preview
|
|
if 'json' in content_type:
|
|
try:
|
|
data = response.json()
|
|
print(f"Response preview: {json.dumps(data, indent=2)[:200]}...")
|
|
except:
|
|
print(f"Response: {response.text[:200]}...")
|
|
elif 'csv' in content_type:
|
|
print(f"CSV preview: {response.text[:200]}...")
|
|
else:
|
|
print(f"Response: {response.text[:200]}...")
|
|
elif response.status_code == 403:
|
|
print(f"Permission denied: {response.text}")
|
|
else:
|
|
print(f"Error: {response.text}")
|
|
|
|
except Exception as e:
|
|
print(f"Exception: {e}")
|
|
|
|
print("\n" + "=" * 60)
|
|
print("Test complete!")
|
|
|
|
if __name__ == "__main__":
|
|
test_export_endpoints()
|