Skip to content

CRUD for automations in the API and UI - #2294

Draft
Flix6x wants to merge 8 commits into
feat/2288-schedule-automationsfrom
feat/2288-automations-crud
Draft

CRUD for automations in the API and UI#2294
Flix6x wants to merge 8 commits into
feat/2288-schedule-automationsfrom
feat/2288-automations-crud

Conversation

@Flix6x

@Flix6x Flix6x commented Jul 11, 2026

Copy link
Copy Markdown
Member

Description

Milestone 3 of #2288 (stacked on #2293, which is stacked on #2290): automations can now be created, edited and deleted through the API and the UI.

  • API (all documented in OpenAPI, all requiring account admin or consultant rights — the same principals that may delete the asset, matching the Automation ACL):
    • POST /assets/<id>/automations — create an automation; parameters are validated by the schema matching the automation type (forecast parameters or a schedule trigger message). Response includes any validation warnings.
    • PATCH /assets/<id>/automations/<automation_id> — update name, cron string and/or activation status.
    • DELETE /assets/<id>/automations/<automation_id> — delete (already-queued jobs are unaffected).
    • Nonexistent/mismatched automation ids yield the documented 404 without leaking id existence across accounts.
  • UI: the automations page gets a New automation modal (name, type, cron string, JSON parameters, active) and per-row (De)activate / Delete actions — rendered only for users with management rights.
  • Refactor: create/update/delete logic including audit-log records moved into flexmeasures/data/services/automations.py, shared by the CLI commands and the new endpoints (audit messages now say "via CLI" or "via API" consistently).

How to test

As an account admin, open /assets/<id>/automations and use the New automation button, or:

curl -X POST .../api/v3_0/assets/<id>/automations -H "Authorization: <token>" -H "Content-Type: application/json" \
  -d '{"name": "Nightly schedules", "cronstr": "0 0 * * *", "type": "schedules", "parameters": {"duration": "PT12H"}}'

Tests: pytest flexmeasures/api/v3_0/tests/test_automations_api.py flexmeasures/cli/tests/test_automations.py (permission matrix: plain member 403, account admin OK, other account 403).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX

related issues

closes #2372

Flix6x and others added 2 commits July 11, 2026 18:44
- New endpoints on assets: POST /automations (create, validating parameters
  by automation type), PATCH /automations/<id> (name, cron string, activation
  status) and DELETE /automations/<id>. Managing automations requires the
  same principals that may delete the asset (account admins and consultants).
- The UI automations page gets a 'New automation' modal and per-row
  (de)activate and delete actions, shown to users with management rights.
- Creation, update and deletion logic (incl. audit log records) moved into
  the automations service, shared by the CLI commands and the API endpoints.

Part of #2288

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
@BelhsanHmida BelhsanHmida linked an issue Jul 30, 2026 that may be closed by this pull request
Flix6x added 4 commits August 5, 2026 18:59
…elves

Context:
- Review of #2290 asked that automations administered through the UI (and hence
  the API) may only involve sensors the creating user has access to; account
  admin rights on the asset should not grant access to another account's sensors

Change:
- Work out the sensors an automation would read from and write to (forecasts:
  the sensor to forecast plus its regressors, and the sensor to save to;
  schedules: the flex-model's device sensors, and whatever the parameters refer to)
- Require read access to the former and create-children (the permission for
  recording data through the API) on the latter, when creating via the API
- The CLI creates automations without a user, and stays unrestricted

Signed-off-by: F.N. Claessen <felix@seita.nl>
Context:
- The endpoint description now states the sensor access rule

Change:
- Regenerated the specs

Signed-off-by: F.N. Claessen <felix@seita.nl>
Context:
- The sensor access rule for created automations needs regression coverage

Change:
- An account admin creating an automation on another account's sensor gets a 403
  naming that sensor, and no automation is created; the same request on their own
  sensor still succeeds (verified to fail without the check)

Signed-off-by: F.N. Claessen <felix@seita.nl>
Context:
- The sensor access rule is user-facing

Change:
- Documented it in the forecasting feature docs, the changelog entry of #2294
  and the API change log

Signed-off-by: F.N. Claessen <felix@seita.nl>
@Flix6x
Flix6x requested a review from BelhsanHmida August 5, 2026 17:00
Flix6x added 2 commits August 5, 2026 23:33
Context:
- Schedulers hand their results to make_schedule as (sensor, data) pairs, and
  those sensors are not only the flex-model's device sensors: a schedule is also
  recorded on a device's state-of-charge, consumption and production sensors, and
  on the flex-context's aggregate-consumption and aggregate-production sensors

Change:
- Derive a schedule's output sensors from all the fields that name where generated
  data goes, at any depth in the flex-model and flex-context (which schedulers
  deserialize themselves, so their sensor references are still raw)
- Everything else the parameters refer to (e.g. price sensors and the sensors of
  inflexible devices, which may also live on the flex-context) counts as an input

Signed-off-by: F.N. Claessen <felix@seita.nl>
Context:
- The flex-context's aggregate-consumption sensor is written to, so it needs the
  same check as the flex-model's own sensors

Change:
- Posting such an automation gets a 403 that names the sensor and the action
  (verified to fail when only the flex-model's sensors are treated as outputs)

Signed-off-by: F.N. Claessen <felix@seita.nl>
@Flix6x

Flix6x commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

@BelhsanHmida — Felix reviewed the automations work and asked for one thing to land here: an automation administered through the UI (and hence the API) may only involve sensors that its creator can access. Could you review these commits, and then take the PR over again?

What we contributed:

  • create_automation now works out which sensors an automation would read from and write to, and requires read access to the former and create-children on the latter — the same permission the API requires for recording data on a sensor. A refused request gets a 403 naming the sensor and the action, through the existing api_message mechanism.
  • This is behind a check_permissions flag that the API passes; the CLI creates automations without a user and stays unrestricted.
  • Forecasts: the sensor to forecast plus its regressors are inputs, the sensor to save to (the same sensor by default) is the output.
  • Schedules: schedulers hand their results to make_schedule as (sensor, data) pairs, so the outputs are not only the flex-model's device sensors — a schedule is also recorded on a device's state-of-charge, consumption and production sensors, and on the flex-context's aggregate-consumption and aggregate-production. We derive the outputs from all of those fields at any depth, since the flex-model and flex-context are deserialized by the scheduler itself and their sensor references are still raw at this point. Everything else the parameters refer to (price sensors, inflexible-device sensors — these can live on the flex-context too) counts as an input.
  • Tests cover both a forecast on another account's sensor and a schedule aggregated onto another account's sensor; both were verified to fail without the check. Docs, changelog and API change log updated.

Two things to be aware of:

  1. This branch is ~108 commits behind its base, so it does not yet have the input_sensors / output_sensors properties we added to DataGenerator in Automations - first roundtrip for forecasts #2290. We kept the sensor resolution inside create_automation rather than duplicating those properties, so syncing the stack should be a small edit rather than a conflict — but the two should be collapsed into one implementation then.
  2. Deriving output sensors statically is an approximation of what a scheduler actually returns at run time. If a scheduler starts writing somewhere else, this check will not know about it, so it is worth revisiting whenever a new output field is added.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CRUD for automations in the UI

1 participant