# BJJ Travel maps the ARD onto this template

The repository's architectural decision, rationale and consequences.

# BJJ Travel maps the ARD onto this template

**Status:** accepted · **Date:** 2026-11-13 · **Related:** [ADR-0017](0017-own-hex-map-without-postgis.md), [ADR-0018](0018-location-is-city-and-window.md), [ADR-0019](0019-instructor-and-academy-are-organizations.md), [ADR-0020](0020-eu-hosting-on-cloudflare-and-neon.md), [ADR-0021](0021-jobs-on-the-cron-tick-and-leased-queue.md), [ADR-0022](0022-adapters-with-fakes-and-money-in-config.md), [ADR-0023](0023-ui-languages-pt-en-de.md)

**Enforcement:** `[convention]` — this ADR is an index; each linked ADR names its own checks.

The product package in `docs/bjj-travel/` (ARD section, ADR-01…ADR-07) was written for PostgreSQL + PostGIS + Drizzle, a Postgres queue (graphile-worker or pg-boss) with isolated workers, Stripe Connect and Hetzner in Germany. This repository is the `template-cloudflare` monorepo: TanStack Start on one Cloudflare Worker, Expo, oRPC, Better Auth, Drizzle on Neon, R2, a one-minute cron tick with leased queue jobs, and row-level security per Organization.

## Decision [#decision]

Keep the product ADRs where the template already agrees and record each deviation as its own ADR:

| Product ADR                                           | Template                                              | Outcome                                                                        |
| ----------------------------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------ |
| ADR-01 Expo + RN, expo-sqlite, Skia                   | Expo SDK 58, Skia 2.14 and react-native-svg installed | kept; offline store decided per story (S5/S6)                                  |
| ADR-02 TanStack Start for web and API                 | TanStack Start + oRPC on one Worker                   | kept; "server functions" are oRPC procedures (`createServerFn` is banned here) |
| ADR-03 Postgres + PostGIS, queue in Postgres          | Neon + Drizzle, cron tick + leased jobs               | deviates → ADR-0017, ADR-0020, ADR-0021                                        |
| ADR-04 Own hex map, no tiles                          | —                                                     | kept → ADR-0017                                                                |
| ADR-05 Location = city + window                       | —                                                     | kept → ADR-0018                                                                |
| ADR-06 Stripe Connect, separate charges and transfers | Stripe/Polar/RevenueCat behind `BILLING_PROVIDERS`    | kept; Connect is a new adapter → ADR-0022                                      |
| ADR-07 AI suggests, rules decide                      | Assistant + Tool catalog                              | kept; deterministic `*.rules.ts` leaves own dates and money → ADR-0022         |
| Hetzner (Germany)                                     | Cloudflare Workers                                    | deviates → ADR-0020                                                            |

## Consequences [#consequences]

- The domain lives in `packages/api/src/features/<feature>/` with the template's roles (ADR-0011): `instructor`, `atlas`, and later `network`, `route`, `tour`, `outreach`, `seminar`, `academy`, `privacy`.
- Every product number that is a hypothesis (split, deposit, fee, payout delay, cancellation window) lives in one leaf (`instructor.rules.ts` → `MONEY_HYPOTHESES`).

