Read all spreadsheet data (plays, box score, pitching decisions) before any
database writes so formula errors like #N/A don't leave the DB in a partial
state. Also preserve SheetsException detail through the error chain and show
users the specific cell/error instead of a generic failure message.
Closes#78
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ensures all client.post() calls to collection endpoints include
trailing slashes, matching the standardized database API routes.
Covers BaseService.create(), TransactionService, InjuryService,
and DraftListService POST calls.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reverts universal trailing slash in _build_url which broke custom_commands
endpoints (401 on /execute/). Instead, add trailing slashes only to the
two batch POST endpoints (plays/, decisions/) that need them to avoid
307 redirects dropping request bodies.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The FastAPI server returns 307 redirects for URLs without trailing slashes.
aiohttp follows these redirects but converts POST to GET, silently dropping
the request body. This caused play-by-play and decision data from
/submit-scorecard to never be persisted to the database despite the API
returning success.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
validate_trade() was passing next_week=None to each team's
validate_transaction(), which skipped load_existing_transactions()
entirely. Trades were validated against the current roster only,
ignoring pending /dropadd transactions for next week.
Now auto-fetches current week from league_service and passes
next_week=current_week+1, matching /dropadd validation behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Quick Status previously only showed "X errors found" with no details.
Now lists each error and suggestion inline. Also stripped all emoji
from embed titles, field names, values, buttons, and messages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove the generic placeholder method from BaseService and replace the
single call site in CustomCommandsService.get_or_create_creator with a
direct client.post("custom_commands/creators", ...) call, consistent
with how _update_creator_stats and _update_creator_info already work.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>