platform-types 1.10.852 → 1.10.853
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/dist/cjs/index.js +1 -0
- package/dist/cjs/serviceOrder.js +5 -0
- package/dist/cjs/serviceTracking.js +64 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/serviceOrder.d.ts +11 -1
- package/dist/serviceOrder.js +5 -0
- package/dist/serviceTracking.d.ts +216 -0
- package/dist/serviceTracking.js +61 -0
- package/dist/store.d.ts +14 -1
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -103,6 +103,7 @@ __exportStar(require("./rma.js"), exports);
|
|
|
103
103
|
__exportStar(require("./roles.js"), exports);
|
|
104
104
|
__exportStar(require("./sentry.js"), exports);
|
|
105
105
|
__exportStar(require("./serviceOrder.js"), exports);
|
|
106
|
+
__exportStar(require("./serviceTracking.js"), exports);
|
|
106
107
|
__exportStar(require("./serviceTemplate.js"), exports);
|
|
107
108
|
__exportStar(require("./socket.js"), exports);
|
|
108
109
|
__exportStar(require("./stock.js"), exports);
|
package/dist/cjs/serviceOrder.js
CHANGED
|
@@ -301,6 +301,11 @@ exports.SERVICE_ORDER_ERROR_CODES = [
|
|
|
301
301
|
'WARRANTY_BELOW_LEGAL_MINIMUM',
|
|
302
302
|
'TECHNICIAN_NOT_FOUND',
|
|
303
303
|
'TECHNICIAN_NOT_ELIGIBLE',
|
|
304
|
+
// The customer tracking link (`mode: 'trackingLink'`) — see `SERVICE_TRACKING_OPERATOR_ERROR_CODES`
|
|
305
|
+
'SERVICE_TRACKING_DISABLED',
|
|
306
|
+
'SERVICE_TRACKING_NO_ADDRESS',
|
|
307
|
+
'SERVICE_TRACKING_LINK_LAPSED',
|
|
308
|
+
'ADMIN_REQUIRED',
|
|
304
309
|
'CUSTODY_ILLEGAL_TRANSITION',
|
|
305
310
|
'SERVICE_ORDER_BILLABLE_FROZEN',
|
|
306
311
|
'SERVICE_ORDER_EDIT_CHANGED',
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Customer service-order tracking — the page a customer opens from a link a
|
|
4
|
+
* shop sends (`/servicio/{handle}`), and the same view for a signed-in customer
|
|
5
|
+
* on their account.
|
|
6
|
+
*
|
|
7
|
+
* The HANDLE is 16 base62 characters (~95 bits), stored server-side and a
|
|
8
|
+
* bearer credential over exactly ONE service order of one store. It authorises
|
|
9
|
+
* the read (`GET /services/tracking?handle=`) and the current presupuesto PDF
|
|
10
|
+
* (`GET /services/tracking?handle=&mode=quote-pdf`), and nothing else. Every
|
|
11
|
+
* earlier link of an order dies when staff revoke it. A link stops reading
|
|
12
|
+
* `serviceTrackingLinkDaysAfterClose` days (platform global, default 90) after
|
|
13
|
+
* the order reached a terminal status.
|
|
14
|
+
*
|
|
15
|
+
* The gate is `ecommerce.config.serviceTracking` AND the `workshop` module on.
|
|
16
|
+
* With the gate off, staff cannot mint and the signed-in reads refuse, but a
|
|
17
|
+
* link minted earlier keeps reading (STORE_MODULES rule 4).
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.SERVICE_TRACKING_HANDLE_RE = exports.SERVICE_TRACKING_PATH_PREFIX = exports.SERVICE_TRACKING_LINK_ACTIONS = exports.SERVICE_TRACKING_OPERATOR_ERROR_CODES = exports.SERVICE_TRACKING_ACCOUNT_ERROR_CODES = exports.SERVICE_TRACKING_ERROR_CODES = void 0;
|
|
21
|
+
/**
|
|
22
|
+
* The refusals the PUBLIC tracking routes answer themselves.
|
|
23
|
+
*
|
|
24
|
+
* - SERVICE_TRACKING_TOKEN_INVALID (401): every reason a handle cannot be
|
|
25
|
+
* honoured — missing, malformed, unknown, revoked, past the lifetime,
|
|
26
|
+
* presented on another store's host or with no store host at all, or naming
|
|
27
|
+
* an order that is gone or disabled — with one identical body, so a handle is
|
|
28
|
+
* never an oracle.
|
|
29
|
+
* - SERVICE_QUOTE_NOT_FOUND (404, `mode=quote-pdf` only): the order has no
|
|
30
|
+
* current presupuesto a customer was sent.
|
|
31
|
+
*/
|
|
32
|
+
exports.SERVICE_TRACKING_ERROR_CODES = ['SERVICE_TRACKING_TOKEN_INVALID', 'SERVICE_QUOTE_NOT_FOUND'];
|
|
33
|
+
/**
|
|
34
|
+
* The refusals of the signed-in reads (`GET /user?mode=service-orders` and
|
|
35
|
+
* `?mode=service-order&serviceOrderId=`).
|
|
36
|
+
*
|
|
37
|
+
* - SERVICE_TRACKING_DISABLED (403): the store's gate is off.
|
|
38
|
+
* - SERVICE_ORDER_NOT_FOUND (404): no such order, a disabled one, or one that
|
|
39
|
+
* belongs to another customer — one answer for all three.
|
|
40
|
+
*/
|
|
41
|
+
exports.SERVICE_TRACKING_ACCOUNT_ERROR_CODES = ['SERVICE_TRACKING_DISABLED', 'SERVICE_ORDER_NOT_FOUND'];
|
|
42
|
+
/**
|
|
43
|
+
* The refusals of the staff `POST /services { mode: 'trackingLink' }`, beside
|
|
44
|
+
* the router's own (`ROLE_FORBIDDEN`, `VALIDATION_FAILED`, `SERVICE_ORDER_NOT_FOUND`).
|
|
45
|
+
*
|
|
46
|
+
* - SERVICE_TRACKING_DISABLED (403, mint only): the store's gate is off.
|
|
47
|
+
* - SERVICE_TRACKING_NO_ADDRESS (409, mint only): the store has no public
|
|
48
|
+
* storefront address to build the link on (no slug, or public links off).
|
|
49
|
+
* - SERVICE_TRACKING_LINK_LAPSED (409, mint only): the order closed more than
|
|
50
|
+
* `serviceTrackingLinkDaysAfterClose` days ago, so a link would not read.
|
|
51
|
+
* - ADMIN_REQUIRED (403, revoke only): revoking takes ADMIN, SUPERVISOR or MANAGER.
|
|
52
|
+
*/
|
|
53
|
+
exports.SERVICE_TRACKING_OPERATOR_ERROR_CODES = [
|
|
54
|
+
'SERVICE_TRACKING_DISABLED',
|
|
55
|
+
'SERVICE_TRACKING_NO_ADDRESS',
|
|
56
|
+
'SERVICE_TRACKING_LINK_LAPSED',
|
|
57
|
+
'ADMIN_REQUIRED',
|
|
58
|
+
];
|
|
59
|
+
/** `POST /services { mode: 'trackingLink' }` actions. */
|
|
60
|
+
exports.SERVICE_TRACKING_LINK_ACTIONS = ['mint', 'revoke'];
|
|
61
|
+
/** The storefront path a tracking link opens: `/servicio/{handle}`. */
|
|
62
|
+
exports.SERVICE_TRACKING_PATH_PREFIX = '/servicio/';
|
|
63
|
+
/** The handle's exact shape: 16 base62 characters. */
|
|
64
|
+
exports.SERVICE_TRACKING_HANDLE_RE = /^[0-9A-Za-z]{16}$/;
|
package/dist/index.d.ts
CHANGED
|
@@ -79,6 +79,7 @@ export * from './rma.ts';
|
|
|
79
79
|
export * from './roles.ts';
|
|
80
80
|
export * from './sentry.ts';
|
|
81
81
|
export * from './serviceOrder.ts';
|
|
82
|
+
export * from './serviceTracking.ts';
|
|
82
83
|
export * from './serviceTemplate.ts';
|
|
83
84
|
export * from './socket.ts';
|
|
84
85
|
export * from './stock.ts';
|
package/dist/index.js
CHANGED
|
@@ -87,6 +87,7 @@ export * from "./rma.js";
|
|
|
87
87
|
export * from "./roles.js";
|
|
88
88
|
export * from "./sentry.js";
|
|
89
89
|
export * from "./serviceOrder.js";
|
|
90
|
+
export * from "./serviceTracking.js";
|
|
90
91
|
export * from "./serviceTemplate.js";
|
|
91
92
|
export * from "./socket.js";
|
|
92
93
|
export * from "./stock.js";
|
package/dist/serviceOrder.d.ts
CHANGED
|
@@ -1131,6 +1131,16 @@ declare global {
|
|
|
1131
1131
|
* CURRENT `printJobId`.
|
|
1132
1132
|
*/
|
|
1133
1133
|
printedAt?: number;
|
|
1134
|
+
/**
|
|
1135
|
+
* The customer tracking link (`/servicio/{handle}`), as staff see it.
|
|
1136
|
+
* Server-written only, by `POST /services { mode: 'trackingLink' }`:
|
|
1137
|
+
* `mintedAt` when a link is minted (a mint that finds a live link writes
|
|
1138
|
+
* nothing), `revokedAt` when every earlier link is revoked; a mint after a
|
|
1139
|
+
* revoke stamps a new `mintedAt` and removes `revokedAt`. Absent on an order
|
|
1140
|
+
* that never had a link. The handle and its fence generation are never on
|
|
1141
|
+
* this row and never reach staff after the mint answer.
|
|
1142
|
+
*/
|
|
1143
|
+
trackingLink?: ServiceTrackingLinkState;
|
|
1134
1144
|
disabled: boolean;
|
|
1135
1145
|
}
|
|
1136
1146
|
/**
|
|
@@ -1521,6 +1531,6 @@ export declare const MAX_SERVICE_PICTURES = 20;
|
|
|
1521
1531
|
* check `GATING_ERROR_CODES` in addition. The deposit's opt-in idempotency
|
|
1522
1532
|
* refusals are included here.
|
|
1523
1533
|
*/
|
|
1524
|
-
export declare const SERVICE_ORDER_ERROR_CODES: readonly ["UNIT_QUANTITY_NOT_WHOLE", "UNIT_REVISION_STALE", "ROLE_FORBIDDEN", "PARENT_FILTER_CONFLICT", "VALIDATION_FAILED", "INVALID_CURSOR", "INVALID_FROM_DATE", "INVALID_TO_DATE", "INVALID_DATE_RANGE", "REWORK_INDEX_UNAVAILABLE", "STORE_NOT_FOUND", "SERVICE_ORDER_NOT_FOUND", "PRINT_JOB_DOCUMENT_NOT_FOUND", "CUSTOMER_NOT_FOUND", "PARENT_SERVICE_ORDER_NOT_FOUND", "SERVICE_TEMPLATE_NOT_FOUND", "SERVICE_TYPE_REQUIRED", "INVALID_IMAGE_REFERENCE", "MISSING_STORE_CONTEXT", "WARRANTY_BELOW_LEGAL_MINIMUM", "TECHNICIAN_NOT_FOUND", "TECHNICIAN_NOT_ELIGIBLE", "CUSTODY_ILLEGAL_TRANSITION", "SERVICE_ORDER_BILLABLE_FROZEN", "SERVICE_ORDER_EDIT_CHANGED", "SERVICE_ORDER_DISABLED_STATE_UNCHANGED", "APPOINTMENT_NOT_FOUND", "APPOINTMENT_NOT_LINKABLE", "APPOINTMENT_NOT_OPEN", "APPOINTMENT_CUSTOMER_MISMATCH", "APPOINTMENT_VERSION_CONFLICT", "SERVICE_ORDER_TERMINAL", "SERVICE_ORDER_DISABLED", "SERVICE_ORDER_ILLEGAL_TRANSITION", "SERVICE_ORDER_STATUS_CHANGED", "SERVICE_ORDER_OUTCOME_REQUIRED", "SERVICE_ORDER_OUTCOME_NOT_ALLOWED", "SERVICE_ORDER_CUSTODY_NOT_RECEIVED", "SERVICE_ORDER_BILLABLE_NOT_AT_THIS_TRANSITION", "PAYMENT_METHODS_NOT_CONFIGURED", "PAYMENT_METHOD_NOT_FOUND", "SERVICE_ORDER_DEPOSIT_CHANGED", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSE", "IDEMPOTENCY_IN_PROGRESS", "IDEMPOTENCY_KEY_FAILED", "IDEMPOTENCY_LOCK_CONTENTION", "SERVICE_DEPOSIT_CURRENCY_MISMATCH", "SERVICE_DEPOSIT_INVALID", "INVALID_AMOUNT", "DEFAULT_DRAWER_UNAVAILABLE", "CURRENCY_MISMATCH", "SHIFT_NOT_OPEN", "SERVICE_BILLING_PRODUCTS_UNAVAILABLE", "CATEGORY_NOT_FOUND", "CATEGORY_DISABLED", "CATEGORY_DISABLE_IN_PROGRESS", "SERVICE_BILLING_PRODUCT_IN_BASKET", "SERVICE_DELIVERY_BASKET_DECISION_REQUIRED", "SERVICE_DELIVERY_BASKET_CURRENCY_MISMATCH", "PRODUCT_NOT_AVAILABLE", "PRODUCT_SALE_LIMIT_EXCEEDED", "PRODUCT_SALE_LIMIT_INVALID", "FX_CONVERSION_UNAVAILABLE", "TRANSACT_ITEMS_LIMIT_EXCEEDED", "SERVICE_LINE_PRICE_TOO_LARGE", "SERVICE_PARTS_RESTORE_EXCEEDS_CONSUMED", "SERVICE_PARTS_RESTORE_EXCEEDS_AMOUNT", "SERVICE_PARTS_STOCK_INSUFFICIENT", "SERVICE_PARTS_PRODUCT_NOT_FOUND", "SERVICE_PARTS_LEDGER_FULL", "SERVICE_PARTS_TOO_MANY", "SERVICE_ORDER_PARTS_CHANGED", "SERVICE_QUOTE_NOT_FOUND", "SERVICE_QUOTE_NOT_OFFERABLE", "SERVICE_QUOTE_HOLDS_TOO_MANY", "SERVICE_QUOTE_SUPERSEDED", "SERVICE_QUOTE_ALREADY_RESOLVED", "SERVICE_QUOTE_LAPSED", "SERVICE_QUOTE_CHANNEL_RESERVED", "SERVICE_QUOTE_CHANNEL_NOT_APPLICABLE", "SERVICE_QUOTE_REASON_NOT_APPLICABLE", "SERVICE_ORDER_QUOTE_CHANGED", "SERVICE_ORDER_NOT_READY", "SERVICE_RENOTIFY_IMPERSONATED", "SERVICE_RENOTIFY_TOO_SOON", "SERVICE_RENOTIFY_CONFLICT", "SERVICE_RENOTIFY_NOT_RECORDED", "SERVICE_RENOTIFY_LEDGER_UNREADABLE", "SERVICE_RENOTIFY_NOT_DISPATCHED", "SERVICE_TIMER_ALREADY_RUNNING", "SERVICE_TIMER_NOT_RUNNING", "SERVICE_TIMER_STOP_CONFLICT", "TECHNICIAN_NOT_CLOCKED_IN", "SERVICE_ORDER_GONE", "SERVICE_WORKLOG_NOT_FOUND", "SERVICE_WORKLOG_NOT_REVERSIBLE", "SERVICE_WORKLOG_ALREADY_REVERSED", "SERVICE_ORDER_WORKLOG_CHANGED", "CART_PROMOTION_UNAVAILABLE", "COUPON_NOT_FOUND", "COUPON_NOT_ACTIVE", "COUPON_EXPIRED", "COUPON_EXHAUSTED", "COUPON_EXHAUSTED_AT_CHECKOUT", "COUPON_MIN_SUBTOTAL", "COUPON_REQUIRES_CUSTOMER", "COUPON_BUDGET_EXHAUSTED", "COUPON_CURRENCY_MISMATCH"];
|
|
1534
|
+
export declare const SERVICE_ORDER_ERROR_CODES: readonly ["UNIT_QUANTITY_NOT_WHOLE", "UNIT_REVISION_STALE", "ROLE_FORBIDDEN", "PARENT_FILTER_CONFLICT", "VALIDATION_FAILED", "INVALID_CURSOR", "INVALID_FROM_DATE", "INVALID_TO_DATE", "INVALID_DATE_RANGE", "REWORK_INDEX_UNAVAILABLE", "STORE_NOT_FOUND", "SERVICE_ORDER_NOT_FOUND", "PRINT_JOB_DOCUMENT_NOT_FOUND", "CUSTOMER_NOT_FOUND", "PARENT_SERVICE_ORDER_NOT_FOUND", "SERVICE_TEMPLATE_NOT_FOUND", "SERVICE_TYPE_REQUIRED", "INVALID_IMAGE_REFERENCE", "MISSING_STORE_CONTEXT", "WARRANTY_BELOW_LEGAL_MINIMUM", "TECHNICIAN_NOT_FOUND", "TECHNICIAN_NOT_ELIGIBLE", "SERVICE_TRACKING_DISABLED", "SERVICE_TRACKING_NO_ADDRESS", "SERVICE_TRACKING_LINK_LAPSED", "ADMIN_REQUIRED", "CUSTODY_ILLEGAL_TRANSITION", "SERVICE_ORDER_BILLABLE_FROZEN", "SERVICE_ORDER_EDIT_CHANGED", "SERVICE_ORDER_DISABLED_STATE_UNCHANGED", "APPOINTMENT_NOT_FOUND", "APPOINTMENT_NOT_LINKABLE", "APPOINTMENT_NOT_OPEN", "APPOINTMENT_CUSTOMER_MISMATCH", "APPOINTMENT_VERSION_CONFLICT", "SERVICE_ORDER_TERMINAL", "SERVICE_ORDER_DISABLED", "SERVICE_ORDER_ILLEGAL_TRANSITION", "SERVICE_ORDER_STATUS_CHANGED", "SERVICE_ORDER_OUTCOME_REQUIRED", "SERVICE_ORDER_OUTCOME_NOT_ALLOWED", "SERVICE_ORDER_CUSTODY_NOT_RECEIVED", "SERVICE_ORDER_BILLABLE_NOT_AT_THIS_TRANSITION", "PAYMENT_METHODS_NOT_CONFIGURED", "PAYMENT_METHOD_NOT_FOUND", "SERVICE_ORDER_DEPOSIT_CHANGED", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSE", "IDEMPOTENCY_IN_PROGRESS", "IDEMPOTENCY_KEY_FAILED", "IDEMPOTENCY_LOCK_CONTENTION", "SERVICE_DEPOSIT_CURRENCY_MISMATCH", "SERVICE_DEPOSIT_INVALID", "INVALID_AMOUNT", "DEFAULT_DRAWER_UNAVAILABLE", "CURRENCY_MISMATCH", "SHIFT_NOT_OPEN", "SERVICE_BILLING_PRODUCTS_UNAVAILABLE", "CATEGORY_NOT_FOUND", "CATEGORY_DISABLED", "CATEGORY_DISABLE_IN_PROGRESS", "SERVICE_BILLING_PRODUCT_IN_BASKET", "SERVICE_DELIVERY_BASKET_DECISION_REQUIRED", "SERVICE_DELIVERY_BASKET_CURRENCY_MISMATCH", "PRODUCT_NOT_AVAILABLE", "PRODUCT_SALE_LIMIT_EXCEEDED", "PRODUCT_SALE_LIMIT_INVALID", "FX_CONVERSION_UNAVAILABLE", "TRANSACT_ITEMS_LIMIT_EXCEEDED", "SERVICE_LINE_PRICE_TOO_LARGE", "SERVICE_PARTS_RESTORE_EXCEEDS_CONSUMED", "SERVICE_PARTS_RESTORE_EXCEEDS_AMOUNT", "SERVICE_PARTS_STOCK_INSUFFICIENT", "SERVICE_PARTS_PRODUCT_NOT_FOUND", "SERVICE_PARTS_LEDGER_FULL", "SERVICE_PARTS_TOO_MANY", "SERVICE_ORDER_PARTS_CHANGED", "SERVICE_QUOTE_NOT_FOUND", "SERVICE_QUOTE_NOT_OFFERABLE", "SERVICE_QUOTE_HOLDS_TOO_MANY", "SERVICE_QUOTE_SUPERSEDED", "SERVICE_QUOTE_ALREADY_RESOLVED", "SERVICE_QUOTE_LAPSED", "SERVICE_QUOTE_CHANNEL_RESERVED", "SERVICE_QUOTE_CHANNEL_NOT_APPLICABLE", "SERVICE_QUOTE_REASON_NOT_APPLICABLE", "SERVICE_ORDER_QUOTE_CHANGED", "SERVICE_ORDER_NOT_READY", "SERVICE_RENOTIFY_IMPERSONATED", "SERVICE_RENOTIFY_TOO_SOON", "SERVICE_RENOTIFY_CONFLICT", "SERVICE_RENOTIFY_NOT_RECORDED", "SERVICE_RENOTIFY_LEDGER_UNREADABLE", "SERVICE_RENOTIFY_NOT_DISPATCHED", "SERVICE_TIMER_ALREADY_RUNNING", "SERVICE_TIMER_NOT_RUNNING", "SERVICE_TIMER_STOP_CONFLICT", "TECHNICIAN_NOT_CLOCKED_IN", "SERVICE_ORDER_GONE", "SERVICE_WORKLOG_NOT_FOUND", "SERVICE_WORKLOG_NOT_REVERSIBLE", "SERVICE_WORKLOG_ALREADY_REVERSED", "SERVICE_ORDER_WORKLOG_CHANGED", "CART_PROMOTION_UNAVAILABLE", "COUPON_NOT_FOUND", "COUPON_NOT_ACTIVE", "COUPON_EXPIRED", "COUPON_EXHAUSTED", "COUPON_EXHAUSTED_AT_CHECKOUT", "COUPON_MIN_SUBTOTAL", "COUPON_REQUIRES_CUSTOMER", "COUPON_BUDGET_EXHAUSTED", "COUPON_CURRENCY_MISMATCH"];
|
|
1525
1535
|
export type ServiceOrderErrorCode = (typeof SERVICE_ORDER_ERROR_CODES)[number];
|
|
1526
1536
|
export {};
|
package/dist/serviceOrder.js
CHANGED
|
@@ -298,6 +298,11 @@ export const SERVICE_ORDER_ERROR_CODES = [
|
|
|
298
298
|
'WARRANTY_BELOW_LEGAL_MINIMUM',
|
|
299
299
|
'TECHNICIAN_NOT_FOUND',
|
|
300
300
|
'TECHNICIAN_NOT_ELIGIBLE',
|
|
301
|
+
// The customer tracking link (`mode: 'trackingLink'`) — see `SERVICE_TRACKING_OPERATOR_ERROR_CODES`
|
|
302
|
+
'SERVICE_TRACKING_DISABLED',
|
|
303
|
+
'SERVICE_TRACKING_NO_ADDRESS',
|
|
304
|
+
'SERVICE_TRACKING_LINK_LAPSED',
|
|
305
|
+
'ADMIN_REQUIRED',
|
|
301
306
|
'CUSTODY_ILLEGAL_TRANSITION',
|
|
302
307
|
'SERVICE_ORDER_BILLABLE_FROZEN',
|
|
303
308
|
'SERVICE_ORDER_EDIT_CHANGED',
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer service-order tracking — the page a customer opens from a link a
|
|
3
|
+
* shop sends (`/servicio/{handle}`), and the same view for a signed-in customer
|
|
4
|
+
* on their account.
|
|
5
|
+
*
|
|
6
|
+
* The HANDLE is 16 base62 characters (~95 bits), stored server-side and a
|
|
7
|
+
* bearer credential over exactly ONE service order of one store. It authorises
|
|
8
|
+
* the read (`GET /services/tracking?handle=`) and the current presupuesto PDF
|
|
9
|
+
* (`GET /services/tracking?handle=&mode=quote-pdf`), and nothing else. Every
|
|
10
|
+
* earlier link of an order dies when staff revoke it. A link stops reading
|
|
11
|
+
* `serviceTrackingLinkDaysAfterClose` days (platform global, default 90) after
|
|
12
|
+
* the order reached a terminal status.
|
|
13
|
+
*
|
|
14
|
+
* The gate is `ecommerce.config.serviceTracking` AND the `workshop` module on.
|
|
15
|
+
* With the gate off, staff cannot mint and the signed-in reads refuse, but a
|
|
16
|
+
* link minted earlier keeps reading (STORE_MODULES rule 4).
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* The refusals the PUBLIC tracking routes answer themselves.
|
|
20
|
+
*
|
|
21
|
+
* - SERVICE_TRACKING_TOKEN_INVALID (401): every reason a handle cannot be
|
|
22
|
+
* honoured — missing, malformed, unknown, revoked, past the lifetime,
|
|
23
|
+
* presented on another store's host or with no store host at all, or naming
|
|
24
|
+
* an order that is gone or disabled — with one identical body, so a handle is
|
|
25
|
+
* never an oracle.
|
|
26
|
+
* - SERVICE_QUOTE_NOT_FOUND (404, `mode=quote-pdf` only): the order has no
|
|
27
|
+
* current presupuesto a customer was sent.
|
|
28
|
+
*/
|
|
29
|
+
export declare const SERVICE_TRACKING_ERROR_CODES: readonly ["SERVICE_TRACKING_TOKEN_INVALID", "SERVICE_QUOTE_NOT_FOUND"];
|
|
30
|
+
export type ServiceTrackingErrorCode = (typeof SERVICE_TRACKING_ERROR_CODES)[number];
|
|
31
|
+
/**
|
|
32
|
+
* The refusals of the signed-in reads (`GET /user?mode=service-orders` and
|
|
33
|
+
* `?mode=service-order&serviceOrderId=`).
|
|
34
|
+
*
|
|
35
|
+
* - SERVICE_TRACKING_DISABLED (403): the store's gate is off.
|
|
36
|
+
* - SERVICE_ORDER_NOT_FOUND (404): no such order, a disabled one, or one that
|
|
37
|
+
* belongs to another customer — one answer for all three.
|
|
38
|
+
*/
|
|
39
|
+
export declare const SERVICE_TRACKING_ACCOUNT_ERROR_CODES: readonly ["SERVICE_TRACKING_DISABLED", "SERVICE_ORDER_NOT_FOUND"];
|
|
40
|
+
export type ServiceTrackingAccountErrorCode = (typeof SERVICE_TRACKING_ACCOUNT_ERROR_CODES)[number];
|
|
41
|
+
/**
|
|
42
|
+
* The refusals of the staff `POST /services { mode: 'trackingLink' }`, beside
|
|
43
|
+
* the router's own (`ROLE_FORBIDDEN`, `VALIDATION_FAILED`, `SERVICE_ORDER_NOT_FOUND`).
|
|
44
|
+
*
|
|
45
|
+
* - SERVICE_TRACKING_DISABLED (403, mint only): the store's gate is off.
|
|
46
|
+
* - SERVICE_TRACKING_NO_ADDRESS (409, mint only): the store has no public
|
|
47
|
+
* storefront address to build the link on (no slug, or public links off).
|
|
48
|
+
* - SERVICE_TRACKING_LINK_LAPSED (409, mint only): the order closed more than
|
|
49
|
+
* `serviceTrackingLinkDaysAfterClose` days ago, so a link would not read.
|
|
50
|
+
* - ADMIN_REQUIRED (403, revoke only): revoking takes ADMIN, SUPERVISOR or MANAGER.
|
|
51
|
+
*/
|
|
52
|
+
export declare const SERVICE_TRACKING_OPERATOR_ERROR_CODES: readonly ["SERVICE_TRACKING_DISABLED", "SERVICE_TRACKING_NO_ADDRESS", "SERVICE_TRACKING_LINK_LAPSED", "ADMIN_REQUIRED"];
|
|
53
|
+
export type ServiceTrackingOperatorErrorCode = (typeof SERVICE_TRACKING_OPERATOR_ERROR_CODES)[number];
|
|
54
|
+
/** `POST /services { mode: 'trackingLink' }` actions. */
|
|
55
|
+
export declare const SERVICE_TRACKING_LINK_ACTIONS: readonly ["mint", "revoke"];
|
|
56
|
+
/** The storefront path a tracking link opens: `/servicio/{handle}`. */
|
|
57
|
+
export declare const SERVICE_TRACKING_PATH_PREFIX: "/servicio/";
|
|
58
|
+
/** The handle's exact shape: 16 base62 characters. */
|
|
59
|
+
export declare const SERVICE_TRACKING_HANDLE_RE: RegExp;
|
|
60
|
+
declare global {
|
|
61
|
+
type ServiceTrackingLinkAction = (typeof SERVICE_TRACKING_LINK_ACTIONS)[number];
|
|
62
|
+
/** `ServiceOrder.trackingLink` — what staff see of the link; the handle never rides it. */
|
|
63
|
+
interface ServiceTrackingLinkState {
|
|
64
|
+
/** Unix ms the current link was minted. */
|
|
65
|
+
mintedAt: number;
|
|
66
|
+
/** Unix ms every earlier link was revoked; removed by the next mint. */
|
|
67
|
+
revokedAt?: number;
|
|
68
|
+
}
|
|
69
|
+
/** `POST /services { mode: 'trackingLink', action: 'mint' }` — any staff who can open the order. */
|
|
70
|
+
interface ServiceTrackingLinkMintRequest {
|
|
71
|
+
mode: 'trackingLink';
|
|
72
|
+
action: 'mint';
|
|
73
|
+
serviceOrderId: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* `POST /services { mode: 'trackingLink', action: 'revoke' }` — ADMIN,
|
|
77
|
+
* SUPERVISOR or MANAGER, never under impersonation. Kills every earlier link;
|
|
78
|
+
* the next mint answers a new one.
|
|
79
|
+
*/
|
|
80
|
+
interface ServiceTrackingLinkRevokeRequest {
|
|
81
|
+
mode: 'trackingLink';
|
|
82
|
+
action: 'revoke';
|
|
83
|
+
serviceOrderId: string;
|
|
84
|
+
}
|
|
85
|
+
type ServiceTrackingLinkRequest = ServiceTrackingLinkMintRequest | ServiceTrackingLinkRevokeRequest;
|
|
86
|
+
/** The mint answer's `data`: the link at the current generation (one link per generation, so a repeat mint answers the same URL). */
|
|
87
|
+
interface ServiceTrackingLinkMintResult {
|
|
88
|
+
url: string;
|
|
89
|
+
trackingLink: ServiceTrackingLinkState;
|
|
90
|
+
}
|
|
91
|
+
/** The revoke answer's `data`. `trackingLink` is absent when the order never had a link (nothing is written on it then). */
|
|
92
|
+
interface ServiceTrackingLinkRevokeResult {
|
|
93
|
+
trackingLink?: ServiceTrackingLinkState;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* `POST /services/tracking/recover` body (strict): ask for the tracking link of
|
|
97
|
+
* one service ticket. Always `202` with one fixed body, whether or not anything
|
|
98
|
+
* matched; a match mails the live link to the address STORED on the ticket's
|
|
99
|
+
* customer (never this one). Only a malformed body answers otherwise (`400`).
|
|
100
|
+
*/
|
|
101
|
+
interface ServiceTrackingRecoverRequest {
|
|
102
|
+
/** The ticket number the shop printed on the order: digits, at least 6. */
|
|
103
|
+
ticketNumber: string;
|
|
104
|
+
email: string;
|
|
105
|
+
}
|
|
106
|
+
/** One step of the status history as the customer sees it — no operator, no note. */
|
|
107
|
+
interface ServiceTrackingTimelineEntry {
|
|
108
|
+
status: ServiceStatus;
|
|
109
|
+
/** Unix ms. */
|
|
110
|
+
at: number;
|
|
111
|
+
}
|
|
112
|
+
/** The equipment as taken in. Every field is optional; the serial travels as its last four characters only. */
|
|
113
|
+
interface ServiceTrackingEquipment {
|
|
114
|
+
type?: string;
|
|
115
|
+
brand?: string;
|
|
116
|
+
model?: string;
|
|
117
|
+
serialLast4?: string;
|
|
118
|
+
accessories?: string[];
|
|
119
|
+
condition?: string;
|
|
120
|
+
reportedIssue?: string;
|
|
121
|
+
}
|
|
122
|
+
/** One material the presupuesto proposes — no product id, no SKU, no money. */
|
|
123
|
+
interface ServiceTrackingQuotePart {
|
|
124
|
+
name: string;
|
|
125
|
+
quantity: number;
|
|
126
|
+
condition: PartCondition;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The current presupuesto as the customer was sent it — never a draft, never
|
|
130
|
+
* a superseded version. `status` is that version's own: `sent` (awaiting a
|
|
131
|
+
* decision), `approved`, `rejected` or `expired`.
|
|
132
|
+
*/
|
|
133
|
+
interface ServiceTrackingQuote {
|
|
134
|
+
quoteId: string;
|
|
135
|
+
status: Exclude<ServiceQuoteStatus, 'draft' | 'superseded'>;
|
|
136
|
+
laborCost?: number;
|
|
137
|
+
partsCost?: number;
|
|
138
|
+
amount: number;
|
|
139
|
+
/** The version's own stamp, else the order's. */
|
|
140
|
+
currency: string;
|
|
141
|
+
/** Unix ms. */
|
|
142
|
+
quotedAt?: number;
|
|
143
|
+
/** Unix ms the offer lapses (Ley 24.240 art. 21(g)). */
|
|
144
|
+
expiresAt?: number;
|
|
145
|
+
parts: ServiceTrackingQuotePart[];
|
|
146
|
+
/** Unix ms of the approval or the rejection. */
|
|
147
|
+
decidedAt?: number;
|
|
148
|
+
}
|
|
149
|
+
/** Whether the customer may decide the presupuesto online. */
|
|
150
|
+
interface ServiceTrackingDecision {
|
|
151
|
+
/** `false` until the online decision ships. */
|
|
152
|
+
canDecide: boolean;
|
|
153
|
+
/** Whether an approval needs the 6-digit code sent to the contact on file. */
|
|
154
|
+
approveNeedsCode: boolean;
|
|
155
|
+
}
|
|
156
|
+
/** The customer's contact as the shop holds it, masked. */
|
|
157
|
+
interface ServiceTrackingContact {
|
|
158
|
+
firstName: string;
|
|
159
|
+
emailMasked?: string;
|
|
160
|
+
phoneMasked?: string;
|
|
161
|
+
}
|
|
162
|
+
/** The shop, as the page names it. `contact` is the storefront's published contact (empty when the shop publishes none). */
|
|
163
|
+
interface ServiceTrackingStore {
|
|
164
|
+
name: string;
|
|
165
|
+
logoUrl?: string;
|
|
166
|
+
contact: StorefrontPublicContact;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* The tracking view, built by ALLOW-LIST. Never carries operator notes,
|
|
170
|
+
* diagnosis notes, merchant part costs, work logs, the technician, any user
|
|
171
|
+
* or customer id, a rejection note, a draft or a superseded quote version.
|
|
172
|
+
*/
|
|
173
|
+
interface ServiceTrackingView {
|
|
174
|
+
ticketNumber: string;
|
|
175
|
+
serviceType: ServiceType;
|
|
176
|
+
status: ServiceStatus;
|
|
177
|
+
/** The status history, oldest first. */
|
|
178
|
+
timeline: ServiceTrackingTimelineEntry[];
|
|
179
|
+
/** Present only while work is blocked. */
|
|
180
|
+
hold?: {
|
|
181
|
+
reason: ServiceHoldReason;
|
|
182
|
+
expectedUntil?: number;
|
|
183
|
+
};
|
|
184
|
+
custody: ServiceCustody;
|
|
185
|
+
/** Unix ms. */
|
|
186
|
+
promisedAt?: number;
|
|
187
|
+
/** Unix ms. */
|
|
188
|
+
readyAt?: number;
|
|
189
|
+
equipment: ServiceTrackingEquipment;
|
|
190
|
+
/** What was actually wrong, as told to the customer. */
|
|
191
|
+
faultFound?: string;
|
|
192
|
+
quote?: ServiceTrackingQuote;
|
|
193
|
+
/** Unix ms. */
|
|
194
|
+
warrantyExpiresAt?: number;
|
|
195
|
+
decision: ServiceTrackingDecision;
|
|
196
|
+
contact: ServiceTrackingContact;
|
|
197
|
+
store: ServiceTrackingStore;
|
|
198
|
+
}
|
|
199
|
+
/** One row of `GET /user?mode=service-orders`. */
|
|
200
|
+
interface ServiceTrackingAccountListItem {
|
|
201
|
+
serviceOrderId: string;
|
|
202
|
+
ticketNumber: string;
|
|
203
|
+
serviceType: ServiceType;
|
|
204
|
+
status: ServiceStatus;
|
|
205
|
+
/** Unix ms. */
|
|
206
|
+
createdAt: number;
|
|
207
|
+
/** Unix ms. */
|
|
208
|
+
promisedAt?: number;
|
|
209
|
+
equipment: Pick<ServiceTrackingEquipment, 'type' | 'brand' | 'model'>;
|
|
210
|
+
}
|
|
211
|
+
/** `GET /user?mode=service-orders` `data`. `truncated` when more orders exist than were returned. */
|
|
212
|
+
interface ServiceTrackingAccountList {
|
|
213
|
+
serviceOrders: ServiceTrackingAccountListItem[];
|
|
214
|
+
truncated: boolean;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customer service-order tracking — the page a customer opens from a link a
|
|
3
|
+
* shop sends (`/servicio/{handle}`), and the same view for a signed-in customer
|
|
4
|
+
* on their account.
|
|
5
|
+
*
|
|
6
|
+
* The HANDLE is 16 base62 characters (~95 bits), stored server-side and a
|
|
7
|
+
* bearer credential over exactly ONE service order of one store. It authorises
|
|
8
|
+
* the read (`GET /services/tracking?handle=`) and the current presupuesto PDF
|
|
9
|
+
* (`GET /services/tracking?handle=&mode=quote-pdf`), and nothing else. Every
|
|
10
|
+
* earlier link of an order dies when staff revoke it. A link stops reading
|
|
11
|
+
* `serviceTrackingLinkDaysAfterClose` days (platform global, default 90) after
|
|
12
|
+
* the order reached a terminal status.
|
|
13
|
+
*
|
|
14
|
+
* The gate is `ecommerce.config.serviceTracking` AND the `workshop` module on.
|
|
15
|
+
* With the gate off, staff cannot mint and the signed-in reads refuse, but a
|
|
16
|
+
* link minted earlier keeps reading (STORE_MODULES rule 4).
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* The refusals the PUBLIC tracking routes answer themselves.
|
|
20
|
+
*
|
|
21
|
+
* - SERVICE_TRACKING_TOKEN_INVALID (401): every reason a handle cannot be
|
|
22
|
+
* honoured — missing, malformed, unknown, revoked, past the lifetime,
|
|
23
|
+
* presented on another store's host or with no store host at all, or naming
|
|
24
|
+
* an order that is gone or disabled — with one identical body, so a handle is
|
|
25
|
+
* never an oracle.
|
|
26
|
+
* - SERVICE_QUOTE_NOT_FOUND (404, `mode=quote-pdf` only): the order has no
|
|
27
|
+
* current presupuesto a customer was sent.
|
|
28
|
+
*/
|
|
29
|
+
export const SERVICE_TRACKING_ERROR_CODES = ['SERVICE_TRACKING_TOKEN_INVALID', 'SERVICE_QUOTE_NOT_FOUND'];
|
|
30
|
+
/**
|
|
31
|
+
* The refusals of the signed-in reads (`GET /user?mode=service-orders` and
|
|
32
|
+
* `?mode=service-order&serviceOrderId=`).
|
|
33
|
+
*
|
|
34
|
+
* - SERVICE_TRACKING_DISABLED (403): the store's gate is off.
|
|
35
|
+
* - SERVICE_ORDER_NOT_FOUND (404): no such order, a disabled one, or one that
|
|
36
|
+
* belongs to another customer — one answer for all three.
|
|
37
|
+
*/
|
|
38
|
+
export const SERVICE_TRACKING_ACCOUNT_ERROR_CODES = ['SERVICE_TRACKING_DISABLED', 'SERVICE_ORDER_NOT_FOUND'];
|
|
39
|
+
/**
|
|
40
|
+
* The refusals of the staff `POST /services { mode: 'trackingLink' }`, beside
|
|
41
|
+
* the router's own (`ROLE_FORBIDDEN`, `VALIDATION_FAILED`, `SERVICE_ORDER_NOT_FOUND`).
|
|
42
|
+
*
|
|
43
|
+
* - SERVICE_TRACKING_DISABLED (403, mint only): the store's gate is off.
|
|
44
|
+
* - SERVICE_TRACKING_NO_ADDRESS (409, mint only): the store has no public
|
|
45
|
+
* storefront address to build the link on (no slug, or public links off).
|
|
46
|
+
* - SERVICE_TRACKING_LINK_LAPSED (409, mint only): the order closed more than
|
|
47
|
+
* `serviceTrackingLinkDaysAfterClose` days ago, so a link would not read.
|
|
48
|
+
* - ADMIN_REQUIRED (403, revoke only): revoking takes ADMIN, SUPERVISOR or MANAGER.
|
|
49
|
+
*/
|
|
50
|
+
export const SERVICE_TRACKING_OPERATOR_ERROR_CODES = [
|
|
51
|
+
'SERVICE_TRACKING_DISABLED',
|
|
52
|
+
'SERVICE_TRACKING_NO_ADDRESS',
|
|
53
|
+
'SERVICE_TRACKING_LINK_LAPSED',
|
|
54
|
+
'ADMIN_REQUIRED',
|
|
55
|
+
];
|
|
56
|
+
/** `POST /services { mode: 'trackingLink' }` actions. */
|
|
57
|
+
export const SERVICE_TRACKING_LINK_ACTIONS = ['mint', 'revoke'];
|
|
58
|
+
/** The storefront path a tracking link opens: `/servicio/{handle}`. */
|
|
59
|
+
export const SERVICE_TRACKING_PATH_PREFIX = '/servicio/';
|
|
60
|
+
/** The handle's exact shape: 16 base62 characters. */
|
|
61
|
+
export const SERVICE_TRACKING_HANDLE_RE = /^[0-9A-Za-z]{16}$/;
|
package/dist/store.d.ts
CHANGED
|
@@ -182,6 +182,19 @@ declare global {
|
|
|
182
182
|
* frame), so the storefront can offer the request.
|
|
183
183
|
*/
|
|
184
184
|
wholesaleRequests?: boolean;
|
|
185
|
+
/**
|
|
186
|
+
* Whether the shop's customers can follow their service orders online: the
|
|
187
|
+
* tracking link (`/servicio/{handle}`) staff mint with
|
|
188
|
+
* `POST /services { mode: 'trackingLink' }`, and the signed-in
|
|
189
|
+
* `GET /user?mode=service-orders`. Absent or `false` = off. Honoured only
|
|
190
|
+
* while the `workshop` module is on (`config.modules.workshop !== false`).
|
|
191
|
+
* Turning it off later stops new links and the signed-in reads; links
|
|
192
|
+
* already minted keep reading (STORE_MODULES rule 4). Written by
|
|
193
|
+
* `PATCH /store` (ADMIN) and `PUT /platform/stores/{storeId}` (MANAGER).
|
|
194
|
+
* SENT TO SHOPPERS as the verdict (web `GET /store` and the customer
|
|
195
|
+
* `stores` frame): stored `true` AND the workshop module on.
|
|
196
|
+
*/
|
|
197
|
+
serviceTracking?: boolean;
|
|
185
198
|
/**
|
|
186
199
|
* Whether the shop sells to shoppers without an account (server guest
|
|
187
200
|
* cart, guest checkout). Absent means ON: a shop opts out by storing
|
|
@@ -260,7 +273,7 @@ declare global {
|
|
|
260
273
|
* (Responsable Inscripto) refuses 409 NET_PLUS_IVA_REQUIRES_RI; nothing written.
|
|
261
274
|
*/
|
|
262
275
|
interface EcommercePatchInput {
|
|
263
|
-
config?: Pick<NonNullable<Ecommerce['config']>, 'showDefaultPriceList' | 'newCustomerPriceList' | 'registrationMode' | 'wholesaleRequests' | 'paymentHoldMinutes'> & StorefrontLiveSettingsPatch;
|
|
276
|
+
config?: Pick<NonNullable<Ecommerce['config']>, 'showDefaultPriceList' | 'newCustomerPriceList' | 'registrationMode' | 'wholesaleRequests' | 'serviceTracking' | 'paymentHoldMinutes'> & StorefrontLiveSettingsPatch;
|
|
264
277
|
sidebar?: Ecommerce['sidebar'];
|
|
265
278
|
home?: Omit<NonNullable<Ecommerce['home']>, 'displayOrders' | 'displayProfile'>;
|
|
266
279
|
themeColors?: Ecommerce['themeColors'];
|