AdaptivMapr

Your data

Schema-only: the header row and three clamped rows pass; the rest of the file stays

The cascade holds nothing between calls — but the product around it has an account, a wallet, an audit trail and your uploads. Here is what each of those is, which store it sits in, how long it survives, and exactly what happens when you press delete.

Schema-only: the header row and three clamped rows pass; the rest of the file staysheadersclamp≤3 rows · ≤80 chars

What we store

Six categories, and nothing else.

The cascade itself is pure compute — it holds no state between calls. The deployed product around it does: an account, a wallet, an audit trail, and your uploads for as long as you need to finish an import.

Account email

Your email address is the only identifier we collect. It is held by Supabase Auth and written to the tenant record on first sign-in. There is no password to store — there is none.

Identityauth.users.id → tenants.id, populated by a handle_new_user trigger that also writes your tenant_members row. Dashboard reads then run on your own user JWT, so row-level security is the gate rather than application code.

Sign-in & sessions

Sign-in runs through Supabase Auth — Google OAuth, or a single-use email link / one-time code. Your session lives in short-lived cookies Supabase issues and refreshes.

Uploaded files & mappings

Files are parsed in memory and the parsed upload is stored in Cloudflare KV under a native expiry taken from your workspace retention setting, mirrored to Supabase for the same window. In schema-only mode only column headers and up to three sample values (≤80 characters each) are retained.

API keys

v1 keys are HMAC-signed and self-contained: verification needs no lookup, and we store only an identifier used for revocation. The full key string is shown once at creation and never persisted.

Why it mattersVerification is a signature check plus a revocation read — a leaked database row cannot mint a key, because the row never contained one.

Usage & audit trail

Request metadata (timestamp, endpoint, status, duration, billed units) and a hash-chained audit log of key creation, revocation, commits and billing events. The audit log is retained for seven years to meet billing and accounting law — above the six-year HIPAA minimum — and edge request logs for fourteen days.

Billing data

Stripe holds your card details — we never see them. We store the Stripe customer id, your prepaid wallet balance and invoicing metadata, plus a billing address and VAT number if you supply them. Pricing is a prepaid token wallet, so there is no stored payment instrument to charge on a schedule.

We do not collect biometric data, precise geolocation, behavioural analytics, or advertising identifiers. See §2 of the Privacy Policy for the complete list.

  • Uploads in KV, on a TTL you set
  • RLS tenant isolation
  • HMAC self-contained API keys
  • Headers + ≤3 rows in schema-only
  • Hash-chained audit_logs

Where it lives

Every row has a store, a clock, and a reader.

“We don’t keep anything” is not a claim we make. This is the actual map: which system holds each thing, how long it survives there, and which identity is allowed to read it back.

WhatRetentionWho can read it
Parsed uploads (may contain PHI)Cloudflare KV (MAPR_KV), mirrored to Supabase0, 24, 168 or 720 h — 24 by defaultService role, tenant-scoped
Account, wallet, workspace settingsSupabase PostgresLife of the workspace, plus 90 daysYour user JWT, under RLS
API keysHMAC-signed, self-containedUntil you revoke themNobody — we store no key
Audit trailSupabase audit_logs, hash-chained and append-only7 years live · 2 years once the workspace is goneYou, and whoever you export it to
Billing recordsStripe + Supabase metadataStripe’s own; our metadata dies with the workspaceStripe holds the card
Edge request logsCloudflare14 daysOperations, metadata only
Retention figures are /legal/privacy §7 and /legal/security §; the upload window is your own retention_hours setting, written straight into the KV expirationTtl. Uploads (PHI), connectors (secrets) and the v1 bearer API run service-role with explicit tenant_id scoping; the dashboard plane runs on your user JWT so RLS enforces isolation in the database rather than in application code.

Two modes

Most imports never send a single row of data.

Schema-only and full-data are two modes of the same cascade, not two tiers of a plan. Both draw the same small flat per-map fee; only one of them can see a row.

Schema-only — data minimization

Only column headers and at most three sample rows, each clamped to 80 characters, ever leave your tenant, and the same clamp is re-applied at the model boundary. It is a mode, not a tier: most columns resolve before any model is consulted, and a DPA is usually unnecessary (one is provided on request).

