- TypeScript 84.6%
- CSS 10.2%
- Makefile 2.5%
- HTML 1.8%
- Nix 0.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
builds and installs the systemd service from a fresh checkout; substitutes real node path / prefix into the unit. README documents it as the quick path. |
||
| client | ||
| deploy | ||
| server | ||
| shared | ||
| .gitignore | ||
| flake.lock | ||
| flake.nix | ||
| Makefile | ||
| NOTES.md | ||
| package.json | ||
| PLAN.md | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| TODO.md | ||
| tsconfig.base.json | ||
wutzcalc
⚠️ AI-generated code
Every file in this repository was written by an AI coding assistant. It has not been independently audited or reviewed line-by-line by a human. Before running this in any setting where correctness matters (real money, real events), read the code yourself, test the edge cases that matter to you, and assume there are bugs. Use at your own risk.
Festival drink-sale tracker. See PLAN.md for architecture, NOTES.md for the original requirements, and TODO.md for deferred work.
Source: https://git.berlin.ccc.de/vinzenz/wutzcalc
Toolchain setup
Requires Node.js 20+ and pnpm 9+. Native SQLite bindings install from prebuilt binaries on x86_64 / arm64 — no compiler needed for most setups.
Nix (Linux / macOS)
nix develop # node 20, pnpm, sqlite, build deps
Debian / Ubuntu
# Node 20 from NodeSource
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
sudo corepack enable # provides pnpm
# Only needed if a prebuilt better-sqlite3 binary is unavailable for your arch
sudo apt install -y build-essential python3
Fedora
# Node 20 + pnpm (corepack ships with the nodejs package)
sudo dnf install -y nodejs
sudo corepack enable # provides pnpm
# Only needed if a prebuilt better-sqlite3 binary is unavailable for your arch
sudo dnf install -y gcc-c++ make python3
Windows
Install Node.js 20 LTS via the official MSI from https://nodejs.org (this also installs the optional "Tools for Native Modules"). Then in PowerShell:
corepack enable # provides pnpm
Use PowerShell to set env vars on the same line, e.g.
$env:ADMIN_PASSWORD="changeme"; pnpm dev:server.
Dev
pnpm install
ADMIN_PASSWORD=changeme pnpm dev:server # http://localhost:3000
pnpm dev:client # http://localhost:5173 (proxies /api, /admin)
Open http://localhost:5173/ for the tablet UI and
http://localhost:5173/admin.html for the backoffice.
Production build
pnpm install
pnpm build
ADMIN_PASSWORD=... DB_PATH=/var/lib/wutzcalc/wutz.db node server/dist/index.js
Single Node process serves the API, both client entries (/ tablet,
/admin backoffice), and writes to one SQLite file.
Run as a systemd service
On Fedora, the Makefile automates everything below — from a fresh checkout, as root:
sudo make install # system deps + build + service
sudoedit /etc/wutzcalc/wutzcalc.env # set ADMIN_PASSWORD
sudo systemctl enable --now wutzcalc
Override paths with e.g. make install PREFIX=/srv/wutzcalc SERVICE_USER=wutz.
The manual steps below do the same thing. Template files live in
deploy/: a unit (wutzcalc.service) and
an environment file (wutzcalc.env.example). They
assume the built app lives in /opt/wutzcalc and the database in
/var/lib/wutzcalc — adjust paths in the unit if yours differ.
# 1. Dedicated system user (no login, no home)
sudo useradd --system --no-create-home --shell /usr/sbin/nologin wutzcalc
# 2. Install the built app (run `pnpm install && pnpm build` first)
sudo mkdir -p /opt/wutzcalc
sudo cp -a . /opt/wutzcalc # or rsync/checkout into place
sudo chown -R root:root /opt/wutzcalc # app dir stays read-only to the service
# 3. Config + secrets (chmod 600 — holds ADMIN_PASSWORD)
sudo mkdir -p /etc/wutzcalc
sudo install -m 600 deploy/wutzcalc.env.example /etc/wutzcalc/wutzcalc.env
sudoedit /etc/wutzcalc/wutzcalc.env # set ADMIN_PASSWORD
# 4. Install and start the unit
sudo cp deploy/wutzcalc.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now wutzcalc
# Logs / status
systemctl status wutzcalc
journalctl -u wutzcalc -f
Confirm ExecStart matches your Node path (command -v node) — it defaults to
/usr/bin/node. The unit creates /var/lib/wutzcalc via StateDirectory, so
the service user owns the database directory automatically.
Env vars
PORT(default3000)HOST(default0.0.0.0)DB_PATH(default./wutz.db)ADMIN_PASSWORD(required for backoffice login)WUTZ_TZ(defaultEurope/Berlin) — timezone for stats display and groupingWUTZ_DAY_CUTOFF_HOUR(default5) — sales before this local hour count toward the previous business day