Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""Add reviewer_status column.

Revision ID: 30a5eeb5f400
Revises: 53f024d8e601
Create Date: 2026-02-19 16:26:32.258055

"""

from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision: str = "30a5eeb5f400"
down_revision: Union[str, Sequence[str], None] = "53f024d8e601"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None

reviewer_status_enum = sa.Enum(
"BLOCKING",
"ADDED",
"ACCEPTED",
"REJECTED",
"COMMENTED",
"ACCEPTED_OLDER",
"REJECTED_OLDER",
"RESIGNED",
name="reviewer_status_enum",
)


def upgrade() -> None:
"""Upgrade schema."""
reviewer_status_enum.create(op.get_bind(), checkfirst=True)
op.add_column(
"review_requests",
sa.Column("reviewer_status", reviewer_status_enum, nullable=True),
)
op.add_column(
"feedback",
sa.Column("reviewer_status", reviewer_status_enum, nullable=True),
)


def downgrade() -> None:
"""Downgrade schema."""
op.drop_column("feedback", "reviewer_status")
op.drop_column("review_requests", "reviewer_status")
reviewer_status_enum.drop(op.get_bind(), checkfirst=True)
14 changes: 13 additions & 1 deletion services/reviewhelper-api/app/database/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
from sqlalchemy.sql import func

from app.enums import ActingCapacity, FeedbackType, Platform, ReviewStatus
from app.enums import (
ActingCapacity,
FeedbackType,
Platform,
ReviewerStatus,
ReviewStatus,
)


class Base(AsyncAttrs, DeclarativeBase):
Expand Down Expand Up @@ -54,6 +60,9 @@ class ReviewRequest(Base):
acting_capacity: Mapped[ActingCapacity | None] = mapped_column(
Enum(ActingCapacity, name="acting_capacity_enum")
)
reviewer_status: Mapped[ReviewerStatus | None] = mapped_column(
Enum(ReviewerStatus, name="reviewer_status_enum")
)

# Status and result
status: Mapped[ReviewStatus] = mapped_column(
Expand Down Expand Up @@ -167,6 +176,9 @@ class Feedback(Base):
acting_capacity: Mapped[ActingCapacity | None] = mapped_column(
Enum(ActingCapacity, name="acting_capacity_enum")
)
reviewer_status: Mapped[ReviewerStatus | None] = mapped_column(
Enum(ReviewerStatus, name="reviewer_status_enum")
)

# Relationships
generated_comment: Mapped[GeneratedComment | None] = relationship(
Expand Down
11 changes: 11 additions & 0 deletions services/reviewhelper-api/app/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,14 @@ class ActingCapacity(str, Enum):
AUTHOR = "author"
REVIEWER = "reviewer"
PARTICIPANT = "participant"


class ReviewerStatus(str, Enum):
BLOCKING = "blocking"
ADDED = "added"
ACCEPTED = "accepted"
REJECTED = "rejected"
COMMENTED = "commented"
ACCEPTED_OLDER = "accepted-older"
REJECTED_OLDER = "rejected-older"
RESIGNED = "resigned"
2 changes: 2 additions & 0 deletions services/reviewhelper-api/app/routers/feedback.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ async def submit_feedback(
user_id=request.user_id,
user_name=request.user_name,
acting_capacity=request.acting_capacity,
reviewer_status=request.reviewer_status,
)

try:
Expand All @@ -74,6 +75,7 @@ async def submit_feedback(
.values(
feedback_type=request.feedback_type,
acting_capacity=request.acting_capacity,
reviewer_status=request.reviewer_status,
)
.where(
Feedback.generated_comment_id == generated_comment_id,
Expand Down
1 change: 1 addition & 0 deletions services/reviewhelper-api/app/routers/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ async def create_or_get_review_request(
user_id=request.user_id,
user_name=request.user_name,
acting_capacity=request.acting_capacity,
reviewer_status=request.reviewer_status,
status=ReviewStatus.PENDING,
)
db.add(review_request)
Expand Down
34 changes: 34 additions & 0 deletions services/reviewhelper-api/app/schemas/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from pydantic import BaseModel, model_validator

from app.enums import ActingCapacity, ReviewerStatus


class UserActionBase(BaseModel):
"""Base model for schemas that include user + acting_capacity fields."""

user_id: int
user_name: str
acting_capacity: ActingCapacity | None = None
reviewer_status: ReviewerStatus | None = None

@model_validator(mode="before")
@classmethod
def split_compound_acting_capacity(cls, data):
if isinstance(data, dict):
raw = data.get("acting_capacity")
if isinstance(raw, str) and ":" in raw:
base, sub = raw.split(":", 1)
data["acting_capacity"] = base
data["reviewer_status"] = sub
return data

@model_validator(mode="after")
def validate_reviewer_status(self):
if (
self.reviewer_status is not None
and self.acting_capacity != ActingCapacity.REVIEWER
):
raise ValueError(
"reviewer_status can only be set when acting_capacity is 'reviewer'"
)
return self
8 changes: 3 additions & 5 deletions services/reviewhelper-api/app/schemas/feedback.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
from pydantic import BaseModel

from app.enums import ActingCapacity, FeedbackType
from app.enums import FeedbackType
from app.schemas.base import UserActionBase


class FeedbackCreate(BaseModel):
class FeedbackCreate(UserActionBase):
"""Request body for submitting feedback."""

comment_id: int
feedback_type: FeedbackType
user_id: int
user_name: str
acting_capacity: ActingCapacity | None = None


class FeedbackResponse(BaseModel):
Expand Down
8 changes: 3 additions & 5 deletions services/reviewhelper-api/app/schemas/review_request.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
from pydantic import BaseModel

from app.enums import ActingCapacity, ReviewStatus
from app.enums import ReviewStatus
from app.schemas.base import UserActionBase


class ReviewRequestCreate(BaseModel):
class ReviewRequestCreate(UserActionBase):
"""Request body for creating a new review request (Phabricator)."""

revision_id: int
diff_id: int
user_id: int
user_name: str
acting_capacity: ActingCapacity | None = None


class ReviewRequestResponse(BaseModel):
Expand Down