# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What this is

A cross-platform (iOS / Android / web) **time-tracking app for insole (orthotics) production**, built on the **"Create" / Anything AI** platform and exported to run locally. The UI is in **Dutch**. The user picks an insole type (`Type zool`: Kurk / Berk / 3D), a handling/task (`Type handeling`), and a count (`Aantal zolen`, default 2), then runs a stopwatch (start / pause / stop & save / double-press discard). History is exportable to CSV (nl-BE locale, `HH:MM:SS` durations); the Settings tab manages handelingen per zooltype.

**This repo is frontend-only.** The backend API routes (`/api/tasks`, `/api/logs`) and the database (`production_tasks`, `time_logs` tables) live on the remote Create web app, reached via `EXPO_PUBLIC_BASE_URL` (see `apps/mobile/.env`). Editing tasks/history happens against that remote DB, not in this code.

## Layout

- Yarn 4 (Berry) monorepo, `node-modules` linker. Workspaces = `apps/*`; only **`apps/mobile`** (the Expo app) exists.
- **`publisher/`** is NOT a workspace — it's a standalone OpenNext + AWS S3 tool (its own `yarn.lock`) for building/deploying the Next.js *web* side. Rarely touched.

## Commands

Run from the repo root unless noted. There are no `start`/`lint`/`test` npm scripts — invoke the tools directly.

```bash
yarn install                       # install (Yarn 4)
npx oxlint                         # lint (config: .oxlintrc.json) — this is the real linter
npx oxfmt                          # format (config: .oxfmtrc.json) — 2-space, single-quote, semi, width 100

cd apps/mobile
npx expo start                     # dev server; press a/i/w or scan the QR with Expo Go
npx expo start --web               # web target only
npx tsc --noEmit                   # typecheck (strict; @/* -> src/*)
yarn jest                          # all tests (jest-expo preset)
yarn jest src/utils/iap/__tests__/useInAppPurchase.test.ts   # single file
yarn jest -t "name"                # single test by name

eas build --profile <development|preview|production> --platform <android|ios>   # native builds (eas.json)
```

> `eslint` / `typescript-eslint` are in devDeps but there is **no eslint config** in the tree — use **oxlint**, not eslint.

## Architecture (the parts that span files)

- **Routing:** Expo Router, file-based under `apps/mobile/src/app/`. `_layout.tsx` is the root: it gates render on `useAuth().initiate()` + `isReady` (loads the persisted session before showing anything) and provides the React Query client. `(tabs)/` holds the three screens — `index.tsx` (Stopwatch), `history.tsx` (Geschiedenis), `tasks.tsx` (Instellingen).
- **Platform vs web entry points are split by file extension.** Native: `index.tsx` → `entrypoint.ts` → `App.tsx`. Web: `index.web.tsx` → `App.web.tsx`. The `.web.*` files add sandbox-iframe plumbing (postMessage handshake, navigation sync, screenshot capture, healthcheck) used by the Create preview panel — this is why the web root looks very different from the native one.
- **Global `fetch` is monkey-patched.** `src/__create/polyfills.ts` replaces `global.fetch` with `src/__create/fetch.ts`, which rewrites first-party (`/...`) URLs onto `EXPO_PUBLIC_BASE_URL`, injects project/host headers, and attaches the SecureStore JWT. App code calls `fetch('/api/...')` and relies on this. For explicit auth, `src/utils/auth/getSession.ts` exposes `authFetch` (better-auth bearer JWT).
- **Web support is achieved via Metro module aliasing**, not separate web code. `apps/mobile/metro.config.js` `resolveRequest` swaps a large set of native modules for stubs in `polyfills/web/` when `platform === 'web'` (and a few in `polyfills/native/`, plus dev-only stubs like `react-native-purchases` outside production). **Consequence: adding a native dependency that gets imported on web requires adding a web polyfill alias here, or the web build breaks.**
- **Styling:** NativeWind/Tailwind config extends `@anythingai/app/tailwind.config`, but the screens themselves mostly use React Native `StyleSheet`/inline styles. Inter is the font.
- **Environment gating:** `EXPO_PUBLIC_CREATE_ENV` (`PRODUCTION` / `DEVELOPMENT`) and `__DEV__` gate analytics, Sentry, the in-app "anything-menu", and dev-only native aliases. Real native SDKs only load in production builds.

## Conventions & gotchas

- **Do not edit platform-managed files.** Files under `apps/mobile/__create/` and `apps/mobile/src/__create/`, and the auth files in `src/utils/auth/` (`useAuth.ts`, `getSession.ts`, etc.), carry `⚠ ANYTHING PLATFORM — DO NOT REWRITE` headers. They define the public auth surface (`signIn`/`signUp`/`signOut`/`auth`/`isAuthenticated`/`isReady`) and the fetch/sandbox plumbing; rewriting them breaks auth or the Create preview. `src/app/_layout.tsx` is editable except for the `<AuthModal />` render and the `initiate()` + `isReady` gate.
- **Do not bump patched dependencies.** `react-native`, `expo-router`, `expo-store-review`, `react-native-purchases(-ui)`, `@expo/cli`, `@react-native-community/netinfo`, and others use `patch:` entries in `package.json` backed by `.yarn/patches/`, pinned further by root `resolutions`/`overrides`. Upgrading them discards the patch and breaks the app. When running `npx expo install --fix`, skip any package marked `patch:`.
- This is an exported template: package versions are pinned exact (no `^`) deliberately. Prefer minimal, targeted changes.
