Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions control_plane/drivers/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -587,17 +587,6 @@ def _route_alias(
route_path="/v1/drivers/odoo/preview-apply",
authz_action="odoo_preview_apply.execute",
),
_action(
"preview_verification",
"Record preview verification",
"Record Odoo product smoke verification for the latest preview generation.",
safety="safe_write",
scope="preview",
route_path="/v1/drivers/odoo/preview-verification",
authz_action="preview_generation.write",
operator_visible=False,
writes_records=("preview", "preview_generation"),
),
_action(
"prod_backup_gate",
"Capture prod backup gate",
Expand Down Expand Up @@ -674,6 +663,11 @@ def _route_alias(
"/v1/drivers/odoo/preview-destroy",
"preview_destroy.execute",
),
_route_alias(
"preview_verification",
"/v1/drivers/odoo/preview-verification",
"preview_generation.write",
),
_route_alias(
"stable_verification",
"/v1/drivers/odoo/stable-verification",
Expand Down
13 changes: 7 additions & 6 deletions docs/driver-descriptors.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,13 @@ workflows: `POST /v1/drivers/odoo/preview-desired-state`,
`POST /v1/drivers/odoo/preview-refresh`,
`POST /v1/drivers/odoo/preview-inventory`,
`POST /v1/drivers/odoo/preview-readiness`, and
`POST /v1/drivers/odoo/preview-destroy`. New product workflows should use the
generic-web routes for generic lifecycle evidence unless the product driver
documents a narrower product-specific contract. The Odoo-specific
`POST /v1/drivers/odoo/preview-verification` route remains a driver action
because it returns the typed `odoo_preview_verification` response shape. The lower-level
`POST /v1/drivers/odoo/preview-apply` route applies a ready isolated-preview
`POST /v1/drivers/odoo/preview-destroy`. Odoo preview verification is also a
non-operator route alias: it keeps the typed `odoo_preview_verification`
response shape for existing workflows while the advertised action and durable
record mutation belong to generic-web preview verification. New product
workflows should use the generic-web routes for generic lifecycle evidence
unless the product driver documents a narrower product-specific contract. The
lower-level `POST /v1/drivers/odoo/preview-apply` route applies a ready isolated-preview
Dokploy plan to provider state after service authorization and idempotency
checks. The route resolves runtime env values from Launchplane-owned
runtime-environment records and managed secret overlays, derives preview-specific
Expand Down
3 changes: 2 additions & 1 deletion docs/service-boundary.md
Original file line number Diff line number Diff line change
Expand Up @@ -1222,7 +1222,8 @@ preview targets while the isolated runtime migration is being exercised.

For
Odoo preview smoke follow-ups, `POST /v1/drivers/odoo/preview-verification`
accepts the product, context, anchor repo/PR, `verification_status`,
remains a compatibility alias for the generic-web preview verification action.
It accepts the product, context, anchor repo/PR, `verification_status`,
`verified_at`, optional checked URLs as an explicit list plus
`timeout_seconds`, and an optional failure summary, then marks the latest preview
generation ready or failed. Scalar or object-shaped `checked_urls` payloads are
Expand Down
23 changes: 17 additions & 6 deletions tests/test_driver_descriptors.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,17 @@ def test_odoo_descriptor_marks_prod_rollback_as_destructive(self) -> None:
self.assertEqual(actions["prod_rollback"].safety, "destructive")
self.assertEqual(actions["prod_rollback"].route_path, "/v1/drivers/odoo/prod-rollback")
self.assertNotIn("preview_refresh", actions)
self.assertNotIn("preview_verification", actions)
self.assertEqual(
route_aliases["preview_refresh"].route_path,
"/v1/drivers/odoo/preview-refresh",
)
self.assertFalse(route_aliases["preview_refresh"].operator_visible)
self.assertEqual(
route_aliases["preview_verification"].route_path,
"/v1/drivers/odoo/preview-verification",
)
self.assertFalse(route_aliases["preview_verification"].operator_visible)
self.assertEqual(actions["stable_bootstrap"].safety, "destructive")
self.assertEqual(
actions["stable_bootstrap"].route_path,
Expand All @@ -175,7 +181,7 @@ def test_effective_odoo_actions_inherit_generic_web_preview_routes(self) -> None
self.assertEqual(actions["preview_destroy"].safety, "destructive")
self.assertEqual(
actions["preview_verification"].route_path,
"/v1/drivers/odoo/preview-verification",
"/v1/drivers/generic-web/preview-verification",
)

def test_verireel_descriptor_exposes_preview_and_stable_capabilities(self) -> None:
Expand Down Expand Up @@ -463,6 +469,16 @@ def test_odoo_preview_execution_metadata_matches_descriptors(self) -> None:
].action_id,
"preview_refresh",
)
self.assertEqual(
control_plane_service._driver_route_metadata_from_descriptors()[
"/v1/drivers/odoo/preview-verification"
].action_id,
"preview_verification",
)
self.assertIs(
control_plane_service._ODOO_PREVIEW_VERIFICATION_ROUTE.envelope_model,
control_plane_service.OdooPreviewVerificationEnvelope,
)
self.assert_route_metadata_matches_descriptor(
driver_id="odoo",
route_metadata_by_action={
Expand All @@ -471,11 +487,6 @@ def test_odoo_preview_execution_metadata_matches_descriptors(self) -> None:
control_plane_service.OdooPreviewApplyEnvelope,
"apply Odoo preview",
),
"preview_verification": (
control_plane_service._ODOO_PREVIEW_VERIFICATION_ROUTE,
control_plane_service.OdooPreviewVerificationEnvelope,
"Odoo preview verification",
),
},
)

Expand Down