# AGENTS.md ## Project МојМајстор — Expo React Native app connecting handymen with customers in Macedonia. Self-deployed Convex backend. All UI text in Macedonian; code variables and comments in English. ## Tech Stack - **Frontend:** Expo SDK 56, React Native 0.85, TypeScript, Expo Router (file-based routing), inline styles (no NativeWind/Tailwind) - **Backend:** Convex (self-deployed at `https://backend-onhwnh06p0g3976vl34yx18v.testbed.mk:3210`) - **Auth:** Custom email/password with SHA-256 (Convex actions), stored in `accounts`/`sessions` tables — no @convex-dev/auth (incompatible with self-hosted) - **Deployment:** EAS Build + Update ## Convex Setup - Deploy with: `npm run convex:dev` or `CONVEX_DEPLOYMENT="" npx convex dev --url https://backend-onhwnh06p0g3976vl34yx18v.testbed.mk:3210 --once` - Self-deployed Convex does **not** support `searchIndex` — use `.filter()` for search instead - Self-deployed Convex does **not** support `@convex-dev/auth` — custom auth via `convex/auth.ts` - Auth env vars already set: `AUTH_SECRET`, `AUTH_SECRET_1`-`AUTH_SECRET_10`, `AUTH_URL` ## Key Conventions - **Language split:** Macedonian for all user-facing text, English for code - **Role system:** `handyman` | `customer` — set at registration. Handymen create ads; customers create posts; both can chat - **Auth token:** Stored in localStorage, passed to Convex queries/mutations as `token` argument. Verified server-side via `sessions` table - **Styling:** Inline styles only, using `useTheme()` hook from `components/theme.tsx`. No NativeWind, no StyleSheet.create - **Convex paths:** `convex/` — one file per domain. Schema in `convex/schema.ts`. Never edit `convex/_generated/` ## Route Structure ``` app/ _layout.tsx — Root: ConvexProvider + ThemeProvider + AuthContext + ErrorBoundary (auth)/ login.tsx — Email/password login register.tsx — Role selection (handyman/customer) + profile creation (tabs)/ (home)/index.tsx — Home: search + categories + recent ads (explore)/index.tsx — Browse categories & filtered ads (posts)/index.tsx — Customer needs feed (open/all tabs) (chat)/index.tsx — Chat list (profile)/index.tsx — User profile, my ads/posts ad/ [id].tsx — Ad detail with reviews & chat button create.tsx — 4-step ad creation form post/ [id].tsx — Post detail with respond button create.tsx — Create customer need chat/ [id].tsx — Chat conversation review/ create.tsx — Star rating + review form ``` ## Commands ```bash npx expo start # Dev server npm run convex:dev # Convex backend dev CONVEX_DEPLOYMENT="" npx convex dev --url $URL --once # Deploy once npx tsc --noEmit # Type check ``` ## Constraints - Max 5 images per ad (stored as string IDs in schema, not `_storage` refs) - All timestamps are `Date.now()` milliseconds - Roles stored as `v.string()` (not `v.union(v.literal(...))`) due to self-deployed Convex compatibility - `useAuth()` export from `app/_layout.tsx` provides `{ token, userId, isAuthenticated, login, logout }` - Deep links: `mojmajstor://ad/[id]`, `mojmajstor://chat/[id]` ## Full Plan See `implementation.md` for phased implementation details and data model.