Module 9 of 9 · Lesson 26 of 26
Integrate a final feature with reviewable evidence
Work through integrate a final feature with reviewable evidence using a runnable reference, a focused regression check and a local extension.
Read in any order. All lessons stay open, including after an unanswered or incorrect check.
A request key handles an uncertain client retry. Repeating the same key returns the already applied result and creates no second event. A different key after check-in returns a deliberate conflict. The key is an idempotency marker scoped to this rental, not proof of identity. Authentication and permission are still required on every request. Capacity becomes available because reservation sums only active rentals; it uses the same equipment lock. The test covers a denied attempt, repeated allowed check-in, one event and a new reservation. Your review bundle should explain these behaviors with code, tests, the API contract and limitations. Local practice evidence remains yours to review; this course does not issue certificates.
Run lesson26 and inspect the transaction's lock order and prior-key lookup. The denied customer attempt leaves the rental active with no event. Two operator attempts with the same key produce one event. A new reservation then succeeds because the checked-in quantity is no longer active. Use the review-ready checklist to organize the evidence.
async def check_in(session, principal, rental_id, request_key):
if not 1 <= len(request_key) <= 64:
raise DomainError(
"invalid_key", "Supply a request key of 1 to 64 characters.", 422
)
async with session.begin():
rental = await session.get(Rental, rental_id)
if rental is None:
raise missing()
if not may(principal, rental.owner_id, "check_in"):
raise forbidden()
# Use the same equipment-first lock order as reservation, then re-read rental state.
await session.scalar(
select(Equipment)
.where(Equipment.id == rental.equipment_id)
.with_for_update()
)
rental = await session.scalar(
select(Rental)
.where(Rental.id == rental_id)
.with_for_update()
.execution_options(populate_existing=True)
)
prior = await session.scalar(
select(Checkin).where(
Checkin.rental_id == rental_id, Checkin.request_key == request_key
)
)
if prior:
return RentalOut.model_validate(rental)
if rental.status != "active":
raise DomainError(
"already_checked_in", "This rental has already been checked in."
)
rental.status = "checked_in"
session.add(
Checkin(rental_id=rental_id, actor_id=principal.id, request_key=request_key)
)
await session.flush() # event and status succeed or roll back together
result = RentalOut.model_validate(rental)
return result
python run_checks.py -k lesson26
Expected result The selected lesson test passes against a new temporary PostgreSQL database; the container is removed afterward.
Keep for reference
Equipment Rental lab and lesson checks
ZIP containing Python source, real Alembic migrations, 26 lesson checks, a dependency lock and text instructions. Extract it before following the local exercise.
Practise locally
Add an endpoint-level integration test for check-in with a valid operator token, a forbidden customer token and the same request key repeated. Add a conflict case with a new key after success. Submit nothing to a real service: save a local bundle containing code, test output, before/after behavior, your contract and a limitations note. Optionally adapt the nine Event Booking milestones in the lab README.
The lesson check verifies the reference behavior. Add your own assertions for your change. Local practice is not uploaded or scored by this learning release.
Pause and reflect
What failure does this lesson prevent, and which assertion in lesson26 would expose it?
Use a concrete input, expected result and limitation from your local work. Saving a reflection does not certify the project.
Optional knowledge check
How should status and check-in event be written?
Commit status first, skip permission, then try recording the event later.
Try another answer. That can leave partial history and lets an unauthorized caller change capacity.
Accept a retry key as sufficient proof that the caller may check in.
Try another answer. Idempotency does not establish identity or permission.
Together in one transaction, after permission and with a scoped retry key.
Correct. Atomic writes and idempotency preserve the result through failures and retries.
This practice does not assess your project or award a certificate.
Keep for reference
Review-ready change checklist
Optional plain-text checklist for behavior changes, tests, migrations, permissions, dependencies and reviewer context.
Your reading progress
Progress is saved in this browser when storage is available.