backend/app/
├── main.py # FastAPI app, CORS, 11 router mounts, health endpoint
├── config.py # Pydantic Settings from environment variables
├── database.py # Async engine + session factory (get_db dependency)
├── seed.py # Idempotent demo data seeder (2,320 athletes, 1,852 deals)
├── models/ # 13 SQLAlchemy models
│ ├── __init__.py # Re-exports all models
│ ├── conference.py # Conference (10 seeded)
│ ├── university.py # University → Conference (17 seeded)
│ ├── sport.py # Sport (6 seeded)
│ ├── position.py # Position → Sport (~32 seeded)
│ ├── athlete.py # Athlete → University, Sport, Position
│ ├── brand.py # Brand (20 seeded)
│ ├── nil_deal.py # NilDeal — the central entity (22 columns)
│ ├── reporting_period.py
│ ├── budget.py # BudgetAllocation → University, Sport, Period
│ ├── user.py # User with role + tier + reset_token
│ ├── peer_group.py # PeerGroup with conference_ids UUID array
│ ├── activity_log.py # ActivityLog + AthleteNote
│ └── role.py # Role constants (no table — string enum on User)
├── routers/ # 11 API modules (55 endpoints total)
│ ├── auth.py # Login, signup, forgot/reset password, public conferences
│ ├── dashboard.py # KPIs, alerts, budget snapshot, expiring deals
│ ├── athletes.py # CRUD, KPIs, notes, full detail with benchmarks
│ ├── deals.py # CRUD, verify, flag, CSV export
│ ├── upload.py # Contract upload, AI extraction, confirm, download
│ ├── benchmarks.py # Summary, grid (premium), positions, filters
│ ├── budget.py # Overview, sports breakdown, allocation update
│ ├── reporting.py # Stats, queue, policy checks, audit log, expiring
│ ├── search.py # Unified search across athletes + deals
│ ├── admin.py # Users, periods, sports, peer groups, conferences
│ └── ref.py # Reference data dropdowns (sports, positions, brands, etc.)
├── auth/
│ ├── security.py # bcrypt hash/verify, JWT create/decode
│ └── deps.py # get_current_user, require_role(), require_tier()
└── services/
├── email.py # Console (dev) or SMTP (prod) email sender
└── extraction/
├── base.py # Abstract BaseExtractionService
├── mock.py # Random data (legacy, no longer used)
└── real.py # pdfplumber + regex NLP extraction