feat: QA nit fixes + email log table #49
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/basketball-api!49
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "48-qa-nits-email-log"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
email_logtable for CRM email tracking withEmailTypeenum andEmailLogmodelChanges
src/basketball_api/routes/register.py: Removed duplicatedSTRIPE_TRYOUT_LINKconstant; all references now usesettings.stripe_tryout_linkfrom configsrc/basketball_api/routes/tryouts.py: AddedPOST /tryouts/admin/{slug}/uncheckin/{player_id}endpoint; fixed admin dashboard query to JOIN on Registration (excludes orphan Players); added Undo button with JS handlersrc/basketball_api/models.py: AddedEmailTypeenum (registration,reminder) andEmailLogmodelsrc/basketball_api/services/email.py: Updatedsend_confirmation_emailto accept optionaldbandemail_typeparams; writes toemail_logwhen db providedalembic/versions/007_add_email_log_table.py: New migration creating theemail_logtabletests/test_tryouts.py: Added tests for un-check-in, admin filtering, Stripe config, EmailLog CRUD, and email logging integrationTest Plan
pytest tests/ -v-- 115 passed)ruff checkandruff formatcleanReview Checklist
Related
plan-2026-03-08-tryout-prepAdd tryout-day endpoints for coach roster (mobile cards with search/filter), print-optimized roster table, admin check-in dashboard with live status, idempotent tryout number assignment, and Stripe payment redirect. Endpoints: - GET /pay -> 302 to Stripe checkout - POST /tryouts/admin/{slug}/assign-numbers (auth, idempotent) - GET /tryouts/roster/{slug} (public, noindex, mobile-first cards) - GET /tryouts/roster/{slug}/print (public, print-optimized table) - GET /tryouts/admin/{slug} (auth, admin check-in dashboard) - POST /tryouts/admin/{slug}/checkin/{id} (auth, mark checked in) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>- Remove duplicated STRIPE_TRYOUT_LINK from register.py, use config setting - Add POST /tryouts/admin/{slug}/uncheckin/{id} to undo check-ins - Fix admin dashboard to only show players with Registration records - Add EmailType enum and EmailLog model for CRM email tracking - Update send_confirmation_email to log to email_log when db provided - Add Alembic migration 007 for email_log table - Add tests for all new functionality Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>Self-Review: Passed
Review scope: All changes in this PR that go beyond PR #47's base (commit
592680e).Findings: No issues. All acceptance criteria from issue #48 are met:
STRIPE_TRYOUT_LINKconstant removed fromregister.py, replaced withsettings.stripe_tryout_linkPOST /tryouts/admin/{slug}/uncheckin/{player_id}endpoint added, auth-gatedEmailTypeenum withregistrationandremindervaluesEmailLogmodel with all required fieldsemail_logtablesend_confirmation_emailaccepts optionaldbandemail_type, logs when db providedPR #49 Review
BLOCKERS
None.
NITS
_clean_allintests/test_tryouts.pydoes not deleteEmailLogrows. The function deletesRegistration,Player, andParent, butEmailLoghas FK constraints to all three of those tables. This is not a problem today because thesetup_dbfixture drops and recreates all tables between tests, so_clean_allalways runs against empty tables. But if the test infrastructure ever switches to transaction-based isolation (rollback instead of drop/create),_clean_allwould fail with FK constraint violations. Consider addingdb.query(EmailLog).delete()as the first line of_clean_allfor defensive completeness.Migration numbering: 007 follows
e09c9e678004(auto-generated hash). The chain is005 -> e09c9e678004 -> 007. The mixing of sequential numbers (005,007) with a hex hash (e09c9e678004) is a cosmetic inconsistency. Not blocking -- Alembic resolves the chain bydown_revision, not by filename convention -- but worth noting for future migrations.EmailLogrelationships are unidirectional. The model definesrelationship()toTenant,Parent, andPlayerwithoutback_populates, meaning you cannot navigate from those models to their email logs (e.g.,parent.email_logs). This is fine for a log/audit table where you typically query EmailLog directly, but if reverse navigation is ever needed,back_populatesand a correspondingMapped[list["EmailLog"]]on the parent models would be required.SOP COMPLIANCE
48-qa-nits-email-logreferences issue #48plan-2026-03-08-tryout-prepCloses #48.env,sk_live,sk_test,whsec_patterns found)TestUncheckin,TestAdminDashboardFiltering,TestStripeLinkConfig,TestEmailLogwith integration testSTRIPE_TRYOUT_LINKconstant fully removed, all references usesettings.stripe_tryout_linkCode Quality Notes
POST /tryouts/admin/{slug}/uncheckin/{player_id}): Properly auth-gated withrequire_admin_role, validates tenant ownership, returns consistentCheckinResponsemodel. Good.JOINonRegistrationcorrectly excludes players without registration records. Test explicitly verifies this with an orphan player fixture.send_confirmation_emailaccepts optionaldbparameter -- backwards compatible. When provided, writes anEmailLogrow with the Gmail message ID. Clean separation of concerns.emailtypeenum andemail_logtable with proper FK constraints and indexes ontenant_id,parent_id,player_id. Downgrade correctly drops the table then the enum.escape()-d.VERDICT: APPROVED
d78eabf1592031b3e206