Close repository requests with manual lock sessions
This commit is contained in:
@@ -38,7 +38,8 @@ by default) and may be explicitly cancelled with
|
||||
`repository.lock.request.cancel`. Manual confirmations expire after
|
||||
`ONEC_REPOSITORY_CONFIRMATION_TTL_SECONDS` (2 hours by default). After the user
|
||||
releases the objects in Configurator, `repository.lock.close` closes the
|
||||
confirmation and immediately blocks further SQL writes through that session.
|
||||
confirmation, marks its originating request as `closed`, and immediately blocks
|
||||
further SQL writes through that session.
|
||||
The adapter keeps a bounded audit trail of request creation, confirmation,
|
||||
cancellation, and closure and exposes it to the administrative requests view.
|
||||
|
||||
|
||||
@@ -538,6 +538,7 @@ def confirm_manual_lock(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
"base_id": base_id, "layer": str(config.get("layer") or "base"), "backend": config.get("backend"),
|
||||
"objects": plan["lock_objects"], "created_at": time.time(), "status": "manual_confirmed",
|
||||
"verification": "user_confirmation_only", "automatically_verified": False,
|
||||
**({"request_id": request_id} if request_id else {}),
|
||||
}
|
||||
if isinstance(request, dict):
|
||||
request["status"] = "confirmed_by_user"
|
||||
@@ -571,13 +572,34 @@ def close_manual_lock(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
session = (state.get("sessions") or {}).get(session_id)
|
||||
if not isinstance(session, dict):
|
||||
return {"schema": "onec_repository_lock_close.v1", "method": METHOD_CLOSE, "status": "not_found", "lock_session_id": session_id}
|
||||
if session.get("status") != "manual_confirmed":
|
||||
if session.get("status") not in {"manual_confirmed", "closed"}:
|
||||
return {"schema": "onec_repository_lock_close.v1", "method": METHOD_CLOSE, "status": "blocked", "error": "manual_confirmation_not_active", "lock_session_id": session_id}
|
||||
already_closed = session.get("status") == "closed"
|
||||
session["status"] = "closed"
|
||||
session["closed_at"] = time.time()
|
||||
_audit(state, "manual_lock_closed", lock_session_id=session_id, base_id=session.get("base_id"), objects=session.get("objects"))
|
||||
closed_at = float(session.get("closed_at") or time.time())
|
||||
session["closed_at"] = closed_at
|
||||
request_id = str(session.get("request_id") or "").strip()
|
||||
request = (state.get("requests") or {}).get(request_id) if request_id else None
|
||||
if not isinstance(request, dict):
|
||||
request_id = next(
|
||||
(
|
||||
str(candidate_id)
|
||||
for candidate_id, candidate in (state.get("requests") or {}).items()
|
||||
if isinstance(candidate, dict) and candidate.get("lock_session_id") == session_id
|
||||
),
|
||||
"",
|
||||
)
|
||||
request = (state.get("requests") or {}).get(request_id) if request_id else None
|
||||
if isinstance(request, dict):
|
||||
request["status"] = "closed"
|
||||
request["closed_at"] = closed_at
|
||||
if not already_closed:
|
||||
_audit(state, "manual_lock_closed", request_id=request_id or None, lock_session_id=session_id, base_id=session.get("base_id"), objects=session.get("objects"))
|
||||
_write_state(state)
|
||||
return {"schema": "onec_repository_lock_close.v1", "method": METHOD_CLOSE, "status": "closed", "lock_session_id": session_id}
|
||||
return {
|
||||
"schema": "onec_repository_lock_close.v1", "method": METHOD_CLOSE, "status": "closed",
|
||||
"lock_session_id": session_id, "request_id": request_id or None,
|
||||
}
|
||||
|
||||
|
||||
def write_gate(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
|
||||
@@ -104,6 +104,13 @@ def test_manual_lock_request_stays_pending_until_user_confirms_exact_saved_scope
|
||||
|
||||
closed = repository_control.close_manual_lock({"lock_session_id": confirmed["lock_session_id"], "user_confirmed_released": True})
|
||||
assert closed["status"] == "closed"
|
||||
assert closed["request_id"] == requested["request_id"]
|
||||
completed = repository_control.lock_request_status({"request_id": requested["request_id"]})
|
||||
assert completed["status"] == "closed"
|
||||
assert completed["request"]["closed_at"] > completed["request"]["confirmed_at"]
|
||||
closed_again = repository_control.close_manual_lock({"lock_session_id": confirmed["lock_session_id"], "user_confirmed_released": True})
|
||||
assert closed_again["status"] == "closed"
|
||||
assert closed_again["request_id"] == requested["request_id"]
|
||||
assert repository_control.write_gate({"base_id": "base", "lock_session_id": confirmed["lock_session_id"], "repository_object": "РегистрСведений.Настройки"})["allowed"] is False
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user