Add incomplete_profiles query to email_queries.py #308

Closed
opened 2026-04-03 22:33:48 +00:00 by forgejo_admin · 1 comment
Contributor

Type

Feature

Lineage

Standalone — part of westside-email-agent capability buildout (2026-04-04). The blast endpoint and query registry exist. This adds the audience query for profile completion reminders.

Repo

forgejo_admin/basketball-api

User Story

As an admin, I want to send profile completion reminder emails to parents whose players have missing data, so that player profiles are complete before the season starts.

Context

The /admin/email/blast endpoint accepts a query parameter that selects recipients from email_queries.py. Currently only unsigned_contracts exists. This adds incomplete_profiles.

Database audit shows: 17 missing photos, 13 missing height, 14 missing position, 14 missing DOB. 20 players have 3+ missing fields. Jersey number/size are excluded (admin-assigned, not parent-fillable).

The profile completion URL is {frontend_url}/register?token={parent.registration_token} — same pattern used by send_profile_reminder_email() in email.py.

File Targets

Files to modify:

  • src/basketball_api/services/email_queries.py — add query_incomplete_profiles function and register in QUERY_REGISTRY

Files NOT to touch:

  • src/basketball_api/routes/admin.py — blast endpoint is generic, no changes needed
  • src/basketball_api/services/email.py — existing send_profile_reminder_email stays, this is a separate path

Acceptance Criteria

  • incomplete_profiles query returns per-player rows for players missing photo, height, position, or date_of_birth
  • Each result includes: to (parent email), parent_id, parent_name, player_name, team_name, missing_fields (comma-separated), profile_url
  • test_email param filters to single parent
  • Players with all four fields complete are excluded
  • Jersey number/size are NOT checked (admin-assigned fields)

Test Expectations

  • Unit test: query returns players with missing fields
  • Unit test: complete players excluded
  • Unit test: test_email filters correctly
  • Unit test: missing_fields string is accurate
  • Run: pytest tests/test_email_blast.py -v

Constraints

  • Follow the query_unsigned_contracts pattern exactly
  • Result dict must include to, parent_id at minimum (blast endpoint requirement)
  • Profile URL uses settings.frontend_url + /register?token={parent.registration_token}

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • arch-email — email architecture
  • project-westside-agency — agent capability buildout
  • Issue #295 — blast endpoint (provides the infrastructure this query uses)
### Type Feature ### Lineage Standalone — part of westside-email-agent capability buildout (2026-04-04). The blast endpoint and query registry exist. This adds the audience query for profile completion reminders. ### Repo `forgejo_admin/basketball-api` ### User Story As an admin, I want to send profile completion reminder emails to parents whose players have missing data, so that player profiles are complete before the season starts. ### Context The `/admin/email/blast` endpoint accepts a `query` parameter that selects recipients from `email_queries.py`. Currently only `unsigned_contracts` exists. This adds `incomplete_profiles`. Database audit shows: 17 missing photos, 13 missing height, 14 missing position, 14 missing DOB. 20 players have 3+ missing fields. Jersey number/size are excluded (admin-assigned, not parent-fillable). The profile completion URL is `{frontend_url}/register?token={parent.registration_token}` — same pattern used by `send_profile_reminder_email()` in email.py. ### File Targets Files to modify: - `src/basketball_api/services/email_queries.py` — add `query_incomplete_profiles` function and register in `QUERY_REGISTRY` Files NOT to touch: - `src/basketball_api/routes/admin.py` — blast endpoint is generic, no changes needed - `src/basketball_api/services/email.py` — existing `send_profile_reminder_email` stays, this is a separate path ### Acceptance Criteria - [ ] `incomplete_profiles` query returns per-player rows for players missing photo, height, position, or date_of_birth - [ ] Each result includes: to (parent email), parent_id, parent_name, player_name, team_name, missing_fields (comma-separated), profile_url - [ ] test_email param filters to single parent - [ ] Players with all four fields complete are excluded - [ ] Jersey number/size are NOT checked (admin-assigned fields) ### Test Expectations - [ ] Unit test: query returns players with missing fields - [ ] Unit test: complete players excluded - [ ] Unit test: test_email filters correctly - [ ] Unit test: missing_fields string is accurate - Run: `pytest tests/test_email_blast.py -v` ### Constraints - Follow the `query_unsigned_contracts` pattern exactly - Result dict must include `to`, `parent_id` at minimum (blast endpoint requirement) - Profile URL uses `settings.frontend_url` + `/register?token={parent.registration_token}` ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes ### Related - `arch-email` — email architecture - `project-westside-agency` — agent capability buildout - Issue #295 — blast endpoint (provides the infrastructure this query uses)
Author
Contributor

Scope Review: READY

Review note: review-758-2026-04-03
Scope is solid. Single file target (email_queries.py) verified on origin/main. All upstream dependencies (#293, #294, #295) are done and validated. Traceability complete (story:WS-S7 verified, arch:email label present). 5 AC all agent-verifiable. Fits single agent pass (~3-4 min).

  • [SCOPE] arch-email architecture note does not exist in pal-e-docs — track creation separately (non-blocking).
## Scope Review: READY Review note: `review-758-2026-04-03` Scope is solid. Single file target (email_queries.py) verified on origin/main. All upstream dependencies (#293, #294, #295) are done and validated. Traceability complete (story:WS-S7 verified, arch:email label present). 5 AC all agent-verifiable. Fits single agent pass (~3-4 min). - **[SCOPE]** `arch-email` architecture note does not exist in pal-e-docs — track creation separately (non-blocking).
forgejo_admin 2026-04-03 22:48:50 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/basketball-api#308
No description provided.