Admin email — profile completion reminders + roster export #101

Closed
opened 2026-03-18 19:43:40 +00:00 by forgejo_admin · 0 comments

Type

Feature

Lineage

plan-wkq → Phase 11 → Girls Tryout prep (admin email operations)

Repo

forgejo_admin/basketball-api

User Story

As an admin
I want to email parents of players with incomplete profiles and email myself the full roster
So that I can ensure all profiles are complete before team placement

Context

The Gmail OAuth email service exists in services/email.py using GmailClient with branded HTML templates. EmailLog tracks sent emails. EmailType enum already has reminder defined but not implemented. The get_gmail_client() helper handles tenant-scoped OAuth. Registration confirmation emails already send successfully.

Admin needs two capabilities before team placement:

  1. Identify and email parents whose players are missing photo, school, height, or position — link them to /players/{id} to complete the profile
  2. Email themselves a formatted roster of all players for team organization

File Targets

Files the agent should modify:

  • src/basketball_api/routes/admin.py — add three new endpoints:
    • GET /admin/players/incomplete — query players missing photo_url, current_school, height, or position
    • POST /admin/email/profile-reminder — send reminder emails to parents of incomplete-profile players
    • POST /admin/email/roster-export — email authenticated admin the full player list as HTML table
  • src/basketball_api/services/email.py — add send_profile_reminder_email() and send_roster_export_email() functions using existing get_gmail_client() and _build_confirmation_html() pattern for branded HTML
  • src/basketball_api/models.py — add roster_export to EmailType enum if needed

Files the agent should NOT touch:

  • src/basketball_api/routes/register.py — registration flow is separate
  • src/basketball_api/routes/upload.py — photo upload endpoint already works

Acceptance Criteria

  • When admin calls GET /admin/players/incomplete, returns list of players with missing fields identified
  • When admin calls POST /admin/email/profile-reminder, reminder emails are sent to each parent with a link to their player's profile page
  • When admin calls POST /admin/email/roster-export, admin receives an email with all players in an HTML table (name, division, team, photo status, parent contact)
  • All emails are logged in EmailLog
  • Non-admin users get 403 on all three endpoints

Test Expectations

  • Unit test: test_incomplete_players_query — verify correct filtering logic
  • Unit test: test_reminder_email_content — verify email HTML contains profile link
  • Unit test: test_roster_export_content — verify email HTML contains player table
  • Unit test: test_admin_only_access — verify 403 for non-admin roles
  • Run command: pytest tests/ -k "incomplete or reminder or roster_export"

Constraints

  • Follow existing route patterns in routes/admin.py
  • Use existing get_gmail_client() helper — do not create new Gmail auth
  • Use existing EmailLog model for tracking
  • HTML emails should use Westside brand colors (red #d42026, black #0a0a0a) matching existing confirmation email style
  • Profile link URL: https://westside.tail5b443a.ts.net/players/{player_id}

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • phase-wkq-11-girls-tryout — pre-team-placement operations
### Type Feature ### Lineage `plan-wkq` → Phase 11 → Girls Tryout prep (admin email operations) ### Repo `forgejo_admin/basketball-api` ### User Story As an admin I want to email parents of players with incomplete profiles and email myself the full roster So that I can ensure all profiles are complete before team placement ### Context The Gmail OAuth email service exists in `services/email.py` using `GmailClient` with branded HTML templates. `EmailLog` tracks sent emails. `EmailType` enum already has `reminder` defined but not implemented. The `get_gmail_client()` helper handles tenant-scoped OAuth. Registration confirmation emails already send successfully. Admin needs two capabilities before team placement: 1. Identify and email parents whose players are missing photo, school, height, or position — link them to `/players/{id}` to complete the profile 2. Email themselves a formatted roster of all players for team organization ### File Targets Files the agent should modify: - `src/basketball_api/routes/admin.py` — add three new endpoints: - `GET /admin/players/incomplete` — query players missing `photo_url`, `current_school`, `height`, or `position` - `POST /admin/email/profile-reminder` — send reminder emails to parents of incomplete-profile players - `POST /admin/email/roster-export` — email authenticated admin the full player list as HTML table - `src/basketball_api/services/email.py` — add `send_profile_reminder_email()` and `send_roster_export_email()` functions using existing `get_gmail_client()` and `_build_confirmation_html()` pattern for branded HTML - `src/basketball_api/models.py` — add `roster_export` to `EmailType` enum if needed Files the agent should NOT touch: - `src/basketball_api/routes/register.py` — registration flow is separate - `src/basketball_api/routes/upload.py` — photo upload endpoint already works ### Acceptance Criteria - [ ] When admin calls `GET /admin/players/incomplete`, returns list of players with missing fields identified - [ ] When admin calls `POST /admin/email/profile-reminder`, reminder emails are sent to each parent with a link to their player's profile page - [ ] When admin calls `POST /admin/email/roster-export`, admin receives an email with all players in an HTML table (name, division, team, photo status, parent contact) - [ ] All emails are logged in `EmailLog` - [ ] Non-admin users get 403 on all three endpoints ### Test Expectations - [ ] Unit test: `test_incomplete_players_query` — verify correct filtering logic - [ ] Unit test: `test_reminder_email_content` — verify email HTML contains profile link - [ ] Unit test: `test_roster_export_content` — verify email HTML contains player table - [ ] Unit test: `test_admin_only_access` — verify 403 for non-admin roles - Run command: `pytest tests/ -k "incomplete or reminder or roster_export"` ### Constraints - Follow existing route patterns in `routes/admin.py` - Use existing `get_gmail_client()` helper — do not create new Gmail auth - Use existing `EmailLog` model for tracking - HTML emails should use Westside brand colors (red `#d42026`, black `#0a0a0a`) matching existing confirmation email style - Profile link URL: `https://westside.tail5b443a.ts.net/players/{player_id}` ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes ### Related - `phase-wkq-11-girls-tryout` — pre-team-placement operations
forgejo_admin 2026-03-18 19:53:22 +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
forgejo_admin/basketball-api#101
No description provided.