Skip to content

Pydantic Schemas — Public Output DTOs#37

Merged
calebyhan merged 7 commits intomainfrom
gabriel
Mar 3, 2026
Merged

Pydantic Schemas — Public Output DTOs#37
calebyhan merged 7 commits intomainfrom
gabriel

Conversation

@ggreat317
Copy link
Copy Markdown
Contributor

@ggreat317 ggreat317 commented Mar 3, 2026

Motivation:
The API needs a typed contract between backend and frontend. Output DTOs define exactly what the frontend receives and ensure consistent serialization from SQLAlchemy models.

Changes:

  • Added all DTOs for the project ( in separate files within app/schemas ), including:
    SenatorDTO, CommitteeAssignmentDTO, CommitteeDTO, LeadershipDTO, NewsDTO
    LegislationDTO, LegislationActionDTO, CalendarEventDTO, CarouselSlideDTO
    FinanceHearingConfigDTO, FinanceHearingDateDTO, StaffDTO, DistrictDTO
    BudgetDataDTO, StaticPageDTO, AccountDTO

  • Exported via init.py

  • Added pydantic==2.7.1 to requirments

  • Added unit tests ( in tests/schemas/test_schemas.py ) for each DTO:
    Instantiated from mock data
    Verified serialization (model_dump)
    Verified nested, recursive, and optional fields
    Verified computed fields like NewsDTO.author_name

Notes:
I also noticed that the Technical Design Document Section 4.5.1, the section relating to the requirements of the DTO's, did not have the CalendarEventDTO. However, the ticket this is responding to asked for a CalendarEventDTO, so I made it with field types of what I believed to be applicable.

Closes #10

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 3, 2026

Test Results

173 tests  +90   173 ✅ +90   0s ⏱️ ±0s
  1 suites ± 0     0 💤 ± 0 
  1 files   ± 0     0 ❌ ± 0 

Results for commit e94fa6b. ± Comparison against base commit 06f46ff.

This pull request removes 3 and adds 93 tests. Note that renamed tests count towards both.
tests.models.test_models ‑ test_budgetdata_self_reference
tests.models.test_models ‑ test_legislation_action_relationship
tests.models.test_models ‑ test_tables_exist
tests.models.test_other_models ‑ test_all_other_models_exported
tests.models.test_other_models.TestBudgetDataModel ‑ test_budgetdata_amount_precision
tests.models.test_other_models.TestBudgetDataModel ‑ test_budgetdata_multiple_children
tests.models.test_other_models.TestBudgetDataModel ‑ test_budgetdata_nullable_description
tests.models.test_other_models.TestBudgetDataModel ‑ test_budgetdata_nullable_parent
tests.models.test_other_models.TestBudgetDataModel ‑ test_budgetdata_self_reference
tests.models.test_other_models.TestBudgetDataModel ‑ test_budgetdata_updated_at_auto_updates
tests.models.test_other_models.TestBudgetDataModel ‑ test_budgetdata_updated_at_default
tests.models.test_other_models.TestBudgetDataModel ‑ test_budgetdata_with_description
tests.models.test_other_models.TestBudgetDataModel ‑ test_columns_exist
…

♻️ This comment has been updated with latest results.

Copy link
Copy Markdown
Contributor

@calebyhan calebyhan left a comment

Choose a reason for hiding this comment

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

Some small changes

Comment thread backend/app/schemas/CalendarEventDTO.py Outdated
description: str
start_datetime: datetime
end_datetime: datetime
location: str | None = None
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
location: str | None = None
location: Optional[str] = None

Comment thread backend/app/schemas/NewsDTO.py Outdated
date_published: datetime
date_last_edited: datetime

admin: Optional[object] = None
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
admin: Optional[object] = None
admin: Optional["Admin"] = None

emlijon added a commit that referenced this pull request Mar 3, 2026
- Add GET /api/news (paginated, published only, most-recent-first)
- Add GET /api/news/{id} (404 for drafts or nonexistent)
- Add GET /api/senators (filterable: search, district_id, committee, session)
- Add GET /api/senators/{id} (with committee assignments, any session)
- Add app/utils/pagination.py reusable paginate() helper
- Add app/schemas/pagination.py PaginatedResponse[T] generic envelope
- Register both routers in app/main.py
- Add try/except guard for PR #37 NewsDTO/SenatorDTO schemas
- Add tests/routes/ integration test suite (43 tests, SQLite in-memory)
  - 13 tests for news endpoints
  - 26 tests for senator endpoints
  - conftest seeds districts, admin, news, committees, senators, memberships

126 tests pass, 0 failures
@ggreat317
Copy link
Copy Markdown
Contributor Author

I incorporated the None = None fix.

Your recommended admin fix appears to be a SQLAlchemy model, so it cannot be easily incorporated into the DTO. Please let me know if I am wrong here.

For now, I incorporated the AccountDTO in its place, as it appears to have the ability to reflect the admin account. I have yet to make NewsDTO check if the AccountDTO has the role of admin, as I am waiting for your review.

Copy link
Copy Markdown
Contributor

@calebyhan calebyhan left a comment

Choose a reason for hiding this comment

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

I just went ahead and changed NewsDTO to match the TDD for now. As for making NewsDTO check if AccountDTO has role of admin, we don't need to for this scope, as the database constraint enforces that with the Foreign Key. NewsDTO is an output DTO anyways, so we wouldn't put that check here.

LGTM! thanks

@calebyhan calebyhan merged commit f45d462 into main Mar 3, 2026
3 checks passed
@calebyhan calebyhan deleted the gabriel branch March 3, 2026 21:00
calebyhan pushed a commit that referenced this pull request Mar 3, 2026
- Add GET /api/news (paginated, published only, most-recent-first)
- Add GET /api/news/{id} (404 for drafts or nonexistent)
- Add GET /api/senators (filterable: search, district_id, committee, session)
- Add GET /api/senators/{id} (with committee assignments, any session)
- Add app/utils/pagination.py reusable paginate() helper
- Add app/schemas/pagination.py PaginatedResponse[T] generic envelope
- Register both routers in app/main.py
- Add try/except guard for PR #37 NewsDTO/SenatorDTO schemas
- Add tests/routes/ integration test suite (43 tests, SQLite in-memory)
  - 13 tests for news endpoints
  - 26 tests for senator endpoints
  - conftest seeds districts, admin, news, committees, senators, memberships

126 tests pass, 0 failures
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.

Pydantic Schemas — Public Output DTOs

2 participants