@bisondesk/core-sdk 1.0.611 → 1.0.612
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/lib/constants.d.ts +2 -0
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +2 -0
- package/lib/constants.js.map +1 -1
- package/lib/types/activities.d.ts.map +1 -1
- package/lib/types/activities.js.map +1 -1
- package/lib/types/crm.d.ts +7 -1
- package/lib/types/crm.d.ts.map +1 -1
- package/lib/types/crm.js.map +1 -1
- package/lib/types/interests.d.ts +9 -14
- package/lib/types/interests.d.ts.map +1 -1
- package/lib/types/interests.js +2 -3
- package/lib/types/interests.js.map +1 -1
- package/lib/types/opportunities.d.ts +3 -2
- package/lib/types/opportunities.d.ts.map +1 -1
- package/lib/types/opportunities.js.map +1 -1
- package/lib/types/prospects.d.ts +126 -5
- package/lib/types/prospects.d.ts.map +1 -1
- package/lib/types/prospects.js +28 -0
- package/lib/types/prospects.js.map +1 -1
- package/lib/types/reports-sales.d.ts +8 -0
- package/lib/types/reports-sales.d.ts.map +1 -1
- package/lib/types/reports-sales.js +1 -0
- package/lib/types/reports-sales.js.map +1 -1
- package/lib/types/users.d.ts +2 -0
- package/lib/types/users.d.ts.map +1 -1
- package/lib/types/users.js.map +1 -1
- package/lib/types/vehicle-timeline.d.ts +96 -0
- package/lib/types/vehicle-timeline.d.ts.map +1 -0
- package/lib/types/vehicle-timeline.js +20 -0
- package/lib/types/vehicle-timeline.js.map +1 -0
- package/lib/types/vehicles.d.ts +4 -0
- package/lib/types/vehicles.d.ts.map +1 -1
- package/lib/types/vehicles.js.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +2 -0
- package/src/types/activities.js +13 -0
- package/src/types/activities.js.map +1 -0
- package/src/types/activities.ts +0 -1
- package/src/types/comparables.js +2 -0
- package/src/types/comparables.js.map +1 -0
- package/src/types/crm.js +58 -0
- package/src/types/crm.js.map +1 -0
- package/src/types/crm.ts +20 -1
- package/src/types/dashboard.js +2 -0
- package/src/types/dashboard.js.map +1 -0
- package/src/types/definitions.js +2 -0
- package/src/types/definitions.js.map +1 -0
- package/src/types/fields.js +2 -0
- package/src/types/fields.js.map +1 -0
- package/src/types/insights.js +2 -0
- package/src/types/insights.js.map +1 -0
- package/src/types/interests.js +6 -0
- package/src/types/interests.js.map +1 -0
- package/src/types/interests.ts +25 -20
- package/src/types/internal-events.js +18 -0
- package/src/types/internal-events.js.map +1 -0
- package/src/types/internet-opportunities.js +2 -0
- package/src/types/internet-opportunities.js.map +1 -0
- package/src/types/internet-vehicles.js +2 -0
- package/src/types/internet-vehicles.js.map +1 -0
- package/src/types/leasing-administration.js +2 -0
- package/src/types/leasing-administration.js.map +1 -0
- package/src/types/leasing-debtors.js +2 -0
- package/src/types/leasing-debtors.js.map +1 -0
- package/src/types/leasing-search.js +2 -0
- package/src/types/leasing-search.js.map +1 -0
- package/src/types/leasing-settings.js +7 -0
- package/src/types/leasing-settings.js.map +1 -0
- package/src/types/leasing.js +38 -0
- package/src/types/leasing.js.map +1 -0
- package/src/types/marketing.js +35 -0
- package/src/types/marketing.js.map +1 -0
- package/src/types/offers.js +56 -0
- package/src/types/opportunities.js +107 -0
- package/src/types/opportunities.js.map +1 -0
- package/src/types/opportunities.ts +5 -2
- package/src/types/payments.js +7 -0
- package/src/types/picklists.js +2 -0
- package/src/types/picklists.js.map +1 -0
- package/src/types/prospects.ts +281 -4
- package/src/types/quotes.js +42 -0
- package/src/types/recently-viewed.js +2 -0
- package/src/types/recently-viewed.js.map +1 -0
- package/src/types/reports-sales.ts +32 -0
- package/src/types/reservations.js +5 -0
- package/src/types/reservations.js.map +1 -0
- package/src/types/roi-ratings.js +5 -0
- package/src/types/roi-ratings.js.map +1 -0
- package/src/types/saved-filters.js +9 -0
- package/src/types/saved-filters.js.map +1 -0
- package/src/types/search.js +2 -0
- package/src/types/search.js.map +1 -0
- package/src/types/settings.js +2 -0
- package/src/types/settings.js.map +1 -0
- package/src/types/templates.js +2 -0
- package/src/types/templates.js.map +1 -0
- package/src/types/tenants.js +21 -0
- package/src/types/tenants.js.map +1 -0
- package/src/types/user-performance.js +7 -0
- package/src/types/user-performance.js.map +1 -0
- package/src/types/users.ts +2 -0
- package/src/types/utils.js +2 -0
- package/src/types/validation.js +2 -0
- package/src/types/validation.js.map +1 -0
- package/src/types/vehicle-sales.js +6 -0
- package/src/types/vehicle-sales.js.map +1 -0
- package/src/types/vehicle-timeline.ts +143 -0
- package/src/types/vehicles.js +98 -0
- package/src/types/vehicles.js.map +1 -0
- package/src/types/vehicles.ts +7 -0
- package/src/utils/leasing.js +6 -0
- package/src/utils/leasing.js.map +1 -0
- package/src/utils/opportunities.js +48 -0
- package/src/utils/opportunities.js.map +1 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/types/prospects.ts
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { Task } from '@bisondesk/commons-sdk/tasks';
|
|
2
|
-
import { MultiLangValue, NextList } from '@bisondesk/commons-sdk/types';
|
|
2
|
+
import { MultiLangValue, NextList, PaginatedList } from '@bisondesk/commons-sdk/types';
|
|
3
|
+
import { Activity } from './activities.js';
|
|
3
4
|
import { Contact, Organization } from './crm.js';
|
|
4
5
|
import { Interest } from './interests.js';
|
|
5
6
|
import { BaseEvent } from './internal-events.js';
|
|
6
|
-
import {
|
|
7
|
+
import { Offer } from './offers.js';
|
|
8
|
+
import { Opportunity } from './opportunities.js';
|
|
9
|
+
import { BaseSearchRequest, SearchRequest, SortFilter } from './search.js';
|
|
7
10
|
import { DataRecord, ReferenceData } from './utils.js';
|
|
8
11
|
|
|
9
12
|
export enum ProspectActions {
|
|
10
13
|
CLOSE = 'close',
|
|
11
14
|
REOPEN = 'reopen',
|
|
12
15
|
ENGAGE = 'engage',
|
|
16
|
+
// Claiming an unassigned prospect is open to any active sales rep — a deliberate widening of
|
|
17
|
+
// ADR-0013's permission matrix (ADR-0021 §7).
|
|
18
|
+
CLAIM = 'claim',
|
|
13
19
|
SET_METADATA = 'set_metadata',
|
|
14
20
|
SET_OBJECTIVES = 'set_objectives',
|
|
15
21
|
SET_CUSTOMER = 'set_customer',
|
|
@@ -46,20 +52,170 @@ export enum ProspectPriority {
|
|
|
46
52
|
LOW = 'low',
|
|
47
53
|
NORMAL = 'normal',
|
|
48
54
|
HIGH = 'high',
|
|
55
|
+
// "Call me" fast lane (ADR-0021 §8): a manual URGENT prospect sorts ahead of every
|
|
56
|
+
// engine-ranked card. Above NORMAL, priority dominates scoreTier in the "next" cursor.
|
|
57
|
+
URGENT = 'urgent',
|
|
49
58
|
}
|
|
50
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Numeric rank for priority, computed at index time into `custom.priorityRank` so OpenSearch
|
|
62
|
+
* can sort ordinally rather than alphabetically. Higher = more urgent.
|
|
63
|
+
*/
|
|
64
|
+
export const PRIORITY_RANK: Record<ProspectPriority, number> = {
|
|
65
|
+
[ProspectPriority.LOW]: 1,
|
|
66
|
+
[ProspectPriority.NORMAL]: 2,
|
|
67
|
+
[ProspectPriority.HIGH]: 3,
|
|
68
|
+
[ProspectPriority.URGENT]: 4,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* How a prospect entered the system (ADR-0021 §3). The engine's truncate-and-regenerate
|
|
73
|
+
* delete predicate only ever touches `AUTO` cards, so `MANUAL`/`IMPORT` cards survive
|
|
74
|
+
* regardless of status. `IMPORT` is reserved for the v2 import pipeline — nothing produces
|
|
75
|
+
* it in v1, but it stays in the enum because the discriminator is part of the delete-predicate
|
|
76
|
+
* safety contract.
|
|
77
|
+
*/
|
|
78
|
+
export enum ProspectSource {
|
|
79
|
+
MANUAL = 'manual',
|
|
80
|
+
AUTO = 'auto',
|
|
81
|
+
IMPORT = 'import',
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Discrete ranking band for an auto prospect (ADR-0021 §4). Each generator maps its own raw
|
|
86
|
+
* score into these bands via its own thresholds; the tier — not a raw number — is what the
|
|
87
|
+
* engine persists and the "next" cursor sorts on.
|
|
88
|
+
*/
|
|
89
|
+
export enum ProspectScoreTier {
|
|
90
|
+
COLD = 'cold',
|
|
91
|
+
LUKEWARM = 'lukewarm',
|
|
92
|
+
WARM = 'warm',
|
|
93
|
+
HOT = 'hot',
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Numeric rank for a score tier, computed at index time into `custom.scoreTierRank`
|
|
98
|
+
* (0 = unscored/no tier). Higher = warmer.
|
|
99
|
+
*/
|
|
100
|
+
export const SCORE_TIER_RANK: Record<ProspectScoreTier, number> = {
|
|
101
|
+
[ProspectScoreTier.COLD]: 1,
|
|
102
|
+
[ProspectScoreTier.LUKEWARM]: 2,
|
|
103
|
+
[ProspectScoreTier.WARM]: 3,
|
|
104
|
+
[ProspectScoreTier.HOT]: 4,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Virtual sort field for search requests: "importance" is the compound priority → tier
|
|
109
|
+
* ranking (ADR-0021 §5). The backend expands it server-side, so clients never spell out
|
|
110
|
+
* the underlying fields.
|
|
111
|
+
*/
|
|
112
|
+
export const PROSPECT_IMPORTANCE_SORT_FIELD = 'prospect.importance';
|
|
113
|
+
|
|
114
|
+
/** One line of the score breakdown recorded for explanation (raw score, thresholds, dampening). */
|
|
115
|
+
export type ProspectScoreDetail = {
|
|
116
|
+
name: string;
|
|
117
|
+
value: number | string;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Denormalized vehicle display data carried on each candidate vehicle, so the UI can render the
|
|
122
|
+
* anchor and runner-ups without a second fetch. Mirrors `InterestLead.vehicleData` (and extends it
|
|
123
|
+
* with make/model/category/vin), keeping the two card surfaces consistent.
|
|
124
|
+
*/
|
|
125
|
+
export type ProspectVehicleData = {
|
|
126
|
+
title: string;
|
|
127
|
+
mainPictureUrl?: string;
|
|
128
|
+
stockNumber?: string;
|
|
129
|
+
|
|
130
|
+
category: string;
|
|
131
|
+
bodywork?: string;
|
|
132
|
+
makeName: string;
|
|
133
|
+
modelName?: string;
|
|
134
|
+
typeName?: string;
|
|
135
|
+
|
|
136
|
+
used?: boolean; // Vehicle.condition.used — false/absent means new.
|
|
137
|
+
damaged?: boolean;
|
|
138
|
+
|
|
139
|
+
advertisingYear?: number;
|
|
140
|
+
km?: number;
|
|
141
|
+
emissionsClass?: string;
|
|
142
|
+
emissionsSubClass?: string;
|
|
143
|
+
cabinModel?: string;
|
|
144
|
+
configuration?: string;
|
|
145
|
+
vin?: string;
|
|
146
|
+
|
|
147
|
+
// Notable boolean equipment, mirroring Vehicle.accessories (and superstructure.crane).
|
|
148
|
+
features?: {
|
|
149
|
+
adr?: boolean;
|
|
150
|
+
jumbo?: boolean;
|
|
151
|
+
crane?: boolean;
|
|
152
|
+
hydraulicTipperKit?: boolean;
|
|
153
|
+
lowDeck?: boolean;
|
|
154
|
+
retarderIntarder?: boolean;
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/** A candidate anchor/runner-up vehicle, scored by the lead-engine matcher. */
|
|
159
|
+
export type ProspectVehicleCandidate = {
|
|
160
|
+
vehicleId: string;
|
|
161
|
+
/** Branch that holds this stock. The anchor's branch decides the card's branch (ADR-0021 §2). */
|
|
162
|
+
branchId: string;
|
|
163
|
+
score: number;
|
|
164
|
+
vehicleData: ProspectVehicleData;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/** A recommended account manager with an affinity score and the reasons behind it. */
|
|
168
|
+
export type ProspectRecommendedAm = {
|
|
169
|
+
userId: string;
|
|
170
|
+
score: number;
|
|
171
|
+
reasons: string[];
|
|
172
|
+
};
|
|
173
|
+
|
|
51
174
|
export type ProspectObjective = {
|
|
52
175
|
id: string;
|
|
53
176
|
title: MultiLangValue;
|
|
54
177
|
};
|
|
55
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Inline identity for a card whose person/company matches no CRM record yet — the "draft party"
|
|
181
|
+
* of ADR-0021 §9. Carries enough structure to materialise a Contact (first/last name, phone,
|
|
182
|
+
* email) and/or an Organization (orgName, VAT, country) when the draft is converted
|
|
183
|
+
* (`SET_CUSTOMER`, grown). Drafts enter through import or manual entry only — the engine never
|
|
184
|
+
* produces them — and the nightly truncate never touches them.
|
|
185
|
+
*/
|
|
186
|
+
export type ProspectPartyDraft = {
|
|
187
|
+
// contact identity
|
|
188
|
+
firstName?: string;
|
|
189
|
+
lastName?: string;
|
|
190
|
+
phone?: string;
|
|
191
|
+
email?: string;
|
|
192
|
+
// organization identity
|
|
193
|
+
orgName?: string;
|
|
194
|
+
vatNumber?: string;
|
|
195
|
+
countryCode?: string;
|
|
196
|
+
/**
|
|
197
|
+
* Client sector (Tier 1) and sub-industry (Tier 2), captured on the draft so they survive
|
|
198
|
+
* promotion to an Organization. Same picklists and semantics as the Organization fields of the
|
|
199
|
+
* same name (`ORG_INDUSTRY_PICKLIST_ID` / `SUB_INDUSTRY_PICKLIST_ID`).
|
|
200
|
+
*/
|
|
201
|
+
industry?: string;
|
|
202
|
+
subIndustry?: string;
|
|
203
|
+
/**
|
|
204
|
+
* The draft party's interests, embedded on the card — a draft has no CRM record to hang
|
|
205
|
+
* interests on, so they ride the card until conversion copies them onto the linked
|
|
206
|
+
* Contact/Organization (where the lead engine picks them up; embedded ones never feed it).
|
|
207
|
+
*/
|
|
208
|
+
interests?: Interest[];
|
|
209
|
+
};
|
|
210
|
+
|
|
56
211
|
type BaseProspect = {
|
|
57
212
|
contactId?: string;
|
|
58
213
|
organizationId?: string;
|
|
214
|
+
/** Draft-party identity when the card is linked to no Contact/Organization yet (ADR §9). */
|
|
215
|
+
partyDraft?: ProspectPartyDraft;
|
|
59
216
|
branchId: string;
|
|
60
217
|
accountManager?: string;
|
|
61
218
|
priority: ProspectPriority;
|
|
62
|
-
score?: number;
|
|
63
219
|
objectives: ProspectObjective[];
|
|
64
220
|
};
|
|
65
221
|
|
|
@@ -76,6 +232,17 @@ export type Prospect = BaseProspect & {
|
|
|
76
232
|
|
|
77
233
|
status: ProspectStatus;
|
|
78
234
|
|
|
235
|
+
// ── Engine-owned fields (ADR-0021). The manual write path treats these as read-only
|
|
236
|
+
// (Joi.forbidden in the user schemas) so a human edit is never silently overwritten by the
|
|
237
|
+
// next nightly run. `source` is always present on a persisted card; the rest exist only on
|
|
238
|
+
// scored auto cards.
|
|
239
|
+
source: ProspectSource;
|
|
240
|
+
scoreTier?: ProspectScoreTier;
|
|
241
|
+
scoreDetails?: ProspectScoreDetail[];
|
|
242
|
+
/** Ordered by score desc; `vehicles[0]` is the anchor the rep opens the call with. */
|
|
243
|
+
vehicles?: ProspectVehicleCandidate[];
|
|
244
|
+
recommendedAccountManagers?: ProspectRecommendedAm[];
|
|
245
|
+
|
|
79
246
|
attemptingAt?: string;
|
|
80
247
|
attemptingBy?: string;
|
|
81
248
|
engagedAt?: string;
|
|
@@ -93,10 +260,10 @@ export type Prospect = BaseProspect & {
|
|
|
93
260
|
export type ProspectUpdate = {
|
|
94
261
|
contactId?: string | null;
|
|
95
262
|
organizationId?: string | null;
|
|
263
|
+
partyDraft?: ProspectPartyDraft | null;
|
|
96
264
|
branchId?: string;
|
|
97
265
|
accountManager?: string | null;
|
|
98
266
|
priority?: ProspectPriority;
|
|
99
|
-
score?: number | null;
|
|
100
267
|
objectives?: ProspectObjective[];
|
|
101
268
|
|
|
102
269
|
close?: boolean;
|
|
@@ -110,6 +277,19 @@ export type ProspectBff = {
|
|
|
110
277
|
contact?: DataRecord<Contact>;
|
|
111
278
|
org?: DataRecord<Organization>;
|
|
112
279
|
tasks: DataRecord<Task>[];
|
|
280
|
+
|
|
281
|
+
/** All interests in scope: the linked contact/org's, or the draft party's embedded ones. */
|
|
282
|
+
interests: Interest[];
|
|
283
|
+
/** Opportunities for the linked contact/org, deduped by id. */
|
|
284
|
+
opportunities: Opportunity[];
|
|
285
|
+
/** Offers for the linked contact/org, deduped by id, newest first. */
|
|
286
|
+
offers: Offer[];
|
|
287
|
+
/** The other prospect lines on the same contact/org (this one excluded), newest first. */
|
|
288
|
+
relatedProspects: Prospect[];
|
|
289
|
+
/** Most-recent interaction history (first page): the card's own + linked contact/org activities. */
|
|
290
|
+
activities: DataRecord<Activity>[];
|
|
291
|
+
/** Cursor for the next page of the merged activity history; absent when fully loaded. */
|
|
292
|
+
activitiesNextToken?: string;
|
|
113
293
|
};
|
|
114
294
|
|
|
115
295
|
/************
|
|
@@ -134,17 +314,107 @@ export type SearchProspect = {
|
|
|
134
314
|
* Country of the lead, preferring contact country over org country when both are set.
|
|
135
315
|
*/
|
|
136
316
|
country?: string;
|
|
317
|
+
/**
|
|
318
|
+
* Numeric ranks computed at index time so OpenSearch sorts ordinally, not alphabetically
|
|
319
|
+
* (ADR-0021 §4, §5). The "next" cursor sorts priorityRank desc → scoreTierRank desc → id asc.
|
|
320
|
+
*/
|
|
321
|
+
priorityRank: number;
|
|
322
|
+
/** 0 = unscored (no tier yet). */
|
|
323
|
+
scoreTierRank: number;
|
|
324
|
+
/** User ids from `recommendedAccountManagers`, for the "suitable for me" filter (ADR §6). */
|
|
325
|
+
recommendedAmIds?: string[];
|
|
326
|
+
/**
|
|
327
|
+
* Collapse key for grouping by main vehicle (minimizing context switch): the anchor's
|
|
328
|
+
* vehicleId when the card carries vehicles, else the prospect id (a singleton group).
|
|
329
|
+
* Mirrors the opportunities kanban's `custom.groupKey` (group-by-client) convention.
|
|
330
|
+
*/
|
|
331
|
+
groupKey: string;
|
|
332
|
+
};
|
|
333
|
+
/** Task counters denormalized at index time, for kanban/list badges. */
|
|
334
|
+
tasks?: {
|
|
335
|
+
totalTasks: number;
|
|
336
|
+
openTasks: number;
|
|
337
|
+
/** Soonest due date among open tasks. */
|
|
338
|
+
nextDueAt?: string;
|
|
137
339
|
};
|
|
138
340
|
};
|
|
139
341
|
|
|
342
|
+
/************
|
|
343
|
+
*
|
|
344
|
+
* Claim
|
|
345
|
+
*/
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Returned with HTTP 409 when a guarded claim finds the prospect already owned (a lost race). On
|
|
349
|
+
* success the endpoint returns the claimed `DataRecord<Prospect>` with 200 instead (ADR-0021 §7).
|
|
350
|
+
*/
|
|
351
|
+
export type ProspectClaimConflict = {
|
|
352
|
+
claimed: false;
|
|
353
|
+
accountManager?: string;
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
/************
|
|
357
|
+
*
|
|
358
|
+
* Next cursor / play mode
|
|
359
|
+
*/
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* The "next prospect" cursor (ADR-0021 §5). Accepts the same filter body as the list search, so
|
|
363
|
+
* "next" walks the rep's current view. Only the filter-defining fields are honored — sort, paging
|
|
364
|
+
* size and `nextToken` are owned by the endpoint (fixed priority→tier sort, `cursor` below). `cursor`
|
|
365
|
+
* is an opaque token embedding the sort position and a hash of the filters — it is rejected if the
|
|
366
|
+
* filter set changed. `claim: true` is play mode: the next matching unassigned card is served and
|
|
367
|
+
* claimed atomically (ADR §7).
|
|
368
|
+
*/
|
|
369
|
+
export type ProspectNextRequest = Pick<SearchRequest, 'fullText' | 'query' | 'geoFilters'> & {
|
|
370
|
+
cursor?: string;
|
|
371
|
+
claim?: boolean;
|
|
372
|
+
/**
|
|
373
|
+
* Serve cards grouped by main vehicle (minimizing context switch): all matching cards anchored
|
|
374
|
+
* on the same vehicle come consecutively before "next" moves to the following vehicle group.
|
|
375
|
+
*/
|
|
376
|
+
groupByVehicle?: boolean;
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
export type ProspectNextResponse = {
|
|
380
|
+
result?: SearchProspect;
|
|
381
|
+
cursor?: string;
|
|
382
|
+
meta: ReferenceData;
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
/** A main-vehicle group (ES collapse on `custom.groupKey`), shared by kanban and list. */
|
|
386
|
+
export type ProspectVehicleGroup = {
|
|
387
|
+
representative: SearchProspect;
|
|
388
|
+
items: SearchProspect[];
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
/** Flat list search, optionally collapsed by the card's main vehicle. */
|
|
392
|
+
export type ProspectsSearchRequest = SearchRequest & {
|
|
393
|
+
/** Collapse on `custom.groupKey`: the page then streams GROUPS (offset-paged), not rows. */
|
|
394
|
+
groupByVehicle?: boolean;
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
export type ProspectsSearchResponse = PaginatedList<SearchProspect, ReferenceData> & {
|
|
398
|
+
/**
|
|
399
|
+
* Populated only when `groupByVehicle` is requested; `results` is then empty and
|
|
400
|
+
* `totalCount` counts groups (collapse cardinality), not rows.
|
|
401
|
+
*/
|
|
402
|
+
groups?: ProspectVehicleGroup[];
|
|
403
|
+
};
|
|
404
|
+
|
|
140
405
|
/************
|
|
141
406
|
*
|
|
142
407
|
* Kanban
|
|
143
408
|
*/
|
|
144
409
|
|
|
410
|
+
/** A main-vehicle group inside a kanban column when `groupByVehicle` is on. */
|
|
411
|
+
export type KanbanProspectGroup = ProspectVehicleGroup;
|
|
412
|
+
|
|
145
413
|
export type ProspectsKanbanColumn = {
|
|
146
414
|
status: string;
|
|
147
415
|
results: SearchProspect[];
|
|
416
|
+
/** Populated only when `groupByVehicle` is requested; `results` is then empty. */
|
|
417
|
+
groups?: KanbanProspectGroup[];
|
|
148
418
|
totalCount: number;
|
|
149
419
|
};
|
|
150
420
|
|
|
@@ -155,6 +425,13 @@ export type MSearchProspectsKanbanColumn = {
|
|
|
155
425
|
|
|
156
426
|
export type KanbanProspectsSearchRequest = BaseSearchRequest & {
|
|
157
427
|
nextTokens?: Record<string, string | undefined>;
|
|
428
|
+
/** Collapse each column by the card's main vehicle (mirrors opportunities' group-by-client). */
|
|
429
|
+
groupByVehicle?: boolean;
|
|
430
|
+
/**
|
|
431
|
+
* Per-column sort overrides, keyed by prospect status. Unlisted columns keep their defaults:
|
|
432
|
+
* the nurture column sorts by the priority→tier "next" order, the rest newest-first.
|
|
433
|
+
*/
|
|
434
|
+
statusSortBy?: Partial<Record<ProspectStatus, SortFilter[]>>;
|
|
158
435
|
};
|
|
159
436
|
|
|
160
437
|
export type KanbanProspectsNextList = Omit<
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export var QuoteActions;
|
|
2
|
+
(function (QuoteActions) {
|
|
3
|
+
QuoteActions["ACCEPT"] = "accept";
|
|
4
|
+
QuoteActions["VALIDATE"] = "validate";
|
|
5
|
+
QuoteActions["DONWLOAD_PDFS"] = "download-pdfs";
|
|
6
|
+
QuoteActions["CANCEL"] = "cancel";
|
|
7
|
+
})(QuoteActions || (QuoteActions = {}));
|
|
8
|
+
export var QuoteStatus;
|
|
9
|
+
(function (QuoteStatus) {
|
|
10
|
+
QuoteStatus["CREATED"] = "created";
|
|
11
|
+
QuoteStatus["VALIDATED"] = "validated";
|
|
12
|
+
QuoteStatus["INVALIDATED"] = "invalidated";
|
|
13
|
+
QuoteStatus["ACCEPTED"] = "accepted";
|
|
14
|
+
QuoteStatus["REJECTED"] = "rejected";
|
|
15
|
+
QuoteStatus["CANCELLED"] = "cancelled";
|
|
16
|
+
QuoteStatus["MANAGER_REJECTED"] = "managerRejected";
|
|
17
|
+
QuoteStatus["MANAGER_ACCEPTED"] = "managerAccepted";
|
|
18
|
+
})(QuoteStatus || (QuoteStatus = {}));
|
|
19
|
+
export var QuoteMetricsScore;
|
|
20
|
+
(function (QuoteMetricsScore) {
|
|
21
|
+
QuoteMetricsScore["DANGER"] = "danger";
|
|
22
|
+
QuoteMetricsScore["NEUTRAL"] = "neutral";
|
|
23
|
+
QuoteMetricsScore["GOOD"] = "good";
|
|
24
|
+
})(QuoteMetricsScore || (QuoteMetricsScore = {}));
|
|
25
|
+
export var DeliveryTypes;
|
|
26
|
+
(function (DeliveryTypes) {
|
|
27
|
+
DeliveryTypes["PICK_UP"] = "pickUp";
|
|
28
|
+
DeliveryTypes["ADDRESS"] = "address";
|
|
29
|
+
DeliveryTypes["PORT"] = "port";
|
|
30
|
+
})(DeliveryTypes || (DeliveryTypes = {}));
|
|
31
|
+
export var SpoilerInfo;
|
|
32
|
+
(function (SpoilerInfo) {
|
|
33
|
+
SpoilerInfo["MOUNT"] = "mount";
|
|
34
|
+
SpoilerInfo["UNMOUNT"] = "unmount";
|
|
35
|
+
SpoilerInfo["NO_ACTION"] = "noAction";
|
|
36
|
+
})(SpoilerInfo || (SpoilerInfo = {}));
|
|
37
|
+
export var TransportationMode;
|
|
38
|
+
(function (TransportationMode) {
|
|
39
|
+
TransportationMode["BY_ROAD"] = "byRoad";
|
|
40
|
+
TransportationMode["ON_LOW_BED"] = "onLowBed";
|
|
41
|
+
})(TransportationMode || (TransportationMode = {}));
|
|
42
|
+
//# sourceMappingURL=quotes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recently-viewed.js","sourceRoot":"","sources":["recently-viewed.ts"],"names":[],"mappings":""}
|
|
@@ -108,6 +108,26 @@ export type SalesReportHistogramBucket = {
|
|
|
108
108
|
count: number;
|
|
109
109
|
};
|
|
110
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Age-of-stock bands, in days of capital tied up. Cut points at 30 / 90 / 180 days,
|
|
113
|
+
* upper bound inclusive; the last band is open-ended, so `180+` means "181 and over".
|
|
114
|
+
*/
|
|
115
|
+
export const STOCK_AGE_BANDS = ['0-30', '31-90', '91-180', '180+'] as const;
|
|
116
|
+
|
|
117
|
+
export type StockAgeBand = (typeof STOCK_AGE_BANDS)[number];
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* One day on the stock-age chart, measured by capital tied up in inventory. A vehicle
|
|
121
|
+
* counts on `date` when the supplier was fully paid on or before that day and it had not
|
|
122
|
+
* been sold yet; its age is `date − supplierFullyPaidAt` in days. Used vehicles only.
|
|
123
|
+
*/
|
|
124
|
+
export type StockAgePoint = {
|
|
125
|
+
/** Snapshot day, `YYYY-MM-DD` (UTC). */
|
|
126
|
+
date: string;
|
|
127
|
+
/** In-stock vehicle count per age band on that day. */
|
|
128
|
+
counts: Record<StockAgeBand, number>;
|
|
129
|
+
};
|
|
130
|
+
|
|
111
131
|
export type SalesReportResponse = {
|
|
112
132
|
period: {
|
|
113
133
|
key: SalesPeriodKey;
|
|
@@ -142,4 +162,16 @@ export type SalesReportResponse = {
|
|
|
142
162
|
conglomerate: SalesReportConglomerate;
|
|
143
163
|
/** Fixed last-18-calendar-months histogram of opps into Preparation (period-independent). */
|
|
144
164
|
histogram: SalesReportHistogramBucket[];
|
|
165
|
+
/**
|
|
166
|
+
* Stock-age evolution measured as capital tied up in inventory: one daily snapshot of
|
|
167
|
+
* vehicles by days from supplier-fully-paid to sold (used vehicles). Fixed to the last
|
|
168
|
+
* 6 months, period-independent.
|
|
169
|
+
*/
|
|
170
|
+
stockAge: StockAgePoint[];
|
|
171
|
+
/**
|
|
172
|
+
* Customer concentration: the 10 largest customers' share of units in the window, as a
|
|
173
|
+
* fraction (0–1); null when there are no sales. A risk signal — over-reliance on a few
|
|
174
|
+
* buyers.
|
|
175
|
+
*/
|
|
176
|
+
concentration: number | null;
|
|
145
177
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reservations.js","sourceRoot":"","sources":["reservations.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,kBAEX;AAFD,WAAY,kBAAkB;IAC5B,kEAA4C,CAAA;AAC9C,CAAC,EAFW,kBAAkB,KAAlB,kBAAkB,QAE7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roi-ratings.js","sourceRoot":"","sources":["roi-ratings.ts"],"names":[],"mappings":"AAIA,MAAM,CAAN,IAAY,WAEX;AAFD,WAAY,WAAW;IACrB,2CAA4B,CAAA;AAC9B,CAAC,EAFW,WAAW,KAAX,WAAW,QAEtB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export var SavedFiltersActions;
|
|
2
|
+
(function (SavedFiltersActions) {
|
|
3
|
+
SavedFiltersActions["Share"] = "share";
|
|
4
|
+
SavedFiltersActions["Update"] = "update";
|
|
5
|
+
SavedFiltersActions["Delete"] = "delete";
|
|
6
|
+
SavedFiltersActions["SetPersonalDefault"] = "set_own_default";
|
|
7
|
+
SavedFiltersActions["SetGlobalDefault"] = "set_global_default";
|
|
8
|
+
})(SavedFiltersActions || (SavedFiltersActions = {}));
|
|
9
|
+
//# sourceMappingURL=saved-filters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saved-filters.js","sourceRoot":"","sources":["saved-filters.ts"],"names":[],"mappings":"AAsBA,MAAM,CAAN,IAAY,mBAMX;AAND,WAAY,mBAAmB;IAC7B,sCAAe,CAAA;IACf,wCAAiB,CAAA;IACjB,wCAAiB,CAAA;IACjB,6DAAsC,CAAA;IACtC,8DAAuC,CAAA;AACzC,CAAC,EANW,mBAAmB,KAAnB,mBAAmB,QAM9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["search.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["settings.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["templates.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export var TenantModule;
|
|
2
|
+
(function (TenantModule) {
|
|
3
|
+
TenantModule["Administration"] = "administration";
|
|
4
|
+
TenantModule["App"] = "app";
|
|
5
|
+
TenantModule["CRM"] = "crm";
|
|
6
|
+
TenantModule["Docs"] = "docs";
|
|
7
|
+
TenantModule["Leads"] = "leads";
|
|
8
|
+
TenantModule["Leasing"] = "leasing";
|
|
9
|
+
TenantModule["Marketing"] = "marketing";
|
|
10
|
+
TenantModule["Insights"] = "insights";
|
|
11
|
+
TenantModule["Opportunities"] = "opportunities";
|
|
12
|
+
TenantModule["Offers"] = "offers";
|
|
13
|
+
TenantModule["VehiclesMasterData"] = "vehicles_master_data";
|
|
14
|
+
TenantModule["Vehicles"] = "vehicles";
|
|
15
|
+
TenantModule["Tasks"] = "tasks";
|
|
16
|
+
TenantModule["TrackAndTrace"] = "track_and_trace";
|
|
17
|
+
TenantModule["Bootstrap"] = "bootstrap";
|
|
18
|
+
TenantModule["WhatsappNotifications"] = "whatsapp_notifications";
|
|
19
|
+
TenantModule["Hexon"] = "hexon";
|
|
20
|
+
})(TenantModule || (TenantModule = {}));
|
|
21
|
+
//# sourceMappingURL=tenants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenants.js","sourceRoot":"","sources":["tenants.ts"],"names":[],"mappings":"AAgBA,MAAM,CAAN,IAAY,YAkBX;AAlBD,WAAY,YAAY;IACtB,iDAAiC,CAAA;IACjC,2BAAW,CAAA;IACX,2BAAW,CAAA;IACX,6BAAa,CAAA;IACb,+BAAe,CAAA;IACf,mCAAmB,CAAA;IACnB,uCAAuB,CAAA;IACvB,qCAAqB,CAAA;IACrB,+CAA+B,CAAA;IAC/B,iCAAiB,CAAA;IACjB,2DAA2C,CAAA;IAC3C,qCAAqB,CAAA;IACrB,+BAAe,CAAA;IACf,iDAAiC,CAAA;IACjC,uCAAuB,CAAA;IACvB,gEAAgD,CAAA;IAChD,+BAAe,CAAA;AACjB,CAAC,EAlBW,YAAY,KAAZ,YAAY,QAkBvB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export var CommissionGrade;
|
|
2
|
+
(function (CommissionGrade) {
|
|
3
|
+
CommissionGrade["TooLow"] = "tooLow";
|
|
4
|
+
CommissionGrade["Low"] = "low";
|
|
5
|
+
CommissionGrade["OnTarget"] = "onTarget";
|
|
6
|
+
})(CommissionGrade || (CommissionGrade = {}));
|
|
7
|
+
//# sourceMappingURL=user-performance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-performance.js","sourceRoot":"","sources":["user-performance.ts"],"names":[],"mappings":"AAsCA,MAAM,CAAN,IAAY,eAIX;AAJD,WAAY,eAAe;IACzB,oCAAiB,CAAA;IACjB,8BAAW,CAAA;IACX,wCAAqB,CAAA;AACvB,CAAC,EAJW,eAAe,KAAf,eAAe,QAI1B"}
|
package/src/types/users.ts
CHANGED
|
@@ -13,8 +13,10 @@ type BaseUser = {
|
|
|
13
13
|
jobTitle?: string;
|
|
14
14
|
language: string;
|
|
15
15
|
lastName: string;
|
|
16
|
+
nationality?: string;
|
|
16
17
|
picture?: AttachmentValue;
|
|
17
18
|
roles: AppRoles[];
|
|
19
|
+
spokenLanguages?: string[];
|
|
18
20
|
preferredBranchIds?: string[];
|
|
19
21
|
preferredOpportunityTypes?: OpportunityType[];
|
|
20
22
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["validation.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export var VehicleSaleInfoActions;
|
|
2
|
+
(function (VehicleSaleInfoActions) {
|
|
3
|
+
VehicleSaleInfoActions["VIEW_COSTS"] = "canSeeCosts";
|
|
4
|
+
VehicleSaleInfoActions["VIEW_CUSTOMER"] = "canSeeCustomer";
|
|
5
|
+
})(VehicleSaleInfoActions || (VehicleSaleInfoActions = {}));
|
|
6
|
+
//# sourceMappingURL=vehicle-sales.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vehicle-sales.js","sourceRoot":"","sources":["vehicle-sales.ts"],"names":[],"mappings":"AAOA,MAAM,CAAN,IAAY,sBAGX;AAHD,WAAY,sBAAsB;IAChC,oDAA0B,CAAA;IAC1B,0DAAgC,CAAA;AAClC,CAAC,EAHW,sBAAsB,KAAtB,sBAAsB,QAGjC"}
|