Outagamie County Sheriff's Office — Greenville Roleplay web app ================================================================ 1) pip install -r requirements.txt 2) Copy .env.example to .env — set SESSION_SECRET and optionally PORTAL_DATA_DIR. 3) First account: INITIAL_ADMIN_* in .env on first start, or: python -m app.add_user --username ... --password ... --display "..." --roles "staff,portal,shift" --rank deputy Ranks (low → high): recruit | deputy, master_deputy, corporal | sergeant, lieutenant | captain | commander, undersheriff, sheriff Include role "staff" so the account can open the staff portal. 4) Public pages: copy data/public_site.example.json to data/public_site.json and edit (hero image URL, values, recruitment HTML + Google Form embed URL, 10 staff slots, press items, 10 document embeds). 5) Run: run-local.bat or python -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000 6) Staff portal (/login → /staff): shift clock in / break / clock out, active roster, LOA request, documents (Google Doc embeds). Recruits only see Documents + Academy training checklist. Management hub /staff/management (nav appears if you have any of the below): Assistant Sheriff (rank commander), Undersheriff, or Sheriff — or role admin — approve pending staff applications and LOAs and manage portal accounts; Sergeant+ or admin manages others’ shifts (start/pause/end, edit completed shift length). Old URLs /staff/admin and /staff/manage/shifts redirect into the same page. Hardcoded root account (always enforced at startup): username `ocso_root`, password `OCSO-ROOT-CHANGE-ME-2026`. Change these constants in `app/auth.py` before production use. 7) Logos: app/static/img/badge.png (sheriff) and app/static/img/gvrp.png (server). Replace files if you update branding. 8) GUILD_ID is only a logical id in the SQLite shift tables (default 1).