@deallony/shared 1.2.56 → 1.2.61
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 +43 -44
- package/dist/cjs/constants/routes/app.d.ts +114 -0
- package/dist/cjs/constants/routes/app.js +44 -0
- package/dist/cjs/dto/ai/gemini-api-key.dto.d.ts +9 -0
- package/dist/cjs/dto/ai/gemini-api-key.dto.js +2 -0
- package/dist/cjs/dto/index.d.ts +1 -0
- package/dist/cjs/dto/index.js +2 -1
- package/dist/cjs/schema/ai/gemini-api-key.schema.d.ts +41 -0
- package/dist/cjs/schema/ai/gemini-api-key.schema.js +54 -0
- package/dist/cjs/schema/ai/index.d.ts +1 -0
- package/dist/cjs/schema/ai/index.js +1 -0
- package/dist/cjs/schema/communication/ai-conversation.schema.d.ts +78 -2
- package/dist/cjs/schema/communication/ai-conversation.schema.js +30 -3
- package/dist/cjs/schema/communication/support-ticket.schema.d.ts +3 -3
- package/dist/cjs/types/index.d.ts +1 -0
- package/dist/cjs/types/index.js +2 -1
- package/dist/cjs/types/integrations/GeminiApiKey.d.ts +26 -0
- package/dist/cjs/types/integrations/GeminiApiKey.js +2 -0
- package/dist/esm/constants/routes/app.js +44 -0
- package/dist/esm/dto/ai/gemini-api-key.dto.js +1 -0
- package/dist/esm/dto/index.js +1 -0
- package/dist/esm/schema/ai/gemini-api-key.schema.js +51 -0
- package/dist/esm/schema/ai/index.js +1 -0
- package/dist/esm/schema/communication/ai-conversation.schema.js +29 -2
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/types/integrations/GeminiApiKey.js +1 -0
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,44 +1,43 @@
|
|
|
1
|
-
# @deallony/shared
|
|
2
|
-
|
|
3
|
-
Shared TypeScript types, DTOs, Zod schemas, and utilities for Deallony projects.
|
|
4
|
-
|
|
5
|
-
## One-command releases
|
|
6
|
-
|
|
7
|
-
Run from a clean, synchronized `main` branch with push access to `origin/main`.
|
|
8
|
-
|
|
9
|
-
| Command | Action |
|
|
10
|
-
| --- | --- |
|
|
11
|
-
| `npm run deploy` | Bump patch, build, publish to npm, commit/tag/push GitLab |
|
|
12
|
-
| `npm run deploy:minor` | npm + GitLab minor release |
|
|
13
|
-
| `npm run deploy:major` | npm + GitLab major release |
|
|
14
|
-
| `npm run deploy:dry-run` | Preview version and inspect current package, no mutation |
|
|
15
|
-
| `npm run deploy:git` | Bump patch, build, commit/tag/push GitLab without npm publish |
|
|
16
|
-
| `npm run deploy:git:minor` | GitLab-only minor release |
|
|
17
|
-
| `npm run deploy:git:major` | GitLab-only major release |
|
|
18
|
-
| `npm run deploy:git:dry-run` | Preview GitLab-only release |
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
the
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
If
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
Merge this feature branch first; merging does not trigger publication automatically.
|
|
1
|
+
# @deallony/shared
|
|
2
|
+
|
|
3
|
+
Shared TypeScript types, DTOs, Zod schemas, and utilities for Deallony projects.
|
|
4
|
+
|
|
5
|
+
## One-command releases
|
|
6
|
+
|
|
7
|
+
Run from a clean, synchronized `main` branch with push access to `origin/main`.
|
|
8
|
+
|
|
9
|
+
| Command | Action |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| `npm run deploy` | Bump patch, build, publish to npm, commit/tag/push GitLab |
|
|
12
|
+
| `npm run deploy:minor` | npm + GitLab minor release |
|
|
13
|
+
| `npm run deploy:major` | npm + GitLab major release |
|
|
14
|
+
| `npm run deploy:dry-run` | Preview version and inspect current package, no mutation |
|
|
15
|
+
| `npm run deploy:git` | Bump patch, build, commit/tag/push GitLab without npm publish |
|
|
16
|
+
| `npm run deploy:git:minor` | GitLab-only minor release |
|
|
17
|
+
| `npm run deploy:git:major` | GitLab-only major release |
|
|
18
|
+
| `npm run deploy:git:dry-run` | Preview GitLab-only release |
|
|
19
|
+
|
|
20
|
+
Version increments follow semantic versioning; `1.2.99` becomes `1.2.100`.
|
|
21
|
+
|
|
22
|
+
### Automatic npm login
|
|
23
|
+
|
|
24
|
+
`npm run deploy` first checks `npm whoami`. If npm returns E401 or ENEEDAUTH,
|
|
25
|
+
the script runs `npm login --registry=https://registry.npmjs.org/ --auth-type=web` and
|
|
26
|
+
opens the browser sign-in flow. After you finish logging in, it rechecks your
|
|
27
|
+
identity and continues the same release. Network failures and canceled logins
|
|
28
|
+
stop the release before modifying the package version. `deploy:git` never logs
|
|
29
|
+
into npm.
|
|
30
|
+
|
|
31
|
+
### npm authentication
|
|
32
|
+
|
|
33
|
+
Run `npm login --registry=https://registry.npmjs.org/` and ensure your account has
|
|
34
|
+
publishing permission for the public scoped package `@deallony/shared`.
|
|
35
|
+
Complete any npm 2FA prompts when required. Never commit npm tokens.
|
|
36
|
+
|
|
37
|
+
### Failure recovery
|
|
38
|
+
|
|
39
|
+
If publishing fails, inspect and restore generated local changes before retrying.
|
|
40
|
+
If npm publication succeeds but Git push/commit fails, **do not republish that version**.
|
|
41
|
+
Resolve the Git issue and push the existing release commit and `vX.Y.Z` tag.
|
|
42
|
+
|
|
43
|
+
Merge this feature branch first; merging does not trigger publication automatically.
|
|
@@ -71,6 +71,18 @@ export declare const APP_ROUTES: {
|
|
|
71
71
|
ad_id: string | number;
|
|
72
72
|
};
|
|
73
73
|
};
|
|
74
|
+
readonly promotionDetails: (params: {
|
|
75
|
+
id: number | string;
|
|
76
|
+
ad_id?: number | string;
|
|
77
|
+
data?: unknown;
|
|
78
|
+
}) => {
|
|
79
|
+
pathname: string;
|
|
80
|
+
params: {
|
|
81
|
+
id: string;
|
|
82
|
+
ad_id: string | undefined;
|
|
83
|
+
promotion: string | undefined;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
74
86
|
readonly list: (params: GenericParams) => {
|
|
75
87
|
pathname: string;
|
|
76
88
|
params: {
|
|
@@ -177,6 +189,9 @@ export declare const APP_ROUTES: {
|
|
|
177
189
|
readonly noInternet: () => {
|
|
178
190
|
pathname: string;
|
|
179
191
|
};
|
|
192
|
+
readonly savedData: () => {
|
|
193
|
+
pathname: string;
|
|
194
|
+
};
|
|
180
195
|
};
|
|
181
196
|
readonly settings: {
|
|
182
197
|
readonly selectCurrency: () => {
|
|
@@ -297,6 +312,105 @@ export declare const APP_ROUTES: {
|
|
|
297
312
|
readonly details: () => {
|
|
298
313
|
pathname: string;
|
|
299
314
|
};
|
|
315
|
+
readonly topup: (amount?: number | string) => {
|
|
316
|
+
pathname: string;
|
|
317
|
+
params: {
|
|
318
|
+
amount: string;
|
|
319
|
+
} | undefined;
|
|
320
|
+
};
|
|
321
|
+
};
|
|
322
|
+
readonly addresses: {
|
|
323
|
+
readonly list: () => {
|
|
324
|
+
pathname: string;
|
|
325
|
+
};
|
|
326
|
+
readonly new: (fromAdDraftId?: string) => {
|
|
327
|
+
pathname: string;
|
|
328
|
+
params: {
|
|
329
|
+
fromAdDraftId: string;
|
|
330
|
+
} | undefined;
|
|
331
|
+
};
|
|
332
|
+
readonly edit: (id: number) => {
|
|
333
|
+
pathname: string;
|
|
334
|
+
params: {
|
|
335
|
+
id: string;
|
|
336
|
+
};
|
|
337
|
+
};
|
|
338
|
+
};
|
|
339
|
+
readonly support: {
|
|
340
|
+
readonly tickets: () => {
|
|
341
|
+
pathname: string;
|
|
342
|
+
};
|
|
343
|
+
};
|
|
344
|
+
readonly kyc: {
|
|
345
|
+
readonly details: () => {
|
|
346
|
+
pathname: string;
|
|
347
|
+
};
|
|
348
|
+
readonly fromSettings: () => {
|
|
349
|
+
pathname: string;
|
|
350
|
+
params: {
|
|
351
|
+
source: string;
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
};
|
|
355
|
+
readonly company: {
|
|
356
|
+
readonly list: () => {
|
|
357
|
+
pathname: string;
|
|
358
|
+
};
|
|
359
|
+
readonly new: () => {
|
|
360
|
+
pathname: string;
|
|
361
|
+
};
|
|
362
|
+
readonly edit: (id: number | string) => {
|
|
363
|
+
pathname: string;
|
|
364
|
+
params: {
|
|
365
|
+
id: string | number;
|
|
366
|
+
};
|
|
367
|
+
};
|
|
368
|
+
readonly details: (id: number | string) => {
|
|
369
|
+
pathname: string;
|
|
370
|
+
params: {
|
|
371
|
+
id: string | number;
|
|
372
|
+
};
|
|
373
|
+
};
|
|
374
|
+
};
|
|
375
|
+
readonly venue: {
|
|
376
|
+
readonly new: (companyId: number | string) => {
|
|
377
|
+
pathname: string;
|
|
378
|
+
params: {
|
|
379
|
+
company_id: string | number;
|
|
380
|
+
};
|
|
381
|
+
};
|
|
382
|
+
readonly edit: (id: number | string) => {
|
|
383
|
+
pathname: string;
|
|
384
|
+
params: {
|
|
385
|
+
id: string | number;
|
|
386
|
+
};
|
|
387
|
+
};
|
|
388
|
+
readonly details: (id: number | string) => {
|
|
389
|
+
pathname: string;
|
|
390
|
+
params: {
|
|
391
|
+
id: string | number;
|
|
392
|
+
};
|
|
393
|
+
};
|
|
394
|
+
};
|
|
395
|
+
readonly event: {
|
|
396
|
+
readonly new: (venueId: number | string) => {
|
|
397
|
+
pathname: string;
|
|
398
|
+
params: {
|
|
399
|
+
venue_id: string | number;
|
|
400
|
+
};
|
|
401
|
+
};
|
|
402
|
+
readonly edit: (id: number | string) => {
|
|
403
|
+
pathname: string;
|
|
404
|
+
params: {
|
|
405
|
+
id: string | number;
|
|
406
|
+
};
|
|
407
|
+
};
|
|
408
|
+
readonly details: (id: number | string) => {
|
|
409
|
+
pathname: string;
|
|
410
|
+
params: {
|
|
411
|
+
id: string | number;
|
|
412
|
+
};
|
|
413
|
+
};
|
|
300
414
|
};
|
|
301
415
|
};
|
|
302
416
|
export type SharedAppRoutes = typeof APP_ROUTES;
|
|
@@ -36,6 +36,14 @@ exports.APP_ROUTES = {
|
|
|
36
36
|
pathname: "/ad/promotions/history/[ad_id]",
|
|
37
37
|
params: { ad_id: params.id },
|
|
38
38
|
}),
|
|
39
|
+
promotionDetails: (params) => ({
|
|
40
|
+
pathname: "/ad/promotions/details/[id]",
|
|
41
|
+
params: {
|
|
42
|
+
id: String(params.id),
|
|
43
|
+
ad_id: params.ad_id != null ? String(params.ad_id) : undefined,
|
|
44
|
+
promotion: params.data ? JSON.stringify(params.data) : undefined,
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
39
47
|
list: (params) => {
|
|
40
48
|
const filter = JSON.stringify(params);
|
|
41
49
|
if (params === null || params === void 0 ? void 0 : params.subject_type) {
|
|
@@ -80,6 +88,7 @@ exports.APP_ROUTES = {
|
|
|
80
88
|
download: () => ({ pathname: "/system/download-app" }),
|
|
81
89
|
needMobileApp: () => ({ pathname: "/system/need-mobile-app" }),
|
|
82
90
|
noInternet: () => ({ pathname: "/system/no-internet" }),
|
|
91
|
+
savedData: () => ({ pathname: "/system/saved-data" }),
|
|
83
92
|
},
|
|
84
93
|
settings: {
|
|
85
94
|
selectCurrency: () => ({ pathname: "/settings/select-currency" }),
|
|
@@ -132,5 +141,40 @@ exports.APP_ROUTES = {
|
|
|
132
141
|
},
|
|
133
142
|
wallet: {
|
|
134
143
|
details: () => ({ pathname: "/wallet" }),
|
|
144
|
+
topup: (amount) => ({
|
|
145
|
+
pathname: "/wallet/topup",
|
|
146
|
+
params: amount != null ? { amount: String(amount) } : undefined,
|
|
147
|
+
}),
|
|
148
|
+
},
|
|
149
|
+
addresses: {
|
|
150
|
+
list: () => ({ pathname: "/user/addresses" }),
|
|
151
|
+
new: (fromAdDraftId) => ({
|
|
152
|
+
pathname: "/user/addresses/new",
|
|
153
|
+
params: fromAdDraftId ? { fromAdDraftId } : undefined,
|
|
154
|
+
}),
|
|
155
|
+
edit: (id) => ({ pathname: "/user/addresses/[id]", params: { id: String(id) } }),
|
|
156
|
+
},
|
|
157
|
+
support: {
|
|
158
|
+
tickets: () => ({ pathname: "/system/support-tickets" }),
|
|
159
|
+
},
|
|
160
|
+
kyc: {
|
|
161
|
+
details: () => ({ pathname: "/kyc" }),
|
|
162
|
+
fromSettings: () => ({ pathname: "/kyc", params: { source: "settings" } }),
|
|
163
|
+
},
|
|
164
|
+
company: {
|
|
165
|
+
list: () => ({ pathname: "/company/list" }),
|
|
166
|
+
new: () => ({ pathname: "/company/new" }),
|
|
167
|
+
edit: (id) => ({ pathname: "/company/new", params: { id } }),
|
|
168
|
+
details: (id) => ({ pathname: "/company/details/[id]", params: { id } }),
|
|
169
|
+
},
|
|
170
|
+
venue: {
|
|
171
|
+
new: (companyId) => ({ pathname: "/venue/new", params: { company_id: companyId } }),
|
|
172
|
+
edit: (id) => ({ pathname: "/venue/new", params: { id } }),
|
|
173
|
+
details: (id) => ({ pathname: "/venue/details/[id]", params: { id } }),
|
|
174
|
+
},
|
|
175
|
+
event: {
|
|
176
|
+
new: (venueId) => ({ pathname: "/event/new", params: { venue_id: venueId } }),
|
|
177
|
+
edit: (id) => ({ pathname: "/event/new", params: { id } }),
|
|
178
|
+
details: (id) => ({ pathname: "/event/details/[id]", params: { id } }),
|
|
135
179
|
},
|
|
136
180
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createGeminiApiKeySchema, geminiApiKeyIdBodySchema, leasedGeminiApiKeySchema, leaseGeminiApiKeySchema, reorderGeminiApiKeysSchema, reportGeminiApiKeyUsageSchema, updateGeminiApiKeySchema } from '../../schema/ai/gemini-api-key.schema';
|
|
3
|
+
export type CreateGeminiApiKeyDto = z.input<typeof createGeminiApiKeySchema>;
|
|
4
|
+
export type UpdateGeminiApiKeyDto = z.input<typeof updateGeminiApiKeySchema>;
|
|
5
|
+
export type GeminiApiKeyIdBodyDto = z.input<typeof geminiApiKeyIdBodySchema>;
|
|
6
|
+
export type ReorderGeminiApiKeysDto = z.input<typeof reorderGeminiApiKeysSchema>;
|
|
7
|
+
export type LeaseGeminiApiKeyDto = z.input<typeof leaseGeminiApiKeySchema>;
|
|
8
|
+
export type LeasedGeminiApiKey = z.infer<typeof leasedGeminiApiKeySchema>;
|
|
9
|
+
export type ReportGeminiApiKeyUsageDto = z.input<typeof reportGeminiApiKeyUsageSchema>;
|
package/dist/cjs/dto/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { AdDto } from './ad/Ad.dto';
|
|
|
2
2
|
export * as AD from './ad/Ad.dto';
|
|
3
3
|
export * as EVENTS from './events';
|
|
4
4
|
export * as Ai from './ai/Ai.dto';
|
|
5
|
+
export * as GEMINI_API_KEYS from './ai/gemini-api-key.dto';
|
|
5
6
|
export * as PAYMENTS from './payments';
|
|
6
7
|
export * as ADDRESSES from './addresses/addresses.dto';
|
|
7
8
|
export * as POTENTIAL_USERS from './potential-users/potential-user-import.dto';
|
package/dist/cjs/dto/index.js
CHANGED
|
@@ -33,12 +33,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.POTENTIAL_USERS = exports.ADDRESSES = exports.PAYMENTS = exports.Ai = exports.EVENTS = exports.AD = exports.AdDto = void 0;
|
|
36
|
+
exports.POTENTIAL_USERS = exports.ADDRESSES = exports.PAYMENTS = exports.GEMINI_API_KEYS = exports.Ai = exports.EVENTS = exports.AD = exports.AdDto = void 0;
|
|
37
37
|
var Ad_dto_1 = require("./ad/Ad.dto");
|
|
38
38
|
Object.defineProperty(exports, "AdDto", { enumerable: true, get: function () { return Ad_dto_1.AdDto; } });
|
|
39
39
|
exports.AD = __importStar(require("./ad/Ad.dto"));
|
|
40
40
|
exports.EVENTS = __importStar(require("./events"));
|
|
41
41
|
exports.Ai = __importStar(require("./ai/Ai.dto"));
|
|
42
|
+
exports.GEMINI_API_KEYS = __importStar(require("./ai/gemini-api-key.dto"));
|
|
42
43
|
exports.PAYMENTS = __importStar(require("./payments"));
|
|
43
44
|
exports.ADDRESSES = __importStar(require("./addresses/addresses.dto"));
|
|
44
45
|
exports.POTENTIAL_USERS = __importStar(require("./potential-users/potential-user-import.dto"));
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Gemini model ID, e.g. gemini-3.1-flash-lite */
|
|
3
|
+
export declare const geminiModelNameSchema: z.ZodString;
|
|
4
|
+
export declare const createGeminiApiKeySchema: z.ZodObject<{
|
|
5
|
+
name: z.ZodString;
|
|
6
|
+
api_key: z.ZodString;
|
|
7
|
+
model_name: z.ZodString;
|
|
8
|
+
is_active: z.ZodDefault<z.ZodBoolean>;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
/** Fields left out keep their current value; the key itself is only replaced when sent. */
|
|
11
|
+
export declare const updateGeminiApiKeySchema: z.ZodObject<{
|
|
12
|
+
id: z.ZodCoercedNumber<unknown>;
|
|
13
|
+
name: z.ZodOptional<z.ZodString>;
|
|
14
|
+
api_key: z.ZodOptional<z.ZodString>;
|
|
15
|
+
model_name: z.ZodOptional<z.ZodString>;
|
|
16
|
+
is_active: z.ZodOptional<z.ZodBoolean>;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
export declare const geminiApiKeyIdBodySchema: z.ZodObject<{
|
|
19
|
+
id: z.ZodCoercedNumber<unknown>;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
/** Every key ID in the new order: the first ID gets sort_order 1. */
|
|
22
|
+
export declare const reorderGeminiApiKeysSchema: z.ZodObject<{
|
|
23
|
+
ids: z.ZodArray<z.ZodCoercedNumber<unknown>>;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
/** Ask backend-core for the least-used available key, optionally only keys for one model. */
|
|
26
|
+
export declare const leaseGeminiApiKeySchema: z.ZodObject<{
|
|
27
|
+
model_name: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
export declare const leasedGeminiApiKeySchema: z.ZodObject<{
|
|
30
|
+
id: z.ZodNumber;
|
|
31
|
+
api_key: z.ZodString;
|
|
32
|
+
model_name: z.ZodString;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
/** Sent after every Gemini call made with a leased key. */
|
|
35
|
+
export declare const reportGeminiApiKeyUsageSchema: z.ZodObject<{
|
|
36
|
+
id: z.ZodCoercedNumber<unknown>;
|
|
37
|
+
total_tokens: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
38
|
+
success: z.ZodDefault<z.ZodBoolean>;
|
|
39
|
+
error_code: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
|
40
|
+
error_message: z.ZodOptional<z.ZodString>;
|
|
41
|
+
}, z.core.$strip>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.reportGeminiApiKeyUsageSchema = exports.leasedGeminiApiKeySchema = exports.leaseGeminiApiKeySchema = exports.reorderGeminiApiKeysSchema = exports.geminiApiKeyIdBodySchema = exports.updateGeminiApiKeySchema = exports.createGeminiApiKeySchema = exports.geminiModelNameSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
/**
|
|
6
|
+
* Gemini API keys are stored in backend-core (one table) and shared by every Deallony service.
|
|
7
|
+
* The dashboard manages them through the admin schemas; other services lease a key and report
|
|
8
|
+
* the tokens they used through the internal schemas.
|
|
9
|
+
*/
|
|
10
|
+
const geminiApiKeyIdSchema = zod_1.z.coerce.number().int().positive();
|
|
11
|
+
/** Gemini model ID, e.g. gemini-3.1-flash-lite */
|
|
12
|
+
exports.geminiModelNameSchema = zod_1.z.string().trim().min(1).max(100);
|
|
13
|
+
// ---------- Admin (dashboard) ----------
|
|
14
|
+
exports.createGeminiApiKeySchema = zod_1.z.object({
|
|
15
|
+
name: zod_1.z.string().trim().min(1).max(255),
|
|
16
|
+
api_key: zod_1.z.string().trim().min(20).max(512),
|
|
17
|
+
model_name: exports.geminiModelNameSchema,
|
|
18
|
+
is_active: zod_1.z.boolean().default(true),
|
|
19
|
+
});
|
|
20
|
+
/** Fields left out keep their current value; the key itself is only replaced when sent. */
|
|
21
|
+
exports.updateGeminiApiKeySchema = zod_1.z.object({
|
|
22
|
+
id: geminiApiKeyIdSchema,
|
|
23
|
+
name: zod_1.z.string().trim().min(1).max(255).optional(),
|
|
24
|
+
api_key: zod_1.z.string().trim().min(20).max(512).optional(),
|
|
25
|
+
model_name: exports.geminiModelNameSchema.optional(),
|
|
26
|
+
is_active: zod_1.z.boolean().optional(),
|
|
27
|
+
});
|
|
28
|
+
exports.geminiApiKeyIdBodySchema = zod_1.z.object({
|
|
29
|
+
id: geminiApiKeyIdSchema,
|
|
30
|
+
});
|
|
31
|
+
/** Every key ID in the new order: the first ID gets sort_order 1. */
|
|
32
|
+
exports.reorderGeminiApiKeysSchema = zod_1.z.object({
|
|
33
|
+
ids: zod_1.z.array(geminiApiKeyIdSchema).min(1),
|
|
34
|
+
});
|
|
35
|
+
// ---------- Internal (other services) ----------
|
|
36
|
+
/** Ask backend-core for the least-used available key, optionally only keys for one model. */
|
|
37
|
+
exports.leaseGeminiApiKeySchema = zod_1.z.object({
|
|
38
|
+
model_name: exports.geminiModelNameSchema.optional(),
|
|
39
|
+
});
|
|
40
|
+
exports.leasedGeminiApiKeySchema = zod_1.z.object({
|
|
41
|
+
id: zod_1.z.number().int().positive(),
|
|
42
|
+
api_key: zod_1.z.string(),
|
|
43
|
+
model_name: zod_1.z.string(),
|
|
44
|
+
});
|
|
45
|
+
/** Sent after every Gemini call made with a leased key. */
|
|
46
|
+
exports.reportGeminiApiKeyUsageSchema = zod_1.z.object({
|
|
47
|
+
id: geminiApiKeyIdSchema,
|
|
48
|
+
/** usageMetadata.totalTokenCount of the Gemini response; 0 when the call failed */
|
|
49
|
+
total_tokens: zod_1.z.coerce.number().int().min(0).default(0),
|
|
50
|
+
success: zod_1.z.boolean().default(true),
|
|
51
|
+
/** HTTP status Gemini answered with, e.g. 429 */
|
|
52
|
+
error_code: zod_1.z.coerce.number().int().optional(),
|
|
53
|
+
error_message: zod_1.z.string().trim().max(2000).optional(),
|
|
54
|
+
});
|
|
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./ai-fill-form.schema"), exports);
|
|
18
18
|
__exportStar(require("./ai-fill-ad-form.schema"), exports);
|
|
19
|
+
__exportStar(require("./gemini-api-key.schema"), exports);
|
|
@@ -25,10 +25,8 @@ export declare const StartAiConversationSchema: z.ZodObject<{
|
|
|
25
25
|
motors: "motors";
|
|
26
26
|
used_products: "used_products";
|
|
27
27
|
}>;
|
|
28
|
-
initial_message: z.ZodString;
|
|
29
28
|
context: z.ZodObject<{
|
|
30
29
|
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
31
|
-
reason: z.ZodString;
|
|
32
30
|
note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
33
31
|
previous_contact_count: z.ZodDefault<z.ZodNumber>;
|
|
34
32
|
}, z.core.$strip>;
|
|
@@ -58,7 +56,85 @@ export declare const PotentialUserConversationEventSchema: z.ZodObject<{
|
|
|
58
56
|
}>;
|
|
59
57
|
summary: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
60
58
|
}, z.core.$strip>;
|
|
59
|
+
export declare const AiConversationStatusSchema: z.ZodEnum<{
|
|
60
|
+
starting: "starting";
|
|
61
|
+
waiting_for_reply: "waiting_for_reply";
|
|
62
|
+
chatting: "chatting";
|
|
63
|
+
interested: "interested";
|
|
64
|
+
human_handoff: "human_handoff";
|
|
65
|
+
not_interested: "not_interested";
|
|
66
|
+
converted: "converted";
|
|
67
|
+
opted_out: "opted_out";
|
|
68
|
+
closed: "closed";
|
|
69
|
+
failed: "failed";
|
|
70
|
+
}>;
|
|
71
|
+
export declare const AiConversationPurposeSchema: z.ZodEnum<{
|
|
72
|
+
marketing: "marketing";
|
|
73
|
+
support: "support";
|
|
74
|
+
}>;
|
|
75
|
+
/** Statuses of a conversation that is still open with the customer. */
|
|
76
|
+
export declare const AI_CONVERSATION_ACTIVE_STATUSES: AiConversationStatus[];
|
|
77
|
+
export declare const AiConversationListSchema: z.ZodObject<{
|
|
78
|
+
page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
79
|
+
limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
80
|
+
statuses: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
81
|
+
starting: "starting";
|
|
82
|
+
waiting_for_reply: "waiting_for_reply";
|
|
83
|
+
chatting: "chatting";
|
|
84
|
+
interested: "interested";
|
|
85
|
+
human_handoff: "human_handoff";
|
|
86
|
+
not_interested: "not_interested";
|
|
87
|
+
converted: "converted";
|
|
88
|
+
opted_out: "opted_out";
|
|
89
|
+
closed: "closed";
|
|
90
|
+
failed: "failed";
|
|
91
|
+
}>>>;
|
|
92
|
+
active_only: z.ZodDefault<z.ZodBoolean>;
|
|
93
|
+
purpose: z.ZodOptional<z.ZodEnum<{
|
|
94
|
+
marketing: "marketing";
|
|
95
|
+
support: "support";
|
|
96
|
+
}>>;
|
|
97
|
+
search: z.ZodOptional<z.ZodString>;
|
|
98
|
+
}, z.core.$strip>;
|
|
61
99
|
export type MarketingSubjectType = z.infer<typeof MarketingSubjectTypeSchema>;
|
|
100
|
+
export type AiConversationStatus = z.infer<typeof AiConversationStatusSchema>;
|
|
101
|
+
export type AiConversationPurpose = z.infer<typeof AiConversationPurposeSchema>;
|
|
102
|
+
export type AiConversationList = z.infer<typeof AiConversationListSchema>;
|
|
103
|
+
export type AiConversationListItem = {
|
|
104
|
+
id: number;
|
|
105
|
+
potential_user_id: number | null;
|
|
106
|
+
user_id: number | null;
|
|
107
|
+
phone: string;
|
|
108
|
+
purpose: AiConversationPurpose;
|
|
109
|
+
subject_type: string;
|
|
110
|
+
status: AiConversationStatus;
|
|
111
|
+
ai_enabled: boolean;
|
|
112
|
+
human_takeover: boolean;
|
|
113
|
+
last_message_at: string | null;
|
|
114
|
+
created_at: string;
|
|
115
|
+
last_message: {
|
|
116
|
+
content: string;
|
|
117
|
+
direction: 'inbound' | 'outbound';
|
|
118
|
+
sender: 'user' | 'ai' | 'human';
|
|
119
|
+
created_at: string;
|
|
120
|
+
} | null;
|
|
121
|
+
/** Filled in by the marketplace from the potential user record. */
|
|
122
|
+
potential_user?: {
|
|
123
|
+
id: number;
|
|
124
|
+
name: string | null;
|
|
125
|
+
saved_by: number | null;
|
|
126
|
+
} | null;
|
|
127
|
+
};
|
|
128
|
+
export type AiConversationListResult = {
|
|
129
|
+
items: AiConversationListItem[];
|
|
130
|
+
page: number;
|
|
131
|
+
limit: number;
|
|
132
|
+
total: number;
|
|
133
|
+
total_pages: number;
|
|
134
|
+
/** Counts over all conversations matching purpose and search, not only this page. */
|
|
135
|
+
status_counts: Record<AiConversationStatus, number>;
|
|
136
|
+
active_count: number;
|
|
137
|
+
};
|
|
62
138
|
export type ConversationLanguage = z.infer<typeof ConversationLanguageSchema>;
|
|
63
139
|
export type StartAiConversation = z.infer<typeof StartAiConversationSchema>;
|
|
64
140
|
export type ConversationEventType = z.infer<typeof ConversationEventTypeSchema>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PotentialUserConversationEventSchema = exports.ConversationEventTypeSchema = exports.StartAiConversationSchema = exports.ConversationLanguageSchema = exports.MarketingSubjectTypeSchema = void 0;
|
|
3
|
+
exports.AiConversationListSchema = exports.AI_CONVERSATION_ACTIVE_STATUSES = exports.AiConversationPurposeSchema = exports.AiConversationStatusSchema = exports.PotentialUserConversationEventSchema = exports.ConversationEventTypeSchema = exports.StartAiConversationSchema = exports.ConversationLanguageSchema = exports.MarketingSubjectTypeSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
exports.MarketingSubjectTypeSchema = zod_1.z.enum([
|
|
6
6
|
'motors',
|
|
@@ -17,10 +17,8 @@ exports.StartAiConversationSchema = zod_1.z.object({
|
|
|
17
17
|
language: exports.ConversationLanguageSchema.default('ar'),
|
|
18
18
|
purpose: zod_1.z.literal('marketing'),
|
|
19
19
|
subject_type: exports.MarketingSubjectTypeSchema,
|
|
20
|
-
initial_message: zod_1.z.string().min(1),
|
|
21
20
|
context: zod_1.z.object({
|
|
22
21
|
name: zod_1.z.string().nullable().optional(),
|
|
23
|
-
reason: zod_1.z.string().min(1),
|
|
24
22
|
note: zod_1.z.string().nullable().optional(),
|
|
25
23
|
previous_contact_count: zod_1.z.number().int().nonnegative().default(0),
|
|
26
24
|
}),
|
|
@@ -41,3 +39,32 @@ exports.PotentialUserConversationEventSchema = zod_1.z.object({
|
|
|
41
39
|
event: exports.ConversationEventTypeSchema,
|
|
42
40
|
summary: zod_1.z.string().max(2000).nullable().optional(),
|
|
43
41
|
});
|
|
42
|
+
exports.AiConversationStatusSchema = zod_1.z.enum([
|
|
43
|
+
'starting',
|
|
44
|
+
'waiting_for_reply',
|
|
45
|
+
'chatting',
|
|
46
|
+
'interested',
|
|
47
|
+
'human_handoff',
|
|
48
|
+
'not_interested',
|
|
49
|
+
'converted',
|
|
50
|
+
'opted_out',
|
|
51
|
+
'closed',
|
|
52
|
+
'failed',
|
|
53
|
+
]);
|
|
54
|
+
exports.AiConversationPurposeSchema = zod_1.z.enum(['marketing', 'support']);
|
|
55
|
+
/** Statuses of a conversation that is still open with the customer. */
|
|
56
|
+
exports.AI_CONVERSATION_ACTIVE_STATUSES = [
|
|
57
|
+
'starting',
|
|
58
|
+
'waiting_for_reply',
|
|
59
|
+
'chatting',
|
|
60
|
+
'interested',
|
|
61
|
+
'human_handoff',
|
|
62
|
+
];
|
|
63
|
+
exports.AiConversationListSchema = zod_1.z.object({
|
|
64
|
+
page: zod_1.z.coerce.number().int().positive().default(1),
|
|
65
|
+
limit: zod_1.z.coerce.number().int().min(1).max(100).default(20),
|
|
66
|
+
statuses: zod_1.z.array(exports.AiConversationStatusSchema).max(10).optional(),
|
|
67
|
+
active_only: zod_1.z.boolean().default(false),
|
|
68
|
+
purpose: exports.AiConversationPurposeSchema.optional(),
|
|
69
|
+
search: zod_1.z.string().trim().max(100).optional(),
|
|
70
|
+
});
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export declare const SupportTicketStatusSchema: z.ZodEnum<{
|
|
3
|
+
closed: "closed";
|
|
3
4
|
open: "open";
|
|
4
5
|
assigned: "assigned";
|
|
5
6
|
in_progress: "in_progress";
|
|
6
7
|
waiting_customer: "waiting_customer";
|
|
7
8
|
resolved: "resolved";
|
|
8
|
-
closed: "closed";
|
|
9
9
|
reopened: "reopened";
|
|
10
10
|
}>;
|
|
11
11
|
export declare const SupportTicketPrioritySchema: z.ZodEnum<{
|
|
@@ -79,12 +79,12 @@ export declare const SupportTicketListSchema: z.ZodObject<{
|
|
|
79
79
|
page: z.ZodDefault<z.ZodNumber>;
|
|
80
80
|
limit: z.ZodDefault<z.ZodNumber>;
|
|
81
81
|
status: z.ZodOptional<z.ZodEnum<{
|
|
82
|
+
closed: "closed";
|
|
82
83
|
open: "open";
|
|
83
84
|
assigned: "assigned";
|
|
84
85
|
in_progress: "in_progress";
|
|
85
86
|
waiting_customer: "waiting_customer";
|
|
86
87
|
resolved: "resolved";
|
|
87
|
-
closed: "closed";
|
|
88
88
|
reopened: "reopened";
|
|
89
89
|
}>>;
|
|
90
90
|
priority: z.ZodOptional<z.ZodEnum<{
|
|
@@ -98,12 +98,12 @@ export declare const SupportTicketListSchema: z.ZodObject<{
|
|
|
98
98
|
export declare const SupportTicketStatusUpdateSchema: z.ZodObject<{
|
|
99
99
|
id: z.ZodNumber;
|
|
100
100
|
status: z.ZodEnum<{
|
|
101
|
+
closed: "closed";
|
|
101
102
|
open: "open";
|
|
102
103
|
assigned: "assigned";
|
|
103
104
|
in_progress: "in_progress";
|
|
104
105
|
waiting_customer: "waiting_customer";
|
|
105
106
|
resolved: "resolved";
|
|
106
|
-
closed: "closed";
|
|
107
107
|
reopened: "reopened";
|
|
108
108
|
}>;
|
|
109
109
|
}, z.core.$strip>;
|
|
@@ -63,5 +63,6 @@ export * as SocialMediaPlatform from "./media/SocialMediaPlatform";
|
|
|
63
63
|
export * as SocialMediaProfile from "./media/SocialMediaProfile";
|
|
64
64
|
export * as Kyc from "./kyc/Kyc";
|
|
65
65
|
export * as Google from "./integrations/Google";
|
|
66
|
+
export * as GeminiApiKey from "./integrations/GeminiApiKey";
|
|
66
67
|
export * as Analysis from "./analysis/AnalysisDailySnapshot";
|
|
67
68
|
export * as Payment from "./payments/Payment";
|
package/dist/cjs/types/index.js
CHANGED
|
@@ -37,7 +37,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.Loyalty = exports.Favorite = exports.Wallet = exports.Permission = exports.Role = exports.User = exports.EventVenue = exports.EventWedding = exports.EventTimeline = exports.EventRsvp = exports.Event = exports.District = exports.City = exports.AdminBoundary = exports.WorkType = exports.UsedProductCondition = exports.UsedProductAge = exports.Unit = exports.Transmission = exports.RegionalSpec = exports.PublisherType = exports.PropertyStatus = exports.PriceType = exports.OfferType = exports.LicenseType = exports.FuelType = exports.Feature = exports.Facility = exports.Currency = exports.Color = exports.CategoryWorkType = exports.Category = exports.CarBody = exports.UsedProduct = exports.Service = exports.PropertySubType = exports.Property = exports.MotorTrim = exports.Motor = exports.AdPromotion = exports.Addresses = exports.AdLocation = exports.Ad = exports.FilterParams = exports.ModuleFetchEndpoints = exports.Config = exports.AccessType = exports.Status = exports.Response = exports.LocalizedName = void 0;
|
|
40
|
-
exports.Payment = exports.Analysis = exports.Google = exports.Kyc = exports.SocialMediaProfile = exports.SocialMediaPlatform = exports.Image = exports.Media = exports.File = exports.NotificationToken = exports.MessageTemplate = exports.Device = exports.Chat = exports.AppStartScreen = exports.MetaData = exports.Company = exports.PotentialUser = void 0;
|
|
40
|
+
exports.Payment = exports.Analysis = exports.GeminiApiKey = exports.Google = exports.Kyc = exports.SocialMediaProfile = exports.SocialMediaPlatform = exports.Image = exports.Media = exports.File = exports.NotificationToken = exports.MessageTemplate = exports.Device = exports.Chat = exports.AppStartScreen = exports.MetaData = exports.Company = exports.PotentialUser = void 0;
|
|
41
41
|
// common
|
|
42
42
|
exports.LocalizedName = __importStar(require("./common/LocalizedName"));
|
|
43
43
|
exports.Response = __importStar(require("./common/Response"));
|
|
@@ -113,6 +113,7 @@ exports.SocialMediaProfile = __importStar(require("./media/SocialMediaProfile"))
|
|
|
113
113
|
exports.Kyc = __importStar(require("./kyc/Kyc"));
|
|
114
114
|
// integrations
|
|
115
115
|
exports.Google = __importStar(require("./integrations/Google"));
|
|
116
|
+
exports.GeminiApiKey = __importStar(require("./integrations/GeminiApiKey"));
|
|
116
117
|
// analysis
|
|
117
118
|
exports.Analysis = __importStar(require("./analysis/AnalysisDailySnapshot"));
|
|
118
119
|
// payments
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Gemini API key as the dashboard sees it. The key itself never leaves backend-core in this
|
|
3
|
+
* shape: only `api_key_masked` is sent.
|
|
4
|
+
*/
|
|
5
|
+
export type IGeminiApiKey = {
|
|
6
|
+
id: number;
|
|
7
|
+
name: string;
|
|
8
|
+
/** e.g. "AIza…f3Kq" */
|
|
9
|
+
api_key_masked: string;
|
|
10
|
+
model_name: string;
|
|
11
|
+
/** Dashboard order, starting at 1 */
|
|
12
|
+
sort_order: number;
|
|
13
|
+
is_active: boolean;
|
|
14
|
+
/** All tokens used with this key */
|
|
15
|
+
total_tokens: number;
|
|
16
|
+
/** Tokens used today; resets every day */
|
|
17
|
+
daily_tokens: number;
|
|
18
|
+
/** The day daily_tokens belongs to (YYYY-MM-DD) */
|
|
19
|
+
daily_usage_date: string | null;
|
|
20
|
+
/** The key is skipped until this time, after Gemini rejected it for quota */
|
|
21
|
+
cooldown_until: string | null;
|
|
22
|
+
last_used_at: string | null;
|
|
23
|
+
last_error: string | null;
|
|
24
|
+
created_at: string;
|
|
25
|
+
updated_at: string;
|
|
26
|
+
};
|
|
@@ -33,6 +33,14 @@ export const APP_ROUTES = {
|
|
|
33
33
|
pathname: "/ad/promotions/history/[ad_id]",
|
|
34
34
|
params: { ad_id: params.id },
|
|
35
35
|
}),
|
|
36
|
+
promotionDetails: (params) => ({
|
|
37
|
+
pathname: "/ad/promotions/details/[id]",
|
|
38
|
+
params: {
|
|
39
|
+
id: String(params.id),
|
|
40
|
+
ad_id: params.ad_id != null ? String(params.ad_id) : undefined,
|
|
41
|
+
promotion: params.data ? JSON.stringify(params.data) : undefined,
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
36
44
|
list: (params) => {
|
|
37
45
|
const filter = JSON.stringify(params);
|
|
38
46
|
if (params === null || params === void 0 ? void 0 : params.subject_type) {
|
|
@@ -77,6 +85,7 @@ export const APP_ROUTES = {
|
|
|
77
85
|
download: () => ({ pathname: "/system/download-app" }),
|
|
78
86
|
needMobileApp: () => ({ pathname: "/system/need-mobile-app" }),
|
|
79
87
|
noInternet: () => ({ pathname: "/system/no-internet" }),
|
|
88
|
+
savedData: () => ({ pathname: "/system/saved-data" }),
|
|
80
89
|
},
|
|
81
90
|
settings: {
|
|
82
91
|
selectCurrency: () => ({ pathname: "/settings/select-currency" }),
|
|
@@ -129,5 +138,40 @@ export const APP_ROUTES = {
|
|
|
129
138
|
},
|
|
130
139
|
wallet: {
|
|
131
140
|
details: () => ({ pathname: "/wallet" }),
|
|
141
|
+
topup: (amount) => ({
|
|
142
|
+
pathname: "/wallet/topup",
|
|
143
|
+
params: amount != null ? { amount: String(amount) } : undefined,
|
|
144
|
+
}),
|
|
145
|
+
},
|
|
146
|
+
addresses: {
|
|
147
|
+
list: () => ({ pathname: "/user/addresses" }),
|
|
148
|
+
new: (fromAdDraftId) => ({
|
|
149
|
+
pathname: "/user/addresses/new",
|
|
150
|
+
params: fromAdDraftId ? { fromAdDraftId } : undefined,
|
|
151
|
+
}),
|
|
152
|
+
edit: (id) => ({ pathname: "/user/addresses/[id]", params: { id: String(id) } }),
|
|
153
|
+
},
|
|
154
|
+
support: {
|
|
155
|
+
tickets: () => ({ pathname: "/system/support-tickets" }),
|
|
156
|
+
},
|
|
157
|
+
kyc: {
|
|
158
|
+
details: () => ({ pathname: "/kyc" }),
|
|
159
|
+
fromSettings: () => ({ pathname: "/kyc", params: { source: "settings" } }),
|
|
160
|
+
},
|
|
161
|
+
company: {
|
|
162
|
+
list: () => ({ pathname: "/company/list" }),
|
|
163
|
+
new: () => ({ pathname: "/company/new" }),
|
|
164
|
+
edit: (id) => ({ pathname: "/company/new", params: { id } }),
|
|
165
|
+
details: (id) => ({ pathname: "/company/details/[id]", params: { id } }),
|
|
166
|
+
},
|
|
167
|
+
venue: {
|
|
168
|
+
new: (companyId) => ({ pathname: "/venue/new", params: { company_id: companyId } }),
|
|
169
|
+
edit: (id) => ({ pathname: "/venue/new", params: { id } }),
|
|
170
|
+
details: (id) => ({ pathname: "/venue/details/[id]", params: { id } }),
|
|
171
|
+
},
|
|
172
|
+
event: {
|
|
173
|
+
new: (venueId) => ({ pathname: "/event/new", params: { venue_id: venueId } }),
|
|
174
|
+
edit: (id) => ({ pathname: "/event/new", params: { id } }),
|
|
175
|
+
details: (id) => ({ pathname: "/event/details/[id]", params: { id } }),
|
|
132
176
|
},
|
|
133
177
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/esm/dto/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export { AdDto } from './ad/Ad.dto.js';
|
|
|
2
2
|
export * as AD from './ad/Ad.dto.js';
|
|
3
3
|
export * as EVENTS from './events/index.js';
|
|
4
4
|
export * as Ai from './ai/Ai.dto.js';
|
|
5
|
+
export * as GEMINI_API_KEYS from './ai/gemini-api-key.dto.js';
|
|
5
6
|
export * as PAYMENTS from './payments/index.js';
|
|
6
7
|
export * as ADDRESSES from './addresses/addresses.dto.js';
|
|
7
8
|
export * as POTENTIAL_USERS from './potential-users/potential-user-import.dto.js';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Gemini API keys are stored in backend-core (one table) and shared by every Deallony service.
|
|
4
|
+
* The dashboard manages them through the admin schemas; other services lease a key and report
|
|
5
|
+
* the tokens they used through the internal schemas.
|
|
6
|
+
*/
|
|
7
|
+
const geminiApiKeyIdSchema = z.coerce.number().int().positive();
|
|
8
|
+
/** Gemini model ID, e.g. gemini-3.1-flash-lite */
|
|
9
|
+
export const geminiModelNameSchema = z.string().trim().min(1).max(100);
|
|
10
|
+
// ---------- Admin (dashboard) ----------
|
|
11
|
+
export const createGeminiApiKeySchema = z.object({
|
|
12
|
+
name: z.string().trim().min(1).max(255),
|
|
13
|
+
api_key: z.string().trim().min(20).max(512),
|
|
14
|
+
model_name: geminiModelNameSchema,
|
|
15
|
+
is_active: z.boolean().default(true),
|
|
16
|
+
});
|
|
17
|
+
/** Fields left out keep their current value; the key itself is only replaced when sent. */
|
|
18
|
+
export const updateGeminiApiKeySchema = z.object({
|
|
19
|
+
id: geminiApiKeyIdSchema,
|
|
20
|
+
name: z.string().trim().min(1).max(255).optional(),
|
|
21
|
+
api_key: z.string().trim().min(20).max(512).optional(),
|
|
22
|
+
model_name: geminiModelNameSchema.optional(),
|
|
23
|
+
is_active: z.boolean().optional(),
|
|
24
|
+
});
|
|
25
|
+
export const geminiApiKeyIdBodySchema = z.object({
|
|
26
|
+
id: geminiApiKeyIdSchema,
|
|
27
|
+
});
|
|
28
|
+
/** Every key ID in the new order: the first ID gets sort_order 1. */
|
|
29
|
+
export const reorderGeminiApiKeysSchema = z.object({
|
|
30
|
+
ids: z.array(geminiApiKeyIdSchema).min(1),
|
|
31
|
+
});
|
|
32
|
+
// ---------- Internal (other services) ----------
|
|
33
|
+
/** Ask backend-core for the least-used available key, optionally only keys for one model. */
|
|
34
|
+
export const leaseGeminiApiKeySchema = z.object({
|
|
35
|
+
model_name: geminiModelNameSchema.optional(),
|
|
36
|
+
});
|
|
37
|
+
export const leasedGeminiApiKeySchema = z.object({
|
|
38
|
+
id: z.number().int().positive(),
|
|
39
|
+
api_key: z.string(),
|
|
40
|
+
model_name: z.string(),
|
|
41
|
+
});
|
|
42
|
+
/** Sent after every Gemini call made with a leased key. */
|
|
43
|
+
export const reportGeminiApiKeyUsageSchema = z.object({
|
|
44
|
+
id: geminiApiKeyIdSchema,
|
|
45
|
+
/** usageMetadata.totalTokenCount of the Gemini response; 0 when the call failed */
|
|
46
|
+
total_tokens: z.coerce.number().int().min(0).default(0),
|
|
47
|
+
success: z.boolean().default(true),
|
|
48
|
+
/** HTTP status Gemini answered with, e.g. 429 */
|
|
49
|
+
error_code: z.coerce.number().int().optional(),
|
|
50
|
+
error_message: z.string().trim().max(2000).optional(),
|
|
51
|
+
});
|
|
@@ -14,10 +14,8 @@ export const StartAiConversationSchema = z.object({
|
|
|
14
14
|
language: ConversationLanguageSchema.default('ar'),
|
|
15
15
|
purpose: z.literal('marketing'),
|
|
16
16
|
subject_type: MarketingSubjectTypeSchema,
|
|
17
|
-
initial_message: z.string().min(1),
|
|
18
17
|
context: z.object({
|
|
19
18
|
name: z.string().nullable().optional(),
|
|
20
|
-
reason: z.string().min(1),
|
|
21
19
|
note: z.string().nullable().optional(),
|
|
22
20
|
previous_contact_count: z.number().int().nonnegative().default(0),
|
|
23
21
|
}),
|
|
@@ -38,3 +36,32 @@ export const PotentialUserConversationEventSchema = z.object({
|
|
|
38
36
|
event: ConversationEventTypeSchema,
|
|
39
37
|
summary: z.string().max(2000).nullable().optional(),
|
|
40
38
|
});
|
|
39
|
+
export const AiConversationStatusSchema = z.enum([
|
|
40
|
+
'starting',
|
|
41
|
+
'waiting_for_reply',
|
|
42
|
+
'chatting',
|
|
43
|
+
'interested',
|
|
44
|
+
'human_handoff',
|
|
45
|
+
'not_interested',
|
|
46
|
+
'converted',
|
|
47
|
+
'opted_out',
|
|
48
|
+
'closed',
|
|
49
|
+
'failed',
|
|
50
|
+
]);
|
|
51
|
+
export const AiConversationPurposeSchema = z.enum(['marketing', 'support']);
|
|
52
|
+
/** Statuses of a conversation that is still open with the customer. */
|
|
53
|
+
export const AI_CONVERSATION_ACTIVE_STATUSES = [
|
|
54
|
+
'starting',
|
|
55
|
+
'waiting_for_reply',
|
|
56
|
+
'chatting',
|
|
57
|
+
'interested',
|
|
58
|
+
'human_handoff',
|
|
59
|
+
];
|
|
60
|
+
export const AiConversationListSchema = z.object({
|
|
61
|
+
page: z.coerce.number().int().positive().default(1),
|
|
62
|
+
limit: z.coerce.number().int().min(1).max(100).default(20),
|
|
63
|
+
statuses: z.array(AiConversationStatusSchema).max(10).optional(),
|
|
64
|
+
active_only: z.boolean().default(false),
|
|
65
|
+
purpose: AiConversationPurposeSchema.optional(),
|
|
66
|
+
search: z.string().trim().max(100).optional(),
|
|
67
|
+
});
|
package/dist/esm/types/index.js
CHANGED
|
@@ -76,6 +76,7 @@ export * as SocialMediaProfile from "./media/SocialMediaProfile.js";
|
|
|
76
76
|
export * as Kyc from "./kyc/Kyc.js";
|
|
77
77
|
// integrations
|
|
78
78
|
export * as Google from "./integrations/Google.js";
|
|
79
|
+
export * as GeminiApiKey from "./integrations/GeminiApiKey.js";
|
|
79
80
|
// analysis
|
|
80
81
|
export * as Analysis from "./analysis/AnalysisDailySnapshot.js";
|
|
81
82
|
// payments
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deallony/shared",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.61",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -42,7 +42,6 @@
|
|
|
42
42
|
"deploy:git:minor": "node ./scripts/publish.js git minor",
|
|
43
43
|
"deploy:git:major": "node ./scripts/publish.js git major",
|
|
44
44
|
"deploy:git:dry-run": "node ./scripts/publish.js git patch --dry-run",
|
|
45
|
-
"test:release": "node --test scripts/publish.test.js",
|
|
46
45
|
"prepublishOnly": "npm run build"
|
|
47
46
|
},
|
|
48
47
|
"dependencies": {
|