ICS React Native App
1# BankingMockAPI
2
3A simple mock banking API for testing and prototyping.
4Provides authentication, accounts, cards, and transactions endpoints backed by a seeded SQLite database.
5Includes a React Native demo app powered by [Expo](https://expo.dev/).
6
7---
8
9## 🚀 Getting Started
10
11### Prerequisites
12
13- [Node.js](https://nodejs.org/) **v18 or higher**
14- [Docker](https://www.docker.com/) (optional, for containerized setup)
15- [Expo CLI](https://docs.expo.dev/get-started/installation/) (for running the React Native app):
16
17 ```bash
18 npm install -g expo
19 ```
20
21---
22
23### Installation
24
25```bash
26git clone git@tangled.sh:mokkenstorm.dev/react-native-demo
27cd react-native-demo
28```
29
30---
31
32### Running the Server
33
34#### Run directly with Node.js
35
36```bash
37cd server && npx ts-node src/server.ts
38```
39
40The server will be available at:
41👉 `http://localhost:3001`
42
43#### Run with Docker Compose
44
45```bash
46docker compose up --build
47```
48
49Stop the service:
50
51```bash
52docker compose down
53```
54
55Server base URL: `http://localhost:3001`
56
57---
58
59### 🎨 Running the App
60
61The repository includes a React Native demo app that connects to the API.
62
63To generate client code from the OpenAPI spec and start the app with Expo:
64
65```bash
66cd app
67npm run generate
68npm run ios
69```
70
71You can replace `npm run ios` with:
72
73- `npm run android` — to run on Android
74- `npm run web` — to run in a web browser
75
76⚠️ **Note:** The app requires and **API server** (see instructions above).
77Without the server running on `http://localhost:3001`, login and data
78fetches will fail by default. If you need a different backend port/url
79and set the `SERVER_URL` environment variable before generating the
80client code, and optionally configure the `compose.yaml` for a different port.
81
82Expo will guide you through launching the app on your chosen platform.
83
84---
85
86## 📚 API Documentation
87
88Interactive documentation and the raw OpenAPI specification are exposed by the server:
89
90- **Swagger UI:**
91 [http://localhost:3001](http://localhost:3001)
92 A browsable interface to test and explore the API endpoints.
93
94- **OpenAPI Spec (YAML):**
95 [http://localhost:3001/openapi.yaml](http://localhost:3001/openapi.yaml)
96 The raw machine-readable specification, suitable for client generation.
97
98---
99
100## 📖 API Endpoints
101
102All protected routes require a **JWT** in the `Authorization` header:
103
104```bash
105Authorization: Bearer <JWT>
106```
107
108### 🔑 Authentication
109
110#### `POST /login`
111
112Authenticate and receive a token pair.
113
114**Request Body**
115
116```json
117{
118 "username": "test@test.test",
119 "password": "password@123"
120}
121```
122
123Response 200\*\*
124
125```json
126{
127 "accessToken": "<JWT>",
128 "refreshToken": "<refresh_JWT>",
129 "expires": "2024-06-01T10:05:00Z"
130}
131```
132
133Response 401\*\*
134
135```json
136{
137 "errors": [],
138 "properties": {
139 "username": { "errors": ["Invalid email address"] },
140 "password": {
141 "errors": ["Too small: expected string to have >=8 characters"]
142 }
143 }
144}
145```
146
147---
148
149#### `POST /refresh-token`
150
151Exchange a refresh token for a new pair.
152
153**Request Body**
154
155```json
156{
157 "refreshToken": "<refresh_JWT>"
158}
159```
160
161Response 200\*\*
162
163```json
164{
165 "accessToken": "<new_JWT>",
166 "refreshToken": "<new_refresh_JWT>"
167}
168```
169
170---
171
172### 👤 Me
173
174#### `GET /me`
175
176Returns the authenticated user.
177
178Response 200\*\*
179
180```json
181{
182 "id": 2,
183 "username": "nmokkenstorm",
184 "fullname": "Niels Mokkenstorm",
185 "created": "2024-06-01T10:00:00Z"
186}
187```
188
189---
190
191### 🏦 Accounts
192
193#### `GET /accounts`
194
195List accounts for the authenticated user.
196
197Response 200\*\*
198
199```json
200[
201 {
202 "id": 1,
203 "user_id": 1,
204 "iban": "NL00BANK0123456789",
205 "name": "Checking",
206 "balance": 1680.16
207 }
208]
209```
210
211#### `GET /accounts/{accountId}`
212
213Retrieve a single account by ID.
214
215Response 200\*\*
216
217```json
218{
219 "id": 1,
220 "user_id": 1,
221 "iban": "NL00BANK0123456789",
222 "name": "Checking",
223 "balance": 1680.16
224}
225```
226
227---
228
229### 💳 Cards
230
231#### `GET /cards`
232
233List stored cards (**demo only**: returns full PAN and CVV).
234
235Response 200\*\*
236
237```json
238[
239 {
240 "id": 1,
241 "user_id": 1,
242 "number": "4111111111111111",
243 "expiry": "12/26",
244 "cvv": "123"
245 }
246]
247```
248
249---
250
251### 🧾 Transactions
252
253#### `GET /transactions`
254
255Search/sort/paginate transactions. Query params: `search`, `sort` (default `date`), `order` (`asc|desc`, default `desc`), `page` (default `1`), `limit` (default `25`), `accountId`, `type`.
256
257Response 200\*\*
258
259```json
260{
261 "data": [
262 {
263 "id": 1,
264 "userId": 1,
265 "accountId": 1,
266 "amount": -50.25,
267 "type": "debit",
268 "description": "Grocery Store",
269 "date": "2024-06-01T10:00:00Z"
270 }
271 ],
272 "meta": {
273 "page": 1,
274 "limit": 25,
275 "hasMore": false,
276 "total": 1
277 }
278}
279```
280
281---
282
283#### `GET /transaction-types`
284
285Aggregate transaction types.
286
287Response 200\*\*
288
289```json
290[
291 { "name": "debit", "count": 12 },
292 { "name": "credit", "count": 5 }
293]
294```
295
296---
297
298## 👤 Default Test User
299
300- **Username:** `test@test.test`
301- **Password:** `password@123`
302
303---
304
305## 🗄️ Database
306
307- Uses **SQLite**.
308- The database is reset and seeded with test data on every server start.