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:45:19 +10:00
commit 1bc2de655a
505 changed files with 56223 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
// Legal wording, lifted unchanged from the previous single tabbed page so the documents keep
// saying exactly what they said. Each key is now its own route under (site).
export type Section = { h: string; ps: string[]; list?: string[] };
export const DOCS: Record<string, Section[]> = {
"Privacy Policy": [
{ h: "1. What this covers", ps: ["This policy explains what personal information ThreadCount handles, why, and who can see it. ThreadCount is a uniform stock management application used by a facilitys linen room or uniform service. The facility that deploys ThreadCount is the owner and controller of all data recorded in it; ThreadCount is a tool the facility operates."] },
{ h: "2. The two Android apps", ps: ["There are two, for two different audiences, and they ask for different things.", "“ThreadCount” is the linen rooms counter app. It signs in to the same coordinator account and shows the same records as the website, and it keeps nothing on the phone beyond your session and a stocktake you have started but not yet filed. It asks for one permission — the camera — and only to read the barcode on a garment label.", "“ThreadCount Staff” is for the people who wear the uniform. It shows one person their own record and nothing else. It asks for no permissions at all beyond internet access: no camera, no location, no contacts, no files, no photos, no microphone. It carries no barcode scanner, because nothing a wearer does involves scanning.", "Neither app works without a connection, neither stores your records on the phone, and neither has access to contacts, location, files, messages or call history."] },
{ h: "3. Information we hold", ps: ["ThreadCount stores only what a uniform service needs to issue and account for garments:"], list: ["Staff register: name, payroll/staff number, work phone number, staff group, department or ward, garment sizes, uniform entitlement, start date, and the one named person who approves that staff members requests.", "Activity records: uniform issues, returns, orders placed on a staff members behalf, pickup contact notes, and manager approval records (approver name, sets approved, FTE).", "Coordinator accounts: name, role (Admin or Issuer) and sign-in credentials.", "Staff self-service accounts, where a staff member has claimed one: the email address they chose as their sign-in and a hashed password. Nothing else — the account attaches to the register entry the linen room already holds.", "Requests raised in the staff app: the garment, size, quantity, the reason chosen from a fixed list, an optional note, who approved or declined it and — if declined — which of three reasons was given.", "Messages about a request, between a staff member and their linen room. Each message belongs to one order and is visible only to that person, their manager, whoever raised it on their behalf, and the facilitys coordinators.", "Kit check answers (how many of each garment a person confirms they still hold), waitlist entries, and queries raised through “This isnt right”.", "Security records: the network address an action came from. It is kept with the audit trail of coordinator actions, with a password reset request, and with a message sent through the contact form, so a change can be traced back to where it was made.", "Messages sent through the contact form on this website: the name, work email address, role and facility you give, the topic you pick, what you write, and the network address it came from. This is not a mailing list — it is the enquiry itself, kept only so it can be answered and followed up, and deleted on the schedule in section 12.", "Operational data that is not personal information: catalogue, stock levels, supplier orders, stocktakes and cost centre codes.", "A billing contact, where a facility is on a paid plan: the email address an administrator chose for invoices to go to. Invoices are paid by bank transfer against a purchase order; ThreadCount holds no card or bank details."] },
{ h: "4. What we never collect", ps: ["ThreadCount holds no clinical or patient information of any kind, no home addresses, no payment or banking details, and no biometric data. There is no money anywhere in the product: no prices shown to staff, no basket, no payment. There is no advertising anywhere in ThreadCount, no advertising or marketing network receives anything, and no third party tracks you through it.", "One thing to be plain about: a staff member who sets up self-service chooses their own sign-in address, and that may be a personal one. ThreadCount uses it to sign them in and to send them the notices in section 9 — nothing else. It is never added to a mailing list, never shared, and never used to contact them about anything but their own uniform.", "ThreadCount does keep its own usage statistics and its own error reports, on its own infrastructure and without cookies — sections 5 and 6 set out exactly what those record."] },
{ h: "5. Usage statistics", ps: ["ThreadCount counts how its own pages are used, so that it can be improved. This is run by ThreadCount on ThreadCount\u2019s own Australian-hosted infrastructure at analytics.threadcount.tech. No analytics company, advertising network or other third party is involved, and nothing is sold, shared or used to build a profile of anyone.", "It sets no cookies and stores nothing on your device. Visitors are counted using a value derived fresh each day and never stored, so the same person cannot be recognised from one day to the next, and nobody can be identified from it \u2014 which is also why ThreadCount shows no cookie banner. If your browser or phone sends a Do Not Track signal, the statistics stop entirely for you.", "What is recorded:"], list: ["The page visited, with record identifiers removed before anything is sent \u2014 a visit to one person\u2019s record is recorded as \u201c/m/person/:id\u201d, never with the staff member\u2019s identifier, and the part of a web address after the \u201c?\u201d is discarded entirely.", "Whether the visit came from the Android app or a browser, the browser and operating system, the screen size, the language, and the country \u2014 worked out from the network address, which the statistics themselves do not keep. The places the network address is kept are in section 3: the audit trail, a password reset request, and a message sent through the contact form.", "Counts of a fixed set of actions in the linen rooms own screens: a stocktake filed, a garment issued, returned or exchanged, a delivery received, a pickup collected, an order raised, a barcode bound, a location saved, a spreadsheet imported, someone invited, settings changed, an account deleted, the scanner opened, and a scan of a barcode ThreadCount did not recognise.", "Counts of the same kind from the staff app: a request raised, approved, declined or messaged about, damage reported, a query raised against a record, a waitlist joined or taken up, a kit check answered, and a ward round signed for.", "Counts of the ways in and out: the app or a page being opened, a sign-in or sign-up succeeding or failing, a security check being shown, a second factor being asked for, and a subscription to the product update list. Where ThreadCount refuses an action, the count says which broad kind of refusal it was — never the message it showed.", "For the website, the site that linked you here.", "All of these are counts. Not one of them carries a name, a barcode, a facility, a record identifier, or anything typed into the product."], },
{ h: "6. Error reports", ps: ["When something goes wrong, ThreadCount sends itself a report so the fault can be found and fixed. This runs on ThreadCount\u2019s own Australian-hosted infrastructure at errors.threadcount.tech. No error-reporting company or other third party is involved.", "A report carries the error message, where in the code it happened, the page it happened on and the browser or app version. Before anything is sent it is scrubbed: email addresses, record identifiers and long runs of digits are removed from the message. No record, no staff name and no message content is included."] },
{ h: "7. Camera, signatures and photographs", ps: ["This section is about the linen room\u2019s counter app and the website. The staff app has no camera permission at all and captures no images of any kind.", "Barcode scanning in the counter app uses the device camera. Frames are read on the device to find a barcode and discarded immediately — no video or still image from scanning is stored or sent anywhere.", "Separately, a coordinator can deliberately capture and save a few kinds of image: a signature drawn on screen when a ward receives a delivery, a handover photograph attached to that delivery, a photograph of a damaged garment attached to a return, and a photographed manager approval form or supplier receipt. These are saved to your facilitys record because they are the evidence the record exists for. They are only ever shown to that facilitys own accounts, and they are deleted with the record they belong to."] },
{ h: "8. Why we hold it", ps: ["Data is used solely to run the uniform service: issuing stock to the right person, tracking entitlements and manager approvals, replenishing stock, contacting staff when an ordered garment arrives, and attributing uniform spend to the correct cost centre for the facilitys internal financial reporting."] },
{ h: "9. Communications", ps: ["ThreadCount emails a staff member only about their own uniform, and only once they have set up self-service with an address they chose. There are four such messages: a request needing your approval, if people report to you; the decision your manager made on your request, including the reason if it was declined; a notice that your garments are ready to collect or are out on the ward round; and a notice that a size you were waiting for has arrived. Nothing else is ever sent.", "Nobody is added to any mailing list because their details are in ThreadCount. A staff member who has not set up self-service is never emailed at all, and pickup contact for them still happens in person or by phone, by a coordinator, from the call list.", "Two things do send email, and only ever to someone who asked for it. If you write to us through the contact form we reply to you \u2014 that is all; the form says so, and an address given there is never added to any list. Separately, you can subscribe to occasional product updates from the sign-up on this website. That list is double opt-in, so you are only on it after clicking a confirmation link, every message carries a one-click unsubscribe, and it is used for release notes rather than advertising. It is run on ThreadCount\u2019s own mail infrastructure at lists.threadcount.tech; the addresses are not shared with anyone."] },
{ h: "10. Storage and security", ps: ["Records are stored on ThreadCounts Australian-hosted infrastructure, isolated per facility, and are only ever shown to that facilitys named accounts. Access requires a named account; the Issuer role cannot alter settings, staff records, pricing or history. Backups are exported and retained by the facility. ThreadCount does not transmit records to third parties, to outside analytics companies or to advertising networks; the usage statistics in section 5 are ThreadCounts own, run on its own infrastructure, and contain no records."] },
{ h: "11. Who can see your record", ps: ["You can, if your linen room has given you self-service — that is what the staff app is for, and it shows you your own record and nobody else\u2019s.", "The one person recorded as approving your requests sees the requests you raise and, on their ward view, what the people reporting to them are holding. That same person can raise a request on your behalf and is named on it alongside you; whoever signs for a ward-round delivery is named on the requester\u2019s order.", "Your facilitys uniform coordinators (Admin and Issuer accounts) can see the staff register and issue history in order to run the service. Cost centre reporting shared with finance is aggregated by ward and cost centre; where individual lines appear (for example the staff spend table), they show name, items and value only."] },
{ h: "12. Retention", ps: ["Issue and order history is retained for the periods the facilitys financial record-keeping requires. When a staff member leaves, their register entry is deactivated — which also stops their self-service sign-in working immediately — and facilities may delete records entirely where no linked history must be preserved for audit.", "Requests, their message threads, kit check answers and waitlist entries are part of the facilitys record and are kept and deleted with it.", "Messages sent through the contact form on this website are kept for 12 months from the day they are sent, and then deleted. That is long enough to answer an enquiry and to pick up the conversation it turns into; nothing is kept beyond it, and the address is never added to any list."] },
{ h: "13. Deleting an account", ps: ["Anyone with a ThreadCount sign-in can delete their own account from Settings, without asking anyone. What that removes depends on whether colleagues remain: if other people can still sign in to the facility, only the login goes and the facilitys records stay, because they belong to the linen room rather than to one person. If nobody else can sign in, deleting the account deletes the whole facility — every user, the catalogue, the staff register, and every issue, return, order, delivery, stocktake and photograph. That happens immediately, cannot be undone, and cannot be recovered by us.", "The full explanation, including how to do it and what taking a backup first gets you, is at threadcount.tech/delete-account.",
"Staff self-service accounts work differently, because the record they attach to belongs to the linen room rather than to the account. Ask your uniform coordinator to remove your access: there is a button on your staff record that does it, it takes effect immediately, and it ends every session you have open. Your register entry and issue history stay, because the facility needs them for its own stock and financial records — deleting those is the facility\u2019s decision under section 12, not something an individual sign-in controls. If you would rather not ask your coordinator, or you want a copy of what is held about you first, write to privacy@threadcount.tech and we will route it through your facility\u2019s privacy process."] },
{ h: "14. Access and correction", ps: ["You may ask your uniform coordinator to show you your record, correct your details or sizes, or update your department. Requests the coordinator cannot resolve follow the facilitys standard privacy process, under the Privacy Act 1988 (Cth) and whichever privacy legislation applies in your state or territory — in Queensland, for instance, the Information Privacy Act 2009 (Qld)."] },
],
"Terms of Service": [
{ h: "1. The agreement", ps: ["These terms govern use of the ThreadCount application by a facility and its authorised users. By signing in you agree to use ThreadCount only for managing your facilitys uniform service and in line with these terms and your facilitys policies."] },
{ h: "2. Accounts and roles", ps: ["Accounts are personal and must not be shared. Admin accounts manage settings, the staff register, catalogue, pricing, suppliers and departments; Issuer accounts issue stock, run stocktakes and receive deliveries. You are responsible for activity recorded under your sign-in, which is why each issue, stocktake and override is stamped with the account that made it."] },
{ h: "3. Acceptable use", ps: ["You must not:"], list: ["Access or alter records except as your role requires for the uniform service.", "Record issues, approvals or adjustments you know to be false.", "Disclose staff register information outside the facilitys legitimate processes.", "Attempt to circumvent role restrictions, or share credentials."] },
{ h: "4. The facilitys data", ps: ["All records entered into ThreadCount belong to the facility. The facility may export its full data at any time from Settings and may delete it entirely. ThreadCount claims no rights over facility data."] },
{ h: "5. Accuracy and responsibility", ps: ["ThreadCount records what its users enter. Stock figures, entitlement balances and cost centre attribution are only as accurate as the issues, receipts and stocktakes recorded. Financial journals produced by ThreadCount are drafts for the facilitys finance team to review before posting; ThreadCount is not an accounting system of record."] },
{ h: "6. Availability and changes", ps: ["ThreadCount is provided as-is for the facilitys internal use. Features may change with notice to facility administrators. Exporting and keeping regular backups is the facilitys own responsibility; ThreadCount shows the date of the last export in Settings."] },
{ h: "7. Termination", ps: ["A facility may stop using ThreadCount at any time by exporting its data and deactivating accounts. ThreadCount may suspend accounts used in breach of these terms, at the request of the facilitys administrators. A facility whose paid period has lapsed is made read-only rather than closed — section 9 says how."] },
{ h: "8. Liability", ps: ["To the extent permitted by law, ThreadCounts liability is limited to re-supplying the software. Nothing in these terms excludes rights under the Australian Consumer Law that cannot be excluded."] },
{ h: "9. Fees", ps: [
"The software is free. Where a plan applies, it pays for hosting on threadcount.tech, for the backups kept there, and for support with a response time. The plans and their prices are on the pricing page. Prices are in Australian dollars and exclude GST, which is added where it applies.",
"A facility created before plans were introduced is grandfathered: hosted free, with every feature, for as long as it exists. A change to these terms does not change that.",
"A hosted plan is invoiced annually in advance against the facilitys purchase order, or monthly where card payment is offered, and renews for the same period unless the facility asks to stop. Sixty days notice of any price change is given by email to the facilitys administrators, and no change applies to a period already paid for.",
"If a trial or a paid period ends without payment, the facility has fourteen days grace and then becomes read-only: every report, export, printed document and the full backup keep working, and nothing is deleted. Writing resumes when a payment is recorded. A facility that chooses to leave instead may export everything and go, as section 7 says.",
"Fees are not refunded for a period already begun, except where the Australian Consumer Law requires it or ThreadCount was unavailable for a substantial part of that period.",
] },
],
"Data Security": [
{ h: "Where data lives", ps: ["All records are held on ThreadCounts Australian-hosted infrastructure, kept separate per facility and never shown across facilities. Nothing is sent to external analytics, advertising or telemetry services.", "ThreadCount keeps cookieless usage statistics on its own Australian infrastructure, covering which pages are opened and counts of a fixed set of actions, with record identifiers stripped before anything is sent; no facility record ever forms part of them. Error reports run on the same footing at errors.threadcount.tech, and are scrubbed of email addresses, identifiers and long digit runs before they are sent."] },
{ h: "Access control", ps: ["Two coordinator roles with least-privilege boundaries: Issuers cannot change settings, staff records, prices, suppliers or history; Admins can. Every material action — issues, overrides, price changes, stocktake applications, order receipts — is recorded against the signed-in account with a date.", "A staff self-service account is a different kind of account, not a lesser coordinator one. It lives in its own table with its own sign-in cookie, signed with a separate key, and it carries a different kind of identifier internally. A staff sign-in therefore cannot become a coordinator sign-in — not because a permission check says no, but because the two are not the same kind of thing. A staff member reaches their own record and nothing else; a ward manager additionally sees requests addressed to them and what their own team holds.", "Approval belongs to the ward and fulfilment to the linen room, and neither side can do the others job. The linen room can re-address a waiting request to the right manager, but it cannot decide one, and it cannot approve on a managers behalf.", "An administrator may record anyone as their own manager. That person then approves their own requests, and a signed order form for their own kit may name them as the approver. No self-approval is silent: a request they decide for themselves is written into its timeline as a self-approval, naming them as both the approver and the one it is for, and a signed form they approved for themselves is marked as self-approved on their staff record. The approvals queue sets a managers own requests apart from the ones they are deciding for other people.", "Nobody approves a request they raised for somebody else. When a manager raises a request for one of their own reports, it goes to the raisers own manager instead; if there is nobody above them, or the raiser is their own manager, it waits for the linen room to address it to someone else."] },
{ h: "Device camera and stored images", ps: ["The ThreadCount Staff app requests no permissions beyond internet access — no camera, no location, no files, no photos — and captures nothing. Everything in this section is about the linen rooms counter app and the website.", "In the counter app, barcode scanning uses the device camera locally. Frames are processed on-device to detect a barcode and immediately discarded; nothing from scanning is stored or leaves the device.", "Images a coordinator deliberately captures are different, and are stored: delivery signatures, handover photographs, damage photographs on a return, and photographed manager approvals or supplier receipts. They are held with the facilitys own records, served only to that facilitys signed-in accounts, and deleted with the record they belong to."] },
{ h: "Backups", ps: ["Admins export a complete JSON backup from Settings. Backups contain the staff register and history and must be stored according to the facilitys records policy. Taking them regularly is the facilitys responsibility; Settings shows the date of the last export."] },
{ h: "Incident process", ps: ["Suspected unauthorised access should be reported to the facilitys privacy officer and IT security team under the facilitys incident procedure, and to security@threadcount.tech. ThreadCounts design limits blast radius: no credentials for external systems, no patient data, no financial account numbers."] },
],
"Acceptable Use": [
{ h: "Purpose", ps: ["ThreadCount exists to run a uniform service: know what is on the shelf, prove where it went, charge the right ward. Use it for that."] },
{ h: "Do", ps: [], list: ["Record every issue at the time it happens, against the right staff member.", "Record manager approvals from the signed order form before issuing against them.", "Use overrides sparingly and only with the coordinators authority — they are permanently recorded.", "Keep the register current: sizes, wards and cost centres drive reporting.", "Export a backup at least weekly."] },
{ h: "Dont", ps: [], list: ["Issue stock without recording it, or record it against the wrong person “to fix later”.", "Share your sign-in or leave a signed-in terminal unattended at the counter.", "Look up staff records for any reason other than running the uniform service.", "Adjust stock outside a stocktake or documented correction."] },
],
"About & Contact": [
{ h: "About ThreadCount", ps: ["ThreadCount was built in a hospital linen room by a uniform coordinator who needed it — not adapted from retail inventory software. It manages stock on hand, issuing, supplier ordering, stocktakes, manager approvals and cost centre reporting for facility uniform services."] },
{ h: "Contact", ps: ["Product and account questions: your facilitys uniform coordinator.", "Privacy requests: privacy@threadcount.tech or your facilitys privacy officer.", "Security reports: security@threadcount.tech — include steps to reproduce; do not include staff personal information in the report."] },
{ h: "Document history", ps: ["Privacy Policy, Terms of Service, Data Security and Acceptable Use — first published 28 August 2026. Material changes are notified to facility administrators in the application.",
"13 September 2026: the Terms of Service gained section 9, Fees, ahead of plans being introduced: what a plan pays for, that every facility created before plans existed stays free with everything, how a hosted plan is invoiced and renewed, sixty days notice of price changes, and that a lapsed plan becomes read-only rather than closed. Section 7 refers to it. The Privacy Policys section 3 now names the one new thing a paid plan adds to what is held — a billing contact address — and section 4 still holds: no card or bank details, ever.", "8 September 2026: the Privacy Policy and Data Security pages were revised for the ThreadCount Staff app — what a staff self-service account holds, the four emails a staff member can receive, error reports, who can see a record, and how a staff member has their access removed. Two earlier statements were corrected rather than extended: ThreadCount does now hold a personal email address where a staff member chose one as their sign-in, and it does now email staff about their own requests.", "Later on 8 September 2026, three further statements in the Privacy Policy were corrected. Section 3 now records the network address kept with the audit trail, with a password reset request and with a contact form message, which the policy had not mentioned and section 5 had implied was never kept at all. Section 5 now lists the counted actions in full, including every one the staff app sends. And section 14 no longer names one states privacy legislation as though it governed every facility.",
"11 September 2026: the Data Security page no longer says nobody can approve their own request. A manager with at least one person reporting to them may now approve a request raised for themselves, so the page sets out the control that replaced the old refusal: the test is direct reports on the register rather than the title, and every such decision is recorded in the requests timeline as a self-approval. The rest of the claim is unchanged — the linen room still cannot approve on a managers behalf, and approval and fulfilment are still separate jobs.",
"12 September 2026: the Data Security page no longer limits self-approval to a manager with someone reporting to them. An administrator may now record anyone as their own manager, and every request or signed order form a person approves for themselves is recorded as a self-approval. The page also now states the rule that did not change: nobody approves a request they raised for somebody else."] },
],
};
/* Each document carries its own date. One shared date made an untouched document announce a
revision it had not had, which at a customer is not a cosmetic problem: a changed date on the
Terms sends the whole pack back through legal review for nothing. */
export const DOC_META: Record<string, { path: string; title: string; desc: string; updated: string }> = {
"Privacy Policy": { path: "/privacy", title: "Privacy Policy", desc: "What personal information ThreadCount holds for a facilitys uniform service, why, and who can see it.", updated: "13 September 2026" },
"Terms of Service": { path: "/terms", title: "Terms of Service", desc: "The terms a facility and its authorised users agree to when using ThreadCount.", updated: "13 September 2026" },
"Data Security": { path: "/data-security", title: "Data Security", desc: "Where ThreadCount records live, how access is controlled, and what the device camera does.", updated: "12 September 2026" },
"Acceptable Use": { path: "/acceptable-use", title: "Acceptable Use", desc: "What coordinators should and shouldnt do with the staff register and the issue record.", updated: "28 August 2026" },
// The document history lives in here. It was written but had no route, so the one reader who
// ever wants it — a privacy officer asking what changed and when — could not reach it.
"About & Contact": { path: "/legal-about", title: "About & Contact", desc: "Who wrote ThreadCount, where to send a privacy or security question, and what changed in these documents.", updated: "13 September 2026" },
};