ThreadCount Community edition

Uniform stock management for healthcare linen rooms: the coordinator app, the phone counter and the staff app, for your own server. Built from f976bd5 on 2026-09-15. Licensed under the Functional Source License (FSL-1.1-ALv2).
This commit is contained in:
ThreadCount
2026-09-15 23:18:05 +10:00
commit c89010a4f1
424 changed files with 53588 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
---
title: Delete an account
section: account
order: 6
summary: Delete your login or the whole facility, clear data without deleting anything else, remove a wearer's staff sign-in, and what stays behind.
screen: Settings People & sign-in
role: Admin or Issuer
keywords: delete account, close account, delete facility, remove login, wipe, wipe activity, start fresh, empty this facility, reset, empty facility, staff app access, remove access, privacy, erase data
---
## The two cases
`Delete my account` is the last heading on `Settings People & sign-in`. What it deletes depends on whether anyone else can still sign in.
- **Other active users remain.** Only your login goes. The facility and its records stay.
- **You are the last active user.** Your account and the whole facility go together.
The note beside the heading says which case you are in: `the facility and its records stay`, or `deletes the facility and everything in it`. The public page at [/delete-account](/delete-account) explains the same thing without signing in.
## Delete your login
1. **Press `Delete my account`.** The box asks `Delete your login?`
2. **Type your password.**
3. **Press `Delete my login`.** You are signed out and taken to the home page.
Your user row is deleted, not deactivated. Issues, stocktakes and slips you recorded keep the name they were stamped with.
If you are an admin and other users remain but no other active admin, it is refused: `You're the only admin left. Make someone else an admin first, or delete the whole facility.`
## Delete the facility
1. **Take a backup.** `Download a backup first` sits above the button. See [Export and backup](/docs/account/export-and-backup).
2. **Press `Delete my account and this facility`.**
3. **Type your password, and type the facility name exactly.**
4. **Press `Delete everything`.**
Every user, the catalogue and barcodes, the register, and every issue, return, order, delivery, stocktake, request, photo and signature are deleted at once. It cannot be undone. This needs an admin account.
| Record | Change | Undo |
|---|---|---|
| Your user | Deleted | None |
| Facility | Deleted with everything in it | None; a backup file can be restored into a new facility |
Deleting works in a read-only facility. In the demo the button is switched off.
> **Careful** Deleting the facility does not stop a card plan. Press `Stop at period end` on `Settings Plan` first.
## Clear data, keep the account
Two boxes on `Settings Data & audit log`, above the audit log, remove data and leave everyone signed in. Only admins see them.
| | Wipe recorded activity | Start fresh |
|---|---|---|
| Confirm | Type `WIPE`, press `Wipe activity` | Type `RESET`, press `Empty this facility`, then confirm |
| Deletes | Issues, orders, pickups, stocktakes, stock moves, approvals, alterations, hand-ins, staff-app requests and messages, waitlist, kit checks, damage reports, record queries, the ward notice, photos | Everything in Wipe, plus the catalogue, barcodes, stock levels, departments, suppliers, locations, the register and its staff sign-ins |
| Keeps | Catalogue, register, departments, suppliers, barcodes, locations, opening balances, users | Users, facility name and settings |
| Also | Stock adjustments and pre-loved counts set to 0; order and request numbers restart | Order, catalogue and request numbers restart |
Both happen at once and cannot be undone.
## Staff sign-ins
A wearer cannot delete their staff sign-in from the staff app. An admin opens their record in `People`, goes to the `Details & access` tab, and in the `Staff app` panel presses `Remove access`, then confirms. The sign-in is deleted and they are signed out. A new code lets them back in later.
Their register entry and issue history stay, because they are the facility's stock records. Removing those is covered in [Deactivating and deleting](/docs/people/deactivating-and-deleting). A wearer who would rather not ask their coordinator can write to privacy@threadcount.tech.
## What is kept
- **Your name on records,** when only your login was deleted.
- **Backup files you downloaded.** They are on your own device. Delete them yourself.
- **Nothing in the facility,** once the facility is deleted. Its rows and its photo files go together.
The [privacy policy](/privacy) describes the hosted service's own encrypted backups.
+71
View File
@@ -0,0 +1,71 @@
---
title: Export and backup
section: account
order: 5
summary: The one-file backup, CSV exports, the last-backup date, what a restore replaces and refuses, and whose backups are whose.
screen: Settings Data & audit log
role: Admin
keywords: backup, export, export backup, download, restore, import backup, JSON, CSV, export CSV, last backup, data, audit log, recovery, take my data, leave
---
## The backup file
`Export backup` on `Settings Data & audit log` downloads the whole facility as one JSON file, named for the date where your facility is, such as `threadcount-backup-2026-09-13.json`. `Download backup` on `Settings Plan` gets the same file. Only admins can take it.
The file holds the facility's settings and every record. That covers the catalogue, barcodes, stock and its movements, and locations. It also covers departments, suppliers, the register, manager approvals, issues, orders and their deliveries, pickups, stocktakes, hand-ins and cost changes. The staff app's side is in it too: requests and their messages, the waitlist, kit checks, damage reports, record queries and the ward notice. Photos and signatures are written into the file.
Left out on purpose:
- users and staff sign-ins, because those rows hold passwords;
- ThreadCount's own notes about your plan.
The newest photos travel, up to 2000 photos or 40 MB. Older ones are counted and left out, so the file stays small enough to restore. After `Export backup`, the line under the buttons says how many were left out. The records they belong to are all in the file, and the images stay on the server.
The backup still downloads when the facility is read-only.
## CSV exports
`Export CSV` appears on `People`, `Requests`, the `On hand` and `Locations` tabs of `Stock`, the order ledger at `Orders All orders`, and `Reports`. On the `Count` tab, each past stocktake in the history has its own `CSV` button. An order's own page has `CSV` under `More` at the top. In Settings it is on the supplier list, the departments and cost centres list, and the audit log. The files are for reading and for finance; see [Reports](/docs/reports/the-nine-reports).
Only the backup file restores a facility. A CSV export does not change the last-backup date.
## The last-backup date
The `Backup` heading on `Settings Data & audit log` shows `Last backup` with the date and how many days ago, or `No backup taken yet.` Issuers see this line too. Past 7 days, or with no backup at all, it is marked in red, and admins see `!` beside `Settings` in the menu.
Each download of the backup file, from either screen, sets the date.
## Restore a backup
1. **Open `Settings Data & audit log` and choose `Import backup`.**
2. **Pick a ThreadCount backup file.**
3. **Confirm.** The warning says the restore replaces all data in this facility, and that users are kept.
Everything in the facility is deleted and rebuilt from the file, facility settings included. The facility name, slips, groups, sets and time zone all come from the file. It keeps the users, single sign-on settings and plan. Staff sign-ins survive, re-attached to register entries by staff number.
| Record | Change | Undo |
|---|---|---|
| Facility | All records replaced by the file's | Restore an earlier file |
| Facility | Settings replaced by the file's | Restore an earlier file |
| Staff sign-ins | Re-attached by staff number | None needed |
A restore is refused when:
- the file is not a ThreadCount backup;
- the facility is read-only;
- the file holds more staff records than the plan allows, 60 on Hosted Small;
- the file exceeds a count limit, such as 20,000 staff or 300,000 issues;
- you have made 20 restores or imports in 10 minutes;
- the upload is over 60 MB.
Photos beyond 2000 in a file are dropped rather than refused, and the line under the buttons says how many. Keep that file, because those images exist only in it.
> **Careful** A restore replaces what is there now. Take a fresh backup first if today's records matter.
## Your backups and the service's
The `Backups` row on `Settings Plan` shows the hosted service's own nightly backups: 14 days on Hosted Small, 35 days on the other plans. What they commit to is in the [Service Level Agreement](/sla) and on [Security](/security).
No screen restores one facility from those backups. The only restore in the app is `Import backup` with a file you hold.
The [Terms](/terms) make exporting and keeping regular backups the facility's own responsibility. Store the file under your records policy; it holds the register. Self-hosted servers need a backup of their own, as described in [Backups](/docs/selfhost/backups).
+92
View File
@@ -0,0 +1,92 @@
---
title: Plan and billing
section: account
order: 4
summary: The hosted plans and prices, the trial, paying by card or invoice, grace and read-only, and every billing email.
screen: Settings Plan
role: Admin
keywords: plan, billing, price, pricing, trial, subscribe, card, invoice, receipt, tax, GST, ABN, monthly, yearly, cancel, stop, read-only, grace, grandfathered, health service, purchase order
---
## Plans and prices
Prices are in Australian dollars before tax, from `PRICES` and `PLANS` in `lib/plan.ts`.
| Plan | Price | Staff records | Backups kept |
|---|---|---|---|
| Hosted Small | Free | 60 | 14 days |
| Hosted Facility | $129 a month or $1,290 a year | No ceiling | 35 days |
| Health Service | $4,990 a year for 5 facilities, $890 each extra | No ceiling | 35 days |
On Hosted Small the 60 counts every staff record, deactivated ones included. Past it, adding a person is refused with `The register is full for this plan — 60 staff records.`
A facility inside a health service takes that plan, shows a `Health service` row, and is invoiced yearly against the health service's purchase order.
A facility created before plans went live is grandfathered. Its status reads `Free · everything included, for good`, and there is nothing to buy.
`Plan` is the last item in the `Settings` side list. It is listed for admins only, and not in the demo. The Community edition has no plans.
## The trial
When you create a facility, choose Hosted Small, or a 30-day Hosted Facility trial. Neither takes a card. During the trial the status reads `Trial` with the days left.
## Pay by invoice or card
`Request an invoice` sends ThreadCount a notice naming your facility and the plan chosen: `Hosted Facility · annual` or `Health Service · annual`. ThreadCount raises the invoice to the `Billing contact` and records the payment. You can ask up to 3 times a day. A renewal is requested the same way.
`Subscribe by card` appears only when card payments are set up on the server, and not while the plan is paid. It opens `Subscribe`, a page in four steps for Hosted Facility:
1. **Plan.** Monthly $129 or yearly $1,290.
2. **Business.** Legal name, address, city and country are required, and so is the postcode, except in Ireland, Hong Kong, the United Arab Emirates and Macao. Tax ID is optional. `Billing email` is your billing contact and cannot be edited here.
3. **Agreements.** Tick the Terms of Service, Privacy Policy and Service Level Agreement. The time of the ticks is recorded.
4. **Card.** Press `Continue to card`, type the card into Stripe's fields on the page, then `Pay`. The total includes tax, which Stripe works out from the country and address. Card numbers never pass through ThreadCount.
Paying during a trial charges that day, and the paid period starts then. The Plan screen shows the plan as paid once Stripe confirms the payment.
## The Plan screen
The `Plan` table shows `Status`, `Staff records` (such as `42 of 60`), `Backups`, the end date (`Trial ends`, `Paid until` or `Writable until`), `Paid by`, `Invoiced to` and `Billing contact`. `Save contact` changes the billing contact.
A facility that pays by card also gets `Billing`, with `Card on file`, `Next charge` and `Cadence`, and `Invoices`, each with a PDF link.
- **`Update card`** takes a new card on the same page. It is used for every later charge, and any unpaid invoice is charged straight away.
- **`Stop at period end`**, then **`Yes, stop it`**, stops the renewal at the end of the paid period. Nothing more is charged, and nothing is refunded. `Keep my plan` undoes it before that date.
| Record | Change | Undo |
|---|---|---|
| Facility | Billing contact | `Save contact` again |
| Facility | Business details and agreement times | Subscribe again |
| Card plan | Card replaced | `Update card` |
| Card plan | Set to stop at period end | `Keep my plan` |
## Grace, then read-only
When a trial or a paid period ends unpaid, 14 days of grace follow. The status reads `Ended · still writable`, with `Writable until`.
After grace the facility is read-only. Changes are refused with `Read-only: this facility's plan has lapsed.` Nothing is deleted. A failed card payment changes nothing until 14 days after `Paid until`.
Still working when read-only:
- signing in, reports, CSV exports, printing and the backup download;
- the billing contact and `Request an invoice`;
- your own name and password, and deleting your account.
Restoring a backup is refused. Writing starts again when a payment is recorded.
## Billing emails
These go to the billing contact, or to every active admin if none is set.
| Email | Sent |
|---|---|
| Trial started | When the facility is created on a trial |
| Five trial notes | On days 1, 3, 7, 21 and 28 of the trial |
| Days left on your trial | Once in the last 7 days, then the day before |
| Trial ended | The day the trial ends |
| Now read-only | The day grace runs out |
| Receipt | Each card payment above zero |
| Payment did not go through | A card payment fails, once a day at most |
| Card updated | A new card is saved |
| Plan will end, or has ended | A card plan is set to stop, and when it ends |
These trial and read-only emails are checked daily and sent once each. Facilities paying by card, grandfathered ones and health-service members do not get them.
+72
View File
@@ -0,0 +1,72 @@
---
title: Single sign-on
section: account
order: 3
summary: Connect your facility's identity provider, route people to it by email domain, make it optional or required, and keep a break-glass admin.
screen: Settings People & sign-in
role: Admin
keywords: single sign-on, SSO, SAML, OpenID Connect, OIDC, Microsoft Entra, Azure AD, Okta, Google Workspace, identity provider, IdP, email domain, required, break-glass, metadata, disconnect
---
## What it does
Single sign-on lets the people at your facility sign in with the work account they already have, through your own identity provider: Microsoft Entra, Okta, Google Workspace, or any provider that speaks SAML or OpenID Connect.
An admin sets it up for one facility under the `Single sign-on` heading on `Settings People & sign-in`. On a server with no sign-on service it says `Single sign-on isnt available on this server.` It is not offered in the demo. Users who are not admins see one line saying whether the facility uses it.
Single sign-on never creates an account. The address your identity provider returns must already belong to an active user at your facility, added as described in [Users and passwords](/docs/account/users). Anyone else is told that the address has no account at this facility yet.
## Connect your identity provider
1. **In your identity provider, add an application for ThreadCount.** The panel shows the two values it asks for: the ACS or redirect URL, ending in `/api/auth/sso/callback`, and the Entity ID.
2. **Give ThreadCount the provider's metadata.** Paste its `Metadata URL`, which must start with `https://`, or paste the XML into `…or metadata XML`.
3. **List your email domains,** comma-separated. A domain is the part after the @, such as `example.com`.
4. **Press `Connect single sign-on`.**
The metadata is handed to the sign-on service and not shown again. The panel then reads `Connected`, with the provider's name when it has one. A later change to the domains is saved with `Save domains`.
Domains are checked each time they are saved:
- 10 at most.
- Public mail services such as `gmail.com` and `outlook.com` are refused.
- A domain belongs to one facility. One already registered elsewhere is refused.
| Record | Change | Undo |
|---|---|---|
| Facility | Connected, domains saved | `Disconnect single sign-on…` |
| Facility | `Require` or `Staff may use it too` switched | Untick it |
| User | Marked break-glass | Untick it |
| Facility | Disconnected, every switch off | Connect again |
## Routing by email domain
ThreadCount has one Log in screen for every facility, so it routes by address. When someone types an address ending in one of your domains, the screen offers `Continue with` and your facility's name. That button takes them to your identity provider, and they come back signed in.
A sign-in through your identity provider asks for no ThreadCount two-factor code. A deactivated user is refused.
## Optional or required
Once connected, single sign-on is optional. The Log in screen offers the button first, and `Prefer your password?` lets a user sign in with a password instead.
Tick `Require single sign-on` and:
- a correct password is refused for every user except break-glass admins, and the Log in screen sends them to single sign-on;
- password reset emails stop, except for break-glass admins.
`Require single sign-on` is refused until at least one active admin is marked break-glass.
## The break-glass admin
Under `Break-glass admins`, tick each admin who keeps a working password for the day the identity provider is down. Only admins are listed. On the Log in screen they open `Break-glass admin? Sign in with a password instead`.
> **Careful** A break-glass admin is the only way in while the identity provider is down. Keep that password, and that admin's two-factor, working.
## Staff sign-ins
Tick `Staff may use it too` and wearers who already have a staff sign-in can use single sign-on. They type their address on the website's Log in screen and land in their own staff view.
This is web only. The ThreadCount Staff app keeps their password, and `Require single sign-on` does not turn staff passwords off. See [The staff app](/docs/apps/staff-app).
## Disconnect
Press `Disconnect single sign-on…`, then `Disconnect`, or `Keep it` to back out. The connection is removed from the sign-on service, and `Require` and `Staff may use it too` are switched off. Everyone goes back to signing in with a password.
+64
View File
@@ -0,0 +1,64 @@
---
title: Two-factor sign-in
section: account
order: 2
summary: Turn on codes from an authenticator app, keep the recovery codes, sign in with them, and recover from a lost phone.
screen: Settings People & sign-in
role: Admin or Issuer
keywords: two-factor, two-factor authentication, 2FA, MFA, authenticator, TOTP, code, six digits, recovery codes, lost phone, new phone, trust this computer, security
---
## What it does
With two-factor on, a correct password is not enough to sign in. The Log in screen also asks for the six-digit code from an authenticator app on your phone.
It is set for your own account, under the `Two-factor` heading on `Settings People & sign-in`. Nobody else can turn it on or off for you, and it is optional for every role. An admin with two-factor off sees a note there saying it is worth turning on.
It covers password sign-in. A sign-in through [single sign-on](/docs/account/single-sign-on) asks for no ThreadCount code, because your identity provider handles the second factor.
## Turn it on
1. **Open `Settings People & sign-in` and press `Set up two-factor`.** A QR code appears, with the key written out under `Or type it in`.
2. **Scan the QR code with any authenticator app,** or type the key into it.
3. **Type the code the app shows into `Code from the app` and press `Turn it on`.** Nothing changes until this code is accepted. `Cancel` leaves your sign-in as it was.
4. **Save the recovery codes.** Ten appear, each in the form `XXXXX-XXXXX`. `Copy all` puts them on the clipboard. Press `I have saved them` when they are safe.
The `Two-factor authentication` box then shows `On` and how many recovery codes are left.
| Record | Change | Undo |
|---|---|---|
| Your user | Two-factor on, 10 recovery codes made | `Turn off` |
| Your user | 10 new recovery codes, the old ones dead | None |
| Your user | Two-factor off, recovery codes deleted | Set it up again |
Each of these is also written to the audit log on `Settings Data & audit log`, which admins can read.
## Recovery codes
Recovery codes are stored hashed. They are shown once, when they are made, and nobody can read them back afterwards, ThreadCount included. Print them or keep them somewhere you can reach without your phone.
Each code works once, in place of a code from the app. When 2 or fewer are left, the box suggests a fresh set.
`New recovery codes` asks you to confirm with your password, then `Generate new codes` shows 10 new codes. Every earlier code stops working at that moment.
## Signing in
After a correct password the Log in screen asks for the code. `Use a recovery code instead` switches the box to take a recovery code.
- Tick `Trust this computer for 30 days` and that browser is not asked for a code for 30 days. Changing your password ends the trust.
- The code step accepts 10 attempts per account in 15 minutes, then answers `Too many attempts — try again in a few minutes.`
- If the step has expired, the screen says `That sign-in has expired. Start again.` Type your password again.
A password reset by email also asks for the code before it signs you in, so a reset is not a way around two-factor.
## A lost or replaced phone
1. **Sign in with a recovery code.**
2. **Open `Settings People & sign-in`, press `Turn off`, type your password and press `Turn it off`.**
3. **Press `Set up two-factor`** and scan the new QR code with the new phone. A new set of recovery codes comes with it.
If the old phone still works, do the same steps with a code from it instead of a recovery code.
There is no screen where an admin turns off two-factor for another user. The `Edit user` dialog has no two-factor control.
> **Careful** A user with no phone and no recovery codes cannot sign in from any screen. For an only admin, that means nobody can. Keep the codes, and keep a second admin.
+73
View File
@@ -0,0 +1,73 @@
---
title: Users and passwords
section: account
order: 1
summary: Add admins and issuers, change your own details and password, reset a forgotten password by email, and keep a second admin so the facility never locks.
screen: Settings People & sign-in
role: Admin or Issuer
keywords: users, add user, edit user, admin, issuer, coordinator, login, sign in, password, change password, forgot password, reset, deactivate, reactivate, second admin, locked out, your account, profile, name
---
## Who can sign in
The people who sign in to the web app and the counter are users. Each has a work email, a password and one of two roles, Admin or Issuer. What each role may do is on [The two roles](/docs/start/the-two-roles).
Users are not the people on the register. A wearer who signs in to the staff app has a staff sign-in attached to their entry. It is managed on their record in `People`, on the `Details & access` tab, not here.
`Settings People & sign-in` opens from the side list on `Settings`, or from your name at the foot of the menu. Everyone sees `Your account`, `Password`, `Two-factor`, `Single sign-on` and `Delete my account`. Only admins see `Users`, and `Deactivated users` once there is one.
## Add or change a user
1. **Press `Add user`** beside the `Users` heading, which counts how many can sign in.
2. **Fill in first name, last name, title and work email.**
3. **Choose the role.** `Issuer` is chosen until you change it.
4. **Set a password of at least 8 characters and press `Save`.**
ThreadCount does not email the new user. The dialog says so: hand the password over yourself. One email address holds one user account across the whole service, so an address already in use is refused with `That email already has an account`.
`Edit` on a user opens the same dialog. It changes name, title and role, and `New password (leave blank to keep)` sets a new password. The work email cannot be changed. A new password ends every session signed in with the old one.
`Deactivate`, in that dialog, asks you to confirm, then stops the login without deleting it. Records keep the name, and the user moves to `Deactivated users`, where `Reactivate` lets them sign in again. The button is not offered on your own account. A deactivated user who signs in is told the account has been deactivated.
| Record | Change | Undo |
|---|---|---|
| User | Added, with a role and a password | `Deactivate` |
| User | Name, title, role or password changed | `Edit` again |
| User | Deactivated, cannot sign in | `Reactivate` |
## Your own details and password
Under `Your account`, change your first name, last name and title, then press `Save my details`. They stamp every issue, stocktake and slip you record.
Under `Password`, type `Current password`, then `New password` and `Confirm`, and press `Change password`. The new one must be at least 8 characters, and the button stays off until the two new passwords match.
You stay signed in on the device you used. Every other session signed in with the old password ends. Neither your details nor your password can be changed in the demo.
## Reset a forgotten password by email
On the Log in screen, type your work email, then choose `Forgot your password?`. The screen says `Reset link sent` whatever the address, so it cannot be used to find out who has an account.
- The link works once and expires in an hour.
- Asking again cancels any earlier link.
- At most 4 reset emails go to one address in an hour.
- A deactivated account is sent nothing.
- At a facility that requires single sign-on, only break-glass admins are sent a link. See [Single sign-on](/docs/account/single-sign-on).
- If two-factor is on, the reset asks for your code before it signs you in.
A completed reset signs you in and ends every other session on the account.
## When the email never arrives
Nothing arrives if the server has no mail set up, or if the address on the account is wrong. The Log in screen says the same thing either way, so it cannot tell you which. Self-hosting admins set mail up as described in [Email](/docs/selfhost/email).
Another admin at your facility can set you a new password with `Edit` under `Users`. The address itself cannot be changed there.
If you are the only admin, the reset screen asks you to write to support from an address you control, naming the facility and the address on the account.
## Why a second admin matters
ThreadCount refuses to demote or deactivate the last active admin, with `Keep at least one active admin`. It does not make you add a second one.
With one admin, that person's inbox is the only way back in when the password is forgotten, and their phone is the only way past [two-factor](/docs/account/two-factor). If the last person who can sign in deletes their account, the facility goes with it. See [Delete an account](/docs/account/delete-an-account).
> **Careful** Add a second admin with a working address before you need one. It is the one way back in that needs no email and no support.