EnforcedThe clamp is applied at the HTTP edge in every route that accepts sample rows, and re-applied defensively at the LLM boundary. One chokepoint, clampForSchemaOnly() in lib/parser.ts.

Full-data — in-region, under a BAA

Row-level AI cleanup goes to phi-cloud with X-PHI and X-Region set, so the gateway forces a PHI-eligible, in-region model. It costs 20% more on the whole map charge, and it is locked until your workspace accepts the BAA/NDA in the app.

GatedAn explicit PHI request without an acceptance returns 403 agreement_required with a pointer to Settings → Security & Data. There is no silent downgrade to the general catalogue.

PHI routing is off by default: an unconfigured workspace runs standard. Turning it on is an explicit opt-in in Settings → Security & Data, in the same place you accept the BAA/NDA. See how the wallet is charged and how one run resolves its routing.

Erasure

Two buttons, one implementation.

“Delete workspace” and “Delete account” destroy the same thing and run the same code path. They used to be two implementations that had drifted — one of them skipped the audit event, the KV purge and the cache clears, and returned success after a failed delete. There is now one.

  1. 1Audit event first

    The erasure intent is written and awaited BEFORE anything is destroyed, so the chain captures it even if a later step fails.

  2. 2Supabase cascade

    Uploads, connectors, rate-limit counters and stored chats are deleted explicitly, then the tenant row — which cascades to api_keys, mapping_statistics, tenant_members and audit_logs.

  3. 3KV purge

    Every upload id from the Supabase list is purged from Cloudflare KV by its canonical key, along with the known per-workspace cache entries.

  4. 4In-process caches cleared

    Entitlements, connectors, workspace settings and agreement caches are invalidated so a warm Worker isolate cannot revive a deleted row.

  5. 5Notification email

    A destructive-action email is queued through the Worker’s waitUntil so it still lands after the response has flushed and the tenant row is gone.

  6. 6No false success

    Neither route may report success when the tenant delete did not happen. A failed erasure returns an error, never “Account deleted.”

bash
# Two buttons, one implementation (lib/workspaceErasure.ts).
# Both require a CSRF token AND a server-side confirmation string.

curl -X DELETE https://adaptivmapr.com/api/v1/me/workspace \
  -H "X-CSRF-Token: $CSRF" \
  -H "content-type: application/json" \
  -d '{"confirm":"delete-my-workspace-<workspace_id>"}'

# The account button is the same cascade behind a different phrase:
curl -X DELETE https://adaptivmapr.com/api/auth/account \
  -H "X-CSRF-Token: $CSRF" \
  -H "content-type: application/json" \
  -d '{"confirm":"delete my account"}'
→ tenant_deleted · uploads purged from KV · audit event written first

You do not need curl: the same cascade runs from Dashboard → Settings → Account, which asks you to type the confirmation phrase first. Audit records required by billing and accounting law are retained for seven years; everything else is destroyed immediately. If you cannot reach the dashboard, email dpo@adaptivmapr.com from the registered address with the subject Account deletion request. We action it within one month.

Export & rights

Portability, access, correction — on request, in a month.

You have the right to receive a copy of your personal data in a machine-readable format (GDPR Art. 20 / nFADP Art. 25), and to access, correct, restrict or object to our processing of it.

Self-serve

Sign in at /dashboard to review your API keys, usage, audit trail and workspace settings. Uploaded files stay reachable in Chat for as long as your workspace retention setting keeps them.

Structured export

For a JSON export of everything we hold — account record, mapping history, billing metadata — email dpo@adaptivmapr.com with the subject Data export request. We respond within one month.

The complete list of rights is in §8 of the Privacy Policy. AdaptivMapr is HIPAA-ready — we offer a BAA and hold a HIPAA security risk assessment on file — and SOC 2 Type II is in progress, with no attestation report yet. HIPAA is not a certification anyone can hold, so we do not claim one.

Ask us anything about your own data.

Our data protection officer answers directly. If you need the DPA, the subprocessor list, or a BAA before you can evaluate, ask and we will send it.

Your Data — AdaptivMapr — AdaptivMapr