Skip to content

feat: Issue #34 — Structured review decisions and findings#95

Open
Chukwuebuka-2003 wants to merge 3 commits into
Flow-Research:mainfrom
Chukwuebuka-2003:feat/issue-34-review-decisions
Open

feat: Issue #34 — Structured review decisions and findings#95
Chukwuebuka-2003 wants to merge 3 commits into
Flow-Research:mainfrom
Chukwuebuka-2003:feat/issue-34-review-decisions

Conversation

@Chukwuebuka-2003

@Chukwuebuka-2003 Chukwuebuka-2003 commented Jul 11, 2026

Copy link
Copy Markdown

Workstream PR Trust Bundle

Chunk

issue-34 - Structured review decisions and findings

Goal

Add persistent, auditable human review decisions (accept/needs_revision/reject) with structured findings.

What Changed

Created backend/app/modules/review/ module with:

  • models.py: Review + ReviewFinding SQLAlchemy tables with DB-level CheckConstraints
  • schemas.py: Pydantic schemas with regex validation
  • service.py: ReviewService enforcing decision rules and audit event creation
  • router.py: FastAPI endpoints at POST/GET /api/v1/reviews
  • 0015_review_models.py: Alembic migration
  • test_review.py: 9 end-to-end tests

Acceptance Criteria Proof

  • API rejects unknown decision values
  • reject requires 1+ finding
  • needs_revision requires 1+ finding
  • accept requires evidence references
  • accept blocked by CheckerResult.blocks_review
  • AuditEvent created with actor identity

Test Delta

  • Added: test_review.py with 9 cases across 5 classes
  • None modified or removed

Human Merge Ownership

  • I can explain what changed.
  • I know what could break.
  • I accept the remaining risks.
  • The user explicitly approved this specific PR for merge.

Add Review + ReviewFinding models with DB-level CheckConstraints enforcing
decision values (accept/needs_revision/reject) and severity levels.

- models.py: Review and ReviewFinding SQLAlchemy models with FK relationships
- schemas.py: Pydantic request/response schemas with pattern validation
- service.py: ReviewService enforcing 3 business rules + AuditEvent creation
- router.py: FastAPI routes (POST/GET /api/v1/reviews)
- 0015_review_models.py: Alembic migration for reviews and review_findings tables
- test_review.py: 9 test cases covering all 5 acceptance criteria

Registered in db/models.py and wired via api/router.py.
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Chukwuebuka-2003, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 17 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 306e296e-85f2-4f61-a989-aaab719b0536

📥 Commits

Reviewing files that changed from the base of the PR and between 1cd3f48 and fcb08d4.

📒 Files selected for processing (2)
  • backend/app/modules/review/service.py
  • backend/tests/test_review.py
📝 Walkthrough

Walkthrough

Adds structured review decision and finding persistence, validation rules, audit events, FastAPI endpoints, router registration, and end-to-end tests for accept, reject, and needs-revision workflows.

Changes

Structured review decisions and findings

Layer / File(s) Summary
Review contracts and persistence
backend/app/modules/review/models.py, backend/app/modules/review/schemas.py, backend/alembic/versions/0015_review_models.py, backend/app/db/models.py
Defines review and finding schemas, ORM relationships, allowed values, database constraints, timestamps, indexes, and migration lifecycle.
Review validation and audit flow
backend/app/modules/review/service.py, backend/tests/test_review.py
Validates submission existence, required findings, acceptance evidence, and blocking checker results; persists findings and audit events and supports review queries.
Review API exposure
backend/app/modules/review/router.py, backend/app/api/router.py
Adds review creation and retrieval endpoints, maps service errors to HTTP responses, and registers the router under /api/v1.
Review workflow tests
backend/tests/test_review.py
Verifies invalid decisions, decision-specific requirements, audit creation, successful review creation, and submission review listing.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ReviewAPI
  participant ReviewService
  participant Database
  participant AuditEvent
  Client->>ReviewAPI: POST /api/v1/reviews
  ReviewAPI->>ReviewService: create_review(payload, actor_id)
  ReviewService->>Database: validate submission and checker results
  ReviewService->>Database: save Review and ReviewFinding records
  ReviewService->>AuditEvent: record review_decision_created
  ReviewService-->>ReviewAPI: ReviewSchema
  ReviewAPI-->>Client: review response
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The description covers the basics but omits many required template sections like intent, design, evidence, reviewer results, and risks. Add the missing template sections: Human-Approved Intent, Why It Changed, Design Chosen, Evidence, Internal Reviewer Results, CI/Gate Integrity, Risks, and Follow-Up Work.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes align with #34 by adding review persistence, decision constraints, findings, acceptance checks, audit events, and tests.
Out of Scope Changes check ✅ Passed No clear out-of-scope changes appear; the migration, API wiring, models, service, and tests all support the review feature.
Title check ✅ Passed The title is concise and accurately summarizes the main change: structured review decisions and findings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/app/modules/review/service.py`:
- Around line 105-107: Update create_review, get_review, and
get_reviews_for_submission to eager-load the Review.findings relationship before
calling ReviewSchema.model_validate. Reuse the existing async query/loading
patterns where available, ensuring each returned Review has findings populated
while preserving the current serialization behavior.

In `@backend/tests/test_review.py`:
- Around line 201-214: Update the test setup around the seeded CheckerResult to
create and persist a CheckerRun first, then assign its generated id to
CheckerResult.checker_run_id instead of using a random UUID. Keep the blocking
result’s existing task, submission, and review-blocking fields unchanged so the
commit succeeds with a valid foreign-key relationship.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f6f7f1fd-e0db-40ba-b190-09938b52b6b2

📥 Commits

Reviewing files that changed from the base of the PR and between a7aa474 and 1cd3f48.

📒 Files selected for processing (8)
  • backend/alembic/versions/0015_review_models.py
  • backend/app/api/router.py
  • backend/app/db/models.py
  • backend/app/modules/review/models.py
  • backend/app/modules/review/router.py
  • backend/app/modules/review/schemas.py
  • backend/app/modules/review/service.py
  • backend/tests/test_review.py

Comment thread backend/app/modules/review/service.py
Comment thread backend/tests/test_review.py Outdated
1. Eager-load Review.findings via selectinload in create_review,
   get_review, and get_reviews_for_submission to prevent MissingGreenlet
   during Pydantic serialization.

2. Seed a real CheckerRun before CheckerResult in test_accept_blocked_by_checker_result
   to satisfy the FK constraint on checker_run_id.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant