Skip to main content

Data ownership

The shop owns every byte of customer, transaction, and inventory data Helm holds. Kvick is the operator of the software; the shop is the owner of the contents. This is the difference between a service and a hostage situation, and we are clear which one Helm is.

Drafted from planning · v0.1

The shortest version

  • Any shop can export all its data, in machine-readable form, on demand. Always free, no support ticket required.
  • If a shop leaves Kvick, they keep their data. Their D1 is exported, their R2 is bundled, the export is handed over, then the deployment is destroyed.
  • A customer of the shop can request their data be deleted; the shop honors the request through a Helm flow that respects audit trail constraints (keep the audit record, scrub the PII).
  • Kvick uses no shop's data for anything except operating that shop's software. No cross-shop analytics, no AI training, no marketing.

Why this matters

Bike shops have been burned by previous POS vendors. AIM doesn't export cleanly — its 12-table mess of cross-references and proprietary fields means leaving is a years-long migration. Lightspeed gates exports behind "data services" upcharges. Square owns the transaction record entirely.

Helm pitches itself as the opposite. The shop's data is theirs, in formats they can actually use, available without negotiation. This is partly an ethical position; it's also a competitive position. A POS that's trivial to leave is a POS that doesn't need to lock you in to be worth using.

The owner's bundle

At any time, the shop owner can request a full export. They receive:

  • db.sql — full D1 dump, schema + data. Restorable in any SQLite environment.
  • db.csv/ — every table as a CSV, for non-SQL tools (Excel, Quickbooks importers).
  • assets/ — every R2 object (receipts, photos, audit archives) in the original directory structure.
  • schema.md — a markdown description of every table and column (rendered from this bible's reference section).
  • README.md — instructions for "what to do with this bundle" — re-importing into a fresh Helm install, importing the CSVs into Lightspeed (the only competitor we have docs for), or just archiving.

The bundle is a .tar.gz. Generation runs on-demand via a button in Settings → Data; the file lands in the shop's R2 bucket with a signed URL that expires in 7 days. Large shops (years of history) might take an hour to generate; small shops finish in seconds.

Customer-side data subject rights

The shop's customers (the people who walk in to buy bikes) also have rights. Helm provides the workflow; the shop is the data controller and decides whether to grant each request.

Right to access: Helm exports one customer's record set (their profile, transactions, tickets, messages, attached photos) as a PDF + JSON. Available from the customer profile via a "Data export" button.

Right to erasure: The customer profile has a "Delete on request" button. The flow:

  1. Confirms intent and identity verification (per shop policy).
  2. Scrubs PII fields (name → "Deleted Customer", phone → null, email → null, address → null, photo links → null) but keeps the row and its IDs.
  3. Updates references in transactions, service_tickets, etc. to point to the scrubbed customer record. Aggregate financial history remains.
  4. Audit-logs the deletion request and the staff member who processed it.
  5. Records the customer's deletion_requested_at and deleted_at timestamps for shop records.

The reason we scrub rather than DELETE rows: the financial audit trail has legal-retention requirements (CRA + provincial). Deleting a transaction row breaks audit-chain integrity. Scrubbing the customer linked to it preserves both the customer's privacy and the audit's correctness.

Right to portability: Same as access, in JSON form. The customer can hand it to another provider if there is one (rare).

Right to opt out of AI: A toggle on the customer profile. When set, the AI Support bubble does not include this customer's identifying data in any Claude API call. See AI integration.

What Kvick does not do with shop data

  • No cross-shop analytics that identify individual shops or customers. Aggregate trends across shops (anonymized) are fair game eventually for product decisions, only with shop consent, never default-on.
  • No AI training on shop data. The Claude API calls we make do not contribute to Anthropic's model training (Anthropic's enterprise policy guarantees this for our usage).
  • No marketing to the shop's customers. Helm does not have a customer-facing email list. The shop's customers are the shop's relationships.
  • No selling data to third parties. Ever.
  • No use of shop data to inform competitors. If we eventually have shops competing in the same town, we do not surface "your competitor just got a new product line" insights from one shop's data to another.

What happens when a shop leaves

The exit ramp is built into the contract and the code:

  1. Shop owner requests termination.
  2. Helm generates the full data bundle (above) and delivers it to the owner.
  3. Owner confirms receipt and acceptable state.
  4. The Worker is decommissioned (wrangler delete helm-{shop}), the D1 database is deleted (wrangler d1 delete helm-{shop}-db), the R2 bucket is emptied and deleted.
  5. The shop branch in git is archived (shops/{shop}-archived-2026-12) but not deleted, so the deployment history is preserved for Kvick's records.
  6. The shop's Stripe sub-account is detached. The shop's Twilio sub-account is detached or kept (depending on whether the shop wants to keep their number).

The goal: a shop should be able to leave Kvick and be back to "AIM, Lightspeed, or Square" within a week, with all their history.

The deal with the bible itself

The bible is Kvick's, not the shop's. It's the engineering documentation of the platform, not anything specific to the shop. The shop does not get a copy of the bible when they leave (though it'll likely become public someday).

What this principle means for code

When designing a new feature, ask: does this give the shop more control over their data, or less? More wins.

When designing a schema, ask: can this row be exported cleanly? Foreign keys to data we can also export, fine. Foreign keys to Kvick-managed external systems (Stripe IDs, Twilio SIDs), include them as IDs in the export and let the shop deal with the external lookup.

When designing an external integration, ask: does this give the shop or the integration partner the source-of-truth role? If it's the integration partner, the shop's leaving us means leaving the partner too. We prefer Helm to be the source-of-truth and the integration to be a syncer.

See also