update README

This commit is contained in:
SowinskiBraeden committed 2026-03-21 13:23:15 -07:00
1 parent 2800525e93
commit ce795d68cd
1 file changed
+66 -23
+66 -23
View File
@@ -1,65 +1,108 @@
# Poker Portal # Poker Portal
A small server-rendered poker ledger app for low-stakes no-limit hold'em nights. A small Flask app I put together for tracking our low-stakes hold'em nights without having to keep a spreadsheet open all the time.
The idea is pretty simple: public pages for stats and session history, plus a small admin area for recording buy-ins, cash-outs, paid amounts, and notes. The data sits in a CSV audit log, so everything is append-only and easy to follow later.
## What it does
- all-time leaderboard
- per-session pages
- per-player stat pages
- admin login for recording events
- open / closed session tracking
- payout tracking with `paid` events
- session and player charts
- CSV import / export from the admin page
- append-only `entries.csv` ledger instead of overwriting old rows
## Stack ## Stack
Built with a pretty lightweight setup:
- Python - Python
- Flask - Flask
- Jinja templates - Jinja templates
- Chart.js - Chart.js
- Append-only CSV event ledger - plain CSS
- CSV event log for storage
## Stuff is does
- All-time leaderboard
- Session archive
- Per player stat pages
- Admin only login for adding ledger events
- Append only `entries.csv` audit trail
- Buy-ins, cash-outs, note-only events, and correction events using negative amounts
- Cumulative profit chart and player charts
## Ledger model ## Ledger model
The app treats the CSV as an append-only audit trail. The app treats `data/entries.csv` as the source of truth.
Each row is one event: Each row is an event, not a final snapshot. Instead of editing an old row, I append another one. That keeps rebuys, corrections, payouts, and session state changes visible in the log instead of hiding them behind edits.
Current event types:
- `buyin` - `buyin`
- `cashout` - `cashout`
- `paid`
- `note` - `note`
- `session_open`
- `session_close`
This means you do not edit old rows when something changes. Instead, you append: A few examples:
- another buy-in row for a rebuy - another `buyin` for a rebuy
- another cash-out row if they cash more later - another `cashout` if chip counts are corrected later
- a negative amount to correct a mistaken buy-in or cash-out - a `paid` event when someone is actually settled up
- a `note` row for bookkeeping context - a `note` event for bookkeeping context
- `session_open` / `session_close` to mark whether a game night is still live
It is still just a small side project, but I wanted the event model to stay clean enough that the numbers are easy to trust and the history is easy to read back through.
## CSV format ## CSV format
Main file:
`data/entries.csv` `data/entries.csv`
Header:
```csv ```csv
id,created_at,session_date,player_name,event_type,amount_cents,note,actor id,created_at,session_date,player_name,event_type,amount_cents,note,actor
``` ```
## Run locally Amounts are stored in cents to avoid floating-point issues.
## Running it locally
```bash ```bash
python -m venv .venv python -m venv .venv
source .venv/bin/activate source .venv/bin/activate
pip install -r requirements.txt pip install -r requirements.txt
cp .env.example .env cp .env.example .env
export $(grep -v '^#' .env | xargs)
python app.py python app.py
``` ```
## Default environment values Then open:
The app reads these environment variables: `http://127.0.0.1:8000`
## Environment values
The app reads these from `.env`:
- `SECRET_KEY` - `SECRET_KEY`
- `ADMIN_USERNAME` - `ADMIN_USERNAME`
- `ADMIN_PASSWORD` - `ADMIN_PASSWORD`
Example:
```env
SECRET_KEY=change-this
ADMIN_USERNAME=admin
ADMIN_PASSWORD=change-me
```
## Notes
A few choices here were deliberate:
- no database for now
- no user accounts, just one admin login
- public-facing stats pages, admin-only controls
- CSV backup before importing a replacement ledger
If I ever decide to take it further, the first real upgrade would probably be moving the storage layer to SQLite while keeping the rest of the app roughly the same.