medusa-plugin-ordinant 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.medusa/server/src/admin/index.js +1636 -0
- package/.medusa/server/src/admin/index.mjs +1635 -0
- package/.medusa/server/src/api/admin/ordinant/classifications/[sku]/confirm/route.js +25 -0
- package/.medusa/server/src/api/admin/ordinant/classifications/bulk-confirm/route.js +29 -0
- package/.medusa/server/src/api/admin/ordinant/classifications/route.js +23 -0
- package/.medusa/server/src/api/admin/ordinant/classify-all/route.js +108 -0
- package/.medusa/server/src/api/admin/ordinant/dictionary/route.js +17 -0
- package/.medusa/server/src/api/admin/ordinant/generate-all-skus/route.js +31 -0
- package/.medusa/server/src/api/admin/ordinant/overview/route.js +69 -0
- package/.medusa/server/src/api/admin/ordinant/products/[id]/classify/route.js +18 -0
- package/.medusa/server/src/api/admin/ordinant/products/[id]/generate-skus/route.js +34 -0
- package/.medusa/server/src/api/admin/ordinant/products/[id]/overview/route.js +59 -0
- package/.medusa/server/src/api/admin/ordinant/stats/route.js +17 -0
- package/.medusa/server/src/api/admin/ordinant/status/route.js +52 -0
- package/.medusa/server/src/api/middlewares.js +14 -0
- package/.medusa/server/src/api/store/ordinant/preview/route.js +110 -0
- package/.medusa/server/src/api/store/ordinant/preview/validators.js +34 -0
- package/.medusa/server/src/lib/client.js +136 -0
- package/.medusa/server/src/modules/ordinant/index.js +14 -0
- package/.medusa/server/src/modules/ordinant/service.js +27 -0
- package/.medusa/server/src/storefront.d.ts +61 -0
- package/.medusa/server/src/storefront.js +61 -0
- package/.medusa/server/src/subscribers/product-upsert.js +52 -0
- package/.medusa/server/src/workflows/bulk-operations.js +59 -0
- package/.medusa/server/src/workflows/classify-product.js +80 -0
- package/.medusa/server/src/workflows/confirm-classification.js +20 -0
- package/.medusa/server/src/workflows/generate-skus.js +81 -0
- package/.medusa/server/src/workflows/hooks/validate-cart-completion.js +127 -0
- package/README.md +495 -0
- package/package.json +92 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const confirm_classification_1 = require("../../../../../../workflows/confirm-classification");
|
|
6
|
+
/**
|
|
7
|
+
* POST /admin/ordinant/classifications/{sku}/confirm
|
|
8
|
+
*
|
|
9
|
+
* Records the merchant's attestation for a SKU with the final attribute set
|
|
10
|
+
* (the proposal as-is, or edited in the widget). Ordinant validates the
|
|
11
|
+
* attributes against its dictionary; violations surface as 4xx errors the
|
|
12
|
+
* widget displays inline.
|
|
13
|
+
*/
|
|
14
|
+
async function POST(req, res) {
|
|
15
|
+
const sku = req.params.sku;
|
|
16
|
+
const attributes = req.body?.attributes;
|
|
17
|
+
if (!attributes || Object.keys(attributes).length === 0) {
|
|
18
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "attributes is required — confirmation attests to a specific attribute set");
|
|
19
|
+
}
|
|
20
|
+
const { result } = await (0, confirm_classification_1.confirmClassificationWorkflow)(req.scope).run({
|
|
21
|
+
input: { sku, attributes },
|
|
22
|
+
});
|
|
23
|
+
res.json(result);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L2NsYXNzaWZpY2F0aW9ucy9bc2t1XS9jb25maXJtL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBZ0JBLG9CQWlCQztBQWhDRCxxREFBdUQ7QUFDdkQsK0ZBQWtHO0FBTWxHOzs7Ozs7O0dBT0c7QUFDSSxLQUFLLFVBQVUsSUFBSSxDQUN4QixHQUE0QyxFQUM1QyxHQUFtQjtJQUVuQixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQTtJQUMxQixNQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQTtJQUN2QyxJQUFJLENBQUMsVUFBVSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3hELE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLDJFQUEyRSxDQUM1RSxDQUFBO0lBQ0gsQ0FBQztJQUVELE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUEsc0RBQTZCLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztRQUNwRSxLQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFO0tBQzNCLENBQUMsQ0FBQTtJQUNGLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7QUFDbEIsQ0FBQyJ9
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const bulk_operations_1 = require("../../../../../workflows/bulk-operations");
|
|
6
|
+
/** Cap per request; the admin page chunks larger selections. */
|
|
7
|
+
const maxSkus = 100;
|
|
8
|
+
/**
|
|
9
|
+
* POST /admin/ordinant/classifications/bulk-confirm
|
|
10
|
+
*
|
|
11
|
+
* Confirms the listed SKUs' proposals AS PROPOSED — a bulk attestation.
|
|
12
|
+
* The admin page shows a category-grouped summary of exactly what is being
|
|
13
|
+
* attested before calling this; the merchant remains the classifier of
|
|
14
|
+
* record.
|
|
15
|
+
*/
|
|
16
|
+
async function POST(req, res) {
|
|
17
|
+
const skus = req.body?.skus;
|
|
18
|
+
if (!Array.isArray(skus) || skus.length === 0) {
|
|
19
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "skus is required");
|
|
20
|
+
}
|
|
21
|
+
if (skus.length > maxSkus) {
|
|
22
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `at most ${maxSkus} skus per request — chunk larger selections`);
|
|
23
|
+
}
|
|
24
|
+
const { result } = await (0, bulk_operations_1.bulkConfirmWorkflow)(req.scope).run({
|
|
25
|
+
input: { skus },
|
|
26
|
+
});
|
|
27
|
+
res.json({ results: result });
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L2NsYXNzaWZpY2F0aW9ucy9idWxrLWNvbmZpcm0vcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFtQkEsb0JBa0JDO0FBcENELHFEQUF1RDtBQUN2RCw4RUFBOEU7QUFNOUUsZ0VBQWdFO0FBQ2hFLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQTtBQUVuQjs7Ozs7OztHQU9HO0FBQ0ksS0FBSyxVQUFVLElBQUksQ0FDeEIsR0FBZ0QsRUFDaEQsR0FBbUI7SUFFbkIsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUE7SUFDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUM5QyxNQUFNLElBQUksbUJBQVcsQ0FBQyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLENBQUMsQ0FBQTtJQUMzRSxDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sRUFBRSxDQUFDO1FBQzFCLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLFdBQVcsT0FBTyw2Q0FBNkMsQ0FDaEUsQ0FBQTtJQUNILENBQUM7SUFDRCxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFBLHFDQUFtQixFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDMUQsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFO0tBQ2hCLENBQUMsQ0FBQTtJQUNGLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQTtBQUMvQixDQUFDIn0=
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const ordinant_1 = require("../../../../modules/ordinant");
|
|
5
|
+
/**
|
|
6
|
+
* GET /admin/ordinant/classifications?skus=a,b,c
|
|
7
|
+
*
|
|
8
|
+
* Proxies the merchant's Ordinant classifications for the admin widget,
|
|
9
|
+
* optionally filtered to a product's SKUs. The Ordinant API key stays
|
|
10
|
+
* server-side; the dashboard authenticates as an ordinary admin user.
|
|
11
|
+
*/
|
|
12
|
+
async function GET(req, res) {
|
|
13
|
+
const ordinant = req.scope.resolve(ordinant_1.ORDINANT_MODULE);
|
|
14
|
+
const skusParam = typeof req.query.skus === "string" ? req.query.skus : "";
|
|
15
|
+
const skus = new Set(skusParam
|
|
16
|
+
.split(",")
|
|
17
|
+
.map((s) => s.trim())
|
|
18
|
+
.filter(Boolean));
|
|
19
|
+
const { items } = await ordinant.client.listClassifications(undefined, 500);
|
|
20
|
+
const filtered = skus.size > 0 ? items.filter((c) => skus.has(c.sku)) : items;
|
|
21
|
+
res.json({ items: filtered });
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L2NsYXNzaWZpY2F0aW9ucy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVdBLGtCQWFDO0FBdkJELDJEQUE4RDtBQUc5RDs7Ozs7O0dBTUc7QUFDSSxLQUFLLFVBQVUsR0FBRyxDQUFDLEdBQStCLEVBQUUsR0FBbUI7SUFDNUUsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQXdCLDBCQUFlLENBQUMsQ0FBQTtJQUMxRSxNQUFNLFNBQVMsR0FBRyxPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtJQUMxRSxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FDbEIsU0FBUztTQUNOLEtBQUssQ0FBQyxHQUFHLENBQUM7U0FDVixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUNwQixNQUFNLENBQUMsT0FBTyxDQUFDLENBQ25CLENBQUE7SUFFRCxNQUFNLEVBQUUsS0FBSyxFQUFFLEdBQUcsTUFBTSxRQUFRLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUMzRSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFBO0lBQzdFLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQTtBQUMvQixDQUFDIn0=
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const ordinant_1 = require("../../../../modules/ordinant");
|
|
6
|
+
const bulk_operations_1 = require("../../../../workflows/bulk-operations");
|
|
7
|
+
const client_1 = require("../../../../lib/client");
|
|
8
|
+
/** SKUs per invocation — kept modest so each request finishes in a few
|
|
9
|
+
* seconds even at real model latency, giving smooth progress and headroom
|
|
10
|
+
* under every timeout; the admin page loops until `remaining` reaches zero. */
|
|
11
|
+
const chunkSize = 20;
|
|
12
|
+
/**
|
|
13
|
+
* POST /admin/ordinant/classify-all
|
|
14
|
+
*
|
|
15
|
+
* Classifies the next chunk of UNCLASSIFIED SKUs (products that predate the
|
|
16
|
+
* plugin, or whose classification previously failed). Returns how many
|
|
17
|
+
* remain so the caller can keep going.
|
|
18
|
+
*/
|
|
19
|
+
async function POST(req, res) {
|
|
20
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
21
|
+
const ordinant = req.scope.resolve(ordinant_1.ORDINANT_MODULE);
|
|
22
|
+
const [{ data: products }, { items: classifications }] = await Promise.all([
|
|
23
|
+
query.graph({
|
|
24
|
+
entity: "product",
|
|
25
|
+
fields: [
|
|
26
|
+
"id",
|
|
27
|
+
"title",
|
|
28
|
+
"description",
|
|
29
|
+
"type.value",
|
|
30
|
+
"collection.title",
|
|
31
|
+
"variants.sku",
|
|
32
|
+
"variants.title",
|
|
33
|
+
],
|
|
34
|
+
pagination: { take: 1000, skip: 0 },
|
|
35
|
+
}),
|
|
36
|
+
ordinant.client.listClassifications(undefined, 5000),
|
|
37
|
+
]);
|
|
38
|
+
const classified = new Set(classifications.map((c) => c.sku));
|
|
39
|
+
const backlog = [];
|
|
40
|
+
for (const product of products) {
|
|
41
|
+
for (const variant of product.variants ?? []) {
|
|
42
|
+
if (!variant?.sku || classified.has(variant.sku)) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
backlog.push({
|
|
46
|
+
sku: variant.sku,
|
|
47
|
+
title: variant.title && variant.title !== "Default variant"
|
|
48
|
+
? `${product.title} — ${variant.title}`
|
|
49
|
+
: product.title,
|
|
50
|
+
description: product.description ?? undefined,
|
|
51
|
+
product_type: product.type?.value ?? product.collection?.title ?? undefined,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const chunk = backlog.slice(0, chunkSize);
|
|
56
|
+
let proposed = 0;
|
|
57
|
+
let failed = 0;
|
|
58
|
+
if (chunk.length > 0) {
|
|
59
|
+
let result;
|
|
60
|
+
try {
|
|
61
|
+
;
|
|
62
|
+
({ result } = await (0, bulk_operations_1.bulkClassifyWorkflow)(req.scope).run({
|
|
63
|
+
input: { items: chunk },
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
// A whole-request failure (engine down, or classification disabled
|
|
68
|
+
// server-side) is a configuration problem the merchant can act on —
|
|
69
|
+
// surface it clearly instead of a generic 500. The workflow may wrap
|
|
70
|
+
// the OrdinantApiError, so match on the 503 signal in the message.
|
|
71
|
+
const cause = unwrap(error);
|
|
72
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
73
|
+
const disabled = (cause instanceof client_1.OrdinantApiError && cause.status === 503) ||
|
|
74
|
+
/not enabled|service_unavailable|503/i.test(message);
|
|
75
|
+
if (disabled) {
|
|
76
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Ordinant classification is not enabled. Set ORDINANT_CLASSIFY_ENABLED " +
|
|
77
|
+
"and ANTHROPIC_API_KEY on the Ordinant deployment.");
|
|
78
|
+
}
|
|
79
|
+
throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Classification request failed: ${message}`);
|
|
80
|
+
}
|
|
81
|
+
for (const r of result) {
|
|
82
|
+
if (r.error) {
|
|
83
|
+
failed++;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
proposed++;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
res.json({
|
|
91
|
+
processed: chunk.length,
|
|
92
|
+
proposed,
|
|
93
|
+
failed,
|
|
94
|
+
remaining: backlog.length - chunk.length,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/** unwrap peels one layer of error wrapping (Medusa workflows re-throw step
|
|
98
|
+
* errors) without relying on the ES2022 `Error.cause` typing. */
|
|
99
|
+
function unwrap(error) {
|
|
100
|
+
if (error && typeof error === "object" && "cause" in error) {
|
|
101
|
+
const cause = error.cause;
|
|
102
|
+
if (cause) {
|
|
103
|
+
return cause;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return error;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L2NsYXNzaWZ5LWFsbC9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQW1CQSxvQkFzRkM7QUF4R0QscURBQWtGO0FBQ2xGLDJEQUE4RDtBQUU5RCwyRUFBNEU7QUFDNUUsbURBQTRFO0FBRTVFOzsrRUFFK0U7QUFDL0UsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFBO0FBRXBCOzs7Ozs7R0FNRztBQUNJLEtBQUssVUFBVSxJQUFJLENBQUMsR0FBK0IsRUFBRSxHQUFtQjtJQUM3RSxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNoRSxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBd0IsMEJBQWUsQ0FBQyxDQUFBO0lBRTFFLE1BQU0sQ0FBQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsQ0FBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUN6RSxLQUFLLENBQUMsS0FBSyxDQUFDO1lBQ1YsTUFBTSxFQUFFLFNBQVM7WUFDakIsTUFBTSxFQUFFO2dCQUNOLElBQUk7Z0JBQ0osT0FBTztnQkFDUCxhQUFhO2dCQUNiLFlBQVk7Z0JBQ1osa0JBQWtCO2dCQUNsQixjQUFjO2dCQUNkLGdCQUFnQjthQUNqQjtZQUNELFVBQVUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtTQUNwQyxDQUFDO1FBQ0YsUUFBUSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDO0tBQ3JELENBQUMsQ0FBQTtJQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxDQUFD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
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const ordinant_1 = require("../../../../modules/ordinant");
|
|
5
|
+
/**
|
|
6
|
+
* GET /admin/ordinant/dictionary
|
|
7
|
+
*
|
|
8
|
+
* The attribute dictionary the current ruleset decides against. The admin UI
|
|
9
|
+
* renders its classification dropdowns from this — the dictionary IS the
|
|
10
|
+
* form schema, so new legal attributes appear automatically with no UI code.
|
|
11
|
+
*/
|
|
12
|
+
async function GET(req, res) {
|
|
13
|
+
const ordinant = req.scope.resolve(ordinant_1.ORDINANT_MODULE);
|
|
14
|
+
const dictionary = await ordinant.client.getDictionary();
|
|
15
|
+
res.json(dictionary);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L2RpY3Rpb25hcnkvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFXQSxrQkFJQztBQWRELDJEQUE4RDtBQUc5RDs7Ozs7O0dBTUc7QUFDSSxLQUFLLFVBQVUsR0FBRyxDQUFDLEdBQStCLEVBQUUsR0FBbUI7SUFDNUUsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQXdCLDBCQUFlLENBQUMsQ0FBQTtJQUMxRSxNQUFNLFVBQVUsR0FBRyxNQUFNLFFBQVEsQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUE7SUFDeEQsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtBQUN0QixDQUFDIn0=
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const generate_skus_1 = require("../../../../workflows/generate-skus");
|
|
6
|
+
/**
|
|
7
|
+
* POST /admin/ordinant/generate-all-skus
|
|
8
|
+
*
|
|
9
|
+
* Generates SKUs for every product that has a SKU-less variant, in one
|
|
10
|
+
* action. SKU generation is DB-only (fast), so this runs synchronously;
|
|
11
|
+
* classification of the newly-SKU'd products is left to the caller's
|
|
12
|
+
* classify-all pass (the dashboard chains them behind one button).
|
|
13
|
+
*/
|
|
14
|
+
async function POST(req, res) {
|
|
15
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
16
|
+
const { data: products } = await query.graph({
|
|
17
|
+
entity: "product",
|
|
18
|
+
fields: ["id", "variants.sku"],
|
|
19
|
+
pagination: { take: 1000, skip: 0 },
|
|
20
|
+
});
|
|
21
|
+
const needsSku = products.filter((p) => (p.variants ?? []).some((v) => !v?.sku));
|
|
22
|
+
let generated = 0;
|
|
23
|
+
for (const product of needsSku) {
|
|
24
|
+
const { result } = await (0, generate_skus_1.generateSkusWorkflow)(req.scope).run({
|
|
25
|
+
input: { product_id: product.id },
|
|
26
|
+
});
|
|
27
|
+
generated += result.length;
|
|
28
|
+
}
|
|
29
|
+
res.json({ products: needsSku.length, generated });
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L2dlbmVyYXRlLWFsbC1za3VzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBWUEsb0JBcUJDO0FBaENELHFEQUFxRTtBQUNyRSx1RUFBMEU7QUFFMUU7Ozs7Ozs7R0FPRztBQUNJLEtBQUssVUFBVSxJQUFJLENBQUMsR0FBK0IsRUFBRSxHQUFtQjtJQUM3RSxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUVoRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxHQUFHLE1BQU0sS0FBSyxDQUFDLEtBQUssQ0FBQztRQUMzQyxNQUFNLEVBQUUsU0FBUztRQUNqQixNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsY0FBYyxDQUFDO1FBQzlCLFVBQVUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRTtLQUNwQyxDQUFDLENBQUE7SUFDRixNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FDckMsQ0FBQyxDQUFDLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQ3hDLENBQUE7SUFFRCxJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUE7SUFDakIsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUMvQixNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFBLG9DQUFvQixFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDM0QsS0FBSyxFQUFFLEVBQUUsVUFBVSxFQUFFLE9BQU8sQ0FBQyxFQUFFLEVBQUU7U0FDbEMsQ0FBQyxDQUFBO1FBQ0YsU0FBUyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUE7SUFDNUIsQ0FBQztJQUVELEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFBO0FBQ3BELENBQUMifQ==
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const ordinant_1 = require("../../../../modules/ordinant");
|
|
6
|
+
/**
|
|
7
|
+
* GET /admin/ordinant/overview
|
|
8
|
+
*
|
|
9
|
+
* The Ordinant admin page's display query: every variant SKU in the store
|
|
10
|
+
* joined with its Ordinant classification state. Medusa is the source of
|
|
11
|
+
* "which SKUs exist"; Ordinant is the source of "which are classified" —
|
|
12
|
+
* the join is what makes unclassified SKUs visible at all.
|
|
13
|
+
*/
|
|
14
|
+
async function GET(req, res) {
|
|
15
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
16
|
+
const ordinant = req.scope.resolve(ordinant_1.ORDINANT_MODULE);
|
|
17
|
+
const [{ data: products }, { items: classifications }] = await Promise.all([
|
|
18
|
+
query.graph({
|
|
19
|
+
entity: "product",
|
|
20
|
+
fields: ["id", "title", "variants.id", "variants.sku", "variants.title"],
|
|
21
|
+
pagination: { take: 1000, skip: 0 },
|
|
22
|
+
}),
|
|
23
|
+
ordinant.client.listClassifications(undefined, 5000),
|
|
24
|
+
]);
|
|
25
|
+
const bySku = new Map(classifications.map((c) => [c.sku, c]));
|
|
26
|
+
const rows = [];
|
|
27
|
+
for (const product of products) {
|
|
28
|
+
for (const variant of product.variants ?? []) {
|
|
29
|
+
if (!variant?.sku) {
|
|
30
|
+
// Surface SKU-less variants instead of hiding them — they can't be
|
|
31
|
+
// sold until they get a SKU, and the merchant fixes that here.
|
|
32
|
+
rows.push({
|
|
33
|
+
sku: "",
|
|
34
|
+
variant_id: variant?.id ?? "",
|
|
35
|
+
product_id: product.id,
|
|
36
|
+
product_title: product.title,
|
|
37
|
+
variant_title: variant?.title ?? null,
|
|
38
|
+
status: "needs_sku",
|
|
39
|
+
confidence: null,
|
|
40
|
+
attributes: null,
|
|
41
|
+
notes: null,
|
|
42
|
+
});
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const record = bySku.get(variant.sku);
|
|
46
|
+
rows.push({
|
|
47
|
+
sku: variant.sku,
|
|
48
|
+
variant_id: variant.id ?? "",
|
|
49
|
+
product_id: product.id,
|
|
50
|
+
product_title: product.title,
|
|
51
|
+
variant_title: variant.title ?? null,
|
|
52
|
+
status: record ? record.status : "unclassified",
|
|
53
|
+
confidence: record ? record.confidence : null,
|
|
54
|
+
attributes: record ? record.attributes : null,
|
|
55
|
+
notes: record?.notes ?? null,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
rows.sort((a, b) => (a.sku || "~").localeCompare(b.sku || "~"));
|
|
60
|
+
const summary = {
|
|
61
|
+
total: rows.length,
|
|
62
|
+
needs_sku: rows.filter((r) => r.status === "needs_sku").length,
|
|
63
|
+
unclassified: rows.filter((r) => r.status === "unclassified").length,
|
|
64
|
+
proposed: rows.filter((r) => r.status === "proposed").length,
|
|
65
|
+
confirmed: rows.filter((r) => r.status === "confirmed").length,
|
|
66
|
+
};
|
|
67
|
+
res.json({ rows, summary });
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L292ZXJ2aWV3L3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBMkJBLGtCQXlEQztBQW5GRCxxREFBcUU7QUFDckUsMkRBQThEO0FBaUI5RDs7Ozs7OztHQU9HO0FBQ0ksS0FBSyxVQUFVLEdBQUcsQ0FBQyxHQUErQixFQUFFLEdBQW1CO0lBQzVFLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ2hFLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUF3QiwwQkFBZSxDQUFDLENBQUE7SUFFMUUsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxDQUFDLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDO1FBQ3pFLEtBQUssQ0FBQyxLQUFLLENBQUM7WUFDVixNQUFNLEVBQUUsU0FBUztZQUNqQixNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLENBQUM7WUFDeEUsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFO1NBQ3BDLENBQUM7UUFDRixRQUFRLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUM7S0FDckQsQ0FBQyxDQUFBO0lBRUYsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUM3RCxN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
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const classify_product_1 = require("../../../../../../workflows/classify-product");
|
|
5
|
+
/**
|
|
6
|
+
* POST /admin/ordinant/products/{id}/classify
|
|
7
|
+
*
|
|
8
|
+
* Manually (re-)classifies a product's variants — the widget's "Classify"
|
|
9
|
+
* action, useful for products created before the plugin was installed or
|
|
10
|
+
* after editing product data.
|
|
11
|
+
*/
|
|
12
|
+
async function POST(req, res) {
|
|
13
|
+
const { result } = await (0, classify_product_1.classifyProductWorkflow)(req.scope).run({
|
|
14
|
+
input: { product_id: req.params.id },
|
|
15
|
+
});
|
|
16
|
+
res.json({ results: result });
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L3Byb2R1Y3RzL1tpZF0vY2xhc3NpZnkvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFVQSxvQkFLQztBQWRELG1GQUFzRjtBQUV0Rjs7Ozs7O0dBTUc7QUFDSSxLQUFLLFVBQVUsSUFBSSxDQUFDLEdBQStCLEVBQUUsR0FBbUI7SUFDN0UsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBQSwwQ0FBdUIsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQzlELEtBQUssRUFBRSxFQUFFLFVBQVUsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRTtLQUNyQyxDQUFDLENBQUE7SUFDRixHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUE7QUFDL0IsQ0FBQyJ9
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POST = POST;
|
|
4
|
+
const generate_skus_1 = require("../../../../../../workflows/generate-skus");
|
|
5
|
+
const classify_product_1 = require("../../../../../../workflows/classify-product");
|
|
6
|
+
/**
|
|
7
|
+
* POST /admin/ordinant/products/{id}/generate-skus
|
|
8
|
+
*
|
|
9
|
+
* Assigns readable, collision-free SKUs to the product's SKU-less variants,
|
|
10
|
+
* then immediately classifies the product — hands-off: one action takes a
|
|
11
|
+
* SKU-less product all the way to a proposed classification, so it lands in
|
|
12
|
+
* "ready to confirm", never stuck as unclassified needing manual work.
|
|
13
|
+
* Classification is best-effort (if the module is off or errors, the SKUs
|
|
14
|
+
* are still written and the product can be classified later).
|
|
15
|
+
*/
|
|
16
|
+
async function POST(req, res) {
|
|
17
|
+
const { result: generated } = await (0, generate_skus_1.generateSkusWorkflow)(req.scope).run({
|
|
18
|
+
input: { product_id: req.params.id },
|
|
19
|
+
});
|
|
20
|
+
let classified = 0;
|
|
21
|
+
if (generated.length > 0) {
|
|
22
|
+
try {
|
|
23
|
+
const { result } = await (0, classify_product_1.classifyProductWorkflow)(req.scope).run({
|
|
24
|
+
input: { product_id: req.params.id },
|
|
25
|
+
});
|
|
26
|
+
classified = result.filter((r) => !r.error).length;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// SKUs are written; classification can be retried from the dashboard.
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
res.json({ generated, classified });
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L3Byb2R1Y3RzL1tpZF0vZ2VuZXJhdGUtc2t1cy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWNBLG9CQWtCQztBQS9CRCw2RUFBZ0Y7QUFDaEYsbUZBQXNGO0FBRXRGOzs7Ozs7Ozs7R0FTRztBQUNJLEtBQUssVUFBVSxJQUFJLENBQUMsR0FBK0IsRUFBRSxHQUFtQjtJQUM3RSxNQUFNLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLE1BQU0sSUFBQSxvQ0FBb0IsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ3RFLEtBQUssRUFBRSxFQUFFLFVBQVUsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRTtLQUNyQyxDQUFDLENBQUE7SUFFRixJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUE7SUFDbEIsSUFBSSxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQztZQUNILE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUEsMENBQXVCLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztnQkFDOUQsS0FBSyxFQUFFLEVBQUUsVUFBVSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFO2FBQ3JDLENBQUMsQ0FBQTtZQUNGLFVBQVUsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUE7UUFDcEQsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLHNFQUFzRTtRQUN4RSxDQUFDO0lBQ0gsQ0FBQztJQUVELEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQTtBQUNyQyxDQUFDIn0=
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
5
|
+
const ordinant_1 = require("../../../../../../modules/ordinant");
|
|
6
|
+
/**
|
|
7
|
+
* GET /admin/ordinant/products/{id}/overview
|
|
8
|
+
*
|
|
9
|
+
* The per-product widget's display query. Resolves the product's variant
|
|
10
|
+
* SKUs SERVER-SIDE via query.graph — the admin widget's injected `data`
|
|
11
|
+
* prop does not reliably carry variants with SKUs, so we never depend on it.
|
|
12
|
+
* Joins each SKU with its Ordinant classification state.
|
|
13
|
+
*/
|
|
14
|
+
async function GET(req, res) {
|
|
15
|
+
const query = req.scope.resolve(utils_1.ContainerRegistrationKeys.QUERY);
|
|
16
|
+
const ordinant = req.scope.resolve(ordinant_1.ORDINANT_MODULE);
|
|
17
|
+
const { data: products } = await query.graph({
|
|
18
|
+
entity: "product",
|
|
19
|
+
fields: ["id", "variants.id", "variants.sku", "variants.title"],
|
|
20
|
+
filters: { id: req.params.id },
|
|
21
|
+
});
|
|
22
|
+
const product = products[0];
|
|
23
|
+
const allVariants = product?.variants ?? [];
|
|
24
|
+
const withSku = allVariants.filter((v) => v?.sku);
|
|
25
|
+
// Only fetch classifications if there are SKUs to look up.
|
|
26
|
+
let bySku = new Map();
|
|
27
|
+
if (withSku.length > 0) {
|
|
28
|
+
const { items } = await ordinant.client.listClassifications(undefined, 5000);
|
|
29
|
+
const skuSet = new Set(withSku.map((v) => v.sku));
|
|
30
|
+
bySku = new Map(items.filter((c) => skuSet.has(c.sku)).map((c) => [c.sku, c]));
|
|
31
|
+
}
|
|
32
|
+
const rows = allVariants.map((variant) => {
|
|
33
|
+
if (!variant?.sku) {
|
|
34
|
+
return {
|
|
35
|
+
sku: "",
|
|
36
|
+
variant_id: variant?.id ?? "",
|
|
37
|
+
variant_title: variant?.title ?? null,
|
|
38
|
+
status: "needs_sku",
|
|
39
|
+
confidence: null,
|
|
40
|
+
attributes: null,
|
|
41
|
+
notes: null,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const record = bySku.get(variant.sku);
|
|
45
|
+
return {
|
|
46
|
+
sku: variant.sku,
|
|
47
|
+
variant_id: variant.id,
|
|
48
|
+
variant_title: variant.title ?? null,
|
|
49
|
+
status: record ? record.status : "unclassified",
|
|
50
|
+
confidence: record ? record.confidence : null,
|
|
51
|
+
attributes: record ? record.attributes : null,
|
|
52
|
+
notes: record?.notes ?? null,
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
const needsSku = rows.some((r) => r.status === "needs_sku");
|
|
56
|
+
// no_skus: every variant lacks a SKU (nothing classifiable at all).
|
|
57
|
+
res.json({ rows, no_skus: rows.length > 0 && rows.every((r) => r.status === "needs_sku"), needs_sku: needsSku });
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L3Byb2R1Y3RzL1tpZF0vb3ZlcnZpZXcvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUF1QkEsa0JBZ0RDO0FBdEVELHFEQUFxRTtBQUNyRSxpRUFBb0U7QUFhcEU7Ozs7Ozs7R0FPRztBQUNJLEtBQUssVUFBVSxHQUFHLENBQUMsR0FBK0IsRUFBRSxHQUFtQjtJQUM1RSxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNoRSxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBd0IsMEJBQWUsQ0FBQyxDQUFBO0lBRTFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEdBQUcsTUFBTSxLQUFLLENBQUMsS0FBSyxDQUFDO1FBQzNDLE1BQU0sRUFBRSxTQUFTO1FBQ2pCLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixDQUFDO1FBQy9ELE9BQU8sRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRTtLQUMvQixDQUFDLENBQUE7SUFDRixNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDM0IsTUFBTSxXQUFXLEdBQUcsT0FBTyxFQUFFLFFBQVEsSUFBSSxFQUFFLENBQUE7SUFDM0MsTUFBTSxPQUFPLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBRWpELDJEQUEyRDtJQUMzRCxJQUFJLEtBQUssR0FBRyxJQUFJLEdBQUcsRUFBNEYsQ0FBQTtJQUMvRyxJQUFJLE9BQU8sQ0FB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
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const ordinant_1 = require("../../../../modules/ordinant");
|
|
5
|
+
/**
|
|
6
|
+
* GET /admin/ordinant/stats
|
|
7
|
+
*
|
|
8
|
+
* Proxies the merchant's blocked-order metrics ("stopped illegal orders")
|
|
9
|
+
* from the engine's durable decision log. The dashboard's impact hero renders
|
|
10
|
+
* from this. Scoped server-side to the merchant behind the API key.
|
|
11
|
+
*/
|
|
12
|
+
async function GET(req, res) {
|
|
13
|
+
const ordinant = req.scope.resolve(ordinant_1.ORDINANT_MODULE);
|
|
14
|
+
const stats = await ordinant.client.blockStats();
|
|
15
|
+
res.json(stats);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L3N0YXRzL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBV0Esa0JBSUM7QUFkRCwyREFBOEQ7QUFHOUQ7Ozs7OztHQU1HO0FBQ0ksS0FBSyxVQUFVLEdBQUcsQ0FBQyxHQUErQixFQUFFLEdBQW1CO0lBQzVFLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUF3QiwwQkFBZSxDQUFDLENBQUE7SUFDMUUsTUFBTSxLQUFLLEdBQUcsTUFBTSxRQUFRLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFBO0lBQ2hELEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUE7QUFDakIsQ0FBQyJ9
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GET = GET;
|
|
4
|
+
const ordinant_1 = require("../../../../modules/ordinant");
|
|
5
|
+
const client_1 = require("../../../../lib/client");
|
|
6
|
+
/**
|
|
7
|
+
* GET /admin/ordinant/status
|
|
8
|
+
*
|
|
9
|
+
* Lightweight readiness probe for the dashboard. Never throws — a gated or
|
|
10
|
+
* offline state is a valid answer, not an error. `reason` tells the gate which
|
|
11
|
+
* message to show:
|
|
12
|
+
* - "not_activated" — no API key configured at all
|
|
13
|
+
* - "unauthorized" — a key is set but the engine rejected it (401/403)
|
|
14
|
+
* - "unreachable" — configured, but the engine didn't respond
|
|
15
|
+
* - null — healthy
|
|
16
|
+
*/
|
|
17
|
+
async function GET(req, res) {
|
|
18
|
+
const ordinant = req.scope.resolve(ordinant_1.ORDINANT_MODULE);
|
|
19
|
+
if (!ordinant.configured) {
|
|
20
|
+
res.json({
|
|
21
|
+
configured: false,
|
|
22
|
+
engine_reachable: false,
|
|
23
|
+
ruleset_version: null,
|
|
24
|
+
reason: "not_activated",
|
|
25
|
+
});
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// Configured: probe the engine with the cheapest authenticated call.
|
|
29
|
+
try {
|
|
30
|
+
const summary = await ordinant.client.currentRuleset();
|
|
31
|
+
res.json({
|
|
32
|
+
configured: true,
|
|
33
|
+
engine_reachable: true,
|
|
34
|
+
ruleset_version: summary.version,
|
|
35
|
+
rule_count: summary.rule_count,
|
|
36
|
+
reason: null,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
// A key that doesn't authenticate is a different problem (and a different
|
|
41
|
+
// message) than an engine that's simply down.
|
|
42
|
+
const httpStatus = err instanceof client_1.OrdinantApiError ? err.status : undefined;
|
|
43
|
+
const reason = httpStatus === 401 || httpStatus === 403 ? "unauthorized" : "unreachable";
|
|
44
|
+
res.json({
|
|
45
|
+
configured: true,
|
|
46
|
+
engine_reachable: false,
|
|
47
|
+
ruleset_version: null,
|
|
48
|
+
reason,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL29yZGluYW50L3N0YXR1cy9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWdCQSxrQkFtQ0M7QUFsREQsMkRBQThEO0FBRTlELG1EQUF5RDtBQUV6RDs7Ozs7Ozs7OztHQVVHO0FBQ0ksS0FBSyxVQUFVLEdBQUcsQ0FBQyxHQUErQixFQUFFLEdBQW1CO0lBQzVFLE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUF3QiwwQkFBZSxDQUFDLENBQUE7SUFFMUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN6QixHQUFHLENBQUMsSUFBSSxDQUFDO1lBQ1AsVUFBVSxFQUFFLEtBQUs7WUFDakIsZ0JBQWdCLEVBQUUsS0FBSztZQUN2QixlQUFlLEVBQUUsSUFBSTtZQUNyQixNQUFNLEVBQUUsZUFBZTtTQUN4QixDQUFDLENBQUE7UUFDRixPQUFNO0lBQ1IsQ0FBQztJQUVELHFFQUFxRTtJQUNyRSxJQUFJLENBQUM7UUFDSCxNQUFNLE9BQU8sR0FBRyxNQUFNLFFBQVEsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUE7UUFDdEQsR0FBRyxDQUFDLElBQUksQ0FBQztZQUNQLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLGdCQUFnQixFQUFFLElBQUk7WUFDdEIsZUFBZSxFQUFFLE9BQU8sQ0FBQyxPQUFPO1lBQ2hDLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtZQUM5QixNQUFNLEVBQUUsSUFBSTtTQUNiLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsMEVBQTBFO1FBQzFFLDhDQUE4QztRQUM5QyxNQUFNLFVBQVUsR0FBRyxHQUFHLFlBQVkseUJBQWdCLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtRQUMzRSxNQUFNLE1BQU0sR0FBRyxVQUFVLEtBQUssR0FBRyxJQUFJLFVBQVUsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFBO1FBQ3hGLEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDUCxVQUFVLEVBQUUsSUFBSTtZQUNoQixnQkFBZ0IsRUFBRSxLQUFLO1lBQ3ZCLGVBQWUsRUFBRSxJQUFJO1lBQ3JCLE1BQU07U0FDUCxDQUFDLENBQUE7SUFDSixDQUFDO0FBQ0gsQ0FBQyJ9
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const http_1 = require("@medusajs/framework/http");
|
|
4
|
+
const validators_1 = require("./store/ordinant/preview/validators");
|
|
5
|
+
exports.default = (0, http_1.defineMiddlewares)({
|
|
6
|
+
routes: [
|
|
7
|
+
{
|
|
8
|
+
matcher: "/store/ordinant/preview",
|
|
9
|
+
method: "POST",
|
|
10
|
+
middlewares: [(0, http_1.validateAndTransformBody)(validators_1.PreviewSchema)],
|
|
11
|
+
},
|
|
12
|
+
],
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBpL21pZGRsZXdhcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbURBQXNGO0FBQ3RGLG9FQUFtRTtBQUVuRSxrQkFBZSxJQUFBLHdCQUFpQixFQUFDO0lBQy9CLE1BQU0sRUFBRTtRQUNOO1lBQ0UsT0FBTyxFQUFFLHlCQUF5QjtZQUNsQyxNQUFNLEVBQUUsTUFBTTtZQUNkLFdBQVcsRUFBRSxDQUFDLElBQUEsK0JBQXdCLEVBQUMsMEJBQWEsQ0FBQyxDQUFDO1NBQ3ZEO0tBQ0Y7Q0FDRixDQUFDLENBQUEifQ==
|