Security & tenancy

Structural, not procedural.

The controls below are properties of the schema. They hold whether or not somebody remembers them, which is the only kind of control worth putting on a page like this. Where something is an open question, it says so.

Tenancy

A cross-tenant reference is structurally impossible.

Every table carries a club identifier, and foreign keys are composite — they include that identifier. A row in one club cannot reference a row in another, because there is no valid key that would let it.

Row-level security sits on top of that as defence in depth, enforced by the database against a restricted role rather than by a filter in application code that somebody might forget to add to the next query.

The distinction matters: filtering by club in the application is a convention, and conventions get broken by the hundredth endpoint. A composite foreign key is a constraint, and constraints do not have a hundredth exception.

The ledger itself

Append-only, and nobody is exempt.

No edits, no deletes

A posted entry cannot be modified or removed by any user, any role, or a superuser at a database prompt. Corrections are reversing entries, which is what an audit expects to see anyway.

Enforced by the database

Constraints and triggers, not application logic. A future integration, a data-fix script or a migration cannot quietly write an unbalanced entry.

Proven by tests that try to break it

299 SQL invariant assertions across six suites exist for one reason: to attempt the bad case and confirm the database refuses it. Plus 134 end-to-end API tests, so invariant violations surface as clean errors rather than as a stack trace.

Card data

No card number ever reaches us.

Card entry happens on Stripe Terminal hardware, and Stripe owns the PCI scope for it. BetterClub receives a reference to a payment, never a card number — and the architecture is designed so that touching one is not a policy we follow but a thing the system has no path to do.

Practically, this is what a club's insurer and its IT contractor both want to hear: the club's software vendor is not a place a card number can leak from, because it is not a place a card number goes.

Deployment

Multi-tenant cloud, or your own server.

Multi-tenant cloud is the default and is what we would recommend to almost every club. It is the deployment that gets updates first and costs least to run.

A dedicated single-tenant install exists for boards that will not be talked out of it. It is the same artifact with different configuration — not a code branch — which is the engineering rule that keeps it viable to offer at all. Set the deployment mode and the club identifier; nothing else changes, and a validly signed token for any other club is refused outright.

  • Same image, both tiersThe dedicated install is not a fork, so it does not fall behind on fixes.
  • Tokens are scoped to one clubOn a dedicated install, a token for any other club is rejected even if the signature is valid.
  • Row-level security is enforced against a restricted roleConnecting as the owner would make it decorative. We do not.
Open questions

Things we have not decided, said plainly.

A trust page that only lists strengths is not a trust page. These are live and unresolved, and if one of them is a blocker for your club we would rather find out now.

  • EU data residency is not decidedWe do not offer an EU region and we are not going to promise a date for one on a marketing page. If a club needs data to stay in the EU, raise it early — it is commercially important to us and the answer today is honestly "not yet."
  • Certified fiscalization devices are not builtThe schema holds the fields they need — signature, provider, QR payload, export status — so they can be scoped when a deal in that market is real. Germany, France, Portugal and Saudi Arabia each require their own dialect of this.
  • E-invoicing transport is not builtPeppol, SdI, KSeF and ZATCA are integrations, not migrations. Same position as above.
  • The full AP approval workflow is not builtAccounts payable ships as a phase-one stub. If your club runs a formal purchase-approval chain today, it will not find it here yet.

Send your IT contractor.

They tend to have better questions than we have pages, and we would rather answer them on a call than have them guess from a datasheet.