Flows and dashboards get ids: the store is addressed by id with a key index, the first start gives every document its key as id, fluksio store migrate --dry-run and ls; the rename routes are gone

This commit is contained in:
2026-11-02 16:54:11 +01:00
parent de13c48c90
commit fae85f5ecb
20 changed files with 1287 additions and 420 deletions
+8 -19
View File
@@ -26,10 +26,6 @@ router = APIRouter(
)
class RenameRequest(BaseModel):
name: str
class PublishRequest(BaseModel):
version: int
@@ -101,7 +97,10 @@ async def generate_results_dashboard(
if await run_in_threadpool(store.exists, name):
raise HTTPException(status_code=409, detail=f"'{name}' already exists")
written = await run_in_threadpool(store.write, results_dashboard(definition))
try:
written = await run_in_threadpool(store.write, results_dashboard(definition))
except DashboardExists as exc:
raise HTTPException(status_code=409, detail=str(exc))
await run_in_threadpool(_apply_history_limits, store, controller)
event_bus.publish(
{"type": "dashboard_changed", "dashboard": name, "ts": time.time()}
@@ -123,6 +122,8 @@ async def save_dashboard(
"""
if body.name != name:
raise HTTPException(status_code=422, detail="The name in the body must match")
if body.id and body.id != name:
raise HTTPException(status_code=422, detail="The id in the body must match")
try:
saved = await run_in_threadpool(store.write_draft, body, body.version)
except StaleVersion as exc:
@@ -133,6 +134,8 @@ async def save_dashboard(
"current_version": exc.current,
},
)
except DashboardExists as exc:
raise HTTPException(status_code=409, detail=str(exc))
return saved
@@ -211,17 +214,3 @@ async def duplicate_dashboard(name: str, store: DashboardStoreDep) -> Any:
return await run_in_threadpool(store.duplicate, name)
except DashboardNotFound:
raise HTTPException(status_code=404, detail=f"No dashboard named '{name}'")
@router.post("/{name}/rename", response_model=DashboardDef)
async def rename_dashboard(
name: str, body: RenameRequest, store: DashboardStoreDep
) -> Any:
try:
return await run_in_threadpool(store.rename, name, body.name)
except DashboardNotFound:
raise HTTPException(status_code=404, detail=f"No dashboard named '{name}'")
except DashboardExists:
raise HTTPException(status_code=409, detail=f"'{body.name}' already exists")
except ValueError as exc:
raise HTTPException(status_code=422, detail=str(exc))
+7 -35
View File
@@ -140,10 +140,6 @@ class ValidationResult(BaseModel):
issues: list[ValidationIssue] = []
class RenameRequest(BaseModel):
new_name: str
class PublishRequest(BaseModel):
version: int
@@ -338,6 +334,7 @@ def read_flows(controller: FlowControllerDep) -> Any:
statuses = controller.node_statuses(name)
summaries.append(
FlowSummary(
id=definition.id,
name=definition.name,
title=definition.title,
mode=definition.mode,
@@ -539,6 +536,10 @@ async def save_flow(
raise HTTPException(
status_code=400, detail="The flow name in the body must match the URL"
)
if definition.id and definition.id != name:
raise HTTPException(
status_code=400, detail="The flow id in the body must match the URL"
)
duplicates = {n.id for n in definition.nodes}
if len(duplicates) != len(definition.nodes):
@@ -559,6 +560,8 @@ async def save_flow(
status_code=409,
detail={"message": str(exc), "current_version": exc.current},
)
except FlowExists as exc:
raise HTTPException(status_code=409, detail=str(exc))
return await run_in_threadpool(_detail, controller, stored)
@@ -641,37 +644,6 @@ async def delete_flow(
return Message(message=f"Deleted flow '{name}'")
@router.post("/{name}/rename", response_model=FlowDetail)
async def rename_flow(
name: str,
body: RenameRequest,
controller: FlowControllerDep,
) -> Any:
"""Rename a flow, along with every reference to its messages."""
if not NAME_PATTERN.match(body.new_name):
raise HTTPException(
status_code=400,
detail=(
"Use lowercase letters, digits and underscores, starting with a letter"
),
)
try:
renamed = await run_in_threadpool(
controller.store.rename_flow, name, body.new_name
)
except FlowNotFound:
raise HTTPException(status_code=404, detail=f"No flow named '{name}'")
except FlowExists as exc:
raise HTTPException(status_code=409, detail=str(exc))
# The old name is nobody's namespace now; its values would sit there under a
# flow that no longer exists. They repopulate under the new name on the next
# run, so this is cleanup rather than a migration.
await run_in_threadpool(controller.forget_flow, name)
await controller.reload()
return await run_in_threadpool(_detail, controller, renamed)
@router.post("/{name}/duplicate", response_model=FlowDetail)
async def duplicate_flow(
name: str, controller: FlowControllerDep, user: CurrentUser