Initial commit: repair cafe kanban board
A per-event queue board for a repair cafe. Customers sign items in on a shared tablet; volunteers drag repairs through Queue, In progress and Done on a dashboard, then export the day's records as CSV. Zero npm dependencies: node:http plus JSON files on disk, no build step. Categories and house rules are set in config.json. Events are deleted 7 days after creation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
# Repair Cafe Kanban
|
||||
|
||||
A small queue board for a repair cafe. Volunteers create a board for one event,
|
||||
customers sign their items in on a shared tablet, and volunteers drag repairs
|
||||
through **Queue → In progress → Done**, then download the day's data as a CSV.
|
||||
|
||||
No database, no build step, no npm dependencies. Just Node.
|
||||
|
||||
## Running it
|
||||
|
||||
```sh
|
||||
git clone ssh://git@git.autonomic.zone:2222/trav/repair-cafe-kanban.git
|
||||
cd repair-cafe-kanban
|
||||
node server.js
|
||||
```
|
||||
|
||||
Then open <http://localhost:8080>. Node 18 or newer is all it needs — there is
|
||||
nothing to install.
|
||||
|
||||
To use a different port:
|
||||
|
||||
```sh
|
||||
PORT=9000 node server.js
|
||||
```
|
||||
|
||||
By default it listens on all interfaces, so other people on the same network can
|
||||
reach it at `http://<this-machine's-ip>:8080`. Set `HOST=127.0.0.1` to keep it on
|
||||
this machine only.
|
||||
|
||||
## How it is used on the day
|
||||
|
||||
1. On the main page press **Create repair cafe kanban** and name the event.
|
||||
Tick *randomise the address* if you want a hard-to-guess URL.
|
||||
2. You land on the **sign-in form** at `/<event-name>`. Leave this open on a
|
||||
tablet or laptop by the door — it clears itself after every submission.
|
||||
3. Open the **dashboard** at `/<event-name>/dashboard` on the volunteers' laptop.
|
||||
There is a link to it at the bottom of the sign-in form.
|
||||
4. Drag cards between columns. Moving a card into *In progress* asks who is
|
||||
repairing it; moving it into *Done* asks how it went. A card that reaches
|
||||
*Done* without a result is outlined in red until someone fills it in.
|
||||
5. Click any card's title to see and edit the full record, and to add notes.
|
||||
6. Press **Download CSV** at the end of the day.
|
||||
|
||||
On a touch screen, drag a card by its **⠿** grip in the top right corner — that
|
||||
leaves the rest of the card free for scrolling. You can also change a card's
|
||||
status from the detail overlay without dragging at all.
|
||||
|
||||
## Configuration
|
||||
|
||||
Everything adjustable lives in `config.json`. Restart the server after editing it.
|
||||
|
||||
| Key | What it does |
|
||||
| --- | --- |
|
||||
| `port` | Port to listen on (the `PORT` environment variable wins). |
|
||||
| `retentionDays` | Events are deleted this many days after creation. Set to `0` to keep them forever. |
|
||||
| `categories` | The item categories offered on the sign-in form, each with the colour of its badge on the board. |
|
||||
| `houseRules` | The text shown in the house rules popup. `\n` starts a new line. |
|
||||
|
||||
Adding a category is a config edit and a restart — no code change.
|
||||
|
||||
## Where the data lives
|
||||
|
||||
One JSON file per event in `data/`, named after its URL. They are plain text, so
|
||||
you can read, back up, or delete them by hand. `data/expired.json` remembers the
|
||||
names of events that have been auto-deleted, so their URLs can say "expired"
|
||||
instead of "not found".
|
||||
|
||||
Each event's CSV is linked from its own dashboard. There is also a **combined CSV
|
||||
of every event at `/export.csv`** — it is not linked from anywhere, since it is
|
||||
for the person running the server rather than for volunteers on the day.
|
||||
|
||||
**Events are permanently deleted after `retentionDays` days** (7 by default),
|
||||
on startup and once a day after that. Download the CSV before then if you want
|
||||
to keep the data.
|
||||
|
||||
## Putting it on a real server
|
||||
|
||||
Copy the folder up and run `node server.js`. To keep it running, a systemd unit
|
||||
is enough:
|
||||
|
||||
```ini
|
||||
# /etc/systemd/system/repair-cafe.service
|
||||
[Unit]
|
||||
Description=Repair Cafe Kanban
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/node /srv/repair-cafe-kanban/server.js
|
||||
WorkingDirectory=/srv/repair-cafe-kanban
|
||||
Environment=HOST=127.0.0.1
|
||||
Restart=always
|
||||
User=www-data
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Then put nginx in front of it for TLS and a real domain name:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
server_name repair.example.org;
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8080;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
There are no accounts and no passwords: anyone with a board's URL can view it,
|
||||
sign items in, and move cards. That is fine for a public repair cafe, but do not
|
||||
put anything on it you would not put on a whiteboard in the room.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
server.js HTTP server: routing, JSON API, CSV export, retention
|
||||
config.json categories, house rules, port, retention
|
||||
lib/store.js reading and writing events on disk
|
||||
lib/csv.js CSV formatting
|
||||
public/ the pages, one stylesheet, two scripts
|
||||
data/ one JSON file per event (created on first run, not in git)
|
||||
```
|
||||
Reference in New Issue
Block a user