ThreadCount Community edition

Uniform stock management for healthcare linen rooms. Licensed under the GNU AGPL v3.
This commit is contained in:
ThreadCount
2026-09-13 08:54:35 +10:00
commit 344b1701dd
505 changed files with 56231 additions and 0 deletions
+60
View File
@@ -0,0 +1,60 @@
# ThreadCount
Uniform stock management for healthcare linen rooms: what is on the shelf, who took it, what it
cost the ward, and the supplier orders and stocktakes in between. Written by a hospital uniform
coordinator for their own room.
- **Hosted** at [threadcount.tech](https://threadcount.tech) — free for a room under 60 staff
records, paid hosting for a facility, a bundle for a health service. [Pricing](https://threadcount.tech/pricing).
- **Community edition** — this repository, run on your own server. Every feature, no plans, no
ceiling, nothing reported anywhere. Licensed under the [GNU AGPL v3](LICENSE).
The two editions are the same code. `EDITION=community` in the environment is the only difference,
and [docs/self-hosting.md](docs/self-hosting.md) says exactly what it changes.
## Run it yourself
You need Docker with Compose, a machine with 2 GB of memory, and a hostname with TLS in front of
it (any reverse proxy — Caddy, nginx, Traefik). The app sets `Secure` cookies in production, so it
will not sign anyone in over plain HTTP from another machine.
```sh
git clone https://gitea.pricehq.tech/kyle/threadcount-community.git
cd threadcount-community
cp .env.example .env
```
Edit `.env` and set at least:
| Variable | What it is |
|---|---|
| `SESSION_SECRET` | Signs every session cookie. `openssl rand -base64 48`. The server refuses to start while it says `change-me`. |
| `POSTGRES_PASSWORD` | The bundled database's password. Anything long. |
| `NEXT_PUBLIC_SITE_URL` | The address people will open the app at, e.g. `https://uniforms.example.health`. Compiled in at build time, so set it before the first build. |
| `EDITION` | `community`. |
| `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASS`, `SMTP_FROM` | Optional. Without them nothing is emailed — password resets and manager approval links then have to be handled at the counter, and the screens say so. |
Then:
```sh
docker compose up -d --build
```
The first start creates the database schema. Open your hostname, choose **Create account**, name
your facility: you are its first administrator. Load the catalogue and staff register from CSV
under Settings Data (templates are there), and set `SIGNUPS_DISABLED=1` in `.env` once your
facility exists so nobody else can create one on your instance.
Upgrading, backups, restoring, single sign-on, Turnstile, and what the two Android apps can and
cannot do against a self-hosted instance: [docs/self-hosting.md](docs/self-hosting.md).
## Developing
Node 24 and a Postgres. `npm ci`, put `DATABASE_URL` and `SESSION_SECRET` in `.env`, then
`npx prisma migrate deploy && npm run dev`. The end-to-end suites are plain bash and curl against a
dev server on port 3111: `scripts/e2e*.sh`. `scripts/check-identity.sh` must stay clean.
## Licence
GNU Affero General Public License v3.0. Run it, change it, host it for others — and if you host a
changed version for others, they get the changed source too. See [LICENSE](LICENSE).