|
| 1 | +# MOBILE E2E GUIDELINES (PRODUCTION MOBILE ENGINEERING) |
| 2 | + |
| 3 | +**Scope:** React Native 0.75+, TypeScript (strict), offline-first, pure native modules, enterprise feature-first architecture. |
| 4 | +**Mode:** Guidelines only — no implementations or code. |
| 5 | + |
| 6 | +--- |
| 7 | + |
| 8 | +## A) PROJECT PRINCIPLES |
| 9 | + |
| 10 | +- Pure React Native (**no Expo**). |
| 11 | +- No Firebase **unless** added via RFC + security review. |
| 12 | +- No Tailwind/NativeWind/Styled Components — **pure RN theming** only. |
| 13 | +- Feature-first modular architecture under `src/features`. |
| 14 | +- Deterministic, typed, predictable code. |
| 15 | +- **No magic numbers** for spacing/colors/fonts (tokens only). |
| 16 | +- Reusable, theme-driven **UI Kit**. |
| 17 | +- Navigation **standardized** and **centralized**. |
| 18 | +- **State:** Zustand for global UI, **React Query** for server data only. |
| 19 | +- **API:** Zod-validated responses; pagination/caching/refetch via **React Query** only. |
| 20 | +- Offline storage — **MMKV** only (plus Keychain/Keystore for secrets). |
| 21 | +- Errors normalized globally. |
| 22 | +- Full CI/CD for iOS & Android; OTA (CodePush) with staged rollout + rollback. |
| 23 | +- **All third-party libs require RFC + security review.** |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## B) TOP-LEVEL STRUCTURE |
| 28 | + |
| 29 | +``` |
| 30 | +assets/ # fonts & svgs (no assets/index.ts), generated icons.ts |
| 31 | +scripts/ # build/release/codegen tools (e.g., generate-icons.js) |
| 32 | +ios/, android/ # native projects |
| 33 | +fastlane/ # lanes & metadata |
| 34 | +src/ # application code only |
| 35 | +``` |
| 36 | + |
| 37 | +### Deeper `src/` Layout |
| 38 | + |
| 39 | +``` |
| 40 | +src/ |
| 41 | + app/ # presentation layer (UI kit + navigation + cross-app hooks/state) |
| 42 | + components/ # stateless primitives (theme-based) |
| 43 | + hooks/ # cross-app hooks |
| 44 | + navigation/ # root/stacks/tabs, options/presets/tokens, modals (global/half-sheet) |
| 45 | + helpers/ modals/ options/ root/ stacks/ tabs/ types/ routes.ts index.ts |
| 46 | + state/ # cross-feature Zustand slices (global UI only) |
| 47 | +
|
| 48 | + features/ # feature packages (auth, user, home, settings, …) |
| 49 | + <feature>/ |
| 50 | + screens/ components/ hooks/ services/ stores/ |
| 51 | + models/ # Zod schemas + mappers |
| 52 | + api/ # query keys + endpoint defs |
| 53 | +
|
| 54 | + core/ |
| 55 | + config/ # app-config.ts, env.ts, feature-flags.ts, constants.ts |
| 56 | + i18n/ # i18n.ts, parser config, typed useT, locales (en/de/ru) |
| 57 | + native/ # device-info, haptics, permissions (JS wrappers) |
| 58 | + theme/ # tokens, light/dark, ThemeProvider, useTheme |
| 59 | + utils/ # cross-cutting utilities |
| 60 | +
|
| 61 | + infra/ |
| 62 | + error/ # normalize-error.ts |
| 63 | + http/ # axios.instance + interceptors + thin api.ts helper |
| 64 | + network/ # netinfo.ts (online/offline bridge) |
| 65 | + offline/ # offline-queue.ts, sync-engine.ts (replay) |
| 66 | + storage/ # mmkv.ts (KV abstraction), cache-engine.ts (snapshots) |
| 67 | + transport/ # adapters(rest/graphql/websocket/firebase), transport.ts, types |
| 68 | + query/ # client/provider, keys factory, policies, netmode, persistence (guidelines only) |
| 69 | +
|
| 70 | + types/ |
| 71 | + globals.d.ts # svg declarations for react-native-svg components |
| 72 | +``` |
| 73 | + |
| 74 | +> **Removed:** `_deprecated` folders; `assets/index.ts` does **not** exist. |
| 75 | +
|
| 76 | +--- |
| 77 | + |
| 78 | +## C) RESPONSIBILITIES & GUARDRAILS (BY AREA) |
| 79 | + |
| 80 | +### C1) Assets |
| 81 | +- **Fonts:** `assets/fonts/*`, registered per RN rules; referenced **only via theme tokens**. |
| 82 | +- **SVGs:** `assets/svgs/*`, rendered as components via `react-native-svg-transformer`. |
| 83 | +- **Icons Registry:** `assets/icons.ts` is **auto-generated** from `assets/svgs/*` by `scripts/generate-icons.js`. |
| 84 | +- **Import Paths:** **only** `@assets/svgs/...`. |
| 85 | +- **CI Guard:** job fails if `icons.ts` is stale vs `assets/svgs/**`. |
| 86 | + |
| 87 | +### C2) Theming & UI Kit |
| 88 | +- **Tokens:** spacing, radius, typography, elevation, **semantic colors** (light/dark parity). |
| 89 | +- **No inline** hex/spacing/fonts; use tokens everywhere. |
| 90 | +- **UI Kit:** `src/app/components/ui/` — stateless, theme-driven primitives; no business/API logic; static styles via `StyleSheet.create`. |
| 91 | +- Every screen is **theme-aware** (light/dark). |
| 92 | + |
| 93 | +### C3) Navigation |
| 94 | +- React Navigation v6+: **Root** (App/Auth/Onboarding + Modals/**Half-Sheet**) → **Stack** → **Tabs**. |
| 95 | +- **Presets:** base, header/back, full modal, half-sheet modal, tab options (**height 60px**, **no border**). |
| 96 | +- **Centralized routes:** `app/navigation/routes.ts` (as const) + typed ParamLists under `app/navigation/types`. |
| 97 | +- **Provider order:** **I18n → Theme → Query Provider → NavigationContainer** (policy). |
| 98 | +- Half-sheet rules: drag-to-close, velocity dismiss, backdrop tap closes, safe-area padding (guideline). |
| 99 | + |
| 100 | +### C4) State Management (Global UI) — **Zustand** |
| 101 | +- **Slices only** (e.g., `auth.store.ts`, `prefs.store.ts`); **no monolithic** store. |
| 102 | +- **What to store:** flags, enums, selected IDs, tiny derived booleans (e.g., `isLoggedIn`). |
| 103 | +- **What not to store:** server collections/entities (React Query owns server state). |
| 104 | +- **Actions:** atomic, predictable; **no side effects** inside store definitions. |
| 105 | +- **Selectors:** always **narrow**; avoid “whole slice” selectors. |
| 106 | +- **Persistence:** only **safe, small** bits (theme/locale) via MMKV; **no secrets/tokens** in Zustand persist. |
| 107 | +- **Logout:** reset slices + clear sensitive storage. |
| 108 | + |
| 109 | +### C5) Server State — **React Query (Guidelines Only)** |
| 110 | +- **Keys format:** `[feature, entity, id?, params?]` |
| 111 | + - Pagination: `[feature, entity, 'infinite', params]`. |
| 112 | + - Keys built via helpers (infra `query/keys` or feature `api/keys.ts`) — **never** in components. |
| 113 | +- **Freshness profiles:** |
| 114 | + - **realtime**: stale 0–5s; refetchOnFocus true; interval 5–15s **or** WS/Push invalidation. |
| 115 | + - **nearRealtime**: stale 30–120s; refetch on focus & reconnect. |
| 116 | + - **reference**: stale 1–24h; manual refetch only. |
| 117 | +- **Global defaults (policy):** stale ~60s, gc ~5m, retry: 2 (5xx/429 only), refetchOnReconnect true, throwOnError false. |
| 118 | +- **Network mode:** bridged from NetInfo (`online`/`offlineFirst`/`always`). |
| 119 | +- **Mutations:** must provide `meta.tags`; on success → **targeted invalidations** (detail + lists). |
| 120 | +- **Offline:** queue mutations; replay on reconnect; **invalidate by tags** (no global). |
| 121 | +- **Conditional requests:** ETag / If-Modified-Since when backend supports. |
| 122 | +- **Feature mapping:** `features/<feature>/api/keys.ts` keeps **tag → keys** mapping. |
| 123 | +- **Testing:** hooks/services cover keys, staleness, offline, invalidations. |
| 124 | + |
| 125 | +#### C5.1 Feature Policies (examples) |
| 126 | +- **Auth** |
| 127 | + - Keys: `['auth','me']`, `['auth','session']` → profile: **nearRealtime**. |
| 128 | + - Mutations → invalidation: |
| 129 | + - `auth.login` → invalidate `['auth','me']`, `['auth','session']` |
| 130 | + - `auth.logout` → clear all auth keys + drop persisted cache + navigate `ROOT_AUTH` |
| 131 | + - `auth.refreshToken` → invalidate `['auth','session']` if payload changed |
| 132 | + - 401/403: no retry; trigger logout/refresh outside Query. |
| 133 | +- **User** |
| 134 | + - Keys: `['user','byId', userId]` (**nearRealtime** or **reference**), `['user','list','infinite', params]` (**nearRealtime**). |
| 135 | + - Mutations → invalidation: |
| 136 | + - `user.updateProfile`/`updateAvatar` → invalidate detail + lists containing id |
| 137 | + - `user.create` → invalidate lists |
| 138 | + - `user.delete` → invalidate lists + drop local snapshots by id |
| 139 | + - Pagination: infinite only; reset on params change. |
| 140 | + |
| 141 | +### C6) Services & API |
| 142 | +- Feature services live under `src/features/<feature>/services`. |
| 143 | +- Services interact with API/Zustand/React Query; **never return raw DTO** — map to domain models. |
| 144 | +- **HTTP:** centralized Axios instance + interceptors (auth/error/logging), thin `api.ts` helper for trivial REST. |
| 145 | +- Authentication handled via interceptor; tokens stored in Keychain/MMKV. |
| 146 | +- Responses validated via **Zod**. |
| 147 | +- **Forbid:** `fetch` and inline axios in screens/components. |
| 148 | + |
| 149 | +### C7) Transport, Offline & Network |
| 150 | +- **Transport layer:** `infra/transport/transport.ts` with adapters: REST/GraphQL/WebSocket/Firebase. |
| 151 | +- **NetInfo:** `infra/network/netinfo.ts` toggles `transport.setOfflineMode`. |
| 152 | +- **Offline queue:** `infra/offline/offline-queue.ts` (FIFO mutations while offline). |
| 153 | +- **Sync engine:** `infra/offline/sync-engine.ts` replays on reconnect; stop on first fatal error; then **invalidate by tags**. |
| 154 | +- **Cache engine:** `infra/storage/cache-engine.ts` — in-memory snapshots (future MMKV/SQLite). |
| 155 | + |
| 156 | +### C8) Error Handling |
| 157 | +- Single normalization point: `infra/error/normalize-error.ts`. |
| 158 | +- **UI never sees raw API errors**; only normalized shape. |
| 159 | +- **ErrorBoundary is required** for fatal UI crashes. |
| 160 | +- Logging redacts sensitive info (Authorization). |
| 161 | + |
| 162 | +### C9) Native Modules |
| 163 | +- Swift/Kotlin under platform projects; JS wrappers in `src/core/native`. |
| 164 | +- Use only allow-listed native deps; permissions via `react-native-permissions`. |
| 165 | + |
| 166 | +### C10) Performance |
| 167 | +- Long lists → **FlashList** (`estimatedItemSize`, item type hints when needed). |
| 168 | +- Remote images → **FastImage**. |
| 169 | +- Avoid inline functions in render; memoize heavy components. |
| 170 | +- Lazy-load screens; preloading allowed; heavy tasks via **InteractionManager** after first paint. |
| 171 | +- Track **TTMI** (time to meaningful interaction) per screen. |
| 172 | + |
| 173 | +### C11) Security & Compliance |
| 174 | +- Tokens & secrets only in **MMKV/Keychain/Keystore**; configs via `react-native-config`. |
| 175 | +- Optional: clear sensitive data on background (product policy). |
| 176 | +- Device integrity checks (root/jail/emulator/debug flags) — informational guard. |
| 177 | +- No logging of sensitive data; sanitize outbound logs/analytics. |
| 178 | +- **All new dependencies via RFC + security review.** |
| 179 | + |
| 180 | +### C12) i18n |
| 181 | +- Typed i18n; feature namespaces; `useT` helper. |
| 182 | +- **Parity across locales** (`en`, `de`, `ru`); RTL readiness. |
| 183 | +- Parser in CI to catch missing keys. |
| 184 | + |
| 185 | +### C13) Testing |
| 186 | +- Coverage: UI components (snapshot + behavior), hooks, services, API, stores, navigation flows. |
| 187 | +- Deterministic: **no real IO** (network/storage/permissions mocked). |
| 188 | +- Mock assets/SVGs with component stubs. |
| 189 | +- Zod-validated fixtures for payloads. |
| 190 | +- Snapshots for simple UI only; behavior tests for logic. |
| 191 | + |
| 192 | +### C14) CI/CD & OTA |
| 193 | +- **CI (GitHub Actions):** lint → typecheck → test → Android AAB → iOS IPA; cache Gradle/Pods; upload artifacts. |
| 194 | +- **Guards:** |
| 195 | + - `check:icons` — `assets/icons.ts` freshness vs `assets/svgs/**`. |
| 196 | + - Import path policy — **no deep relatives**, use aliases only. |
| 197 | +- **Fastlane:** `gym`, `match`, `pilot` (iOS), `supply` (Android), version bump, screenshots, changelog. |
| 198 | +- **OTA (CodePush optional):** staged rollout, rollback rule, crash-rate threshold, native compatibility policy. |
| 199 | + |
| 200 | +### C15) Code Style |
| 201 | +- TS **strict**; named imports; default exports **only** for React components. |
| 202 | +- Functional components; hooks start with `use`. |
| 203 | +- Filenames: components **PascalCase**, hooks **camelCase**, stores/services **kebab-case**. |
| 204 | +- **No deep relative imports**; use absolute imports; ESLint + Prettier enforced in CI. |
| 205 | + |
| 206 | +### C16) Path Aliases & Types |
| 207 | +- `@assets/*` → `assets/*`; `@/*`, `@app/*`, `@features/*`, `@core/*`, `@infra/*`, `@types/*`. |
| 208 | +- `src/types/globals.d.ts` declares `*.svg` as react-native-svg components. |
| 209 | + |
| 210 | +### C17) Icons Generator & Tooling |
| 211 | +- `scripts/generate-icons.js` produces `assets/icons.ts` with `@assets/svgs/...` imports. |
| 212 | +- Run `npm run gen:icons` after SVG changes. |
| 213 | +- CI job fails if stale; husky pre-commit may run freshness & import-path guards. |
| 214 | + |
| 215 | +### C18) Non-Functional Requirements (NFR) |
| 216 | +- Accessibility on all interactive components (roles, labels, focus order, hitSlop, dynamic type). |
| 217 | +- Theming compliance (no raw values), **contrast QA** for light/dark. |
| 218 | +- Offline UX: cached data shows gracefully; pull-to-refresh always available. |
| 219 | +- **TTMI budgets** per screen; perf budgets tracked. |
| 220 | +- Security checklist per feature (secrets, logging, storage). |
| 221 | +- Documentation governance: ADR/RFC templates; CI checks guide freshness. |
| 222 | + |
| 223 | +### C19) AI Agent Rules |
| 224 | +- **MUST:** follow folder structure & theme system; use UI Kit only; TS strict; typed navigation; provide full file paths when outputting code; ask for missing context. |
| 225 | +- **MUST NOT:** add new deps; break structure; use inline styles (except dynamic); use `fetch`; use Redux/Tailwind/NativeWind; use Expo. |
| 226 | + |
| 227 | +--- |
| 228 | + |
| 229 | +## D) “WHAT SHOULD BE DONE” (ACTIONABLE ROADMAP — GUIDELINES ONLY) |
| 230 | + |
| 231 | +1. **UI Kit Hardening** — add required primitives (Input, Card, Spacer, Divider, Icon, Avatar, Badge, Loader); document token usage; accessibility rules. |
| 232 | +2. **Cross-cutting Hooks** — `useOnlineStatus`, `useAppLaunch`, `useToast`, `useSafeAreaScroll` (design & contract only). |
| 233 | +3. **Zustand** — define cross-feature slices (theme/locale); persist safe bits via MMKV; narrow selectors; logout reset policy. |
| 234 | +4. **React Query Policies** — finalize freshness/retry matrices; keys factory usage; tag→keys mapping per feature; persistence & netmode policies documented. |
| 235 | +5. **Domain Services** — auth/user contracts (schemas + mappers + error mapping); pagination spec (infinite keys & merge rules); auth lifecycle (attach/refresh/revoke). |
| 236 | +6. **HTTP Policies** — timeouts, headers, retry/backoff matrix (5xx/429 only), idempotent mutation guidance. |
| 237 | +7. **Transport ADR** — when to use REST/GraphQL/WebSocket/Firebase; how to route operations; offline queueing expectations. |
| 238 | +8. **Offline Playbook** — queue triggers, replay strategy, conflict resolution policy (default: last-write-wins; feature overrides allowed), TTL per resource. |
| 239 | +9. **Error Taxonomy** — codes/classes → user messages; toast/snackbar policy; redaction. |
| 240 | +10. **Navigation Governance** — route naming, presets, deep linking, analytics screen names; half-sheet/modal rules. |
| 241 | +11. **i18n** — namespaces per feature; parser in CI; parity across `en/de/ru`; RTL readiness. |
| 242 | +12. **Testing Matrix** — across layers; deterministic; fixtures validated by Zod; asset/SVG mocks policy. |
| 243 | +13. **CI/CD** — ensure guards (`check:icons`, import path policy) & artifacts; staged vs prod lanes with promotion gates; secrets via env only. |
| 244 | +14. **Security** — sensitive data redaction, device integrity checks, config via env, key rotation doc. |
| 245 | +15. **Performance** — FlashList for lists; FastImage for remote images; memoization; InteractionManager; TTMI budgets per screen. |
| 246 | +16. **Documentation & Governance** — ADR/RFC templates; CI doc freshness check. |
| 247 | + |
| 248 | +--- |
| 249 | + |
| 250 | +## E) PR CHECKLISTS |
| 251 | + |
| 252 | +**React Query PR Checklist** |
| 253 | +- [ ] Keys via `api/keys.ts` (not in components). |
| 254 | +- [ ] Freshness profile from `policy/freshness.ts` (no magic numbers). |
| 255 | +- [ ] Mutations include `meta.tags`; `api/keys.ts` contains tag→keys mapping. |
| 256 | +- [ ] Zod validation before caching. |
| 257 | +- [ ] Normalized errors only. |
| 258 | +- [ ] Infinite pagination only. |
| 259 | +- [ ] Offline behavior & post-replay invalidations defined. |
| 260 | + |
| 261 | +**State & Stores PR Checklist** |
| 262 | +- [ ] One responsibility per slice; no monolithic store. |
| 263 | +- [ ] Actions atomic; no side effects in store definitions. |
| 264 | +- [ ] Narrow selectors; components subscribe to specific fields. |
| 265 | +- [ ] Persist only safe bits; secrets elsewhere. |
| 266 | +- [ ] No duplication of server data (Query is source of truth). |
| 267 | +- [ ] Logout resets slices + clears sensitive storage. |
| 268 | + |
| 269 | +**Navigation PR Checklist** |
| 270 | +- [ ] Routes from centralized `routes.ts`. |
| 271 | +- [ ] ParamLists typed; presets used (base/header/back/full/half/tab). |
| 272 | +- [ ] Half-sheet/modal follow gesture/backdrop/safe-area rules. |
| 273 | +- [ ] Provider order respected (I18n → Theme → Query → Nav). |
| 274 | + |
| 275 | +**Assets & Theming PR Checklist** |
| 276 | +- [ ] No raw colors/spacing/fonts; tokens only. |
| 277 | +- [ ] SVGs via `@assets/svgs/*`; `icons.ts` updated (`gen:icons`). |
| 278 | +- [ ] Contrast compliance (light/dark). |
| 279 | + |
| 280 | +**Security & NFRs PR Checklist** |
| 281 | +- [ ] No sensitive logs; secrets in env; tokens in secure storage. |
| 282 | +- [ ] Offline UX acceptable; TTMI budget met. |
| 283 | +- [ ] i18n keys exist with locale parity. |
0 commit comments