whale-code 6.5.8 → 6.5.9
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/cli/services/agent-loop.js +26 -2
- package/dist/cli/services/agent-loop.js.map +1 -1
- package/dist/cli/services/hooks.js +2 -1
- package/dist/cli/services/hooks.js.map +1 -1
- package/dist/cli/services/telemetry-spans.js +1 -0
- package/dist/cli/services/telemetry-spans.js.map +1 -1
- package/dist/cli/services/telemetry.d.ts +23 -0
- package/dist/cli/services/telemetry.js +45 -1
- package/dist/cli/services/telemetry.js.map +1 -1
- package/dist/server/handlers/__test-utils__/test-db.d.ts +17 -3
- package/dist/server/handlers/__test-utils__/test-db.js +113 -14
- package/dist/server/handlers/__test-utils__/test-db.js.map +1 -1
- package/dist/server/handlers/affiliates.d.ts +9 -0
- package/dist/server/handlers/affiliates.js +197 -0
- package/dist/server/handlers/affiliates.js.map +1 -0
- package/dist/server/handlers/api-docs.d.ts +4 -2
- package/dist/server/handlers/api-docs.js +204 -1681
- package/dist/server/handlers/api-docs.js.map +1 -1
- package/dist/server/handlers/campaigns.d.ts +9 -0
- package/dist/server/handlers/campaigns.js +237 -0
- package/dist/server/handlers/campaigns.js.map +1 -0
- package/dist/server/handlers/catalog-schemas.js +9 -9
- package/dist/server/handlers/catalog-schemas.js.map +1 -1
- package/dist/server/handlers/catalog.js +1 -1
- package/dist/server/handlers/catalog.js.map +1 -1
- package/dist/server/handlers/comms-documents.js +28 -2
- package/dist/server/handlers/comms-documents.js.map +1 -1
- package/dist/server/handlers/comms-pdf-generation.js +25 -3
- package/dist/server/handlers/comms-pdf-generation.js.map +1 -1
- package/dist/server/handlers/comms-pdf-helpers.js +4 -4
- package/dist/server/handlers/comms-pdf-helpers.js.map +1 -1
- package/dist/server/handlers/comms.d.ts +100 -0
- package/dist/server/handlers/comms.js +146 -12
- package/dist/server/handlers/comms.js.map +1 -1
- package/dist/server/handlers/coupons.d.ts +9 -0
- package/dist/server/handlers/coupons.js +220 -0
- package/dist/server/handlers/coupons.js.map +1 -0
- package/dist/server/handlers/embeddings.js +1 -1
- package/dist/server/handlers/embeddings.js.map +1 -1
- package/dist/server/handlers/enrichment.js +2 -622
- package/dist/server/handlers/enrichment.js.map +1 -1
- package/dist/server/handlers/fulfillment.d.ts +9 -0
- package/dist/server/handlers/fulfillment.js +209 -0
- package/dist/server/handlers/fulfillment.js.map +1 -0
- package/dist/server/handlers/google-ads.d.ts +24 -0
- package/dist/server/handlers/google-ads.js +2199 -0
- package/dist/server/handlers/google-ads.js.map +1 -0
- package/dist/server/handlers/invoices.d.ts +9 -0
- package/dist/server/handlers/invoices.js +252 -0
- package/dist/server/handlers/invoices.js.map +1 -0
- package/dist/server/handlers/loyalty.d.ts +9 -0
- package/dist/server/handlers/loyalty.js +197 -0
- package/dist/server/handlers/loyalty.js.map +1 -0
- package/dist/server/handlers/meta-ads-graph-api.js +18 -3
- package/dist/server/handlers/meta-ads-graph-api.js.map +1 -1
- package/dist/server/handlers/phone.d.ts +9 -0
- package/dist/server/handlers/phone.js +197 -0
- package/dist/server/handlers/phone.js.map +1 -0
- package/dist/server/handlers/pipeline.d.ts +9 -0
- package/dist/server/handlers/pipeline.js +277 -0
- package/dist/server/handlers/pipeline.js.map +1 -0
- package/dist/server/handlers/qr-codes.d.ts +9 -0
- package/dist/server/handlers/qr-codes.js +198 -0
- package/dist/server/handlers/qr-codes.js.map +1 -0
- package/dist/server/handlers/reviews.d.ts +9 -0
- package/dist/server/handlers/reviews.js +171 -0
- package/dist/server/handlers/reviews.js.map +1 -0
- package/dist/server/handlers/segments.d.ts +9 -0
- package/dist/server/handlers/segments.js +229 -0
- package/dist/server/handlers/segments.js.map +1 -0
- package/dist/server/handlers/social.d.ts +9 -0
- package/dist/server/handlers/social.js +81 -0
- package/dist/server/handlers/social.js.map +1 -0
- package/dist/server/handlers/tax.d.ts +9 -0
- package/dist/server/handlers/tax.js +182 -0
- package/dist/server/handlers/tax.js.map +1 -0
- package/dist/server/handlers/wallet.d.ts +9 -0
- package/dist/server/handlers/wallet.js +203 -0
- package/dist/server/handlers/wallet.js.map +1 -0
- package/dist/server/handlers/webhooks-mgmt.d.ts +9 -0
- package/dist/server/handlers/webhooks-mgmt.js +181 -0
- package/dist/server/handlers/webhooks-mgmt.js.map +1 -0
- package/dist/server/handlers/wholesale.d.ts +9 -0
- package/dist/server/handlers/wholesale.js +219 -0
- package/dist/server/handlers/wholesale.js.map +1 -0
- package/dist/server/index.js +20 -9
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/clickhouse-buffer.js +1 -0
- package/dist/server/lib/clickhouse-buffer.js.map +1 -1
- package/dist/server/lib/coa-renderer.d.ts +1 -1
- package/dist/server/lib/coa-renderer.js +32 -10
- package/dist/server/lib/coa-renderer.js.map +1 -1
- package/dist/server/server-worker.d.ts +1 -0
- package/dist/server/server-worker.js +464 -3
- package/dist/server/server-worker.js.map +1 -1
- package/dist/server/tool-router.js +118 -4
- package/dist/server/tool-router.js.map +1 -1
- package/package.json +26 -3
- package/vendor/ink/package.json +0 -2
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// server/handlers/reviews.ts — Product review listing and moderation
|
|
2
|
+
|
|
3
|
+
export async function handleReviews(sb, args, storeId) {
|
|
4
|
+
const sid = storeId;
|
|
5
|
+
switch (args.action) {
|
|
6
|
+
// ---- LIST: list reviews with filters ----
|
|
7
|
+
case "list":
|
|
8
|
+
{
|
|
9
|
+
let q = sb.from("product_reviews").select("id, product_id, customer_id, order_id, rating, title, review_text, verified_purchase, status, helpful_count, not_helpful_count, store_response, responded_at, review_images, created_at, product:products!product_id(name, sku)").eq("store_id", sid).order("created_at", {
|
|
10
|
+
ascending: false
|
|
11
|
+
});
|
|
12
|
+
if (args.status) q = q.eq("status", args.status);
|
|
13
|
+
if (args.product_id) q = q.eq("product_id", args.product_id);
|
|
14
|
+
if (args.rating) q = q.eq("rating", args.rating);
|
|
15
|
+
if (args.min_rating) q = q.gte("rating", args.min_rating);
|
|
16
|
+
if (args.max_rating) q = q.lte("rating", args.max_rating);
|
|
17
|
+
if (args.verified_only === true) q = q.eq("verified_purchase", true);
|
|
18
|
+
q = q.limit(args.limit || 50);
|
|
19
|
+
const {
|
|
20
|
+
data,
|
|
21
|
+
error
|
|
22
|
+
} = await q;
|
|
23
|
+
return error ? {
|
|
24
|
+
success: false,
|
|
25
|
+
error: error.message
|
|
26
|
+
} : {
|
|
27
|
+
success: true,
|
|
28
|
+
count: data?.length,
|
|
29
|
+
data
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ---- GET: get a single review ----
|
|
34
|
+
case "get":
|
|
35
|
+
{
|
|
36
|
+
const reviewId = args.review_id;
|
|
37
|
+
if (!reviewId) return {
|
|
38
|
+
success: false,
|
|
39
|
+
error: "review_id is required"
|
|
40
|
+
};
|
|
41
|
+
const {
|
|
42
|
+
data,
|
|
43
|
+
error
|
|
44
|
+
} = await sb.from("product_reviews").select("*, product:products!product_id(name, sku)").eq("id", reviewId).eq("store_id", sid).single();
|
|
45
|
+
return error ? {
|
|
46
|
+
success: false,
|
|
47
|
+
error: error.message
|
|
48
|
+
} : {
|
|
49
|
+
success: true,
|
|
50
|
+
data
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ---- APPROVE: approve a pending review ----
|
|
55
|
+
case "approve":
|
|
56
|
+
{
|
|
57
|
+
const reviewId = args.review_id;
|
|
58
|
+
if (!reviewId) return {
|
|
59
|
+
success: false,
|
|
60
|
+
error: "review_id is required"
|
|
61
|
+
};
|
|
62
|
+
const {
|
|
63
|
+
data,
|
|
64
|
+
error
|
|
65
|
+
} = await sb.from("product_reviews").update({
|
|
66
|
+
status: "approved",
|
|
67
|
+
updated_at: new Date().toISOString()
|
|
68
|
+
}).eq("id", reviewId).eq("store_id", sid).select().single();
|
|
69
|
+
return error ? {
|
|
70
|
+
success: false,
|
|
71
|
+
error: error.message
|
|
72
|
+
} : {
|
|
73
|
+
success: true,
|
|
74
|
+
data
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ---- REJECT: reject a review ----
|
|
79
|
+
case "reject":
|
|
80
|
+
{
|
|
81
|
+
const reviewId = args.review_id;
|
|
82
|
+
if (!reviewId) return {
|
|
83
|
+
success: false,
|
|
84
|
+
error: "review_id is required"
|
|
85
|
+
};
|
|
86
|
+
const {
|
|
87
|
+
data,
|
|
88
|
+
error
|
|
89
|
+
} = await sb.from("product_reviews").update({
|
|
90
|
+
status: "rejected",
|
|
91
|
+
updated_at: new Date().toISOString()
|
|
92
|
+
}).eq("id", reviewId).eq("store_id", sid).select().single();
|
|
93
|
+
return error ? {
|
|
94
|
+
success: false,
|
|
95
|
+
error: error.message
|
|
96
|
+
} : {
|
|
97
|
+
success: true,
|
|
98
|
+
data
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ---- RESPOND: add a store response to a review ----
|
|
103
|
+
case "respond":
|
|
104
|
+
{
|
|
105
|
+
const reviewId = args.review_id;
|
|
106
|
+
const response = args.response;
|
|
107
|
+
if (!reviewId || !response) return {
|
|
108
|
+
success: false,
|
|
109
|
+
error: "review_id and response are required"
|
|
110
|
+
};
|
|
111
|
+
const {
|
|
112
|
+
data,
|
|
113
|
+
error
|
|
114
|
+
} = await sb.from("product_reviews").update({
|
|
115
|
+
store_response: response,
|
|
116
|
+
responded_at: new Date().toISOString(),
|
|
117
|
+
updated_at: new Date().toISOString()
|
|
118
|
+
}).eq("id", reviewId).eq("store_id", sid).select().single();
|
|
119
|
+
return error ? {
|
|
120
|
+
success: false,
|
|
121
|
+
error: error.message
|
|
122
|
+
} : {
|
|
123
|
+
success: true,
|
|
124
|
+
data
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ---- SUMMARY: get review stats per product or store ----
|
|
129
|
+
case "summary":
|
|
130
|
+
{
|
|
131
|
+
let q = sb.from("product_reviews").select("product_id, rating, status").eq("store_id", sid);
|
|
132
|
+
if (args.product_id) q = q.eq("product_id", args.product_id);
|
|
133
|
+
const {
|
|
134
|
+
data,
|
|
135
|
+
error
|
|
136
|
+
} = await q;
|
|
137
|
+
if (error) return {
|
|
138
|
+
success: false,
|
|
139
|
+
error: error.message
|
|
140
|
+
};
|
|
141
|
+
const reviews = data || [];
|
|
142
|
+
const approved = reviews.filter(r => r.status === "approved");
|
|
143
|
+
const pending = reviews.filter(r => r.status === "pending");
|
|
144
|
+
const avgRating = approved.length > 0 ? Math.round(approved.reduce((s, r) => s + r.rating, 0) / approved.length * 10) / 10 : 0;
|
|
145
|
+
const ratingDist = {
|
|
146
|
+
1: 0,
|
|
147
|
+
2: 0,
|
|
148
|
+
3: 0,
|
|
149
|
+
4: 0,
|
|
150
|
+
5: 0
|
|
151
|
+
};
|
|
152
|
+
for (const r of approved) ratingDist[r.rating] = (ratingDist[r.rating] || 0) + 1;
|
|
153
|
+
return {
|
|
154
|
+
success: true,
|
|
155
|
+
data: {
|
|
156
|
+
total_reviews: reviews.length,
|
|
157
|
+
approved_count: approved.length,
|
|
158
|
+
pending_count: pending.length,
|
|
159
|
+
average_rating: avgRating,
|
|
160
|
+
rating_distribution: ratingDist
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
default:
|
|
165
|
+
return {
|
|
166
|
+
success: false,
|
|
167
|
+
error: `Unknown reviews action: ${args.action}. Valid: list, get, approve, reject, respond, summary`
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=reviews.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviews.js","names":["handleReviews","sb","args","storeId","sid","action","q","from","select","eq","order","ascending","status","product_id","rating","min_rating","gte","max_rating","lte","verified_only","limit","data","error","success","message","count","length","reviewId","review_id","single","update","updated_at","Date","toISOString","response","store_response","responded_at","reviews","approved","filter","r","pending","avgRating","Math","round","reduce","s","ratingDist","total_reviews","approved_count","pending_count","average_rating","rating_distribution"],"sources":["../../../src/server/handlers/reviews.ts"],"sourcesContent":["// server/handlers/reviews.ts — Product review listing and moderation\n\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\n\ntype Result = { success: boolean; data?: unknown; error?: string; [key: string]: unknown };\n\nexport async function handleReviews(\n sb: SupabaseClient,\n args: Record<string, unknown>,\n storeId?: string,\n): Promise<Result> {\n const sid = storeId as string;\n\n switch (args.action) {\n // ---- LIST: list reviews with filters ----\n case \"list\": {\n let q = sb.from(\"product_reviews\")\n .select(\"id, product_id, customer_id, order_id, rating, title, review_text, verified_purchase, status, helpful_count, not_helpful_count, store_response, responded_at, review_images, created_at, product:products!product_id(name, sku)\")\n .eq(\"store_id\", sid)\n .order(\"created_at\", { ascending: false });\n if (args.status) q = q.eq(\"status\", args.status as string);\n if (args.product_id) q = q.eq(\"product_id\", args.product_id as string);\n if (args.rating) q = q.eq(\"rating\", args.rating as number);\n if (args.min_rating) q = q.gte(\"rating\", args.min_rating as number);\n if (args.max_rating) q = q.lte(\"rating\", args.max_rating as number);\n if (args.verified_only === true) q = q.eq(\"verified_purchase\", true);\n q = q.limit(args.limit as number || 50);\n const { data, error } = await q;\n return error ? { success: false, error: error.message } : { success: true, count: data?.length, data };\n }\n\n // ---- GET: get a single review ----\n case \"get\": {\n const reviewId = args.review_id as string;\n if (!reviewId) return { success: false, error: \"review_id is required\" };\n const { data, error } = await sb.from(\"product_reviews\")\n .select(\"*, product:products!product_id(name, sku)\")\n .eq(\"id\", reviewId)\n .eq(\"store_id\", sid)\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- APPROVE: approve a pending review ----\n case \"approve\": {\n const reviewId = args.review_id as string;\n if (!reviewId) return { success: false, error: \"review_id is required\" };\n const { data, error } = await sb.from(\"product_reviews\")\n .update({ status: \"approved\", updated_at: new Date().toISOString() })\n .eq(\"id\", reviewId)\n .eq(\"store_id\", sid)\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- REJECT: reject a review ----\n case \"reject\": {\n const reviewId = args.review_id as string;\n if (!reviewId) return { success: false, error: \"review_id is required\" };\n const { data, error } = await sb.from(\"product_reviews\")\n .update({ status: \"rejected\", updated_at: new Date().toISOString() })\n .eq(\"id\", reviewId)\n .eq(\"store_id\", sid)\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- RESPOND: add a store response to a review ----\n case \"respond\": {\n const reviewId = args.review_id as string;\n const response = args.response as string;\n if (!reviewId || !response) return { success: false, error: \"review_id and response are required\" };\n const { data, error } = await sb.from(\"product_reviews\")\n .update({ store_response: response, responded_at: new Date().toISOString(), updated_at: new Date().toISOString() })\n .eq(\"id\", reviewId)\n .eq(\"store_id\", sid)\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- SUMMARY: get review stats per product or store ----\n case \"summary\": {\n let q = sb.from(\"product_reviews\")\n .select(\"product_id, rating, status\")\n .eq(\"store_id\", sid);\n if (args.product_id) q = q.eq(\"product_id\", args.product_id as string);\n const { data, error } = await q;\n if (error) return { success: false, error: error.message };\n\n const reviews = data || [];\n const approved = reviews.filter(r => r.status === \"approved\");\n const pending = reviews.filter(r => r.status === \"pending\");\n const avgRating = approved.length > 0\n ? Math.round((approved.reduce((s, r) => s + r.rating, 0) / approved.length) * 10) / 10\n : 0;\n const ratingDist: Record<number, number> = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 };\n for (const r of approved) ratingDist[r.rating] = (ratingDist[r.rating] || 0) + 1;\n\n return {\n success: true,\n data: {\n total_reviews: reviews.length,\n approved_count: approved.length,\n pending_count: pending.length,\n average_rating: avgRating,\n rating_distribution: ratingDist,\n },\n };\n }\n\n default:\n return { success: false, error: `Unknown reviews action: ${args.action}. Valid: list, get, approve, reject, respond, summary` };\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
type Result = {
|
|
3
|
+
success: boolean;
|
|
4
|
+
data?: unknown;
|
|
5
|
+
error?: string;
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
};
|
|
8
|
+
export declare function handleSegments(sb: SupabaseClient, args: Record<string, unknown>, storeId?: string): Promise<Result>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
// server/handlers/segments.ts — Customer segment creation and management
|
|
2
|
+
|
|
3
|
+
export async function handleSegments(sb, args, storeId) {
|
|
4
|
+
const sid = storeId;
|
|
5
|
+
switch (args.action) {
|
|
6
|
+
// ---- LIST: list all segments ----
|
|
7
|
+
case "list":
|
|
8
|
+
{
|
|
9
|
+
let q = sb.from("customer_segments").select("id, name, description, ai_description, type, segment_rules, filter_criteria, customer_count, is_active, color, icon, targeting_tips, is_system, auto_refresh, last_refreshed_at, created_at").eq("store_id", sid).order("customer_count", {
|
|
10
|
+
ascending: false
|
|
11
|
+
});
|
|
12
|
+
if (args.is_active !== undefined) q = q.eq("is_active", args.is_active);
|
|
13
|
+
if (args.type) q = q.eq("type", args.type);
|
|
14
|
+
if (args.limit) q = q.limit(args.limit);
|
|
15
|
+
const {
|
|
16
|
+
data,
|
|
17
|
+
error
|
|
18
|
+
} = await q;
|
|
19
|
+
return error ? {
|
|
20
|
+
success: false,
|
|
21
|
+
error: error.message
|
|
22
|
+
} : {
|
|
23
|
+
success: true,
|
|
24
|
+
count: data?.length,
|
|
25
|
+
data
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ---- GET: get a segment with member count ----
|
|
30
|
+
case "get":
|
|
31
|
+
{
|
|
32
|
+
const segId = args.segment_id;
|
|
33
|
+
if (!segId) return {
|
|
34
|
+
success: false,
|
|
35
|
+
error: "segment_id is required"
|
|
36
|
+
};
|
|
37
|
+
const {
|
|
38
|
+
data,
|
|
39
|
+
error
|
|
40
|
+
} = await sb.from("customer_segments").select("*").eq("id", segId).eq("store_id", sid).single();
|
|
41
|
+
return error ? {
|
|
42
|
+
success: false,
|
|
43
|
+
error: error.message
|
|
44
|
+
} : {
|
|
45
|
+
success: true,
|
|
46
|
+
data
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ---- CREATE: create a new segment ----
|
|
51
|
+
case "create":
|
|
52
|
+
{
|
|
53
|
+
const name = args.name;
|
|
54
|
+
if (!name) return {
|
|
55
|
+
success: false,
|
|
56
|
+
error: "name is required"
|
|
57
|
+
};
|
|
58
|
+
const record = {
|
|
59
|
+
store_id: sid,
|
|
60
|
+
name,
|
|
61
|
+
segment_rules: args.segment_rules || {},
|
|
62
|
+
filter_criteria: args.filter_criteria || {}
|
|
63
|
+
};
|
|
64
|
+
if (args.description !== undefined) record.description = args.description;
|
|
65
|
+
if (args.ai_description !== undefined) record.ai_description = args.ai_description;
|
|
66
|
+
if (args.type !== undefined) record.type = args.type;
|
|
67
|
+
if (args.color !== undefined) record.color = args.color;
|
|
68
|
+
if (args.icon !== undefined) record.icon = args.icon;
|
|
69
|
+
if (args.is_dynamic !== undefined) record.is_dynamic = args.is_dynamic;
|
|
70
|
+
if (args.auto_refresh !== undefined) record.auto_refresh = args.auto_refresh;
|
|
71
|
+
if (args.targeting_tips !== undefined) record.targeting_tips = args.targeting_tips;
|
|
72
|
+
const {
|
|
73
|
+
data,
|
|
74
|
+
error
|
|
75
|
+
} = await sb.from("customer_segments").insert(record).select().single();
|
|
76
|
+
return error ? {
|
|
77
|
+
success: false,
|
|
78
|
+
error: error.message
|
|
79
|
+
} : {
|
|
80
|
+
success: true,
|
|
81
|
+
data
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ---- UPDATE: modify a segment ----
|
|
86
|
+
case "update":
|
|
87
|
+
{
|
|
88
|
+
const segId = args.segment_id;
|
|
89
|
+
if (!segId) return {
|
|
90
|
+
success: false,
|
|
91
|
+
error: "segment_id is required"
|
|
92
|
+
};
|
|
93
|
+
const updates = {
|
|
94
|
+
updated_at: new Date().toISOString()
|
|
95
|
+
};
|
|
96
|
+
if (args.name !== undefined) updates.name = args.name;
|
|
97
|
+
if (args.description !== undefined) updates.description = args.description;
|
|
98
|
+
if (args.ai_description !== undefined) updates.ai_description = args.ai_description;
|
|
99
|
+
if (args.segment_rules !== undefined) updates.segment_rules = args.segment_rules;
|
|
100
|
+
if (args.filter_criteria !== undefined) updates.filter_criteria = args.filter_criteria;
|
|
101
|
+
if (args.is_active !== undefined) updates.is_active = args.is_active;
|
|
102
|
+
if (args.color !== undefined) updates.color = args.color;
|
|
103
|
+
if (args.icon !== undefined) updates.icon = args.icon;
|
|
104
|
+
if (args.targeting_tips !== undefined) updates.targeting_tips = args.targeting_tips;
|
|
105
|
+
const {
|
|
106
|
+
data,
|
|
107
|
+
error
|
|
108
|
+
} = await sb.from("customer_segments").update(updates).eq("id", segId).eq("store_id", sid).select().single();
|
|
109
|
+
return error ? {
|
|
110
|
+
success: false,
|
|
111
|
+
error: error.message
|
|
112
|
+
} : {
|
|
113
|
+
success: true,
|
|
114
|
+
data
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ---- MEMBERS: list members of a segment ----
|
|
119
|
+
case "members":
|
|
120
|
+
{
|
|
121
|
+
const segId = args.segment_id;
|
|
122
|
+
if (!segId) return {
|
|
123
|
+
success: false,
|
|
124
|
+
error: "segment_id is required"
|
|
125
|
+
};
|
|
126
|
+
const {
|
|
127
|
+
data,
|
|
128
|
+
error
|
|
129
|
+
} = await sb.from("customer_segment_memberships").select("added_at, customer:v_segment_customers!customer_id(id, first_name, last_name, email, phone, total_spent, total_orders, loyalty_tier, rfm_segment)").eq("segment_id", segId).order("added_at", {
|
|
130
|
+
ascending: false
|
|
131
|
+
}).limit(args.limit || 50);
|
|
132
|
+
if (error) return {
|
|
133
|
+
success: false,
|
|
134
|
+
error: error.message
|
|
135
|
+
};
|
|
136
|
+
const members = (data || []).map(r => ({
|
|
137
|
+
added_at: r.added_at,
|
|
138
|
+
...r.customer
|
|
139
|
+
})).filter(m => m.store_id === sid);
|
|
140
|
+
return {
|
|
141
|
+
success: true,
|
|
142
|
+
count: members.length,
|
|
143
|
+
data: members
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ---- ADD_MEMBER: manually add a customer to a segment ----
|
|
148
|
+
case "add_member":
|
|
149
|
+
{
|
|
150
|
+
const segId = args.segment_id;
|
|
151
|
+
const custId = args.customer_id;
|
|
152
|
+
if (!segId || !custId) return {
|
|
153
|
+
success: false,
|
|
154
|
+
error: "segment_id and customer_id are required"
|
|
155
|
+
};
|
|
156
|
+
const {
|
|
157
|
+
data,
|
|
158
|
+
error
|
|
159
|
+
} = await sb.from("customer_segment_memberships").upsert({
|
|
160
|
+
segment_id: segId,
|
|
161
|
+
customer_id: custId,
|
|
162
|
+
added_at: new Date().toISOString()
|
|
163
|
+
}, {
|
|
164
|
+
onConflict: "segment_id,customer_id"
|
|
165
|
+
}).select().single();
|
|
166
|
+
return error ? {
|
|
167
|
+
success: false,
|
|
168
|
+
error: error.message
|
|
169
|
+
} : {
|
|
170
|
+
success: true,
|
|
171
|
+
data
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// ---- REMOVE_MEMBER: remove a customer from a segment ----
|
|
176
|
+
case "remove_member":
|
|
177
|
+
{
|
|
178
|
+
const segId = args.segment_id;
|
|
179
|
+
const custId = args.customer_id;
|
|
180
|
+
if (!segId || !custId) return {
|
|
181
|
+
success: false,
|
|
182
|
+
error: "segment_id and customer_id are required"
|
|
183
|
+
};
|
|
184
|
+
const {
|
|
185
|
+
error
|
|
186
|
+
} = await sb.from("customer_segment_memberships").delete().eq("segment_id", segId).eq("customer_id", custId);
|
|
187
|
+
return error ? {
|
|
188
|
+
success: false,
|
|
189
|
+
error: error.message
|
|
190
|
+
} : {
|
|
191
|
+
success: true,
|
|
192
|
+
data: {
|
|
193
|
+
removed: true
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// ---- DELETE: deactivate a segment ----
|
|
199
|
+
case "delete":
|
|
200
|
+
{
|
|
201
|
+
const segId = args.segment_id;
|
|
202
|
+
if (!segId) return {
|
|
203
|
+
success: false,
|
|
204
|
+
error: "segment_id is required"
|
|
205
|
+
};
|
|
206
|
+
const {
|
|
207
|
+
error
|
|
208
|
+
} = await sb.from("customer_segments").update({
|
|
209
|
+
is_active: false,
|
|
210
|
+
updated_at: new Date().toISOString()
|
|
211
|
+
}).eq("id", segId).eq("store_id", sid);
|
|
212
|
+
return error ? {
|
|
213
|
+
success: false,
|
|
214
|
+
error: error.message
|
|
215
|
+
} : {
|
|
216
|
+
success: true,
|
|
217
|
+
data: {
|
|
218
|
+
deactivated: true
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
default:
|
|
223
|
+
return {
|
|
224
|
+
success: false,
|
|
225
|
+
error: `Unknown segments action: ${args.action}. Valid: list, get, create, update, members, add_member, remove_member, delete`
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=segments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segments.js","names":["handleSegments","sb","args","storeId","sid","action","q","from","select","eq","order","ascending","is_active","undefined","type","limit","data","error","success","message","count","length","segId","segment_id","single","name","record","store_id","segment_rules","filter_criteria","description","ai_description","color","icon","is_dynamic","auto_refresh","targeting_tips","insert","updates","updated_at","Date","toISOString","update","members","map","r","added_at","customer","filter","m","custId","customer_id","upsert","onConflict","delete","removed","deactivated"],"sources":["../../../src/server/handlers/segments.ts"],"sourcesContent":["// server/handlers/segments.ts — Customer segment creation and management\n\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\n\ntype Result = { success: boolean; data?: unknown; error?: string; [key: string]: unknown };\n\nexport async function handleSegments(\n sb: SupabaseClient,\n args: Record<string, unknown>,\n storeId?: string,\n): Promise<Result> {\n const sid = storeId as string;\n\n switch (args.action) {\n // ---- LIST: list all segments ----\n case \"list\": {\n let q = sb.from(\"customer_segments\")\n .select(\"id, name, description, ai_description, type, segment_rules, filter_criteria, customer_count, is_active, color, icon, targeting_tips, is_system, auto_refresh, last_refreshed_at, created_at\")\n .eq(\"store_id\", sid)\n .order(\"customer_count\", { ascending: false });\n if (args.is_active !== undefined) q = q.eq(\"is_active\", args.is_active as boolean);\n if (args.type) q = q.eq(\"type\", args.type as string);\n if (args.limit) q = q.limit(args.limit as number);\n const { data, error } = await q;\n return error ? { success: false, error: error.message } : { success: true, count: data?.length, data };\n }\n\n // ---- GET: get a segment with member count ----\n case \"get\": {\n const segId = args.segment_id as string;\n if (!segId) return { success: false, error: \"segment_id is required\" };\n const { data, error } = await sb.from(\"customer_segments\")\n .select(\"*\")\n .eq(\"id\", segId)\n .eq(\"store_id\", sid)\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- CREATE: create a new segment ----\n case \"create\": {\n const name = args.name as string;\n if (!name) return { success: false, error: \"name is required\" };\n const record: Record<string, unknown> = {\n store_id: sid,\n name,\n segment_rules: args.segment_rules || {},\n filter_criteria: args.filter_criteria || {},\n };\n if (args.description !== undefined) record.description = args.description;\n if (args.ai_description !== undefined) record.ai_description = args.ai_description;\n if (args.type !== undefined) record.type = args.type;\n if (args.color !== undefined) record.color = args.color;\n if (args.icon !== undefined) record.icon = args.icon;\n if (args.is_dynamic !== undefined) record.is_dynamic = args.is_dynamic;\n if (args.auto_refresh !== undefined) record.auto_refresh = args.auto_refresh;\n if (args.targeting_tips !== undefined) record.targeting_tips = args.targeting_tips;\n\n const { data, error } = await sb.from(\"customer_segments\")\n .insert(record)\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- UPDATE: modify a segment ----\n case \"update\": {\n const segId = args.segment_id as string;\n if (!segId) return { success: false, error: \"segment_id is required\" };\n const updates: Record<string, unknown> = { updated_at: new Date().toISOString() };\n if (args.name !== undefined) updates.name = args.name;\n if (args.description !== undefined) updates.description = args.description;\n if (args.ai_description !== undefined) updates.ai_description = args.ai_description;\n if (args.segment_rules !== undefined) updates.segment_rules = args.segment_rules;\n if (args.filter_criteria !== undefined) updates.filter_criteria = args.filter_criteria;\n if (args.is_active !== undefined) updates.is_active = args.is_active;\n if (args.color !== undefined) updates.color = args.color;\n if (args.icon !== undefined) updates.icon = args.icon;\n if (args.targeting_tips !== undefined) updates.targeting_tips = args.targeting_tips;\n\n const { data, error } = await sb.from(\"customer_segments\")\n .update(updates)\n .eq(\"id\", segId)\n .eq(\"store_id\", sid)\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- MEMBERS: list members of a segment ----\n case \"members\": {\n const segId = args.segment_id as string;\n if (!segId) return { success: false, error: \"segment_id is required\" };\n const { data, error } = await sb.from(\"customer_segment_memberships\")\n .select(\"added_at, customer:v_segment_customers!customer_id(id, first_name, last_name, email, phone, total_spent, total_orders, loyalty_tier, rfm_segment)\")\n .eq(\"segment_id\", segId)\n .order(\"added_at\", { ascending: false })\n .limit(args.limit as number || 50);\n if (error) return { success: false, error: error.message };\n const members = (data || [])\n .map((r: any) => ({ added_at: r.added_at, ...r.customer }))\n .filter((m: any) => m.store_id === sid);\n return { success: true, count: members.length, data: members };\n }\n\n // ---- ADD_MEMBER: manually add a customer to a segment ----\n case \"add_member\": {\n const segId = args.segment_id as string;\n const custId = args.customer_id as string;\n if (!segId || !custId) return { success: false, error: \"segment_id and customer_id are required\" };\n const { data, error } = await sb.from(\"customer_segment_memberships\")\n .upsert({ segment_id: segId, customer_id: custId, added_at: new Date().toISOString() }, { onConflict: \"segment_id,customer_id\" })\n .select()\n .single();\n return error ? { success: false, error: error.message } : { success: true, data };\n }\n\n // ---- REMOVE_MEMBER: remove a customer from a segment ----\n case \"remove_member\": {\n const segId = args.segment_id as string;\n const custId = args.customer_id as string;\n if (!segId || !custId) return { success: false, error: \"segment_id and customer_id are required\" };\n const { error } = await sb.from(\"customer_segment_memberships\")\n .delete()\n .eq(\"segment_id\", segId)\n .eq(\"customer_id\", custId);\n return error ? { success: false, error: error.message } : { success: true, data: { removed: true } };\n }\n\n // ---- DELETE: deactivate a segment ----\n case \"delete\": {\n const segId = args.segment_id as string;\n if (!segId) return { success: false, error: \"segment_id is required\" };\n const { error } = await sb.from(\"customer_segments\")\n .update({ is_active: false, updated_at: new Date().toISOString() })\n .eq(\"id\", segId)\n .eq(\"store_id\", sid);\n return error ? { success: false, error: error.message } : { success: true, data: { deactivated: true } };\n }\n\n default:\n return { success: false, error: `Unknown segments action: ${args.action}. Valid: list, get, create, update, members, add_member, remove_member, delete` };\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
type Result = {
|
|
3
|
+
success: boolean;
|
|
4
|
+
data?: unknown;
|
|
5
|
+
error?: string;
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
};
|
|
8
|
+
export declare function handleSocial(sb: SupabaseClient, args: Record<string, unknown>, storeId?: string): Promise<Result>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// server/handlers/social.ts — Unified Meta/Google ad campaign management
|
|
2
|
+
// Delegates to meta-ads.ts and google-ads.ts handlers for platform-specific operations.
|
|
3
|
+
// This tool provides a single entry point for multi-platform ad management.
|
|
4
|
+
|
|
5
|
+
import { handleMetaAds } from "./meta-ads.js";
|
|
6
|
+
import { handleGoogleAds } from "./google-ads.js";
|
|
7
|
+
export async function handleSocial(sb, args, storeId) {
|
|
8
|
+
const platform = args.platform;
|
|
9
|
+
if (!platform) {
|
|
10
|
+
return {
|
|
11
|
+
success: false,
|
|
12
|
+
error: "platform is required ('meta' or 'google')"
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
switch (platform.toLowerCase()) {
|
|
16
|
+
case "meta":
|
|
17
|
+
case "facebook":
|
|
18
|
+
case "instagram":
|
|
19
|
+
{
|
|
20
|
+
// Delegate to meta_ads handler
|
|
21
|
+
const {
|
|
22
|
+
platform: _,
|
|
23
|
+
...metaArgs
|
|
24
|
+
} = args;
|
|
25
|
+
return handleMetaAds(sb, metaArgs, storeId);
|
|
26
|
+
}
|
|
27
|
+
case "google":
|
|
28
|
+
{
|
|
29
|
+
// Delegate to google_ads handler
|
|
30
|
+
const {
|
|
31
|
+
platform: _,
|
|
32
|
+
...googleArgs
|
|
33
|
+
} = args;
|
|
34
|
+
return handleGoogleAds(sb, googleArgs, storeId);
|
|
35
|
+
}
|
|
36
|
+
case "all":
|
|
37
|
+
{
|
|
38
|
+
// Cross-platform summary: fetch campaigns from both platforms
|
|
39
|
+
if (args.action !== "summary") {
|
|
40
|
+
return {
|
|
41
|
+
success: false,
|
|
42
|
+
error: "platform 'all' only supports action 'summary'"
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const [metaResult, googleResult] = await Promise.all([handleMetaAds(sb, {
|
|
46
|
+
action: "list"
|
|
47
|
+
}, storeId).catch(e => ({
|
|
48
|
+
success: false,
|
|
49
|
+
error: e.message,
|
|
50
|
+
data: []
|
|
51
|
+
})), handleGoogleAds(sb, {
|
|
52
|
+
action: "list"
|
|
53
|
+
}, storeId).catch(e => ({
|
|
54
|
+
success: false,
|
|
55
|
+
error: e.message,
|
|
56
|
+
data: []
|
|
57
|
+
}))]);
|
|
58
|
+
return {
|
|
59
|
+
success: true,
|
|
60
|
+
data: {
|
|
61
|
+
meta: {
|
|
62
|
+
connected: metaResult.success,
|
|
63
|
+
campaigns: metaResult.success ? metaResult.data : [],
|
|
64
|
+
error: metaResult.success ? undefined : metaResult.error
|
|
65
|
+
},
|
|
66
|
+
google: {
|
|
67
|
+
connected: googleResult.success,
|
|
68
|
+
campaigns: googleResult.success ? googleResult.data : [],
|
|
69
|
+
error: googleResult.success ? undefined : googleResult.error
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
default:
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
error: `Unknown platform: ${platform}. Valid: meta, google, all`
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=social.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"social.js","names":["handleMetaAds","handleGoogleAds","handleSocial","sb","args","storeId","platform","success","error","toLowerCase","_","metaArgs","googleArgs","action","metaResult","googleResult","Promise","all","catch","e","message","data","meta","connected","campaigns","undefined","google"],"sources":["../../../src/server/handlers/social.ts"],"sourcesContent":["// server/handlers/social.ts — Unified Meta/Google ad campaign management\n// Delegates to meta-ads.ts and google-ads.ts handlers for platform-specific operations.\n// This tool provides a single entry point for multi-platform ad management.\n\nimport type { SupabaseClient } from \"@supabase/supabase-js\";\nimport { handleMetaAds } from \"./meta-ads.js\";\nimport { handleGoogleAds } from \"./google-ads.js\";\n\ntype Result = { success: boolean; data?: unknown; error?: string; [key: string]: unknown };\n\nexport async function handleSocial(\n sb: SupabaseClient,\n args: Record<string, unknown>,\n storeId?: string,\n): Promise<Result> {\n const platform = args.platform as string;\n if (!platform) {\n return { success: false, error: \"platform is required ('meta' or 'google')\" };\n }\n\n switch (platform.toLowerCase()) {\n case \"meta\":\n case \"facebook\":\n case \"instagram\": {\n // Delegate to meta_ads handler\n const { platform: _, ...metaArgs } = args;\n return handleMetaAds(sb, metaArgs, storeId);\n }\n\n case \"google\": {\n // Delegate to google_ads handler\n const { platform: _, ...googleArgs } = args;\n return handleGoogleAds(sb, googleArgs, storeId);\n }\n\n case \"all\": {\n // Cross-platform summary: fetch campaigns from both platforms\n if (args.action !== \"summary\") {\n return { success: false, error: \"platform 'all' only supports action 'summary'\" };\n }\n\n const [metaResult, googleResult] = await Promise.all([\n handleMetaAds(sb, { action: \"list\" }, storeId).catch(e => ({ success: false, error: e.message, data: [] })),\n handleGoogleAds(sb, { action: \"list\" }, storeId).catch(e => ({ success: false, error: e.message, data: [] })),\n ]);\n\n return {\n success: true,\n data: {\n meta: {\n connected: metaResult.success,\n campaigns: metaResult.success ? metaResult.data : [],\n error: metaResult.success ? undefined : (metaResult as any).error,\n },\n google: {\n connected: googleResult.success,\n campaigns: googleResult.success ? googleResult.data : [],\n error: googleResult.success ? undefined : (googleResult as any).error,\n },\n },\n };\n }\n\n default:\n return { success: false, error: `Unknown platform: ${platform}. Valid: meta, google, all` };\n }\n}\n"],"mappings":"AAAA;AACA;AACA;;AAGA,SAASA,aAAa,QAAQ,eAAe;AAC7C,SAASC,eAAe,QAAQ,iBAAiB;AAIjD,OAAO,eAAeC,YAAYA,CAChCC,EAAkB,EAClBC,IAA6B,EAC7BC,OAAgB,EACC;EACjB,MAAMC,QAAQ,GAAGF,IAAI,CAACE,QAAkB;EACxC,IAAI,CAACA,QAAQ,EAAE;IACb,OAAO;MAAEC,OAAO,EAAE,KAAK;MAAEC,KAAK,EAAE;IAA4C,CAAC;EAC/E;EAEA,QAAQF,QAAQ,CAACG,WAAW,CAAC,CAAC;IAC5B,KAAK,MAAM;IACX,KAAK,UAAU;IACf,KAAK,WAAW;MAAE;QAChB;QACA,MAAM;UAAEH,QAAQ,EAAEI,CAAC;UAAE,GAAGC;QAAS,CAAC,GAAGP,IAAI;QACzC,OAAOJ,aAAa,CAACG,EAAE,EAAEQ,QAAQ,EAAEN,OAAO,CAAC;MAC7C;IAEA,KAAK,QAAQ;MAAE;QACb;QACA,MAAM;UAAEC,QAAQ,EAAEI,CAAC;UAAE,GAAGE;QAAW,CAAC,GAAGR,IAAI;QAC3C,OAAOH,eAAe,CAACE,EAAE,EAAES,UAAU,EAAEP,OAAO,CAAC;MACjD;IAEA,KAAK,KAAK;MAAE;QACV;QACA,IAAID,IAAI,CAACS,MAAM,KAAK,SAAS,EAAE;UAC7B,OAAO;YAAEN,OAAO,EAAE,KAAK;YAAEC,KAAK,EAAE;UAAgD,CAAC;QACnF;QAEA,MAAM,CAACM,UAAU,EAAEC,YAAY,CAAC,GAAG,MAAMC,OAAO,CAACC,GAAG,CAAC,CACnDjB,aAAa,CAACG,EAAE,EAAE;UAAEU,MAAM,EAAE;QAAO,CAAC,EAAER,OAAO,CAAC,CAACa,KAAK,CAACC,CAAC,KAAK;UAAEZ,OAAO,EAAE,KAAK;UAAEC,KAAK,EAAEW,CAAC,CAACC,OAAO;UAAEC,IAAI,EAAE;QAAG,CAAC,CAAC,CAAC,EAC3GpB,eAAe,CAACE,EAAE,EAAE;UAAEU,MAAM,EAAE;QAAO,CAAC,EAAER,OAAO,CAAC,CAACa,KAAK,CAACC,CAAC,KAAK;UAAEZ,OAAO,EAAE,KAAK;UAAEC,KAAK,EAAEW,CAAC,CAACC,OAAO;UAAEC,IAAI,EAAE;QAAG,CAAC,CAAC,CAAC,CAC9G,CAAC;QAEF,OAAO;UACLd,OAAO,EAAE,IAAI;UACbc,IAAI,EAAE;YACJC,IAAI,EAAE;cACJC,SAAS,EAAET,UAAU,CAACP,OAAO;cAC7BiB,SAAS,EAAEV,UAAU,CAACP,OAAO,GAAGO,UAAU,CAACO,IAAI,GAAG,EAAE;cACpDb,KAAK,EAAEM,UAAU,CAACP,OAAO,GAAGkB,SAAS,GAAIX,UAAU,CAASN;YAC9D,CAAC;YACDkB,MAAM,EAAE;cACNH,SAAS,EAAER,YAAY,CAACR,OAAO;cAC/BiB,SAAS,EAAET,YAAY,CAACR,OAAO,GAAGQ,YAAY,CAACM,IAAI,GAAG,EAAE;cACxDb,KAAK,EAAEO,YAAY,CAACR,OAAO,GAAGkB,SAAS,GAAIV,YAAY,CAASP;YAClE;UACF;QACF,CAAC;MACH;IAEA;MACE,OAAO;QAAED,OAAO,EAAE,KAAK;QAAEC,KAAK,EAAE,qBAAqBF,QAAQ;MAA6B,CAAC;EAC/F;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
type Result = {
|
|
3
|
+
success: boolean;
|
|
4
|
+
data?: unknown;
|
|
5
|
+
error?: string;
|
|
6
|
+
[key: string]: unknown;
|
|
7
|
+
};
|
|
8
|
+
export declare function handleTax(sb: SupabaseClient, args: Record<string, unknown>, storeId?: string): Promise<Result>;
|
|
9
|
+
export {};
|