155 lines
4.1 KiB
Python
155 lines
4.1 KiB
Python
from datetime import datetime
|
|
from typing import ClassVar
|
|
|
|
from ninja import ModelSchema, Schema
|
|
from pydantic import Field
|
|
|
|
from apps.reviews.models import ApproverGroup, ReviewSettings
|
|
from apps.users.models import User
|
|
|
|
|
|
class ApproverOut(ModelSchema):
|
|
class Meta:
|
|
model = User
|
|
fields: ClassVar[tuple[str, ...]] = (
|
|
User.id.field.name,
|
|
User.username.field.name,
|
|
User.email.field.name,
|
|
User.first_name.field.name,
|
|
User.last_name.field.name,
|
|
)
|
|
|
|
|
|
class ExperimenterOut(ModelSchema):
|
|
class Meta:
|
|
model = User
|
|
fields: ClassVar[tuple[str, ...]] = (
|
|
User.id.field.name,
|
|
User.username.field.name,
|
|
User.email.field.name,
|
|
)
|
|
|
|
|
|
class ApproverGroupOut(ModelSchema):
|
|
experimenter: ExperimenterOut
|
|
approvers: list[ApproverOut]
|
|
min_approvals: int
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Meta:
|
|
model = ApproverGroup
|
|
fields: ClassVar[tuple[str, ...]] = (
|
|
ApproverGroup.id.field.name,
|
|
ApproverGroup.experimenter.field.name,
|
|
ApproverGroup.approvers.field.name,
|
|
ApproverGroup.min_approvals.field.name,
|
|
ApproverGroup.created_at.field.name,
|
|
ApproverGroup.updated_at.field.name,
|
|
)
|
|
|
|
|
|
class ApproverGroupCreateIn(Schema):
|
|
experimenter_id: str = Field(
|
|
...,
|
|
description="UUID of the experimenter user this group belongs to.",
|
|
)
|
|
approver_ids: list[str] = Field(
|
|
default_factory=list,
|
|
description=(
|
|
"List of user UUIDs to add as approvers. "
|
|
"Each user must have the 'approver' role."
|
|
),
|
|
)
|
|
min_approvals: int = Field(
|
|
1,
|
|
ge=1,
|
|
description=(
|
|
"Number of distinct approvals required. "
|
|
"Must be >= 1 and <= number of approvers (if any are provided)."
|
|
),
|
|
)
|
|
|
|
|
|
class ApproverGroupUpdateIn(Schema):
|
|
approver_ids: list[str] | None = Field(
|
|
None,
|
|
description=(
|
|
"If provided, replaces the current set of approvers. "
|
|
"Each user must have the 'approver' role."
|
|
),
|
|
)
|
|
min_approvals: int | None = Field(
|
|
None,
|
|
ge=1,
|
|
description="New minimum approval threshold.",
|
|
)
|
|
|
|
|
|
class ApproverGroupListOut(Schema):
|
|
count: int
|
|
items: list[ApproverGroupOut]
|
|
|
|
|
|
class ApproverGroupAddApproverIn(Schema):
|
|
approver_id: str = Field(
|
|
...,
|
|
description="UUID of the user to add as an approver.",
|
|
)
|
|
|
|
|
|
class ApproverGroupRemoveApproverIn(Schema):
|
|
approver_id: str = Field(
|
|
...,
|
|
description="UUID of the approver to remove.",
|
|
)
|
|
|
|
|
|
class ReviewSettingsOut(ModelSchema):
|
|
default_min_approvals: int
|
|
allow_any_approver: bool
|
|
updated_at: datetime
|
|
|
|
class Meta:
|
|
model = ReviewSettings
|
|
fields: ClassVar[tuple[str, ...]] = (
|
|
ReviewSettings.id.field.name,
|
|
ReviewSettings.default_min_approvals.field.name,
|
|
ReviewSettings.allow_any_approver.field.name,
|
|
ReviewSettings.updated_at.field.name,
|
|
)
|
|
|
|
|
|
class ReviewSettingsUpdateIn(Schema):
|
|
default_min_approvals: int | None = Field(
|
|
None,
|
|
ge=1,
|
|
description="New default minimum approval threshold.",
|
|
)
|
|
allow_any_approver: bool | None = Field(
|
|
None,
|
|
description="New fallback policy for approver eligibility.",
|
|
)
|
|
|
|
|
|
class EffectiveReviewPolicyOut(Schema):
|
|
experimenter_id: str = Field(..., description="UUID of the experimenter.")
|
|
min_approvals: int = Field(
|
|
..., description="Effective number of approvals required."
|
|
)
|
|
approvers: list[ApproverOut] = Field(
|
|
...,
|
|
description="List of users who are eligible to approve.",
|
|
)
|
|
source: str = Field(
|
|
...,
|
|
description=(
|
|
"Where the policy comes from: "
|
|
"'approver_group' or 'global_fallback'."
|
|
),
|
|
)
|
|
has_explicit_group: bool = Field(
|
|
...,
|
|
description="Whether the experimenter has an explicit approver group.",
|
|
)
|