@pelygo/janus 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +597 -170
- package/USAGE.md +376 -0
- package/dist/index.d.ts +1898 -11
- package/dist/index.js +593 -253
- package/package.json +3 -2
package/USAGE.md
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
# @pelygo/janus — Quick Usage Reference
|
|
2
|
+
|
|
3
|
+
This file ships inside the npm package for AI tools to reference.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import { createJanusApi } from '@pelygo/janus';
|
|
9
|
+
import { configure } from '@pelygo/auth/core';
|
|
10
|
+
|
|
11
|
+
// Auth and API are separate servers — both URLs required
|
|
12
|
+
configure({
|
|
13
|
+
apiBaseUrl: 'https://api.janus.dev.pelygo.com',
|
|
14
|
+
authBaseUrl: 'https://api.auth.dev.pelygo.com',
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export const janus = createJanusApi({
|
|
18
|
+
baseUrl: 'https://api.janus.dev.pelygo.com',
|
|
19
|
+
onUnauthorized: () => {
|
|
20
|
+
setTimeout(() => { window.location.href = '/SignIn'; }, 100);
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Rules
|
|
26
|
+
|
|
27
|
+
1. **Always pass `clientId`** to every query. Get it from `useClient()`:
|
|
28
|
+
```js
|
|
29
|
+
const { clientId } = useClient();
|
|
30
|
+
```
|
|
31
|
+
New endpoints reject without it (400). Older endpoints return ALL clients' data without it.
|
|
32
|
+
|
|
33
|
+
2. **Use exact field names** from the tables below. Do not guess field names.
|
|
34
|
+
|
|
35
|
+
3. **Navigation in callbacks** (onSuccess, onSelect, logout) must use:
|
|
36
|
+
```js
|
|
37
|
+
setTimeout(() => { window.location.href = '/path'; }, 100);
|
|
38
|
+
```
|
|
39
|
+
This is required for Base44 and other iframe-based environments.
|
|
40
|
+
|
|
41
|
+
4. **Use `Object.entries(data)`** for dynamic response shapes (like `getStats`).
|
|
42
|
+
|
|
43
|
+
## Query Filter Reference
|
|
44
|
+
|
|
45
|
+
### PaginatedQueryFilters (v2 endpoints: products, stocks, locations, etc.)
|
|
46
|
+
|
|
47
|
+
| Param | Type | Description |
|
|
48
|
+
|-------|------|-------------|
|
|
49
|
+
| `clientId` | `number` | **Required.** Client ID from `useClient()` |
|
|
50
|
+
| `pageSize` | `number` | Results per page (default: 25) |
|
|
51
|
+
| `pageNumber` | `number` | Page number, 1-based (default: 1) |
|
|
52
|
+
| `orderColumn` | `string` | Column to sort by (e.g. `'id'`, `'created'`) |
|
|
53
|
+
| `orderDirection` | `'ASC' \| 'DESC'` | Sort direction (default: DESC) |
|
|
54
|
+
| `query` | `string` | Free-text search across key fields |
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
const { data, meta } = await janus.products.getAll({
|
|
58
|
+
clientId, pageSize: 25, pageNumber: 1, orderDirection: 'DESC', query: 'widget',
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### ReturnsQueryFilters (janus.returns.query)
|
|
63
|
+
|
|
64
|
+
| Param | Type | Description |
|
|
65
|
+
|-------|------|-------------|
|
|
66
|
+
| `clientId` | `number` | Client ID |
|
|
67
|
+
| `page` | `number` | Page number |
|
|
68
|
+
| `pageSize` | `number` | Results per page |
|
|
69
|
+
| `created_at` | `string` | Start date (ISO, e.g. `'2025-01-01'`) |
|
|
70
|
+
| `created_to` | `string` | End date (ISO) |
|
|
71
|
+
| `last_status_ids` | `string` | Comma-separated status IDs to match current status |
|
|
72
|
+
| `include_status_ids` | `string` | Include returns with any of these status IDs |
|
|
73
|
+
| `exclude_status_ids` | `string` | Exclude returns with these status IDs |
|
|
74
|
+
| `include_associations` | `string` | Include nested data: `'return_items'`, `'return_comments'`, or both comma-separated |
|
|
75
|
+
| `csv` | `boolean` | Export as CSV instead of JSON |
|
|
76
|
+
| `group_by` | `string` | Group results by field |
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
const returns = await janus.returns.query({
|
|
80
|
+
clientId, page: 1, pageSize: 25,
|
|
81
|
+
created_at: '2025-01-01', created_to: '2025-12-31',
|
|
82
|
+
last_status_ids: '1,2', include_associations: 'return_items',
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### OrdersQueryFilters (janus.orders.getAll)
|
|
87
|
+
|
|
88
|
+
| Param | Type | Description |
|
|
89
|
+
|-------|------|-------------|
|
|
90
|
+
| `clientId` | `number` | Client ID |
|
|
91
|
+
| `page` | `number` | Page number |
|
|
92
|
+
| `pageSize` | `number` | Results per page |
|
|
93
|
+
| `order_column` | `string` | Sort column |
|
|
94
|
+
| `order_direction` | `'ASC' \| 'DESC'` | Sort direction |
|
|
95
|
+
| `created_at` | `string` | Start date (ISO) |
|
|
96
|
+
| `created_to` | `string` | End date (ISO) |
|
|
97
|
+
| `channel` | `string` | Filter by sales channel |
|
|
98
|
+
| `courier` | `string` | Filter by courier name |
|
|
99
|
+
| `status` | `string` | Filter by order status |
|
|
100
|
+
| `query` | `string` | Free-text search |
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
const orders = await janus.orders.getAll({
|
|
104
|
+
clientId, page: 1, pageSize: 25, order_direction: 'DESC',
|
|
105
|
+
created_at: '2025-01-01', created_to: '2025-12-31', query: 'ORD-123',
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### ReturnsSummaryFilters (janus.reports.returnsSummary)
|
|
110
|
+
|
|
111
|
+
| Param | Type | Description |
|
|
112
|
+
|-------|------|-------------|
|
|
113
|
+
| `clientId` | `number` | Client ID |
|
|
114
|
+
| `createdFrom` | `string` | Start date (ISO) |
|
|
115
|
+
| `createdTo` | `string` | End date (ISO) |
|
|
116
|
+
| `approvedFrom` | `string` | Approval start date |
|
|
117
|
+
| `approvedTo` | `string` | Approval end date |
|
|
118
|
+
| `courierServiceId` | `number` | Filter by courier service |
|
|
119
|
+
| `approved` | `boolean` | Only approved returns |
|
|
120
|
+
| `page` | `number` | Page number |
|
|
121
|
+
| `pageSize` | `number` | Results per page |
|
|
122
|
+
| `csv` | `boolean` | Set true for CSV export (use `returnsSummaryCsv` instead) |
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
const summary = await janus.reports.returnsSummary({
|
|
126
|
+
clientId, createdFrom: '2025-01-01', createdTo: '2025-12-31',
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Resource-specific extra filters
|
|
131
|
+
|
|
132
|
+
| Resource | Extra param | Type | Description |
|
|
133
|
+
|----------|-----------|------|-------------|
|
|
134
|
+
| `janus.stockTransactions.getAll` | `stockId` | `number` | Filter by stock record |
|
|
135
|
+
| `janus.stockAllocations.getAll` | `orderId` | `number` | Filter by order |
|
|
136
|
+
| `janus.dispatches.getAll` | `orderId` | `number` | Filter by order |
|
|
137
|
+
| `janus.audits.getAll` | `filter` | `string` | Additional filter |
|
|
138
|
+
| `janus.users.getAll` | `filterRole` | `string` | Filter by role |
|
|
139
|
+
| `janus.users.getAll` | `filterType` | `string` | Filter by user type |
|
|
140
|
+
| `janus.users.getAll` | `filterClientId` | `number` | Filter by assigned client |
|
|
141
|
+
|
|
142
|
+
## All Resources
|
|
143
|
+
|
|
144
|
+
| Resource | Access | Description |
|
|
145
|
+
|----------|--------|-------------|
|
|
146
|
+
| `janus.clients` | Auth | Client CRUD, courier services, return reasons, integrations, files |
|
|
147
|
+
| `janus.returns` | Auth | Returns CRUD, items, comments, statuses, reasons, categories, sources |
|
|
148
|
+
| `janus.orders` | Auth | Order queries, stats, returns, filter options, CRUD |
|
|
149
|
+
| `janus.reports` | Auth | Returns summary/reasons/overview/stats + CSV exports |
|
|
150
|
+
| `janus.products` | Auth | Product CRUD (preferred over legacy.queryProducts) |
|
|
151
|
+
| `janus.productCategories` | Auth | Product category CRUD |
|
|
152
|
+
| `janus.stocks` | Auth | Stock record CRUD |
|
|
153
|
+
| `janus.stockTransactions` | Auth | Stock movement CRUD |
|
|
154
|
+
| `janus.stockAllocations` | Auth | Stock allocation CRUD (no delete) |
|
|
155
|
+
| `janus.locations` | Auth | Warehouse location CRUD |
|
|
156
|
+
| `janus.audits` | Auth | Audit trail (read-only) |
|
|
157
|
+
| `janus.asns` | Auth | ASNs with nested lines and receipts |
|
|
158
|
+
| `janus.dispatches` | Auth | Dispatch CRUD |
|
|
159
|
+
| `janus.consignments` | Auth | Consignment tracking |
|
|
160
|
+
| `janus.invoices` | Auth | Invoices with nested line items |
|
|
161
|
+
| `janus.users` | Auth | User CRUD, password management |
|
|
162
|
+
| `janus.couriers` | Auth | Courier and service management |
|
|
163
|
+
| `janus.integrations` | Auth | Integration management |
|
|
164
|
+
| `janus.logs` | Auth | Activity and issue logging |
|
|
165
|
+
| `janus.tasks` | Auth | Task history |
|
|
166
|
+
| `janus.legacy` | Auth | Legacy couriers, post services, products (deprecated) |
|
|
167
|
+
| `janus.helpers` | Public | Client settings, notifications |
|
|
168
|
+
| `janus.customer` | Public | Customer tracking and login |
|
|
169
|
+
|
|
170
|
+
## Return Entity Fields
|
|
171
|
+
|
|
172
|
+
| Field | Type | Description |
|
|
173
|
+
|-------|------|-------------|
|
|
174
|
+
| `id` | `number` | Unique ID |
|
|
175
|
+
| `return_reference` | `string` | Return reference number |
|
|
176
|
+
| `wms_order_ref` | `string` | Original order reference |
|
|
177
|
+
| `customername` | `string` | Full customer name |
|
|
178
|
+
| `forename` | `string` | First name |
|
|
179
|
+
| `surname` | `string` | Last name |
|
|
180
|
+
| `email` | `string` | Customer email |
|
|
181
|
+
| `approval_status` | `string` | "pending", "approved", or "rejected" |
|
|
182
|
+
| `tracking_number` | `string` | Courier tracking number |
|
|
183
|
+
| `latestStatus` | `object` | `{ name: string }` — current status |
|
|
184
|
+
| `return_items` | `array` | Line items (when include_associations set) |
|
|
185
|
+
| `created_ts` | `string` | ISO timestamp |
|
|
186
|
+
| `updated_ts` | `string` | ISO timestamp |
|
|
187
|
+
|
|
188
|
+
## Order Entity Fields
|
|
189
|
+
|
|
190
|
+
| Field | Type | Description |
|
|
191
|
+
|-------|------|-------------|
|
|
192
|
+
| `id` | `number` | Order ID |
|
|
193
|
+
| `reference` | `string` | Order reference number |
|
|
194
|
+
| `channel` | `string` | Sales channel ("shopify", "amazon", etc.) |
|
|
195
|
+
| `transaction_type` | `string` | "b2c", "b2b", "internal_transfer", "damage", "expiry" |
|
|
196
|
+
| `orderDate` | `string` | ISO date when order was placed |
|
|
197
|
+
| `orderStatus` | `number` | Numeric status code |
|
|
198
|
+
| `notes` | `string` | Order notes |
|
|
199
|
+
| `hold` | `number` | 0 = not on hold, 1 = on hold |
|
|
200
|
+
| `draft` | `number` | 0 = confirmed, 1 = draft |
|
|
201
|
+
| `created` | `string` | ISO date when created |
|
|
202
|
+
| `modified` | `string` | ISO date when last modified |
|
|
203
|
+
| `orderItems` | `array` | Order line items |
|
|
204
|
+
| `dispatches` | `array` | Dispatch records |
|
|
205
|
+
|
|
206
|
+
## Product Entity Fields (from /products endpoint)
|
|
207
|
+
|
|
208
|
+
| Field | Type | Description |
|
|
209
|
+
|-------|------|-------------|
|
|
210
|
+
| `product_id` | `number` | Product ID |
|
|
211
|
+
| `client_id` | `number` | Client ID |
|
|
212
|
+
| `sku_code` | `string` | Product SKU |
|
|
213
|
+
| `product_name` | `string` | Product name |
|
|
214
|
+
| `description` | `string` | Product description |
|
|
215
|
+
| `barcode` | `string` | Barcode (EAN/UPC) |
|
|
216
|
+
| `price` | `number` | Unit price |
|
|
217
|
+
| `currency` | `string` | Currency code ("GBP", "USD") |
|
|
218
|
+
| `weight_grams` | `number` | Weight in grams |
|
|
219
|
+
| `product_status` | `string` | "active", "discontinued", "inactive", "archived" |
|
|
220
|
+
| `product_type` | `string` | "sellable_unit", "packaging", "component", "consumables" |
|
|
221
|
+
| `stock` | `number` | Current stock level |
|
|
222
|
+
| `image_url` | `string` | Product image URL |
|
|
223
|
+
| `low_stock_threshold` | `number` | Low stock alert threshold |
|
|
224
|
+
| `created_date` | `string` | ISO date |
|
|
225
|
+
| `updated_date` | `string` | ISO date |
|
|
226
|
+
|
|
227
|
+
## Stock Entity Fields
|
|
228
|
+
|
|
229
|
+
| Field | Type | Description |
|
|
230
|
+
|-------|------|-------------|
|
|
231
|
+
| `id` | `number` | Stock record ID |
|
|
232
|
+
| `clientId` | `number` | Client ID |
|
|
233
|
+
| `sku_code` | `string` | Product SKU |
|
|
234
|
+
| `location` | `string` | Storage location |
|
|
235
|
+
| `quantity` | `number` | Current quantity |
|
|
236
|
+
| `batch_number` | `string` | Batch/lot number |
|
|
237
|
+
| `serial_number` | `string` | Serial number |
|
|
238
|
+
| `best_before_date` | `string` | ISO date |
|
|
239
|
+
| `stock_status` | `string` | "available", "quarantined", "expired", "damaged", "reserved" |
|
|
240
|
+
| `fulfilment_location_name` | `string` | Warehouse name |
|
|
241
|
+
| `notes` | `string` | Notes |
|
|
242
|
+
|
|
243
|
+
## Invoice Entity Fields
|
|
244
|
+
|
|
245
|
+
| Field | Type | Description |
|
|
246
|
+
|-------|------|-------------|
|
|
247
|
+
| `id` | `number` | Invoice ID |
|
|
248
|
+
| `clientId` | `number` | Client ID |
|
|
249
|
+
| `invoice_date` | `string` | ISO date |
|
|
250
|
+
| `xero_reference` | `string` | Xero accounting reference |
|
|
251
|
+
| `total` | `number` | Total amount |
|
|
252
|
+
| `emailed` | `number` | 0 = not emailed, 1 = emailed |
|
|
253
|
+
| `paid` | `number` | 0 = unpaid, 1 = paid |
|
|
254
|
+
| `invoiceLines` | `array` | Line items |
|
|
255
|
+
|
|
256
|
+
## ReturnsStatsResponse Fields
|
|
257
|
+
|
|
258
|
+
```js
|
|
259
|
+
const stats = await janus.reports.returnsStats(clientId);
|
|
260
|
+
// stats = {
|
|
261
|
+
// total: 150,
|
|
262
|
+
// awaiting_processing: 12,
|
|
263
|
+
// in_progress: 25,
|
|
264
|
+
// completed: 100,
|
|
265
|
+
// awaiting_approval: 5,
|
|
266
|
+
// approved: 90,
|
|
267
|
+
// rejected: 8,
|
|
268
|
+
// by_status: { "Processing": 25, "Complete": 100, ... },
|
|
269
|
+
// by_reason: { "Faulty": 30, "Wrong item": 20, ... }
|
|
270
|
+
// }
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## OrdersStatsResponse Fields
|
|
274
|
+
|
|
275
|
+
```js
|
|
276
|
+
const stats = await janus.orders.getStats({ clientId, dashboard: true });
|
|
277
|
+
// Returns a flat object with numeric counts — keys vary by data.
|
|
278
|
+
// Use Object.entries(stats) to iterate. Do NOT hardcode field names.
|
|
279
|
+
// Example: { total_orders: 150, dispatched: 120, processing: 15, ... }
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## API Behaviour Notes
|
|
283
|
+
|
|
284
|
+
### Error response format
|
|
285
|
+
All errors follow this shape:
|
|
286
|
+
```json
|
|
287
|
+
{ "statusCode": 400, "message": "Error description" }
|
|
288
|
+
```
|
|
289
|
+
Common codes: 400 (bad request/validation), 401 (unauthorized), 404 (not found).
|
|
290
|
+
|
|
291
|
+
### Date formats
|
|
292
|
+
- **Query params:** ISO 8601 (`'2025-01-01'` or `'2025-01-01 12:00:00'`)
|
|
293
|
+
- **Response fields:** ISO 8601 timestamps (e.g. `created_ts`, `orderDate`, `created`)
|
|
294
|
+
- **CSV exports:** formatted as `DD-MM-YYYY HH:mm`
|
|
295
|
+
|
|
296
|
+
### Pagination defaults
|
|
297
|
+
- Default `pageSize`: 50 (v2 endpoints), varies for legacy
|
|
298
|
+
- Default `pageNumber`: 1 (1-based indexing)
|
|
299
|
+
- Default sort: DESC (newest first)
|
|
300
|
+
|
|
301
|
+
### Search behaviour (`query` param)
|
|
302
|
+
Free-text search is case-insensitive LIKE matching across key text columns:
|
|
303
|
+
- Products: searches `sku`, `name`, `description`
|
|
304
|
+
- Returns: searches order references, tracking numbers
|
|
305
|
+
- Clients: searches client names
|
|
306
|
+
|
|
307
|
+
### Returns default behaviour
|
|
308
|
+
- Archived returns (status 10) are **excluded by default** — pass `include_archived: true` to include them
|
|
309
|
+
- Returns with `return_type: 0` are regular returns, `return_type: 1` are exchanges
|
|
310
|
+
- `include_associations: 'return_items'` eagerly loads line items; `'return_items,return_comments'` loads both
|
|
311
|
+
|
|
312
|
+
### Stats responses
|
|
313
|
+
`getStats` endpoints return flat objects with numeric values. The keys vary based on the client's data. **Always use `Object.entries(stats)` to iterate — never hardcode expected keys.**
|
|
314
|
+
|
|
315
|
+
## Common Patterns
|
|
316
|
+
|
|
317
|
+
### Paginated list query
|
|
318
|
+
```js
|
|
319
|
+
const { data, meta } = await janus.products.getAll({
|
|
320
|
+
clientId,
|
|
321
|
+
pageSize: 25,
|
|
322
|
+
pageNumber: 1,
|
|
323
|
+
orderDirection: 'DESC',
|
|
324
|
+
query: searchText,
|
|
325
|
+
});
|
|
326
|
+
// meta = { total_items, total_pages, current_page, page_size }
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### CSV export
|
|
330
|
+
```js
|
|
331
|
+
const csv = await janus.reports.returnsSummaryCsv({ clientId, createdFrom, createdTo });
|
|
332
|
+
const blob = new Blob([csv], { type: 'text/csv' });
|
|
333
|
+
const url = URL.createObjectURL(blob);
|
|
334
|
+
const a = document.createElement('a');
|
|
335
|
+
a.href = url;
|
|
336
|
+
a.download = 'export.csv';
|
|
337
|
+
a.click();
|
|
338
|
+
URL.revokeObjectURL(url);
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Login page
|
|
342
|
+
```jsx
|
|
343
|
+
import { LoginForm } from '@pelygo/auth/react';
|
|
344
|
+
|
|
345
|
+
<LoginForm
|
|
346
|
+
onSuccess={() => setTimeout(() => { window.location.href = '/clients'; }, 100)}
|
|
347
|
+
onError={(error) => console.log('Login error:', error)}
|
|
348
|
+
/>
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Client selection
|
|
352
|
+
```jsx
|
|
353
|
+
import { SelectClientForm } from '@pelygo/auth/react';
|
|
354
|
+
|
|
355
|
+
<SelectClientForm
|
|
356
|
+
onSelect={() => setTimeout(() => { window.location.href = '/dashboard'; }, 100)}
|
|
357
|
+
/>
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Route guard (must check isLoading)
|
|
361
|
+
```jsx
|
|
362
|
+
const { isAuthenticated, isLoading } = useAuth();
|
|
363
|
+
const { requiresClientSelection, hasSelectedClient } = useClient();
|
|
364
|
+
|
|
365
|
+
if (isLoading) return <LoadingSpinner />;
|
|
366
|
+
if (!isAuthenticated) return <Navigate to="/SignIn" replace />;
|
|
367
|
+
if (requiresClientSelection && !hasSelectedClient) return <Navigate to="/clients" replace />;
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Logout
|
|
371
|
+
```jsx
|
|
372
|
+
onClick={() => {
|
|
373
|
+
logout();
|
|
374
|
+
setTimeout(() => { window.location.href = '/SignIn'; }, 100);
|
|
375
|
+
}}
|
|
376
|
+
```
|