|
|
"""Team collaboration features for deployment reviews.""" |
|
|
|
|
|
from __future__ import annotations |
|
|
|
|
|
import time |
|
|
from dataclasses import dataclass, field |
|
|
from typing import Any, Dict, List, Optional |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class ReviewComment: |
|
|
"""A comment on a deployment readiness review.""" |
|
|
author: str |
|
|
comment: str |
|
|
timestamp: float |
|
|
category: str = "general" |
|
|
resolved: bool = False |
|
|
|
|
|
|
|
|
@dataclass |
|
|
class Approval: |
|
|
"""An approval from a stakeholder.""" |
|
|
approver: str |
|
|
role: str |
|
|
approved: bool |
|
|
timestamp: float |
|
|
notes: Optional[str] = None |
|
|
|
|
|
|
|
|
class CollaborationManager: |
|
|
"""Manages team collaboration for deployment reviews.""" |
|
|
|
|
|
def __init__(self): |
|
|
self.reviews: Dict[str, Dict[str, Any]] = {} |
|
|
|
|
|
def create_review( |
|
|
self, |
|
|
review_id: str, |
|
|
project_name: str, |
|
|
stakeholders: List[str] |
|
|
) -> Dict[str, Any]: |
|
|
"""Create a new review session.""" |
|
|
review = { |
|
|
"id": review_id, |
|
|
"project_name": project_name, |
|
|
"stakeholders": stakeholders, |
|
|
"comments": [], |
|
|
"approvals": [], |
|
|
"status": "pending", |
|
|
"created_at": time.time() |
|
|
} |
|
|
self.reviews[review_id] = review |
|
|
return review |
|
|
|
|
|
def add_comment( |
|
|
self, |
|
|
review_id: str, |
|
|
author: str, |
|
|
comment: str, |
|
|
category: str = "general" |
|
|
) -> Dict[str, Any]: |
|
|
"""Add a comment to a review.""" |
|
|
if review_id not in self.reviews: |
|
|
return {"error": "Review not found"} |
|
|
|
|
|
comment_obj = ReviewComment( |
|
|
author=author, |
|
|
comment=comment, |
|
|
timestamp=time.time(), |
|
|
category=category |
|
|
) |
|
|
self.reviews[review_id]["comments"].append(comment_obj) |
|
|
return {"success": True, "comment": comment_obj} |
|
|
|
|
|
def add_approval( |
|
|
self, |
|
|
review_id: str, |
|
|
approver: str, |
|
|
role: str, |
|
|
approved: bool, |
|
|
notes: Optional[str] = None |
|
|
) -> Dict[str, Any]: |
|
|
"""Add an approval from a stakeholder.""" |
|
|
if review_id not in self.reviews: |
|
|
return {"error": "Review not found"} |
|
|
|
|
|
approval = Approval( |
|
|
approver=approver, |
|
|
role=role, |
|
|
approved=approved, |
|
|
timestamp=time.time(), |
|
|
notes=notes |
|
|
) |
|
|
self.reviews[review_id]["approvals"].append(approval) |
|
|
|
|
|
|
|
|
review = self.reviews[review_id] |
|
|
required_stakeholders = set(review["stakeholders"]) |
|
|
approved_by = {a.approver for a in review["approvals"] if a.approved} |
|
|
|
|
|
if required_stakeholders.issubset(approved_by): |
|
|
review["status"] = "approved" |
|
|
elif any(not a.approved for a in review["approvals"]): |
|
|
review["status"] = "blocked" |
|
|
|
|
|
return {"success": True, "approval": approval, "review_status": review["status"]} |
|
|
|
|
|
def get_review_summary(self, review_id: str) -> Dict[str, Any]: |
|
|
"""Get summary of a review.""" |
|
|
if review_id not in self.reviews: |
|
|
return {"error": "Review not found"} |
|
|
|
|
|
review = self.reviews[review_id] |
|
|
return { |
|
|
"id": review_id, |
|
|
"project_name": review["project_name"], |
|
|
"status": review["status"], |
|
|
"total_comments": len(review["comments"]), |
|
|
"total_approvals": len(review["approvals"]), |
|
|
"approved_by": [a.approver for a in review["approvals"] if a.approved], |
|
|
"blocked_by": [a.approver for a in review["approvals"] if not a.approved], |
|
|
"pending_approvals": [ |
|
|
s for s in review["stakeholders"] |
|
|
if s not in [a.approver for a in review["approvals"]] |
|
|
] |
|
|
} |
|
|
|
|
|
|