Skip to content

feat(interview): add cancel interview enpoint#28

Merged
Benji918 merged 3 commits into
devfrom
feat/cancel-interview
May 19, 2026
Merged

feat(interview): add cancel interview enpoint#28
Benji918 merged 3 commits into
devfrom
feat/cancel-interview

Conversation

@Bnabdulwasiu
Copy link
Copy Markdown
Collaborator

@Bnabdulwasiu Bnabdulwasiu commented May 19, 2026

Description

This PR implements the "Cancel Interview" endpoint (POST /api/v1/interviews/:id/cancel) as specified in the Interviews Core CRUD feature set. It allows recruiters to cancel a scheduled or draft interview session, transitions its status to cancelled, and prevents already-cancelled or completed interviews from being modified.

Type of Change

  • feat — New feature
  • fix — Bug fix
  • refactor — Code refactoring (no functional change)
  • docs — Documentation update
  • test — Adding or updating tests
  • chore — Maintenance (dependencies, CI, tooling)

Related Issue

Closes #

Changes Made

  • Service Layer (app/services/interview.py): Added cancel_interview method to manage the cancelled state transitions and prevent operations on completed/cancelled interviews (raising 409 Conflict).
  • Route Layer (app/api/v1/routes/interviews.py): Defined the POST /api/v1/interviews/{interview_id}/cancel route ensuring secure authorization (only owners/interviewers can cancel their own interviews).
  • Test Suite (tests/test_cancel_interview.py): Added comprehensive test cases verifying happy path cancellation, state transitions, authentication (401), query safety (404), cross-user leak protection (404), and double-cancellation conflicts (409).

Proof of Work

API Response / Screenshots
// POST /api/v1/interviews/a905c9f.../cancel
// Status: 200 OK
{
  "status": "success",
  "message": "Interview cancelled successfully",
  "data": {
    "id": "a905c9f2-...",
    "title": "Senior Backend Engineer",
    "status": "cancelled",
    "role_title": "Senior Backend Engineer",
    "platform": "zoom",
    "ai_tone": "professional",
    "candidate_name": "Jane Doe",
    "candidate_email": "jane@example.com",
    "summary": {
      "job_description": "Build scalable APIs using FastAPI and PostgreSQL.",
      "scoring_rubric": "Communication, API design, problem-solving, scalability.",
      "ai_assessment": null,
      "status": "pending"
    },
    "criteria": [
      "Communication",
      "API Design",
      "Problem Solving"
    ],
    "created_at": "2026-05-19T14:52:00Z"
  }
}

## Test Cases

- [x] Test case 1: `test_cancel_draft_interview_returns_200`
- [x] Test case 2: `test_cancel_returns_correct_interview_fields`
- [x] Test case 3: `test_cancel_is_reflected_in_get`
- [x] Test case 4: `test_cancel_returns_404_for_nonexistent_interview`
- [x] Test case 5: `test_cancel_returns_404_for_another_users_interview`
- [x] Test case 6: `test_cancel_returns_401_without_token`
- [x] Test case 7: `test_cancel_already_cancelled_returns_409`

<details>
<summary>Test output</summary>

```bash
$ uv run pytest tests/test_cancel_interview.py -v
============================= test session starts =============================
platform win32 -- Python 3.13.13, pytest-9.0.3, pluggy-1.6.0
cachedir: .pytest_cache
rootdir: C:\Users\USER\Desktop\meetmind-api
configfile: pyproject.toml
plugins: anyio-4.13.0, asyncio-1.3.0
asyncio: mode=Mode.AUTO, debug=False
collected 7 items

tests/test_cancel_interview.py::TestCancelInterview::test_cancel_draft_interview_returns_200 PASSED [ 14%]
tests/test_cancel_interview.py::TestCancelInterview::test_cancel_returns_correct_interview_fields PASSED [ 28%]
tests/test_cancel_interview.py::TestCancelInterview::test_cancel_is_reflected_in_get PASSED [ 42%]
tests/test_cancel_interview.py::TestCancelInterview::test_cancel_returns_404_for_nonexistent_interview PASSED [ 57%]
tests/test_cancel_interview.py::TestCancelInterview::test_cancel_returns_404_for_another_users_interview PASSED [ 71%]
tests/test_cancel_interview.py::TestCancelInterview::test_cancel_returns_401_without_token PASSED [ 85%]
tests/test_cancel_interview.py::TestCancelInterview::test_cancel_already_cancelled_returns_409 PASSED [100%]

============================== 7 passed in 8.73s ==============================


## Checklist

- [x] My branch follows the naming convention (`<type>/<short-description>`)
- [x] My commits follow [Conventional Commits](https://www.conventionalcommits.org/)
- [x] I have added meaningful tests that cover success and failure paths
- [x] All new and existing tests pass locally (`uv run pytest`)
- [x] I have included proof of work (JSON responses or screenshots)
- [ ] I have updated documentation if needed
- [x] My code follows the project's style guidelines

@Bnabdulwasiu Bnabdulwasiu requested review from Afeh and Benji918 May 19, 2026 14:13
@Bnabdulwasiu Bnabdulwasiu changed the title Feat/cancel interview feat(interview): add cancel interview enpoint May 19, 2026
@Benji918 Benji918 merged commit d13b540 into dev May 19, 2026
6 checks passed
@Bnabdulwasiu Bnabdulwasiu deleted the feat/cancel-interview branch May 24, 2026 08:09
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.

2 participants