Scheduler & Automated Crons Engine
The Scheduler & Automated Crons Engine handles time-driven automation, timeseries database rollups, appointment reminders, and regulatory market monitors across Planovi.
Functions Matrix
| Function Name | Schedule / Trigger | Execution Window | Primary Output |
|---|---|---|---|
run-scheduler | Cron (*/5 * * * *) | Every 5 minutes | Dispatches queued background tasks from job_queue |
reminder-scheduler | Cron (*/15 * * * *) | Every 15 minutes | Sends meeting, voting, and payment reminders |
tender-cron | Cron (0 8 * * *) | Daily at 08:00 UTC | Scrapes and ingests public energy tender opportunities |
aggregate-hourly | Cron (5 * * * *) | Hourly at minute 05 | Computes 1-hour rollups into telemetry_hourly |
aggregate-daily | Cron (15 0 * * *) | Daily at 00:15 UTC | Computes 24-hour rollups into telemetry_daily |
main | HTTP GET / Health Probe | Ad-hoc / Monitoring | System health status, version, and routing index |
1. Timeseries Aggregation Architecture
Because high-frequency telemetry generates gigabytes of raw records, analytics and charts are serviced via multi-stage time-bucket rollups:
flowchart TD
Raw["telemetry_raw (15s-60s readings)"] -->|"aggregate-hourly (Hourly :05)"| Hourly["telemetry_hourly (1h buckets)"]
Hourly -->|"aggregate-daily (Daily 00:15)"| Daily["telemetry_daily (24h buckets)"]
Raw --> FastQueries["Realtime Gauges (Last 60 mins)"]
Hourly --> IntradayCharts["Weekly & Monthly Load Curves"]
Daily --> BillingEngine["Monthly Invoicing & Year-over-Year Audits"]
aggregate-hourly Aggregation Logic
- Computes
avg_power_kw,max_power_kw,total_generation_kwh,total_consumption_kwh, andnet_balance_kwh. - Identifies missing interval readings and records data-quality completeness scores.
aggregate-daily Aggregation Logic
- Aggregates 24 hourly buckets.
- Calculates peak solar production hours, minimum night-time base load, and self-consumption ratio percentage ($\frac{\text{Self-Consumed}}{\text{Total Generated}} \times 100%$).
2. run-scheduler (Job Queue Processor)
Acts as a distributed, transaction-safe background worker:
sequenceDiagram
autonumber
participant Cron as Cron Dispatcher
participant Worker as run-scheduler
participant DB as "PostgreSQL (job_queue)"
Cron->>Worker: Trigger POST /run-scheduler
Worker->>DB: SELECT * FROM job_queue WHERE status = 'PENDING' AND run_at <= NOW() FOR UPDATE SKIP LOCKED LIMIT 10
DB-->>Worker: Return locked job records
loop For each job
Worker->>Worker: Execute job handler (e.g. sync_external_profile)
alt Success
Worker->>DB: UPDATE job_queue SET status = 'COMPLETED', updated_at = NOW()
else Failure
Worker->>DB: UPDATE job_queue SET retry_count = retry_count + 1, status = CASE WHEN retry_count > 3 THEN 'FAILED' ELSE 'PENDING' END
end
end
3. reminder-scheduler
Scans upcoming events across cooperative and CRM modules:
- Meeting & Voting Deadlines: Alerts cooperative members 24h and 2h before statutory voting sessions close.
- Invoice Due Dates: Sends friendly reminder 3 days prior to invoice due date, and urgent notification 1 day post-overdue.
- Calendar Appointments: Integrates with client booking schedules from the Flutter scheduler module.
4. main (Health & Routing Probe)
Serves as the root API gateway monitor:
- Endpoint:
/functions/v1/main - Response:
{"service": "planovi-backend","status": "healthy","version": "1.4.0","timestamp": "2026-09-16T10:00:00Z","features": {"telemetry_ingest": "operational","ai_balancer": "operational","ocr_vision": "operational","billing_engine": "operational"}}