New endpoints:
- GET /api/v1/version — returns VERSIONS.json (no auth required)
For field engineers to check platform version from login page
- GET /api/v1/kpi/solar — returns PR, self-consumption rate,
equivalent utilization hours, and daily revenue
Handles station-level vs device-level data deduplication
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace all hardcoded Tianpu/天普 defaults with generic "EMS Platform"
- Add energy_today fallback: query raw energy_data when daily summary empty
- Fix PV device filter to include sungrow_inverter device type
- Update APP_NAME, CUSTOMER default, SECRET_KEY, SMTP, Celery, email templates
BREAKING: CUSTOMER default changed from "tianpu" to "default"
Existing deployments with CUSTOMER=tianpu in .env are unaffected.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove frontend/ and nginx/ from core (each customer owns their frontend)
- Update docker-compose.yml to backend-only (postgres + redis + backend)
- Update docker-compose.prod.yml to backend-only
- Add CLAUDE.md with dev guidelines
- Update README.md with new architecture diagram
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New plugin architecture for customer-specific business logic:
- hooks/base.py: CustomerHooks base class with 12 hook points
(on_alarm_created, on_alarm_resolved, on_energy_data_received,
on_device_status_changed, on_quota_exceeded, on_work_order_created,
on_work_order_completed, on_inspection_completed, on_report_generated,
calculate_custom_kpis, on_charging_order_created/completed)
- hooks/loader.py: Dynamic loader that imports from customers/{CUSTOMER}/hooks/
- alarm_checker.py: calls on_alarm_created and on_alarm_resolved hooks
- quota_checker.py: calls on_quota_exceeded hook
Customers override hooks by creating customers/{name}/hooks/__init__.py
without modifying core code. Scales to 10-20+ customers.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>