TFB Platform

All three documents · 17 unfilled markers in this document

Privacy Policy

Draft — not reviewed by a lawyer

This document was drafted by the engineer who built the software, by reading the database models and the code that writes to them. It has not been reviewed by a lawyer. It must not be put in front of a customer, linked from a signup flow, or relied on by anybody until a qualified person has read it. Every [NEEDS ZACH: ...] marker below is a fact only Zach can supply, and a marker that is still showing means this document is unfinished.

It is written to be true about this specific application rather than generic. If you change what the software collects, this document is wrong until somebody changes it too.


1. Who we are

[NEEDS ZACH: the legal entity name, exactly as registered], of [NEEDS ZACH: the registered business address], operates the business development platform described here ("the Platform").

For anything in this document that needs a reply from us, write to [NEEDS ZACH: the contact address for data requests — a mailbox somebody actually reads, which may or may not be the same one as the legal notices address in the Terms of Service].

2. Two very different sets of people

Almost every privacy policy describes one relationship: the company and its users. This Platform has two, and conflating them would make this document useless.

Our customers' staff. The restoration company's owner, managers and sales reps. They have accounts, they sign in, they chose to be here. For their personal data we are the controller of the account itself (their sign-in address, their password, their sign-in history) and the processor of everything they do with it.

Everybody else in the database. Facilities managers, property managers, hospital and hotel and university staff, networking-group members, and the owners of commercial buildings. These people did not sign up, have usually never heard of us, and are in the system because one of our customers is trying to win their business. We hold their data only on our customers' instructions. Our customer is the controller; we are the processor. Where the law gives those people rights, the obligation to answer sits with the customer who holds the record, and we help them do it.

[NEEDS ZACH: the lawyer needs to confirm this split, and in particular who owes the notice duty to a prospect whose details were collected from public map data without their knowledge. This is the single biggest legal question the product raises and it is not a question an engineer should answer.]

3. What the Platform actually holds

Written from the database, table by table, grouped by whose data it is.

About a customer's staff

About the people our customers are selling to

About events in the world

About how the Platform was used

4. What we do not hold, and do not do

These are all true of the software as it stands, which is why they are worth stating rather than being left to inference.

5. Who can see it

Inside a customer's company. Every record belongs to exactly one company, and every read is filtered by that company's identifier at a single chokepoint in the code. A request for another company's record is answered "not found" rather than "not allowed", because confirming that a record exists is itself a disclosure. Within a company: a manager or owner sees the whole company's data; a sales rep sees the contacts they own and the drafts they wrote, and not their colleagues'. A colleague's IP address is visible to managers only.

Us. A small number of platform administrators can see across all companies. This is real and it should be stated plainly rather than buried: the administrator screens list every company, their user counts and record counts, and the audit log across all companies. It exists so that a support call can be answered and a fault investigated. Every administrator action is itself written to the audit trail.

[NEEDS ZACH: how many people will have platform administrator access, and whether you want a written internal rule about when it may be used. A lawyer will ask, and a buyer with an IT department will definitely ask.]

Sub-processors. The third parties that necessarily touch customer data in order for the Platform to run.

Sub-processorWhat they doWhat of yours they hold
RailwayHosts the application and the PostgreSQL databaseEverything in the Platform
[NEEDS ZACH: transactional email provider — Postmark or similar, not yet chosen]Would deliver password resets and the weekly reportStaff email addresses and report contents
[NEEDS ZACH: payment provider — Stripe, account not yet created]Would take paymentBilling contact and payment details
[NEEDS ZACH: contact-enrichment provider, not yet chosen]Would find a facilities manager's name and emailProperty records sent for lookup

The last three are listed because they are planned, not because they exist. Today the only sub-processor is Railway.

Services the Platform reads from, which receive no personal data. The Platform fetches from three kinds of outside source, and it is worth being precise about what travels outbound, because "we use a third-party API" is usually left ambiguous:

Disclosure required by law. If we are compelled to hand over data we will do so, and we will tell the affected customer unless we are prohibited from telling them. [NEEDS ZACH: confirm with the lawyer whether a commitment to notify is one you can safely make.]

6. How long it is kept

This section describes retention controls that actually run, not an intention.

Deleted records go to a bin for 30 days. Deleting a contact, a job, a company account, a group or a draft marks it deleted and takes it out of every screen, every list and every export immediately. It is recoverable from the bin for 30 days, and a countdown on the bin screen says how long is left. The window is one constant in the code (SOFT_DELETE_WINDOW_DAYS in app/models.py), currently 30 days: long enough that somebody notices a mistake after a holiday, short enough that a former customer's data is not sitting around indefinitely.

