Single-player contract email endpoint #462

Closed
opened 2026-04-12 23:29:13 +00:00 by forgejo_admin · 1 comment
Contributor

Type

Feature

Lineage

Standalone — discovered during contract schedule fix session 2026-04-12.

Repo

forgejo_admin/basketball-api

User Story

As an admin
I want to send a branded contract email to a single player's parent
So that I can test or target individual contract sends without blasting all unsigned parents

Context

Currently the only way to send a branded contract email is POST /admin/email/contract-reminder, which emails ALL unsigned rostered players' parents. The test_email param filters by parent email, not by player — useless for targeting a specific player. During the 2026-04-12 contract schedule fix, we had to fall back to raw Gmail (plain text, no branding) because there was no way to send a branded email for one player.

File Targets

  • src/basketball_api/routes/admin.py — new endpoint POST /admin/email/contract/{player_id}
  • src/basketball_api/services/email.py — reuse send_contract_reminder_email or extract single-player variant

Files the agent should NOT touch:

  • src/basketball_api/services/contract_offers.py — contract minting logic, unrelated

Acceptance Criteria

  • POST /admin/email/contract/{player_id} sends branded contract email to that player's parent
  • Uses _brand_wrapper template system (Queens pink accent for Queens teams)
  • Optional ?test_email= query param redirects the send to a test address
  • Returns confirmation of what was sent, to whom, and the contract link
  • 404 if player not found or has no contract token

Test Expectations

  • Unit test: send for player with contract token returns 200 and sends email
  • Unit test: send for player without token returns 422
  • Unit test: test_email param redirects send
  • Run command: pytest tests/ -k test_contract_email

Constraints

  • Follow existing route style in routes/admin.py
  • Reuse existing send_contract_reminder_email logic or extract shared helper
  • Must use _brand_wrapper with division-aware accent color

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • westside-basketball — project this affects
  • story:WS-S20 — parent signs contracts digitally
  • Existing: POST /admin/email/contract-reminder (blast endpoint)
### Type Feature ### Lineage Standalone — discovered during contract schedule fix session 2026-04-12. ### Repo `forgejo_admin/basketball-api` ### User Story As an admin I want to send a branded contract email to a single player's parent So that I can test or target individual contract sends without blasting all unsigned parents ### Context Currently the only way to send a branded contract email is `POST /admin/email/contract-reminder`, which emails ALL unsigned rostered players' parents. The `test_email` param filters by parent email, not by player — useless for targeting a specific player. During the 2026-04-12 contract schedule fix, we had to fall back to raw Gmail (plain text, no branding) because there was no way to send a branded email for one player. ### File Targets - `src/basketball_api/routes/admin.py` — new endpoint `POST /admin/email/contract/{player_id}` - `src/basketball_api/services/email.py` — reuse `send_contract_reminder_email` or extract single-player variant Files the agent should NOT touch: - `src/basketball_api/services/contract_offers.py` — contract minting logic, unrelated ### Acceptance Criteria - [ ] `POST /admin/email/contract/{player_id}` sends branded contract email to that player's parent - [ ] Uses `_brand_wrapper` template system (Queens pink accent for Queens teams) - [ ] Optional `?test_email=` query param redirects the send to a test address - [ ] Returns confirmation of what was sent, to whom, and the contract link - [ ] 404 if player not found or has no contract token ### Test Expectations - [ ] Unit test: send for player with contract token returns 200 and sends email - [ ] Unit test: send for player without token returns 422 - [ ] Unit test: test_email param redirects send - Run command: `pytest tests/ -k test_contract_email` ### Constraints - Follow existing route style in `routes/admin.py` - Reuse existing `send_contract_reminder_email` logic or extract shared helper - Must use `_brand_wrapper` with division-aware accent color ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes ### Related - `westside-basketball` — project this affects - `story:WS-S20` — parent signs contracts digitally - Existing: `POST /admin/email/contract-reminder` (blast endpoint)
Author
Contributor

Scope Review: READY

Review note: review-997-2026-04-12
Ticket scope is solid — all template sections present, file targets verified against codebase, traceability complete (story:WS-S20 confirmed on project page). Single repo, 2 file targets, 5 AC — fits in one agent pass.

One non-blocking scope item:

  • [SCOPE] Create architecture note arch-email (pre-existing gap across all email tickets, not specific to this one)
## Scope Review: READY Review note: `review-997-2026-04-12` Ticket scope is solid — all template sections present, file targets verified against codebase, traceability complete (story:WS-S20 confirmed on project page). Single repo, 2 file targets, 5 AC — fits in one agent pass. **One non-blocking scope item:** - `[SCOPE]` Create architecture note `arch-email` (pre-existing gap across all email tickets, not specific to this one)
forgejo_admin 2026-04-12 23:42:44 +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#462
No description provided.