From acda2c90f872aea6265e0ffd8b7fb96e52ac3d3b Mon Sep 17 00:00:00 2001 From: indifferentketchup Date: Mon, 4 May 2026 03:12:29 +0000 Subject: [PATCH] first commit --- README.md | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f47f531 --- /dev/null +++ b/README.md @@ -0,0 +1,68 @@ +# sortof + +A Project Zomboid mod load-order sorter. Paste Steam Workshop IDs or a +collection URL, get back the three lines (`WorkshopItems=`, `Mods=`, +`Map=`) you paste into your dedicated server's `.ini` file. + +## Stack + +- **API** — FastAPI + asyncpg, Python 3.12. +- **Cache** — PostgreSQL 16. One row per `(workshop_id, mod_id)` parsed + from each mod's `mod.info`. Cache invalidates on Steam's + `time_updated`; no manual TTLs. +- **Drain worker** — pulls cache misses via DepotDownloader, parses + `mod.info` and `media/maps/*/map.info`, writes back to Postgres. +- **Frontend** — vanilla JSX in `frontend/`, served by FastAPI + `StaticFiles`, transpiled in-browser by Babel-standalone. No build + step, no npm. +- **Deployment** — Docker for Postgres only; the API and drain workers + run as systemd units on the host. + +## What it actually does + +- Resolves bare workshop IDs **and** collection URLs (anonymous Steam API + expansion). +- Topologically sorts mods by `requirements`, `loadAfter`, `loadBefore` + with explicit support for `loadFirst` / `loadLast` and the "patch" + tier. +- Detects multi-branch wsids (e.g. AuthenticZ, Project RV Interior), + auto-picks a sensible default by build flavor or input cross-reference, + and surfaces the alternates in a picker. +- Emits actionable warnings: missing dependencies (with one-click "add" + buttons when the dep is in our cache), build-mismatch flags with + swap-or-remove actions, duplicate-mod_id conflicts, addon detection, + and required-item suggestions scraped from the Workshop page. +- Tracks community-reported broken mods per PZ build, with thumbs-up / + thumbs-down voting and a search panel. + +## Bootstrapping (rough) + +1. `docker compose up -d sortof_db` — runs Postgres on `127.0.0.1:5439`, + applies `init/*.sql` migrations on first boot. +2. Create the two virtualenvs: + ```bash + python3.12 -m venv api/.venv && api/.venv/bin/pip install -r api/requirements.txt + python3.12 -m venv worker/.venv && worker/.venv/bin/pip install -r worker/requirements.txt + ``` +3. Drop a `.env` next to `docker-compose.yml` with `POSTGRES_USER`, + `POSTGRES_PASSWORD`, `POSTGRES_DB`, and `SORTOF_CORS_ORIGINS`. +4. Set `DD_PATH` to wherever DepotDownloader lives, then start the API + (`api/.venv/bin/uvicorn app:app --host 127.0.0.1 --port 8801`) and a + drain worker (`worker/.venv/bin/python drain.py`). + +For the systemd units, see `docs/` (and the running host). + +## Layout + +``` +api/ FastAPI service + adapters + sort engine +worker/ drain worker — DepotDownloader + mod.info parser +frontend/ vanilla JSX + index.html (no build step) +init/ Postgres bootstrap migrations (runs in order) +data/ checked-in JSON like pz_versions.json +docs/ specs, plans, audit notes +``` + +## License + +TBD.