| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- from __future__ import annotations
- from flask import g, jsonify, request
- from app import db
- from app.api.system import bp
- from app.core.governance.responsibilities import (
- ResponsibilityConflict,
- ResponsibilityService,
- ResponsibilityUserUnavailable,
- ResponsibilityValidationError,
- SqlAlchemyResponsibilityRepository,
- )
- from app.core.system.permissions import (
- RESPONSIBILITIES_MANAGE,
- RESPONSIBILITIES_READ,
- require_permissions,
- )
- from app.models.result import failed, success
- def _service() -> ResponsibilityService:
- return ResponsibilityService(SqlAlchemyResponsibilityRepository(db.session))
- def _etag(response, revision: int):
- response.headers["ETag"] = f'"{int(revision)}"'
- return response
- def _expected_revision() -> int:
- raw = str(request.headers.get("If-Match") or "").strip()
- if raw.startswith("W/"):
- raw = raw[2:].strip()
- raw = raw.strip('"')
- if not raw or not raw.isdigit():
- raise ResponsibilityValidationError("missing valid If-Match revision")
- return int(raw)
- @bp.route(
- "/responsibilities/<resource_type>/<resource_uid>",
- methods=["GET"],
- )
- @require_permissions(RESPONSIBILITIES_READ)
- def get_responsibility_matrix(resource_type: str, resource_uid: str):
- try:
- result = _service().get(resource_type, resource_uid)
- return _etag(jsonify(success(result)), result["revision"])
- except ResponsibilityValidationError as exc:
- return jsonify(failed(str(exc), code=400)), 400
- @bp.route(
- "/responsibilities/<resource_type>/<resource_uid>",
- methods=["PUT"],
- )
- @require_permissions(RESPONSIBILITIES_MANAGE)
- def replace_responsibility_matrix(resource_type: str, resource_uid: str):
- try:
- revision = _expected_revision()
- body = request.get_json(silent=True) or {}
- result = _service().replace(
- resource_type=resource_type,
- resource_uid=resource_uid,
- assignments=body.get("assignments"),
- expected_revision=revision,
- actor_uid=g.current_user["id"],
- )
- db.session.commit()
- return _etag(jsonify(success(result, "责任矩阵已更新")), result["revision"])
- except ResponsibilityConflict as exc:
- db.session.rollback()
- return jsonify(failed(str(exc), code=409)), 409
- except ResponsibilityUserUnavailable as exc:
- db.session.rollback()
- return jsonify(failed(str(exc), code=422)), 422
- except ResponsibilityValidationError as exc:
- db.session.rollback()
- status = 428 if "If-Match" in str(exc) else 400
- return jsonify(failed(str(exc), code=status)), status
|