Files
Lotty/src/backend/api/v1/reviews/schemas.py
T
2026-02-12 22:29:57 +03:00

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.",
)