@sales-planner/http-client 0.12.0 → 0.13.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 +298 -269
- package/dist/clients/api-keys-client.d.ts +2 -2
- package/dist/clients/api-keys-client.d.ts.map +1 -1
- package/dist/clients/api-keys-client.js +2 -2
- package/dist/clients/brands-client.d.ts +8 -8
- package/dist/clients/brands-client.d.ts.map +1 -1
- package/dist/clients/brands-client.js +9 -9
- package/dist/clients/categories-client.d.ts +8 -8
- package/dist/clients/categories-client.d.ts.map +1 -1
- package/dist/clients/categories-client.js +9 -9
- package/dist/clients/groups-client.d.ts +8 -8
- package/dist/clients/groups-client.d.ts.map +1 -1
- package/dist/clients/groups-client.js +9 -9
- package/dist/clients/marketplaces-client.d.ts +8 -8
- package/dist/clients/marketplaces-client.d.ts.map +1 -1
- package/dist/clients/marketplaces-client.js +9 -9
- package/dist/clients/roles-client.d.ts +3 -3
- package/dist/clients/roles-client.d.ts.map +1 -1
- package/dist/clients/roles-client.js +4 -4
- package/dist/clients/sales-history-client.d.ts +7 -7
- package/dist/clients/sales-history-client.d.ts.map +1 -1
- package/dist/clients/sales-history-client.js +8 -8
- package/dist/clients/sales-planner-client.d.ts +0 -126
- package/dist/clients/sales-planner-client.d.ts.map +1 -1
- package/dist/clients/sales-planner-client.js +1 -126
- package/dist/clients/shops-client.d.ts +3 -3
- package/dist/clients/shops-client.d.ts.map +1 -1
- package/dist/clients/shops-client.js +4 -4
- package/dist/clients/skus-client.d.ts +8 -8
- package/dist/clients/skus-client.d.ts.map +1 -1
- package/dist/clients/skus-client.js +9 -9
- package/dist/clients/statuses-client.d.ts +8 -8
- package/dist/clients/statuses-client.d.ts.map +1 -1
- package/dist/clients/statuses-client.js +9 -9
- package/dist/clients/suppliers-client.d.ts +8 -34
- package/dist/clients/suppliers-client.d.ts.map +1 -1
- package/dist/clients/suppliers-client.js +9 -9
- package/dist/clients/tenants-client.d.ts +4 -4
- package/dist/clients/tenants-client.d.ts.map +1 -1
- package/dist/clients/tenants-client.js +6 -6
- package/dist/clients/user-roles-client.d.ts +2 -2
- package/dist/clients/user-roles-client.d.ts.map +1 -1
- package/dist/clients/user-roles-client.js +2 -2
- package/dist/clients/users-client.d.ts +2 -2
- package/dist/clients/users-client.d.ts.map +1 -1
- package/dist/clients/users-client.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ import { SalesPlannerClient } from '@sales-planner/http-client';
|
|
|
17
17
|
|
|
18
18
|
const client = new SalesPlannerClient({
|
|
19
19
|
baseUrl: 'https://sales-planner-back.vercel.app',
|
|
20
|
-
|
|
20
|
+
apiKey: 'your-api-key',
|
|
21
21
|
});
|
|
22
22
|
|
|
23
23
|
// Check if API is healthy
|
|
@@ -25,321 +25,314 @@ const health = await client.getHealth();
|
|
|
25
25
|
console.log(health); // { status: 'ok', version: '1.0.0' }
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
### Shop Context
|
|
29
|
+
|
|
30
|
+
Most operations require a shop context (`ctx`) as the **first argument**:
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
const ctx = { tenant_id: 1, shop_id: 1 };
|
|
34
|
+
|
|
35
|
+
// All entity methods follow: client.<entity>.<method>(ctx, ...args)
|
|
36
|
+
const skus = await client.skus.getSkus(ctx);
|
|
37
|
+
const sku = await client.skus.getSku(ctx, 123);
|
|
38
|
+
const brand = await client.brands.getBrandByCode(ctx, 'apple');
|
|
39
|
+
```
|
|
40
|
+
|
|
28
41
|
### Namespaced Sub-Clients
|
|
29
42
|
|
|
30
43
|
Access resources through domain-specific sub-clients:
|
|
31
44
|
|
|
32
45
|
```typescript
|
|
33
|
-
// Users
|
|
46
|
+
// Users (system-level, no ctx)
|
|
34
47
|
const users = await client.users.getUsers();
|
|
35
48
|
const user = await client.users.getUser(1);
|
|
36
49
|
|
|
37
|
-
// Tenants
|
|
50
|
+
// Tenants (system-level, no ctx)
|
|
38
51
|
const tenants = await client.tenants.getTenants();
|
|
39
|
-
const shops = await client.shops.getShops(tenantId);
|
|
40
52
|
|
|
41
|
-
//
|
|
42
|
-
const
|
|
43
|
-
await client.skus.importJson(items, { tenantId, shopId });
|
|
44
|
-
const csv = await client.skus.exportCsv({ tenantId, shopId });
|
|
45
|
-
|
|
46
|
-
// Brands with import/export
|
|
47
|
-
const brands = await client.brands.getBrands({ tenantId, shopId });
|
|
48
|
-
await client.brands.importJson(items, { tenantId, shopId });
|
|
49
|
-
const brandsCsv = await client.brands.exportCsv({ tenantId, shopId });
|
|
50
|
-
|
|
51
|
-
// Categories with import/export
|
|
52
|
-
const categories = await client.categories.getCategories({ tenantId, shopId });
|
|
53
|
-
await client.categories.importJson(items, { tenantId, shopId });
|
|
53
|
+
// Shops (tenant-level)
|
|
54
|
+
const shops = await client.shops.getShops(tenantId);
|
|
54
55
|
|
|
55
|
-
//
|
|
56
|
-
const
|
|
57
|
-
await client.groups.importJson(items, { tenantId, shopId });
|
|
56
|
+
// Shop-scoped entities (require ctx)
|
|
57
|
+
const ctx = { tenant_id: 1, shop_id: 1 };
|
|
58
58
|
|
|
59
|
-
//
|
|
60
|
-
const
|
|
61
|
-
await client.
|
|
59
|
+
// SKUs
|
|
60
|
+
const skus = await client.skus.getSkus(ctx);
|
|
61
|
+
await client.skus.createSku(ctx, { code: 'SKU-001', title: 'Product 1' });
|
|
62
|
+
await client.skus.importJson(ctx, items);
|
|
63
|
+
const csv = await client.skus.exportCsv(ctx);
|
|
62
64
|
|
|
63
|
-
//
|
|
64
|
-
const
|
|
65
|
-
await client.
|
|
66
|
-
const suppliersCsv = await client.suppliers.exportCsv({ tenantId, shopId });
|
|
65
|
+
// Brands
|
|
66
|
+
const brands = await client.brands.getBrands(ctx);
|
|
67
|
+
await client.brands.importJson(ctx, [{ code: 'apple', title: 'Apple' }]);
|
|
67
68
|
|
|
68
|
-
//
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
);
|
|
69
|
+
// Categories, Groups, Statuses, Suppliers - same pattern
|
|
70
|
+
const categories = await client.categories.getCategories(ctx);
|
|
71
|
+
const groups = await client.groups.getGroups(ctx);
|
|
72
|
+
const statuses = await client.statuses.getStatuses(ctx);
|
|
73
|
+
const suppliers = await client.suppliers.getSuppliers(ctx);
|
|
73
74
|
|
|
74
75
|
// Marketplaces
|
|
75
|
-
const marketplaces = await client.marketplaces.getMarketplaces(
|
|
76
|
+
const marketplaces = await client.marketplaces.getMarketplaces(ctx);
|
|
76
77
|
|
|
77
|
-
//
|
|
78
|
+
// Sales History (with optional period filter)
|
|
79
|
+
const history = await client.salesHistory.getSalesHistory(ctx, {
|
|
80
|
+
start: '2024-01',
|
|
81
|
+
end: '2024-12',
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Entity Metadata (no auth required)
|
|
78
85
|
const metadata = await client.metadata.getEntitiesMetadata();
|
|
79
|
-
// Returns field definitions for brands, categories, groups, statuses, suppliers, marketplaces, skus, sales history
|
|
80
86
|
```
|
|
81
87
|
|
|
82
|
-
##
|
|
88
|
+
## API Conventions
|
|
89
|
+
|
|
90
|
+
### Argument Order
|
|
83
91
|
|
|
84
|
-
|
|
92
|
+
All methods follow a consistent pattern: **context first, then other arguments**.
|
|
85
93
|
|
|
86
94
|
```typescript
|
|
87
|
-
//
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
{ code: 'SKU-001', title: 'Product 1' },
|
|
91
|
-
{ code: 'SKU-002', title: 'Product 2' },
|
|
92
|
-
],
|
|
93
|
-
{ tenantId, shopId }
|
|
94
|
-
);
|
|
95
|
-
// Returns: { created: 2, updated: 0, errors: [] }
|
|
96
|
-
|
|
97
|
-
// Import from CSV file
|
|
98
|
-
const csvContent = await fs.readFile('skus.csv', 'utf-8');
|
|
99
|
-
const result = await client.skus.importCsv(csvContent, { tenantId, shopId });
|
|
95
|
+
// Get by ID
|
|
96
|
+
await client.skus.getSku(ctx, id);
|
|
97
|
+
await client.brands.getBrand(ctx, id);
|
|
100
98
|
|
|
101
|
-
//
|
|
102
|
-
|
|
99
|
+
// Get by code
|
|
100
|
+
await client.skus.getSkuByCode(ctx, code);
|
|
101
|
+
await client.brands.getBrandByCode(ctx, code);
|
|
103
102
|
|
|
104
|
-
//
|
|
105
|
-
|
|
103
|
+
// Create
|
|
104
|
+
await client.skus.createSku(ctx, request);
|
|
105
|
+
await client.brands.createBrand(ctx, request);
|
|
106
106
|
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
{ tenantId, shopId }
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
const categoryResult = await client.categories.importJson(
|
|
114
|
-
[{ code: 'electronics', title: 'Electronics' }],
|
|
115
|
-
{ tenantId, shopId }
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
const groupResult = await client.groups.importJson(
|
|
119
|
-
[{ code: 'smartphones', title: 'Smartphones' }],
|
|
120
|
-
{ tenantId, shopId }
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
const statusResult = await client.statuses.importJson(
|
|
124
|
-
[{ code: 'active', title: 'Active' }],
|
|
125
|
-
{ tenantId, shopId }
|
|
126
|
-
);
|
|
127
|
-
```
|
|
107
|
+
// Update
|
|
108
|
+
await client.skus.updateSku(ctx, id, request);
|
|
109
|
+
await client.brands.updateBrand(ctx, id, request);
|
|
128
110
|
|
|
129
|
-
|
|
111
|
+
// Delete
|
|
112
|
+
await client.skus.deleteSku(ctx, id);
|
|
113
|
+
await client.brands.deleteBrand(ctx, id);
|
|
130
114
|
|
|
131
|
-
|
|
115
|
+
// Import
|
|
116
|
+
await client.skus.importJson(ctx, items);
|
|
117
|
+
await client.skus.importCsv(ctx, csvContent);
|
|
132
118
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
119
|
+
// Export
|
|
120
|
+
await client.skus.exportJson(ctx);
|
|
121
|
+
await client.skus.exportCsv(ctx);
|
|
122
|
+
```
|
|
136
123
|
|
|
137
|
-
|
|
138
|
-
- `code` (optional): String, 1-100 characters
|
|
139
|
-
- `title` (optional): String, 1-200 characters
|
|
124
|
+
### IDs vs Codes
|
|
140
125
|
|
|
141
|
-
|
|
126
|
+
- **Create/Update operations** use numeric IDs for references (e.g., `marketplace_id`)
|
|
127
|
+
- **Import/Export operations** use string codes for human readability (e.g., `marketplace: 'amazon'`)
|
|
142
128
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
129
|
+
```typescript
|
|
130
|
+
// Create uses IDs
|
|
131
|
+
await client.salesHistory.createSalesHistory(ctx, {
|
|
132
|
+
sku_id: 123,
|
|
133
|
+
marketplace_id: 1,
|
|
134
|
+
period: '2026-01',
|
|
135
|
+
quantity: 100,
|
|
136
|
+
});
|
|
146
137
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
-
|
|
138
|
+
// Import uses codes (auto-resolves to IDs)
|
|
139
|
+
await client.salesHistory.importJson(ctx, [
|
|
140
|
+
{ sku: 'SKU-001', marketplace: 'amazon', period: '2026-01', quantity: 100 },
|
|
141
|
+
]);
|
|
150
142
|
|
|
151
|
-
|
|
143
|
+
// Export returns codes
|
|
144
|
+
const exported = await client.salesHistory.exportJson(ctx);
|
|
145
|
+
// [{ sku: 'SKU-001', marketplace: 'amazon', period: '2026-01', quantity: 100 }]
|
|
146
|
+
```
|
|
152
147
|
|
|
153
|
-
|
|
154
|
-
- `code` (required): String, 1-100 characters, unique per shop
|
|
155
|
-
- `title` (required): String, 1-200 characters
|
|
148
|
+
## Import/Export Pattern
|
|
156
149
|
|
|
157
|
-
|
|
158
|
-
- `code` (optional): String, 1-100 characters
|
|
159
|
-
- `title` (optional): String, 1-200 characters
|
|
150
|
+
All shop-scoped entities support bulk import/export:
|
|
160
151
|
|
|
161
|
-
|
|
152
|
+
```typescript
|
|
153
|
+
const ctx = { tenant_id: 1, shop_id: 1 };
|
|
162
154
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
-
|
|
155
|
+
// Import from JSON array
|
|
156
|
+
const result = await client.skus.importJson(ctx, [
|
|
157
|
+
{ code: 'SKU-001', title: 'Product 1' },
|
|
158
|
+
{ code: 'SKU-002', title: 'Product 2' },
|
|
159
|
+
]);
|
|
160
|
+
console.log(result); // { created: 2, updated: 0, errors: [] }
|
|
166
161
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
-
|
|
162
|
+
// Import from CSV string
|
|
163
|
+
const csvContent = `code,title
|
|
164
|
+
SKU-001,Product 1
|
|
165
|
+
SKU-002,Product 2`;
|
|
166
|
+
const result = await client.skus.importCsv(ctx, csvContent);
|
|
170
167
|
|
|
171
|
-
|
|
168
|
+
// Export to JSON
|
|
169
|
+
const items = await client.skus.exportJson(ctx);
|
|
172
170
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
- `title` (required): String, 1-200 characters
|
|
171
|
+
// Export to CSV
|
|
172
|
+
const csv = await client.skus.exportCsv(ctx);
|
|
176
173
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
174
|
+
// Get example templates (no auth required)
|
|
175
|
+
const exampleJson = await client.skus.getExampleJson();
|
|
176
|
+
const exampleCsv = await client.skus.getExampleCsv();
|
|
177
|
+
```
|
|
180
178
|
|
|
181
|
-
|
|
179
|
+
**Supported entities:** SKUs, Brands, Categories, Groups, Statuses, Suppliers, Marketplaces, Sales History
|
|
182
180
|
|
|
183
|
-
|
|
184
|
-
- `code` (required): String, 1-100 characters, unique per shop
|
|
185
|
-
- `title` (required): String, 1-200 characters
|
|
181
|
+
## Data Requirements
|
|
186
182
|
|
|
187
|
-
|
|
188
|
-
- `code` (optional): String, 1-100 characters
|
|
189
|
-
- `title` (optional): String, 1-200 characters
|
|
183
|
+
### SKUs
|
|
190
184
|
|
|
191
|
-
|
|
185
|
+
| Field | Create/Import | Update | Export |
|
|
186
|
+
|-------|---------------|--------|--------|
|
|
187
|
+
| `code` | Required, unique per shop | Optional | ✓ |
|
|
188
|
+
| `title` | Required | Optional | ✓ |
|
|
189
|
+
| `title2` | Optional | Optional | ✓ |
|
|
190
|
+
| `category` | Optional (code) | - | code |
|
|
191
|
+
| `group` | Optional (code) | - | code |
|
|
192
|
+
| `status` | Optional (code) | - | code |
|
|
193
|
+
| `supplier` | Optional (code) | - | code |
|
|
192
194
|
|
|
193
|
-
|
|
194
|
-
- `sku_id` (required): Number, must reference existing SKU
|
|
195
|
-
- `period` (required): String, format `YYYY-MM` (e.g., "2026-01")
|
|
196
|
-
- `quantity` (required): Number, integer
|
|
197
|
-
- `marketplace_id` (required): Number, must reference existing marketplace
|
|
195
|
+
### Brands, Categories, Groups, Statuses, Suppliers
|
|
198
196
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
- `marketplace` (required): String (marketplace code), must match existing marketplace or will be auto-created
|
|
197
|
+
| Field | Create/Import | Update | Export |
|
|
198
|
+
|-------|---------------|--------|--------|
|
|
199
|
+
| `code` | Required, unique per shop | Optional | ✓ |
|
|
200
|
+
| `title` | Required | Optional | ✓ |
|
|
204
201
|
|
|
205
|
-
|
|
202
|
+
### Marketplaces
|
|
206
203
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
- `marketplace_id` (optional): Number
|
|
204
|
+
| Field | Create/Import | Update | Export |
|
|
205
|
+
|-------|---------------|--------|--------|
|
|
206
|
+
| `code` | Required, unique per shop | Optional | ✓ |
|
|
207
|
+
| `title` | Required | Optional | ✓ |
|
|
212
208
|
|
|
213
|
-
###
|
|
209
|
+
### Sales History
|
|
210
|
+
|
|
211
|
+
| Field | Create | Import | Update | Export |
|
|
212
|
+
|-------|--------|--------|--------|--------|
|
|
213
|
+
| `sku_id` | Required | - | Optional | - |
|
|
214
|
+
| `sku` | - | Required (code) | - | code |
|
|
215
|
+
| `marketplace_id` | Required | - | Optional | - |
|
|
216
|
+
| `marketplace` | - | Required (code) | - | code |
|
|
217
|
+
| `period` | Required (YYYY-MM) | Required | Optional | ✓ |
|
|
218
|
+
| `quantity` | Required | Required | Optional | ✓ |
|
|
214
219
|
|
|
215
|
-
|
|
216
|
-
- `email` (required): String, valid email format, unique
|
|
217
|
-
- `name` (required): String, 1-200 characters
|
|
218
|
-
- `default_shop_id` (optional): Number
|
|
220
|
+
### Users
|
|
219
221
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
222
|
+
| Field | Create | Update |
|
|
223
|
+
|-------|--------|--------|
|
|
224
|
+
| `email` | Required, unique | Optional |
|
|
225
|
+
| `name` | Required | Optional |
|
|
226
|
+
| `default_shop_id` | Optional | Optional (null to clear) |
|
|
224
227
|
|
|
225
228
|
### Tenants
|
|
226
229
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
**Update:**
|
|
232
|
-
- `title` (optional): String, 1-200 characters
|
|
233
|
-
- `owner_id` (optional): Number or null
|
|
230
|
+
| Field | Create | Update |
|
|
231
|
+
|-------|--------|--------|
|
|
232
|
+
| `title` | Required | Optional |
|
|
233
|
+
| `owner_id` | Optional | Optional (null to clear) |
|
|
234
234
|
|
|
235
235
|
### Shops
|
|
236
236
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
**Update:**
|
|
242
|
-
- `title` (optional): String, 1-200 characters
|
|
243
|
-
|
|
244
|
-
### Marketplaces
|
|
245
|
-
|
|
246
|
-
**Create:**
|
|
247
|
-
- `code` (required): String, 1-100 characters, unique (e.g., "amazon", "ebay")
|
|
248
|
-
- `title` (required): String, 1-200 characters
|
|
249
|
-
|
|
250
|
-
**Update:**
|
|
251
|
-
- `code` (optional): String, 1-100 characters
|
|
252
|
-
- `title` (optional): String, 1-200 characters
|
|
237
|
+
| Field | Create | Update |
|
|
238
|
+
|-------|--------|--------|
|
|
239
|
+
| `title` | Required | Optional |
|
|
240
|
+
| `tenant_id` | Required | - |
|
|
253
241
|
|
|
254
242
|
## Available Sub-Clients
|
|
255
243
|
|
|
256
|
-
|
|
244
|
+
### System-Level (no context required)
|
|
257
245
|
|
|
258
|
-
|
|
246
|
+
#### `client.me`
|
|
259
247
|
- `getMe()` - Get current user with roles and tenants
|
|
260
248
|
|
|
261
|
-
|
|
262
|
-
- `getUsers()
|
|
263
|
-
- `
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
- `
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
- `
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
- `
|
|
249
|
+
#### `client.users`
|
|
250
|
+
- `getUsers()` - List users (system admin sees all, tenant admin sees their tenants)
|
|
251
|
+
- `getUser(id)` - Get user by ID
|
|
252
|
+
- `createUser(request)` - Create user
|
|
253
|
+
- `updateUser(id, request)` - Update user
|
|
254
|
+
- `deleteUser(id)` - Delete user
|
|
255
|
+
|
|
256
|
+
#### `client.tenants`
|
|
257
|
+
- `getTenants()` - List tenants
|
|
258
|
+
- `getTenant(id)` - Get tenant by ID
|
|
259
|
+
- `createTenant(request)` - Create tenant (system admin only)
|
|
260
|
+
- `updateTenant(id, request)` - Update tenant
|
|
261
|
+
- `deleteTenant(id)` - Delete tenant
|
|
262
|
+
- `createTenantWithShopAndUser(request)` - Create tenant with initial shop and user
|
|
263
|
+
|
|
264
|
+
#### `client.shops`
|
|
265
|
+
- `getShops(tenantId?)` - List shops (optionally filtered by tenant)
|
|
266
|
+
- `getShop(id)` - Get shop by ID
|
|
267
|
+
- `createShop(request)` - Create shop
|
|
268
|
+
- `updateShop(id, request)` - Update shop
|
|
269
|
+
- `deleteShop(id)` - Delete shop
|
|
273
270
|
- `deleteShopData(id)` - Delete all data (SKUs, sales history) for a shop
|
|
274
271
|
|
|
275
|
-
|
|
276
|
-
- `
|
|
277
|
-
- `
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
- `
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
- `
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
- `
|
|
287
|
-
- `
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
- `
|
|
292
|
-
|
|
293
|
-
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
- `
|
|
299
|
-
- `
|
|
300
|
-
- `
|
|
301
|
-
- `
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
- `
|
|
305
|
-
- `
|
|
306
|
-
- `
|
|
307
|
-
- `
|
|
308
|
-
- `getExampleJson()
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
- `
|
|
315
|
-
- `
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
- `
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
- `
|
|
322
|
-
- `
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
- `
|
|
326
|
-
- `
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
- `
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
- `
|
|
337
|
-
- `
|
|
338
|
-
- `
|
|
339
|
-
- `exportJson(ctx)`, `exportCsv(ctx)` - Requires read access
|
|
340
|
-
|
|
341
|
-
### `client.metadata`
|
|
342
|
-
- `getEntitiesMetadata()` - Get field definitions for all entities (no auth required)
|
|
272
|
+
#### `client.roles`
|
|
273
|
+
- `getRoles()` - List roles (system admin only)
|
|
274
|
+
- `getRole(id)` - Get role by ID
|
|
275
|
+
|
|
276
|
+
#### `client.userRoles`
|
|
277
|
+
- `getUserRoles(query)` - List user roles
|
|
278
|
+
- `getUserRole(id)` - Get user role by ID
|
|
279
|
+
- `createUserRole(request)` - Create user role
|
|
280
|
+
- `deleteUserRole(id)` - Delete user role
|
|
281
|
+
|
|
282
|
+
#### `client.apiKeys`
|
|
283
|
+
- `getApiKeys()` - List API keys (system admin only)
|
|
284
|
+
- `createApiKey(request)` - Create API key
|
|
285
|
+
- `deleteApiKey(id)` - Delete API key
|
|
286
|
+
|
|
287
|
+
#### `client.metadata`
|
|
288
|
+
- `getEntitiesMetadata()` - Get field definitions for all entities (no auth)
|
|
289
|
+
|
|
290
|
+
### Shop-Scoped (context required)
|
|
291
|
+
|
|
292
|
+
All shop-scoped clients follow the same pattern:
|
|
293
|
+
|
|
294
|
+
#### `client.skus`
|
|
295
|
+
- `getSkus(ctx)` - List SKUs
|
|
296
|
+
- `getSku(ctx, id)` - Get SKU by ID
|
|
297
|
+
- `getSkuByCode(ctx, code)` - Get SKU by code
|
|
298
|
+
- `createSku(ctx, request)` - Create SKU
|
|
299
|
+
- `updateSku(ctx, id, request)` - Update SKU
|
|
300
|
+
- `deleteSku(ctx, id)` - Delete SKU
|
|
301
|
+
- `importJson(ctx, items)` - Import from JSON array
|
|
302
|
+
- `importCsv(ctx, csvContent)` - Import from CSV string
|
|
303
|
+
- `exportJson(ctx)` - Export to JSON
|
|
304
|
+
- `exportCsv(ctx)` - Export to CSV
|
|
305
|
+
- `getExampleJson()` - Get JSON import example (no auth)
|
|
306
|
+
- `getExampleCsv()` - Get CSV import example (no auth)
|
|
307
|
+
|
|
308
|
+
#### `client.brands`, `client.categories`, `client.groups`, `client.statuses`, `client.suppliers`
|
|
309
|
+
|
|
310
|
+
Same methods as `client.skus`:
|
|
311
|
+
- `get<Entity>s(ctx)`, `get<Entity>(ctx, id)`, `get<Entity>ByCode(ctx, code)`
|
|
312
|
+
- `create<Entity>(ctx, request)`, `update<Entity>(ctx, id, request)`, `delete<Entity>(ctx, id)`
|
|
313
|
+
- `importJson(ctx, items)`, `importCsv(ctx, csvContent)`
|
|
314
|
+
- `exportJson(ctx)`, `exportCsv(ctx)`
|
|
315
|
+
- `getExampleJson()`, `getExampleCsv()`
|
|
316
|
+
|
|
317
|
+
#### `client.marketplaces`
|
|
318
|
+
- `getMarketplaces(ctx)` - List marketplaces
|
|
319
|
+
- `getMarketplace(ctx, id)` - Get marketplace by ID
|
|
320
|
+
- `getMarketplaceByCode(ctx, code)` - Get marketplace by code
|
|
321
|
+
- `createMarketplace(ctx, request)` - Create marketplace
|
|
322
|
+
- `updateMarketplace(ctx, id, request)` - Update marketplace
|
|
323
|
+
- `deleteMarketplace(ctx, id)` - Delete marketplace
|
|
324
|
+
- `importJson(ctx, items)`, `importCsv(ctx, csvContent)` - Import
|
|
325
|
+
- `exportJson(ctx)`, `exportCsv(ctx)` - Export
|
|
326
|
+
|
|
327
|
+
#### `client.salesHistory`
|
|
328
|
+
- `getSalesHistory(ctx, query?)` - List sales history (optional period filter)
|
|
329
|
+
- `getSalesHistoryItem(ctx, id)` - Get sales history item by ID
|
|
330
|
+
- `createSalesHistory(ctx, request)` - Create sales history
|
|
331
|
+
- `updateSalesHistory(ctx, id, request)` - Update sales history
|
|
332
|
+
- `deleteSalesHistory(ctx, id)` - Delete sales history
|
|
333
|
+
- `importJson(ctx, items)`, `importCsv(ctx, csvContent)` - Import
|
|
334
|
+
- `exportJson(ctx, query?)`, `exportCsv(ctx, query?)` - Export (optional period filter)
|
|
335
|
+
- `getExampleJson()`, `getExampleCsv()` - Examples (no auth)
|
|
343
336
|
|
|
344
337
|
## Error Handling
|
|
345
338
|
|
|
@@ -356,35 +349,71 @@ try {
|
|
|
356
349
|
}
|
|
357
350
|
```
|
|
358
351
|
|
|
359
|
-
Common HTTP status codes
|
|
360
|
-
- `409 Conflict` - Duplicate resource (email, SKU code, sales period)
|
|
361
|
-
- `404 Not Found` - Resource not found
|
|
362
|
-
- `403 Forbidden` - Insufficient permissions
|
|
352
|
+
**Common HTTP status codes:**
|
|
363
353
|
- `400 Bad Request` - Validation error
|
|
354
|
+
- `401 Unauthorized` - Missing or invalid API key
|
|
355
|
+
- `403 Forbidden` - Insufficient permissions
|
|
356
|
+
- `404 Not Found` - Resource not found
|
|
357
|
+
- `409 Conflict` - Duplicate resource (email, code, period)
|
|
364
358
|
|
|
365
359
|
## Types
|
|
366
360
|
|
|
367
|
-
|
|
361
|
+
Types are re-exported from `@sales-planner/shared`:
|
|
368
362
|
|
|
369
363
|
```typescript
|
|
370
|
-
import type {
|
|
364
|
+
import type {
|
|
365
|
+
// Context
|
|
366
|
+
ShopContextParams,
|
|
367
|
+
PeriodQuery,
|
|
368
|
+
|
|
371
369
|
// Entities
|
|
372
|
-
User,
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
370
|
+
User,
|
|
371
|
+
Tenant,
|
|
372
|
+
Shop,
|
|
373
|
+
Sku,
|
|
374
|
+
Brand,
|
|
375
|
+
Category,
|
|
376
|
+
Group,
|
|
377
|
+
Status,
|
|
378
|
+
Supplier,
|
|
379
|
+
Marketplace,
|
|
380
|
+
SalesHistory,
|
|
381
|
+
Role,
|
|
382
|
+
UserRole,
|
|
383
|
+
ApiKey,
|
|
384
|
+
|
|
385
|
+
// Request types (for create/update)
|
|
386
|
+
CreateUserRequest,
|
|
387
|
+
UpdateUserRequest,
|
|
388
|
+
CreateTenantRequest,
|
|
389
|
+
UpdateTenantRequest,
|
|
390
|
+
CreateShopRequest,
|
|
391
|
+
UpdateShopRequest,
|
|
392
|
+
CreateSkuRequest,
|
|
393
|
+
UpdateSkuRequest,
|
|
394
|
+
CreateBrandRequest,
|
|
395
|
+
UpdateBrandRequest,
|
|
396
|
+
CreateSalesHistoryRequest,
|
|
397
|
+
UpdateSalesHistoryRequest,
|
|
398
|
+
// ... etc
|
|
399
|
+
|
|
400
|
+
// Import types (for import operations)
|
|
401
|
+
ImportSkuItem,
|
|
402
|
+
ImportBrandItem,
|
|
403
|
+
ImportSalesHistoryItem,
|
|
404
|
+
// ... etc
|
|
405
|
+
|
|
379
406
|
// Response types
|
|
380
|
-
UserWithRolesAndTenants,
|
|
381
|
-
|
|
382
|
-
|
|
407
|
+
UserWithRolesAndTenants,
|
|
408
|
+
TenantWithShopAndApiKey,
|
|
409
|
+
ImportResult,
|
|
410
|
+
SkuImportResult,
|
|
411
|
+
DeleteDataResult,
|
|
412
|
+
|
|
413
|
+
// Export types
|
|
414
|
+
SkuExportItem,
|
|
415
|
+
SalesHistoryExportItem,
|
|
383
416
|
} from '@sales-planner/http-client';
|
|
384
|
-
|
|
385
|
-
// For additional types (Brand, Category, Group, Status, Supplier, etc.)
|
|
386
|
-
// import directly from @sales-planner/shared
|
|
387
|
-
import type { Brand, Category, Group, Status, Supplier } from '@sales-planner/shared';
|
|
388
417
|
```
|
|
389
418
|
|
|
390
419
|
## License
|