feat(features,database,service): an automation is made on a workspace with the repositories its runs work in and no plan

Merged
DA
4d ago
+343-39

Automations at workspace level, as D1 decided: drop per-plan automations; automations belong to the workspace or the person. This is the API the step-11 editor creates with. Until now an automation could only be made on a plan, whose workspace and repository it took.

What changes

  • Create on a workspace. POST /api/automations takes either planId (as before) or workspaceId with repositories (1–10, owner/name each; a run starts in the first, as #2705 has it).
    • A request naming both, or a workspace with no repositories, is refused as invalid.
    • A workspace the account isn't a member of is refused as not found.
    • Each repository is read through the workspace's installation (workspaceRepository) and stored as GitHub spells it. One the installation doesn't reach is refused as repository-not-reachable, saying why, exactly as a Start's is.
    • The scope check (checkedScope) applies to the workspace named.
  • Change the repositories. PATCH takes repositories, read through the automation's own workspace the same way.
  • List by workspace. GET /api/automations?workspaceId= lists one workspace's automations the account may read, beside ?planId=.
  • The summary carries the workspace.
    • planId and planName are nullable (null for an automation made with no plan), and workspaceId is new and optional.
    • No desktop build reads automations yet, so no client depends on the old required plan.
  • Store.
    • createAutomation takes planId: null with organizationId and repositories, made only by a member of that workspace.
    • The reads left-join the plan, so a planless automation is listed, read, and run. The dormant GitHub-event listener still matches on the plan's repository.
    • listAutomations takes a filter (planId / organizationId).
    • AUTOMATION_WORKSPACE names the coalesced workspace expression the access rules already used.

Tests

  • automations-app.test.ts:
    • An automation made on a workspace has no plan, its workspace, and the repository as GitHub spells it (sent lower-cased). It lists under ?workspaceId=, reads as not found for another account, and refuses a change to an unreached repository while taking a reached one.
    • Refusals: an account outside the workspace, a plan named beside it, no repositories, and an unreached repository.
  • automation-store.test.ts: a planless automation takes the workspace and repositories named, lists under its workspace for its owner and not for an outsider, and an outsider can't make one there.
  • No golden changes: the automation wire schemas aren't among the recorded JSON Schema fixtures.

pnpm check:affected passes. This change is server and wire only; CI cannot verify the Mac UI, and ./scripts/verify.sh was not run (LUKE-159 stands in before the first release).

šŸ¤– Generated with Claude Code