After 30 days they are really deleted. A scheduled job removes expired records permanently. When a contact is removed, the things written about that contact go with them: every draft and sent message written to them, their tags, their networking-group memberships, and their referral records. That last one moves a networking group's referral balance, and that is the honest outcome — a balance attributed to somebody the customer asked us to forget would be worse.

The audit trail survives it. The record that a message was sent to somebody remains; the text of the message does not. The audit trail is append-only and nothing in the Platform updates or deletes a row in it.

[NEEDS ZACH: how long may the audit trail keep a person's email address and IP address? Today the answer is "for ever", because nothing prunes it. That is defensible as a security and accountability record and it is exactly the kind of "for ever" a regulator asks about. The lawyer should give a number, and then I will build the pruning job. The same question applies to the sign-in attempt log, which keeps an email address and an IP address per attempt and is also never pruned.]

Backups. Backups are retained for 14 days, with the three most recent always kept even if they are older than that, so that a corruption introduced on a Friday is still recoverable the following week. The consequence, stated rather than hidden: a record that has been deleted and purged can still exist inside a backup for up to a further 14 days. The retention numbers live in app/backup.py so that this paragraph can be checked against the code.

When a customer leaves. Their records are deleted on the schedule above. [NEEDS ZACH: how long after an account closes should the data be deleted rather than merely deletable — immediately, 30 days, 90? And should a customer be able to ask for an immediate wipe? A lawyer will want a number here, and whatever it is, I will build it.]

7. Where it is kept, and how it is protected

The application and the database run on Railway. [NEEDS ZACH: which region the Railway project is in, because that determines whether data leaves the country the customer is in, and therefore whether international transfer language is needed at all.]

What the software does to protect it, specifically:

[NEEDS ZACH: whether the Railway PostgreSQL volume is encrypted at rest, and whether Railway will provide that in writing. Do not let the lawyer write "encrypted at rest" into a contract until the host has confirmed it.]

8. Rights, and how to use them

If you are a customer's member of staff and want to see, correct or delete your account data, ask the owner or administrator of your own company first — they can do most of it from inside the Platform. If they cannot, write to us at the address in section 1.

If you are somebody a customer of ours has in their system — a facilities manager who received an email, say — the company that contacted you is the one holding your details, and they are the ones who can remove you. If you write to us instead, we will pass your request to the customer concerned and tell you that we have, within [NEEDS ZACH: a number of business days. A lawyer will know what the applicable law requires; pick the shortest one you can actually meet.]

If you want to stop receiving messages, say so in a reply to the message. Reaching a person at the company that sent it is faster than reaching us, because they have the record and the stop switch.

[NEEDS ZACH: which privacy laws you are accepting that you fall under. That decides what rights have to be listed and in what words — the California rights, the GDPR rights, both, or neither. It depends on where you sell and to whom, and it is not a judgment an engineer should make.]

9. Automated processing, stated plainly

The Platform makes two kinds of automated judgment about people, and both deserve naming rather than hiding in a feature list.

Lead scrubbing scores a prospect on the size and age of their business, whether they own or rent their building, whether a decision maker has been verified and whether a trigger event matched. A low score holds the prospect back from the outreach queue, so the score does decide whether a particular person receives a commercial message. A human can override it, and the override is recorded.

The retention engine decides who is due a touchpoint, from the calendar, from a storm or fire landing on a town where they have a building, from a job anniversary, or from how long they have been quiet.

In both cases the output is a draft that waits for a person. Nothing is sent automatically unless the customer has deliberately switched automatic sending on for a specific campaign.

[NEEDS ZACH: ask the lawyer whether scoring a business contact for commercial outreach counts as automated decision-making that needs a disclosure or an opt-out under any law you sell into. My reading is that it does not, because the effect is "receives a sales email or does not". That is a reading, not advice.]

10. Things the Platform cannot do yet, so that nothing here is read as a promise

Named because a privacy policy that describes features that do not exist is exactly as misleading as one that hides features that do.

11. Changes

If we change what the Platform collects, this document changes with it. We will tell customers before a change that affects them. [NEEDS ZACH: how much notice, and by what means, given that there is no email delivery yet.]


Last revised 8 October 2026. This is a draft. It has not been reviewed by a lawyer.