Skip to content

Write once, check by the rows changed, and serve the lists over an HTTP API - #37

Merged
stphnwlsh merged 3 commits into
mainfrom
feature/data-and-api-correctness
Nov 3, 2026
Merged

stphnwlsh merged 3 commits into
mainfrom
feature/data-and-api-correctness

Conversation

@stphnwlsh

@stphnwlsh stphnwlsh commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Updating or deleting a review no longer checks that the review exists before it writes. The write goes first, and if no rows changed the handler throws not found. That's one trip to the database instead of two, and it closes the gap where another request could slip in between the check and the write. Update now returns the changed review from Application.

The database gets a few sensible defaults in one migration (AddCollationsAndIndexes):

  • queries don't track unless they need to
  • author names and movie titles sort without caring about case
  • the columns we sort and filter by have indexes
  • new rows get version 7 GUIDs, so inserts land at the end of the key index instead of somewhere random

While I was in there, some tidy-ups:

  • dropped the [ForeignKey] and [Required] attributes that repeated the fluent configuration
  • Page<T>.Items is now an IReadOnlyList<T>
  • the container owns MovieReviewsDatabase, so its connection gets closed
  • virtual is on every repository method
  • Version is now VersionInfo, so it stops tripping over System.Version, and its handler can be tested
  • removed usings the implicit usings already cover

The shared layers are the same as LeanMeanCleanApps/CleanMinimalApi#67, with the name swapped.

The lists also come over HTTP now. HttpGetMovies, HttpGetAuthors and HttpGetReviews sit behind an API Gateway HTTP API at GET /movies, GET /authors and GET /reviews, reading query, offset, limit, movieId and authorId from the query string. They answer 200 with the same page JSON as the direct functions, or 400 with application/problem+json when the request doesn't add up. Anything else fails the invocation and API Gateway answers 500. HTTP APIs are the cheaper option AWS points to when you don't need REST API-only features. The direct functions haven't changed, and the stack prints the API's address as ApiUrl.

A couple of Lambda Annotations quirks shaped it:

  • it only binds primitive types from the query string and its generated code has nullable off, so ids arrive as string and are parsed, with a 400 for anything that isn't a GUID
  • the classes it generates for [HttpApi] methods carry a doc link to our method that can't resolve, so Presentation.csproj has CS1574 in NoWarn, with a comment saying why. A nested .editorconfig doesn't reach generated files. The expose-a-use-case skill records it as our one suppression

The data-access-ef-core, database-migrations, errors-and-exceptions, paging, unit-tests, test-design, api-conventions, expose-a-use-case, json-serialization, presentation-integration-tests and lambda-emulator skills now match the code, and the README and docs/RUN.md show how to call the routes.

Type of change

  • Breaking change (the generated solution or template parameters change in a way existing users will notice)
  • New feature
  • Refactoring or clean-up

Shared layers

  • This touches the Application or Infrastructure layers, tests, pipeline or repository setup, so it needs to be carried across all five templates.

Checklist

  • dotnet build and dotnet test pass locally with no warnings.
  • I added or updated tests, and line coverage stays at or above 95%.
  • If this changes how we do something, I updated the matching skill in .agents/skills.

Carries the shared changes from CleanMinimalApi.
HttpGetMovies, HttpGetAuthors and HttpGetReviews answer GET /movies,
/authors and /reviews from the query string, with 200 and the page or
400 problem details. The direct functions are unchanged.
@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Build Pipeline

✅ Ready to merge. Every stage passed.

Stage Result Details
Build 🟢 Passed Version 2026.11.03.130-pr-37 · Template package 183 KB
Test 🟢 Passed 173 passed · 0 failed · 0 skipped · Template installs, builds and passes its tests
Coverage 🟢 Passed 100% (570 of 570 lines) · Needs 95%
Static Analysis 🟢 Passed No open CodeQL alerts
Dependency Review 🟢 Passed 0 vulnerable packages · 0 licence problems
Container Scan 🟢 Passed Image starts and answers · 3 open Trivy alerts, none blocking: 1 medium, 1 low, 1 note · 1 ignored in .trivyignore

Commit f520795 · Full run

@stphnwlsh
stphnwlsh merged commit 407258d into main Nov 3, 2026
13 checks passed
@stphnwlsh
stphnwlsh deleted the feature/data-and-api-correctness branch November 3, 2026 23:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants