Skip to content

feat(COG-146): Add provider availability management backend - #18

Open
devin-ai-integration[bot] wants to merge 3 commits into
mainfrom
devin/COG-146-1774672059
Open

devin-ai-integration[bot] wants to merge 3 commits into
mainfrom
devin/COG-146-1774672059

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Mar 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds full-stack backend support for managing provider scheduling availability. This includes:

  • Flyway V3 migration creating provider_availability table with constraints for block types, time ranges, slot durations, and a recurring-vs-specific-date XOR check
  • JPA entity (ProviderAvailability) with @ManyToOne to Provider, optimistic locking via @Version, @JsonIgnore on the LAZY provider field, and a @Transient getProviderId() getter for JSON serialization
  • DTO with @NotNull validation on required fields
  • Repository with derived queries and two custom JPQL queries for effective-date and date-range lookups
  • Service with CRUD operations, soft-delete (deactivate), and validation (time ordering, slot duration whitelist, recurring/specific-date constraints)
  • Controller at /v1/providers/{providerId}/availability with 8 endpoints (list, get, recurring, by-date, effective, range, create, update, delete) including provider ownership checks
  • 15 unit tests covering service validation, CRUD operations, block type enumeration, and effective-date merging

Updates since last revision

  • Fixed @Table(indexes=...) to use SQL column names (day_of_week, block_type) instead of Java field names, avoiding potential duplicate-index conflicts with the Flyway migration
  • Fixed findEffectiveForDate to copy the JPA-returned list into a new ArrayList before appending overrides, preventing UnsupportedOperationException on unmodifiable lists
  • Added ProviderAvailabilityServiceTest with 15 Mockito-based unit tests
  • Added @JsonIgnore on the provider field to prevent LazyInitializationException on GET endpoints
  • Added @Transient getProviderId() so the JSON response still includes the provider's ID without triggering lazy loading

Review & Testing Checklist for Human

  • getProviderId() outside transaction: The @Transient getter calls provider.getId() on a LAZY proxy. Hibernate proxies store the ID without lazy loading, so this should work outside the @Transactional boundary — but verify with a live request that GET responses include providerId correctly and don't throw LazyInitializationException.
  • No overlap detection: The service allows creating multiple blocks for the same provider/day/time range. Decide whether overlapping blocks should be rejected or are acceptable.
  • JPQL queries untested: The unit tests mock the repository, so the two custom @Query methods (findEffectiveRecurringForDate, findByProviderIdAndDateRange) are not exercised against a real database. Consider adding an integration test with H2 to verify these queries.
  • Day-of-week mapping: date.getDayOfWeek().getValue() % 7 maps Sunday→0, Monday→1 ... Saturday→6. Verify this matches the frontend's convention and the chk_day_of_week constraint (0–6).

Suggested test plan: Start the API with a running Postgres instance, execute the Flyway migration, and manually test the CRUD endpoints via curl/Postman. Specifically verify: creating a recurring block, creating a specific-date override, the /effective endpoint returns both, the DELETE endpoint soft-deletes correctly, and that GET responses include providerId in the JSON without errors.

Notes

  • DELETE endpoint performs soft-delete (active=false) rather than hard delete — this is intentional
  • The BlockType enum is shared with the frontend PR (COG-GTM/demos-coghealth-ehr-web)
  • findByProviderIdAndBlockTypeAndActiveTrue is declared in the repository but not currently called by the service or controller — it's available for future use

Link to Devin session: https://app.devin.ai/sessions/f65523f6eeb84bbb9f183b66eea0786a
Requested by: @stephencornwell

- Flyway V3 migration creating provider_availability table
- BlockType enum (AVAILABLE, ADMIN, LUNCH, MEETING)
- ProviderAvailability JPA entity with @manytoone to Provider
- ProviderAvailabilityDTO with validation annotations
- ProviderAvailabilityRepository with custom queries
- ProviderAvailabilityService with CRUD and validation
- ProviderAvailabilityController with RESTful endpoints

Co-Authored-By: Stephen Cornwell <stephen@cognition.ai>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

devin-ai-integration Bot and others added 2 commits March 28, 2026 04:41
- Fix @table index annotations to use SQL column names instead of Java field names
- Fix findEffectiveForDate to not mutate JPA-returned list
- Add 15 unit tests for ProviderAvailabilityService covering:
  - CRUD operations (create, update, deactivate)
  - Validation: time range, recurring/specific date, slot duration, day of week
  - All block types and slot duration values
  - Effective date combining recurring + overrides

Co-Authored-By: Stephen Cornwell <stephen@cognition.ai>
… getter

- Prevent LazyInitializationException on GET endpoints by hiding LAZY provider
- Add @transient getProviderId() so JSON response still includes provider ID

Co-Authored-By: Stephen Cornwell <stephen@cognition.ai>
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