Skip to content

feat(api): add GET /forms/{submission_id} endpoint with tests#167

Open
aryan-2255 wants to merge 1 commit intofireform-core:mainfrom
aryan-2255:feat/get-form-submission-by-id
Open

feat(api): add GET /forms/{submission_id} endpoint with tests#167
aryan-2255 wants to merge 1 commit intofireform-core:mainfrom
aryan-2255:feat/get-form-submission-by-id

Conversation

@aryan-2255
Copy link

This PR adds a new read endpoint to retrieve an existing form submission by ID, completes the missing retrieval path for form records, and adds focused tests to validate success and error behavior.

##What Changed -

1.) API Route

Added a new endpoint in api/routes/forms.py:
GET /forms/{submission_id}
Returns 200 with the submission payload when found
Returns 404 with a clear message when not found

2.) Repository Layer

Added a repository helper in api/db/repositories.py:
get_form_submission(session, submission_id)
direct primary-key lookup for efficient retrieval

3.) Tests

Replaced placeholder form tests with real endpoint tests in tests/test_forms.py:
test_get_form_submission_by_id
test_get_form_submission_by_id_not_found
Test design avoids external LLM/Ollama dependency by monkeypatching controller fill behavior, so tests remain fast and deterministic.

Behaviour Before vs After -

Before

Submissions could be created via POST /forms/fill
No API endpoint existed to fetch a submission later by ID

After

Submissions can now be retrieved via GET /forms/{submission_id}
Clients can reliably fetch generated output metadata (including output_pdf_path)
Missing records return a consistent 404 response

##API Contract

GET /forms/{submission_id}
200 OK: returns FormFillResponse payload
404 Not Found: returns error detail "Form submission not found"

##Why This Change Matters

Completes a core CRUD read path for form submissions
Enables frontend/history/detail views to load a submission directly
Improves operational usability for follow-up access to generated form outputs
Keeps architecture aligned with existing repository + route separation

##Impact Assessment

Backward compatibility: Fully backward-compatible (additive endpoint only)
Risk level: Low
Performance impact: Minimal; single-row lookup by primary key
External dependency impact: None

##Validation Performed

Ran local test suite:
source .venv/bin/activate && PYTHONPATH=. pytest -q
Result: 3 passed

##Files Included in This PR
api/routes/forms.py
api/db/repositories.py
tests/test_forms.py

##Out of Scope
No changes to fill pipeline logic
No schema model restructuring
No Docker/runtime config changes

closed #165

Copilot AI review requested due to automatic review settings March 3, 2026 14:51
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a read endpoint to retrieve an existing form submission by ID, completing the “GET by id” path for form submissions and adding tests to validate success and not-found behavior.

Changes:

  • Added GET /forms/{submission_id} to return a FormFillResponse or a 404 when missing.
  • Added a repository helper get_form_submission(session, submission_id) using a primary-key lookup.
  • Replaced placeholder form tests with real endpoint tests for success and not-found cases.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
api/routes/forms.py Adds the GET submission-by-id route and wires it to repository lookup + 404 behavior.
api/db/repositories.py Adds get_form_submission() helper for direct primary-key retrieval.
tests/test_forms.py Adds endpoint tests for retrieving a submission and for the 404 not-found case.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1 to +5
from fastapi import APIRouter, Depends, HTTPException
from sqlmodel import Session
from api.deps import get_db
from api.schemas.forms import FormFill, FormFillResponse
from api.db.repositories import create_form, get_template
from api.db.repositories import create_form, get_template, get_form_submission
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

fill_form raises AppError, but api/main.py never registers register_exception_handlers, so AppError will surface as an unhandled exception (500) rather than the intended 404. Since this file now introduces HTTPException-based 404s, consider standardizing by switching the existing AppError("Template not found") path to HTTPException(status_code=404, detail=...), or alternatively register the AppError handler in api/main.py and align the error response shape (currently {"error": ...} vs {"detail": ...}).

Copilot uses AI. Check for mistakes.
Comment on lines +23 to +29
template_response = client.post("/templates/create", json=_template_payload("Form Template"))
template_id = template_response.json()["id"]

fill_response = client.post(
"/forms/fill",
json={"template_id": template_id, "input_text": "test transcript"},
)
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

The test uses template_response.json()["id"] without asserting the template creation succeeded. Adding assert template_response.status_code == 200 (and similarly for fill_response) will make failures clearer and avoid misleading KeyError/JSONDecodeError when the request fails.

Suggested change
template_response = client.post("/templates/create", json=_template_payload("Form Template"))
template_id = template_response.json()["id"]
fill_response = client.post(
"/forms/fill",
json={"template_id": template_id, "input_text": "test transcript"},
)
template_response = client.post("/templates/create", json=_template_payload("Form Template"))
assert template_response.status_code == 200
template_id = template_response.json()["id"]
fill_response = client.post(
"/forms/fill",
json={"template_id": template_id, "input_text": "test transcript"},
)
assert fill_response.status_code == 200

Copilot uses AI. Check for mistakes.
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.

[FEAT]: Add GET /forms/{submission_id} endpoint

2 participants