feat: add on-site check-in, door checks, and product redemption#53
feat: add on-site check-in, door checks, and product redemption#53JacobCoffee merged 6 commits intomainfrom
Conversation
Implements Phase 17: on-site check-in scanner with staff-facing UI, per-product door checks, and line-item redemption with double-use prevention. Modeled after pycon-site's DoorCheck + redemption flow. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds on-site operations support to the registration/manage apps: server-side check-in/redemption models + services, staff-only JSON endpoints, and a staff UI (scanner + dashboard) to drive check-ins and product redemption during the conference.
Changes:
- Introduces
CheckIn,DoorCheck, andProductRedemptionmodels (with admin registration) plus migration. - Adds
CheckInService/RedemptionServicebusiness logic and staff-only JSON API views (scan/lookup/redeem/preload) wired into registration URLs. - Adds manage-side check-in dashboard + scanner templates and routes, plus a new test suite for the feature set.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_registration/test_checkin.py | New unit/integration tests for models, services, and check-in API endpoints |
| src/django_program/registration/views_checkin.py | New staff-only JSON API views for scan/lookup/redeem/preload |
| src/django_program/registration/urls.py | Registers the new check-in API endpoints under registration routes |
| src/django_program/registration/services/checkin.py | New service layer for check-in, door checks, and redemption logic |
| src/django_program/registration/checkin.py | New on-site operations models (check-in, door checks, redemptions) |
| src/django_program/registration/migrations/0016_checkin_doorcheck_productredemption.py | Migration creating the new on-site operation tables/constraints |
| src/django_program/registration/models.py | Re-exports the new models from registration.checkin |
| src/django_program/registration/admin.py | Adds read-only admin views for check-in / door check / redemption records |
| src/django_program/manage/views_checkin.py | Adds dashboard and scanner page views (manage app) |
| src/django_program/manage/urls.py | Adds manage routes for dashboard/scanner pages |
| src/django_program/manage/templates/django_program/manage/checkin_scanner.html | Adds the scanner UI and client-side API integration |
| src/django_program/manage/templates/django_program/manage/checkin_dashboard.html | Adds dashboard template for stats/recent activity |
| src/django_program/manage/templates/django_program/manage/base.html | Adds sidebar navigation entry for check-in |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/django_program/registration/migrations/0016_checkin_doorcheck_productredemption.py
Show resolved
Hide resolved
src/django_program/manage/templates/django_program/manage/checkin_scanner.html
Outdated
Show resolved
Hide resolved
src/django_program/manage/templates/django_program/manage/checkin_scanner.html
Outdated
Show resolved
Hide resolved
src/django_program/manage/templates/django_program/manage/checkin_scanner.html
Outdated
Show resolved
Hide resolved
src/django_program/manage/templates/django_program/manage/checkin_scanner.html
Show resolved
Hide resolved
src/django_program/manage/templates/django_program/manage/checkin_scanner.html
Outdated
Show resolved
Hide resolved
…ue_together - Remove unique_together on ProductRedemption to allow quantity-tracked redemption (multiple rows per line item up to purchased quantity) - Add select_for_update() locking in redeem_product() to prevent concurrent over-redemption race conditions - Remove csrf_exempt from ScanView/RedeemView; scanner JS sends X-CSRFToken from cookie - Fix scanner UI to match actual API response shapes (nested attendee object, redeemable list, correct field names) - Sanitize error messages to avoid leaking internal IDs - Validate line_item_id as integer before DB lookup Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…mption - Align API permission check with ManagePermissionMixin (require change_conference perm, not just is_staff) - Add order status validation on scan/redeem (reject refunded/cancelled), include PARTIALLY_REFUNDED in preload export - Return redeemed_count/remaining instead of boolean for multi-quantity redemption tracking - Filter redeemable products to add-ons only (tickets use check-in) - Add has_delete_permission=False to CheckIn/DoorCheck admin - Add conference validation to record_door_check() - Fix scanner UI: session-based re-entry detection, multi-qty display, error banner persistence, redemption toast key, order status warning Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds on-site operational support to the registration and manage apps by introducing check-in / door-check / redemption data models, staff-facing JSON endpoints for scanning + redemption, and a staff UI (scanner + dashboard) for real-time venue operations.
Changes:
- Introduce
CheckIn,DoorCheck, andProductRedemptionmodels (plus admin read-only views) and related migrations. - Add
CheckInService/RedemptionServicebusiness logic and staff-only JSON API endpoints (scan/lookup/redeem/offline preload). - Add manage app scanner + dashboard pages and navigation entry; add test suite for core model/service/API behavior.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_registration/test_checkin.py | New tests covering check-in, door checks, redemptions, and API endpoints |
| src/django_program/registration/views_checkin.py | Staff-only JSON API endpoints for scan/lookup/redeem/offline preload |
| src/django_program/registration/urls.py | Exposes check-in API routes under the registration app |
| src/django_program/registration/services/checkin.py | Business logic for check-in and redemption (incl. locking for redemption) |
| src/django_program/registration/models.py | Re-exports new check-in models via registration models module |
| src/django_program/registration/checkin.py | New models for check-in, door checks, and redemptions |
| src/django_program/registration/admin.py | Admin registrations for the new audit models (read-only) |
| src/django_program/registration/migrations/0016_checkin_doorcheck_productredemption.py | Creates new DB tables for check-in/door check/redemption |
| src/django_program/registration/migrations/0017_alter_productredemption_unique_together.py | Removes redemption uniqueness constraint to support quantity-based redemption |
| src/django_program/manage/views_checkin.py | Manage UI views for scanner + dashboard |
| src/django_program/manage/urls.py | Adds manage routes for dashboard + scanner |
| src/django_program/manage/templates/django_program/manage/checkin_scanner.html | Scanner UI (vanilla JS) wired to JSON API |
| src/django_program/manage/templates/django_program/manage/checkin_dashboard.html | Dashboard UI for check-in/redemption stats |
| src/django_program/manage/templates/django_program/manage/base.html | Adds “Check-in” entry to manage sidebar nav |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Use prefetched redemptions in Python instead of per-attendee annotated queries in OfflinePreloadView - Add 6 tests for manage:checkin-dashboard and manage:checkin-scanner (permission checks, 200 responses, context stats) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e except syntax - Use prefetched line items from lookup_attendee() instead of redundant select_related() queries in ScanView and LookupView - Include order_status in scan success response for UI warning display - Use _get_ticket_type_name() with prefetched iteration instead of filter query - Normalize except syntax to tuple form for tooling compatibility Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces end-to-end on-site operations for the registration system: persistent check-in / door-check / redemption models, staff-only JSON endpoints for scanners, and manage-app UI pages for scanning and dashboarding.
Changes:
- Added
CheckIn,DoorCheck, andProductRedemptionmodels (plus admin) and corresponding migrations. - Implemented check-in and redemption business logic services and staff-only JSON endpoints (scan/lookup/redeem/offline preload).
- Added manage UI pages (scanner + dashboard) and integrated them into manage navigation and routing, with tests covering the new functionality.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
tests/test_registration/test_checkin.py |
Adds model/service/API/manage-view coverage for check-in and redemption flows. |
src/django_program/registration/views_checkin.py |
New staff-only JSON API endpoints backing the scanner UI and offline preload export. |
src/django_program/registration/urls.py |
Wires new check-in API routes into the registration URLconf. |
src/django_program/registration/services/checkin.py |
Adds CheckInService and RedemptionService business logic (incl. transactional redemption). |
src/django_program/registration/models.py |
Re-exports new check-in/redemption models from the registration models module. |
src/django_program/registration/checkin.py |
Defines new on-site operations models. |
src/django_program/registration/admin.py |
Adds read-only admin views for auditing check-ins/door-checks/redemptions. |
src/django_program/registration/migrations/0016_checkin_doorcheck_productredemption.py |
Creates new DB tables for check-in/door-check/redemption. |
src/django_program/registration/migrations/0017_alter_productredemption_unique_together.py |
Removes uniqueness constraint to allow multi-quantity redemptions. |
src/django_program/manage/views_checkin.py |
Adds manage dashboard + scanner views and dashboard statistics queries. |
src/django_program/manage/urls.py |
Adds manage routes for dashboard and scanner pages. |
src/django_program/manage/templates/django_program/manage/checkin_scanner.html |
Adds scanner UI (vanilla JS + fetch against JSON API). |
src/django_program/manage/templates/django_program/manage/checkin_dashboard.html |
Adds dashboard UI for aggregate check-in and redemption stats. |
src/django_program/manage/templates/django_program/manage/base.html |
Adds “Check-in” entry to manage sidebar navigation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import json | ||
| import logging | ||
|
|
||
| from django.db.models import Count, Prefetch | ||
| from django.http import HttpRequest, HttpResponse, JsonResponse | ||
| from django.shortcuts import get_object_or_404 | ||
| from django.utils import timezone | ||
| from django.views import View | ||
|
|
||
| from django_program.conference.models import Conference | ||
| from django_program.registration.attendee import Attendee | ||
| from django_program.registration.models import Order, OrderLineItem | ||
| from django_program.registration.services.checkin import CheckInService, RedemptionService | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
| return json.loads(request.body) # type: ignore[no-any-return] | ||
| except (json.JSONDecodeError, ValueError): | ||
| return None | ||
|
|
||
|
|
| context["active_nav"] = "checkin" | ||
|
|
||
| total_attendees = Attendee.objects.filter(conference=conference).count() | ||
| checked_in_count = Attendee.objects.filter(conference=conference, checkins__isnull=False).distinct().count() |
Summary
Design notes
?ticket_type=<slug>filtering for targeted scanner deploymentTest plan
tests/test_registration/test_checkin.py)make ci)🤖 Generated with Claude Code