Team Purplicious — CS 3200, Summer B 2026
TalentScout is a bidirectional recruiting platform for high school athletes and college recruiters. Too many promising athletes go unnoticed because they don't know how to market themselves, don't live where scouts travel, and can't afford a $2,000 recruiting service. TalentScout replaces that with data: athletes publish their metrics, personal records, and highlight clips, and recruiters publish the rosters and openings they actually need to fill. Both sides can see who has been looking at them.
Key features:
- Athlete profiles with GPA, height/weight, graduation year, recruitment status, personal record history, and highlight clips.
- A recruiter clip feed with athlete metrics one tap away, plus filtered athlete search on GPA, height, graduation year, and status.
- Roster openings so athletes can see which programs match their numbers, and recruiters can see which athletes are looking at their rosters.
- View tracking in both directions — the coaches who viewed an athlete, and the athletes who viewed a roster.
- Aggregate, de-identified analytics for researchers studying high school athletics.
| Persona | Who they are | What they do in the app |
|---|---|---|
| Bethany — High School Athlete | Sophomore hurdler in a region scouts rarely visit | Maintains her profile and PRs, uploads clips, checks which programs match her numbers and which coaches viewed her |
| Kevin — College Recruiter | Football recruiter whose travel budget was cut | Posts rosters and openings, scrolls the clip feed, queries athletes by metric, sees who viewed his rosters |
| Jonathan — Administrator | Moderates content and supports accounts | Reads an unfiltered feed, deletes clips, comments, rosters, and accounts, posts platform announcements |
| Lori — Data Analyst | Master's researcher studying young-adult athletics | Pulls aggregate metrics, filters by gender/sport/class year, exports de-identified rows |
The design document — personas, user stories, ER diagrams, and the SQL behind each user story — is in docs/TalentScout.md.
Three Docker containers, defined in docker-compose.yaml:
| Container | Stack | Port | Source |
|---|---|---|---|
web-app |
Streamlit | 8501 | ./app |
web-api |
Flask REST API | 4000 | ./api |
mysql_db |
MySQL 9 | 3200 (host) → 3306 | ./database-files |
Streamlit pages never touch MySQL directly. They call the Flask API at
http://web-api:4000, and only the API opens database connections
(api/backend/db_connection/__init__.py hands out one connection per request).
app/ Streamlit front end
src/Home.py Persona picker (the mock "login" screen)
src/pages/ One file per screen, numbered by persona
src/modules/nav.py Role-based sidebar navigation
src/modules/api.py Shared API request/flash-message helpers
src/modules/clips.py Playing a clip's video, and where its file lives
src/modules/moderation.py Admin-only page guard and two-click delete
api/ Flask REST API
backend/rest_entry.py create_app(): config, DB hook, blueprint registration
backend/<domain>/ One blueprint per domain (see below)
backend/db_connection/ Per-request MySQL connection
assets/clips/ Clip video files, served from /assets/clips
database-files/ 01_..._ddl.sql schema + 02_..._seed.sql data, run on first DB start
docs/ Design document and course setup guides
datasets/, ml-src/ Empty placeholders from the course template
Full instructions are in docs/RepoSetup.md. The short version:
cp api/.env.template api/.env # then fill in SECRET_KEY and MYSQL_ROOT_PASSWORD
docker compose up -dThen open http://localhost:8501. If you change anything in database-files/, the volume has
to be dropped for MySQL to re-run the SQL:
docker compose down db -v && docker compose up db -dHome.py shows one button per persona. Clicking a button sets role, first_name, and
user_id in st.session_state and jumps to that persona's home page; nav.py then builds a
sidebar containing only that role's pages. There are no passwords and no real authentication —
this is the course template's RBAC pattern, described in docs/RBAC.md, and it
is deliberate: the project is about the data model, not about auth.
database-files/01_talent_scout_ddl.sql creates the talent_scout schema and
database-files/02_talent_scout_seed.sql fills it. MySQL runs every .sql file in that
folder in alphabetical order the first time the container starts, which is why the files are
numbered — the DDL has to run before the data.
The seed file is generated by database-files/generate_seed.py (Python Faker, fixed RNG
seed, so it reproduces byte-for-byte). Edit the generator and re-run it rather than editing
the SQL by hand:
pip install faker
python database-files/generate_seed.pyBecause the init scripts only run on an empty data directory, picking up a changed seed file
means dropping the volume: docker compose down -v && docker compose up -d.
user is a supertype with athlete, recruiter, administrator, and analyst subtype
tables keyed on user_id, which is why deleting an account means deleting the user row and
letting ON DELETE CASCADE do the rest.
| Document | Description |
|---|---|
| docs/TalentScout.md | Phase 1/2 design document: personas, user stories, wireframes, ER diagrams, SQL |
| docs/README.md | Index of the course template documentation |
| docs/PreReq.md | Python environment and tooling setup |
| docs/RepoSetup.md | Forking, .env, running the containers |
| docs/ImportantTips.md | Hot reloading, container recovery, MySQL gotchas |
| docs/RBAC.md | How the role-based sidebar works |
| docs/Theming.md | Colors and fonts via app/src/.streamlit/config.toml |