Add rollback-target resolver over the deployment journal
Summary
- Resolve the release to roll back to for a
(project, environment): the most recent successfully-deployed release that differs from the current one. - Reads the existing deployment-completion journal joined to
Deployment+Release— no schema change — ordered newest-first, excluding failed deployments. - Pure selection rule (
RollbackTargetSelector) is separated from data access (IRollbackService→IDeploymentCompletionDataProvider), so the "which release?" logic is unit-testable in isolation. - Foundation for the upcoming rollback command, which will re-dispatch the resolved release through the existing
DeploymentService.CreateDeploymentAsyncpipeline. Additive and non-breaking — nothing consumes it yet.
Test plan
-
Unit ( RollbackTargetSelectorTests, 7): empty/null history, single release, same release re-deployed, linear v1→v2→v3, release re-deployed after a newer one, prior release deployed multiple times (most-recent wins) -
Integration vs Postgres ( RollbackTargetResolutionTests, 5): linear history resolves the preceding release; journal query returns newest-first with versions; environment isolation (a later deploy to another environment is ignored); failed deployments excluded; single-release returns null -
Full solution builds clean (0 errors)
E2E lands with the rollback action PR (seed prior releases → invoke rollback → assert the prior release re-deploys end-to-end), where there is a user-facing entry point to exercise.