fix(backend): validate inputs and add boundary guards in database feedback

Closed
BR
8h ago
+370-16

Summary

Hardens backend/database/feedback.py and backend/routers/mobile_feedback.py with rigorous input validation, whitespace normalization, and boundary guards:

  1. Deterministic Coordinate Normalization:
    • Strips uid and target_id before database write operations.
    • Refuses empty, non-string, or blank whitespace inputs.
    • record_feedback_event: logs a warning and returns None by default (best-effort, preserving caller flow), and raises descriptive ValueError when raise_on_error=True.
  2. Hash Normalization Parity:
    • _idempotent_event_id and record_feedback_event_idempotent normalize and strip uid and feedback_id prior to computing the SHA-256 digest, ensuring identical idempotent keys regardless of client whitespace variance.
  3. Safe Fetch & Parsing Boundary Guards:
    • get_feedback_event: safely validates event_id string and returns None immediately if blank/invalid without firing an invalid document path query.
    • get_report: validates date string and returns None immediately if blank/invalid.
    • save_report: validates that report is a valid FeedbackReport instance with a non-empty date string.
    • list_negative_events: rejects non-datetime arguments or inverted datetime ranges (start_at > end_at), and returns an empty list for limit <= 0.
    • list_report_dates: returns empty list for limit <= 0 and safely handles client transport exceptions.
  4. Router Error Mapping:
    • In backend/routers/mobile_feedback.py, catches database-level ValueError and converts to HTTPException(status_code=400, detail=str(exc)).

Invariants & Failure-Class

  • Product invariants affected: none
  • Failure-Class: none

How it was verified

Hermetic unit tests executed via pytest:

$env:PYTHONPATH="backend"
python -m pytest tests/unit/test_database_feedback_resilience.py tests/unit/test_feedback_report.py

Results:

  • tests/unit/test_database_feedback_resilience.py: 40/40 passed (0.08s)
  • tests/unit/test_feedback_report.py: 20/20 passed (0.16s)
  • Total: 60 passed in 2.29s (100% passing, hermetic mocks, 0 external network dependencies).