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+343+012345678901234567890123456789-39-39-01234567890123456789
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/automationstakes eitherplanId(as before) orworkspaceIdwithrepositories(1ā10,owner/nameeach; 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 asrepository-not-reachable, saying why, exactly as a Start's is. - The scope check (
checkedScope) applies to the workspace named.
- Change the repositories.
PATCHtakesrepositories, 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.
planIdandplanNameare nullable (null for an automation made with no plan), andworkspaceIdis new and optional.- No desktop build reads automations yet, so no client depends on the old required plan.
- Store.
createAutomationtakesplanId: nullwithorganizationIdandrepositories, 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.
listAutomationstakes a filter (planId/organizationId).AUTOMATION_WORKSPACEnames 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.
- An automation made on a workspace has no plan, its workspace, and the repository as GitHub spells it (sent lower-cased). It lists under
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