|
1 | 1 | # Ruffl mobile app |
2 | 2 |
|
3 | | -Ruffl is an Expo/React Native mobile app for iOS and Android. The codebase is TypeScript with Expo Router, which keeps navigation and business-facing screens consistent across both platforms. |
| 3 | +Ruffl is the iOS and Android application used by commissioners and makers. This repository contains only the mobile client. It connects to the separate `Ruffl-Backend` repository for accounts, maker profiles, commissions, messages, warnings, and disputes. |
4 | 4 |
|
5 | | -## Why this stack |
| 5 | +This guide assumes you have not used React Native, Expo, or a mobile emulator before. |
6 | 6 |
|
7 | | -- One maintainable codebase for iOS and Android |
8 | | -- Fast physical-device testing through Expo Go during early development |
9 | | -- A clear path to production development builds when native notification, monitoring, and upload integrations are enabled |
10 | | -- Strict TypeScript plus separately testable domain helpers |
11 | | -- Secure device storage for the bearer token through Expo SecureStore |
| 7 | +## Technology in plain English |
12 | 8 |
|
13 | | -## Install packages |
| 9 | +- **React Native** lets the project build Android and iOS interfaces from one codebase. |
| 10 | +- **Expo** supplies the development server and mobile tooling around React Native. |
| 11 | +- **Expo Go** is a phone app that can open Ruffl during early development without creating an app-store build. |
| 12 | +- **Expo Router** turns files under `app/` into screens and navigation routes. |
| 13 | +- **TypeScript** is JavaScript with additional checks that catch many mistakes before the app runs. |
| 14 | +- **npm** downloads the libraries listed in `package.json` and runs the commands under `scripts`. |
| 15 | +- **Environment variables** are local settings, such as the backend address, which should not be hard-coded into the application. |
14 | 16 |
|
15 | | -Requirements: |
| 17 | +## Repository structure |
16 | 18 |
|
17 | | -- Node.js 20.19 or newer; Node 22 LTS is recommended |
18 | | -- npm |
19 | | -- Expo Go on an Android or iOS phone for the quickest local test |
| 19 | +```text |
| 20 | +Ruffl-Frontend/ |
| 21 | +|-- app/ Screens and navigation routes |
| 22 | +|-- src/api/ Backend request client |
| 23 | +|-- src/components/ Shared interface components |
| 24 | +|-- src/context/ Login session and live account-status checks |
| 25 | +|-- src/lib/ Calculations and display helpers |
| 26 | +|-- src/theme.ts Colours and shared visual values |
| 27 | +|-- test/ Automated tests |
| 28 | +|-- app.json Expo application configuration |
| 29 | +|-- .env.example Example local settings |
| 30 | +`-- package.json Libraries and development commands |
| 31 | +``` |
| 32 | + |
| 33 | +## Before the first run |
| 34 | + |
| 35 | +Install the following: |
| 36 | + |
| 37 | +1. **Node.js 22 LTS** from [nodejs.org](https://nodejs.org/). npm is installed with Node.js. |
| 38 | +2. **Expo Go** from the iOS App Store or Google Play if you want to test on a physical phone. |
| 39 | +3. A code editor such as [Visual Studio Code](https://code.visualstudio.com/). |
| 40 | +4. The `Ruffl-Backend` repository beside this repository. |
| 41 | + |
| 42 | +After installing Node.js, open PowerShell and confirm it works: |
| 43 | + |
| 44 | +```powershell |
| 45 | +node --version |
| 46 | +npm --version |
| 47 | +``` |
| 48 | + |
| 49 | +If either command is not recognised, close and reopen PowerShell. If it still fails, reinstall Node.js and allow its installer to add Node to `PATH`. |
| 50 | + |
| 51 | +## First-time setup |
| 52 | + |
| 53 | +Open PowerShell and move into this repository: |
| 54 | + |
| 55 | +```powershell |
| 56 | +cd C:\Users\thoma\Documents\Ruffl\Ruffl-Frontend |
| 57 | +``` |
| 58 | + |
| 59 | +Install the packages: |
20 | 60 |
|
21 | 61 | ```powershell |
22 | 62 | npm install |
23 | 63 | ``` |
24 | 64 |
|
25 | | -## Test the app on a physical phone |
| 65 | +`npm install` reads `package.json`, downloads the required libraries into `node_modules`, and creates or updates `package-lock.json`. Run it again whenever `package.json` changes or after pulling dependency changes from Git. |
26 | 66 |
|
27 | | -1. Start `Ruffl-Backend` with `npm run dev`. |
28 | | -2. Find the development computer's LAN IPv4 address with `ipconfig`. |
29 | | -3. Copy `.env.example` to `.env`. |
30 | | -4. Replace `localhost` in `EXPO_PUBLIC_API_URL` with that LAN address, for example `http://192.168.1.20:3000`. |
31 | | -5. Make sure the phone and computer are on the same network. |
32 | | -6. Start Expo: |
| 67 | +Create your local environment file: |
33 | 68 |
|
34 | 69 | ```powershell |
35 | | -npm start |
| 70 | +Copy-Item .env.example .env |
| 71 | +``` |
| 72 | + |
| 73 | +The `.env` file is ignored by Git. Do not commit it. |
| 74 | + |
| 75 | +## Configure the backend address |
| 76 | + |
| 77 | +Open `.env` and set `EXPO_PUBLIC_API_URL`. |
| 78 | + |
| 79 | +### Physical phone |
| 80 | + |
| 81 | +`localhost` on a phone means the phone itself, not the development computer. Use the computer's local network address instead. |
| 82 | + |
| 83 | +1. In PowerShell, run: |
| 84 | + |
| 85 | + ```powershell |
| 86 | + ipconfig |
| 87 | + ``` |
| 88 | + |
| 89 | +2. Find the active Wi-Fi or Ethernet adapter. |
| 90 | +3. Find its **IPv4 Address**, for example `192.168.1.238`. |
| 91 | +4. Set `.env` to: |
| 92 | + |
| 93 | + ```dotenv |
| 94 | + EXPO_PUBLIC_API_URL=http://192.168.1.238:3000 |
| 95 | + ``` |
| 96 | + |
| 97 | +5. Make sure the computer and phone are connected to the same home or office network. |
| 98 | + |
| 99 | +### Android Emulator |
| 100 | + |
| 101 | +The standard Android Emulator reaches the Windows host through `10.0.2.2`: |
| 102 | + |
| 103 | +```dotenv |
| 104 | +EXPO_PUBLIC_API_URL=http://10.0.2.2:3000 |
| 105 | +``` |
| 106 | + |
| 107 | +### iOS Simulator |
| 108 | + |
| 109 | +The iOS Simulator normally reaches the host through `localhost`: |
| 110 | + |
| 111 | +```dotenv |
| 112 | +EXPO_PUBLIC_API_URL=http://localhost:3000 |
36 | 113 | ``` |
37 | 114 |
|
38 | | -7. Scan the QR code with Expo Go. |
39 | | -8. Tap **Commissioner** or **Maker** on the demo sign-in panel. |
| 115 | +The iOS Simulator requires macOS and Xcode. It cannot run natively on Windows. |
40 | 116 |
|
41 | | -For local Expo Go testing this project intentionally targets Expo SDK 54. The current Expo documentation identifies SDK 54 as the compatible physical-device path during the SDK 57 transition. |
| 117 | +## Start Ruffl for the first time |
42 | 118 |
|
43 | | -## Test with an emulator |
| 119 | +Ruffl needs two terminals: one for the backend and one for the mobile app. |
44 | 120 |
|
45 | | -Start the backend and Expo, then: |
| 121 | +### Terminal 1: start the backend |
46 | 122 |
|
47 | 123 | ```powershell |
48 | | -npm run android |
| 124 | +cd C:\Users\thoma\Documents\Ruffl\Ruffl-Backend |
| 125 | +npm run dev |
49 | 126 | ``` |
50 | 127 |
|
51 | | -Android Emulator commonly reaches the host at `http://10.0.2.2:3000`; set that as `EXPO_PUBLIC_API_URL`. iOS Simulator can normally use `http://localhost:3000`: |
| 128 | +Leave this terminal open. The backend should report that it is listening on port `3000`. |
| 129 | + |
| 130 | +### Terminal 2: start Expo |
52 | 131 |
|
53 | 132 | ```powershell |
54 | | -npm run ios |
| 133 | +cd C:\Users\thoma\Documents\Ruffl\Ruffl-Frontend |
| 134 | +npm start |
55 | 135 | ``` |
56 | 136 |
|
57 | | -The iOS Simulator requires macOS/Xcode. Android Studio is required for the Android emulator. |
| 137 | +Leave this terminal open too. Expo prints a QR code. |
| 138 | + |
| 139 | +### Open the app on a phone |
| 140 | + |
| 141 | +1. Open Expo Go. |
| 142 | +2. Scan the QR code from the Expo terminal. |
| 143 | +3. Wait for the JavaScript bundle to finish loading. |
| 144 | +4. On the Ruffl sign-in screen, choose a demo role. |
| 145 | + |
| 146 | +Demo accounts: |
| 147 | + |
| 148 | +| Role | Email | Password | |
| 149 | +|---|---|---| |
| 150 | +| Commissioner | `commissioner@demo.ruffl` | `RufflDemo1!` | |
| 151 | +| Maker | `maker@demo.ruffl` | `RufflDemo1!` | |
| 152 | + |
| 153 | +The buttons on the login screen enter these values automatically. |
| 154 | + |
| 155 | +## What normal development looks like |
| 156 | + |
| 157 | +1. Start the backend with `npm run dev`. |
| 158 | +2. Start Expo with `npm start`. |
| 159 | +3. Edit files in `app/` or `src/`. |
| 160 | +4. Save the file. |
| 161 | +5. Expo normally refreshes the app automatically. |
| 162 | +6. Watch both terminals for errors. |
| 163 | +7. Run the validation commands before committing. |
| 164 | + |
| 165 | +Useful Expo terminal keys include: |
| 166 | + |
| 167 | +- Press `r` to reload the app. |
| 168 | +- Press `a` to open Android when an emulator is installed. |
| 169 | +- Press `w` to open the browser version. |
| 170 | +- Press `Ctrl+C` to stop Expo. |
| 171 | + |
| 172 | +If `.env` changes, stop Expo with `Ctrl+C` and start it again. A normal hot reload may not reload environment variables. |
| 173 | + |
| 174 | +## Available npm commands |
| 175 | + |
| 176 | +| Command | Purpose | |
| 177 | +|---|---| |
| 178 | +| `npm start` | Starts the Expo development server and prints a QR code | |
| 179 | +| `npm run android` | Starts Expo and attempts to open an Android emulator/device | |
| 180 | +| `npm run ios` | Starts Expo and attempts to open the iOS Simulator | |
| 181 | +| `npm run web` | Runs the web-compatible version for quick layout checks | |
| 182 | +| `npm run typecheck` | Checks TypeScript without creating a build | |
| 183 | +| `npm run lint` | Checks code style and common programming mistakes | |
| 184 | +| `npm test` | Runs the automated tests once | |
| 185 | +| `npm run test:watch` | Keeps tests running and reruns them after changes | |
58 | 186 |
|
59 | 187 | ## Automated validation |
60 | 188 |
|
| 189 | +Run these before committing: |
| 190 | + |
61 | 191 | ```powershell |
62 | 192 | npm run typecheck |
63 | 193 | npm run lint |
64 | 194 | npm test |
65 | 195 | ``` |
66 | 196 |
|
67 | | -Tests cover price/deposit/payout calculations, progress percentage, and user-facing lifecycle labels. API permission and lifecycle tests live in `Ruffl-Backend`. |
| 197 | +The mobile tests cover calculations, progress display, API errors, rate-limit messages, and account restriction propagation. Backend permissions and commission lifecycle tests live in `Ruffl-Backend`. |
| 198 | + |
| 199 | +## Live warnings, suspension, and deletion |
| 200 | + |
| 201 | +- The app checks the current account with the backend every three seconds. |
| 202 | +- It checks again whenever the app returns from the background. |
| 203 | +- A warning appears as a global dialog, regardless of the current screen. |
| 204 | +- Selecting **I understand** marks the warning as read on the backend. |
| 205 | +- Suspension, soft deletion, and permanent deletion clear the local authenticated session and force the dedicated account-status screen. |
| 206 | +- The backend also rejects every authenticated action immediately, so the three-second client check is not the security boundary. |
| 207 | + |
| 208 | +The interface update is not literally instantaneous. Its normal maximum delay is approximately three seconds. True real-time delivery would require WebSockets or push-notification handling. |
| 209 | + |
| 210 | +## Product flows currently available |
| 211 | + |
| 212 | +- Commissioner and maker signup/login |
| 213 | +- Role-aware home summaries |
| 214 | +- Maker search, profiles, pricing, queue state, reviews, and waitlists |
| 215 | +- Structured commission requests |
| 216 | +- Price negotiation |
| 217 | +- Simulated deposits and milestone releases |
| 218 | +- Ordered progress updates and approvals |
| 219 | +- Shipping and receipt confirmation |
| 220 | +- Reviews and dispute entry points |
| 221 | +- Commission, direct, dispute, and support conversation types |
| 222 | +- Maker price and payout calculator |
| 223 | +- Warning, suspension, and deletion handling |
| 224 | + |
| 225 | +No real payment is taken. Every payment-related action is symbolic. |
68 | 226 |
|
69 | | -## Available product flows |
| 227 | +## Troubleshooting |
70 | 228 |
|
71 | | -- Commissioner and maker signup/login with one-tap local demo accounts |
72 | | -- Role-aware home summaries and activity |
73 | | -- Maker search, queue status, pricing, profiles, reviews, and waitlist joining |
74 | | -- Structured commission requests and price negotiation |
75 | | -- Explicitly simulated deposit and milestone releases |
76 | | -- Ordered milestone updates and approvals |
77 | | -- Shipping, receipt confirmation, review, and dispute entry points |
78 | | -- One inbox over commission/direct/dispute/support conversation types |
79 | | -- Maker-local price/payout calculator |
80 | | -- Warning and suspension-aware session handling |
| 229 | +### “Could not connect to Ruffl” or “Network request failed” |
81 | 230 |
|
82 | | -## Production development builds |
| 231 | +Check all of the following: |
83 | 232 |
|
84 | | -Expo Go is appropriate for the current integration-light development phase. Before app-store testing, install the Expo development client and create development builds: |
| 233 | +- The backend terminal is still running. |
| 234 | +- The backend uses port `3000`. |
| 235 | +- `EXPO_PUBLIC_API_URL` contains the computer's IPv4 address, not `localhost`, when using a phone. |
| 236 | +- The phone and computer are on the same network. |
| 237 | +- The IP address has not changed since `.env` was created. |
| 238 | +- Windows Firewall is not blocking Node.js on private networks. |
| 239 | +- Expo was restarted after editing `.env`. |
| 240 | + |
| 241 | +Test the backend from the computer: |
| 242 | + |
| 243 | +```powershell |
| 244 | +Invoke-RestMethod http://localhost:3000/health |
| 245 | +``` |
| 246 | + |
| 247 | +Expected result: |
| 248 | + |
| 249 | +```text |
| 250 | +status service |
| 251 | +------ ------- |
| 252 | +ok ruffl-api |
| 253 | +``` |
| 254 | + |
| 255 | +### The QR code opens but Ruffl never loads |
| 256 | + |
| 257 | +1. Stop Expo with `Ctrl+C`. |
| 258 | +2. Restart with a cleared Metro cache: |
| 259 | + |
| 260 | + ```powershell |
| 261 | + npx expo start --clear |
| 262 | + ``` |
| 263 | + |
| 264 | +3. Reopen Expo Go and scan the new QR code. |
| 265 | + |
| 266 | +### Login reports too many attempts |
| 267 | + |
| 268 | +`POST /auth/login` allows ten attempts from one IP address within fifteen minutes. Successful and unsuccessful attempts both count. Wait for the displayed time or restart the development backend to clear its in-memory limiter. |
| 269 | + |
| 270 | +### Account warnings or suspension do not update |
| 271 | + |
| 272 | +- Confirm the mobile app is connected to the same backend instance as the admin dashboard. |
| 273 | +- Check `EXPO_PUBLIC_API_URL`. |
| 274 | +- Leave the app open for at least three seconds. |
| 275 | +- Background and foreground the app to trigger an immediate check. |
| 276 | +- Inspect the backend terminal for `GET /me`. |
| 277 | + |
| 278 | +### Expo reports incompatible packages |
| 279 | + |
| 280 | +Run: |
| 281 | + |
| 282 | +```powershell |
| 283 | +npx expo install --check |
| 284 | +``` |
| 285 | + |
| 286 | +Use `npx expo install <package-name>` for Expo-native packages because Expo chooses a compatible version. |
| 287 | + |
| 288 | +## Expo Go versus a development build |
| 289 | + |
| 290 | +Expo Go is the easiest first development environment, but it only contains a fixed set of native libraries. A **development build** is a custom version of the Ruffl app containing its own native libraries. Use development builds before adding full native push notifications, monitoring, or app-store testing. |
| 291 | + |
| 292 | +Install the development client: |
85 | 293 |
|
86 | 294 | ```powershell |
87 | 295 | npx expo install expo-dev-client |
| 296 | +``` |
| 297 | + |
| 298 | +Configure Expo Application Services: |
| 299 | + |
| 300 | +```powershell |
88 | 301 | npx eas-cli@latest build:configure |
| 302 | +``` |
| 303 | + |
| 304 | +Create development builds: |
| 305 | + |
| 306 | +```powershell |
89 | 307 | npx eas-cli@latest build --profile development --platform android |
90 | 308 | npx eas-cli@latest build --profile development --platform ios |
91 | 309 | ``` |
92 | 310 |
|
93 | | -EAS requires an Expo account. A macOS build machine is not required when using EAS cloud builds, but Apple Developer and Google Play accounts are required for store distribution. |
| 311 | +EAS requires an Expo account. Apple Developer and Google Play accounts are required for store distribution. |
94 | 312 |
|
95 | | -## Known boundary |
| 313 | +## Security and current limitations |
96 | 314 |
|
97 | | -Media picking/upload UI, native Expo Push registration, and Sentry initialization need the real service credentials and production development builds. The backend already defines the relevant data and upload-slot boundaries. All money actions are deliberately labelled simulated because there is no payment processor. |
| 315 | +- Authentication tokens are stored through Expo SecureStore. |
| 316 | +- Never place private server keys in `EXPO_PUBLIC_*` variables. Anything beginning with `EXPO_PUBLIC_` is included in the client application. |
| 317 | +- Media selection/upload UI, Expo Push registration, and Sentry initialisation still require production service integration. |
| 318 | +- The backend currently stores development data in memory, so restarting it resets accounts and commissions. |
| 319 | +- No payment processor is integrated. |
98 | 320 |
|
99 | | -As of 26 July 2026, `npm audit --omit=dev` reports high-severity advisories in transitive Expo/React Native build-tool dependencies (`brace-expansion` and `postcss`) with no compatible fix published for the SDK 54 tree. The backend and admin production dependency audits are clean. Do not run `npm audit fix --force` blindly because it can move native packages outside Expo's supported version set; reassess the advisories when moving from Expo Go to a production development build. |
| 321 | +As of 26 July 2026, `npm audit --omit=dev` reports high-severity advisories in transitive Expo/React Native build-tool dependencies (`brace-expansion` and `postcss`) with no compatible fix published for the SDK 54 dependency tree. Do not run `npm audit fix --force` blindly because that can move native packages outside Expo's supported versions. |
0 commit comments