@cimplify/sdk 0.45.3 → 0.45.5
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/advanced.d.mts +3 -2
- package/dist/advanced.d.ts +3 -2
- package/dist/{chunk-J7BUGTAG.mjs → chunk-IF22UYTT.mjs} +1 -1
- package/dist/{chunk-B2MJQ7SU.js → chunk-K6FCVLZA.js} +999 -1
- package/dist/{chunk-ZTPP7PDU.mjs → chunk-RQ3ILHUQ.mjs} +999 -1
- package/dist/{chunk-KD2HHETX.js → chunk-ZH6ZST5T.js} +2 -2
- package/dist/{client-DjzIoewX.d.ts → client-BDYBB-ME.d.ts} +2 -2
- package/dist/{client-C5LcbNxL.d.mts → client-CDUY-6nC.d.mts} +2 -1
- package/dist/{client-EM8xKCPO.d.mts → client-MUD63aYS.d.mts} +2 -2
- package/dist/{client-Bsd4Vi_y.d.ts → client-aZInadOY.d.ts} +2 -1
- package/dist/{index-yMe4VZqR.d.mts → index-3C9J8Wb-.d.mts} +3 -2
- package/dist/{index-PbBuEWp7.d.ts → index-DC_ZcSgO.d.ts} +3 -2
- package/dist/index.d.mts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/mock/cli.mjs +999 -1
- package/dist/mock/library.d.mts +2 -2
- package/dist/mock/library.d.ts +2 -2
- package/dist/mock/library.js +999 -1
- package/dist/mock/library.mjs +999 -1
- package/dist/mock/msw.d.mts +1 -1
- package/dist/mock/msw.d.ts +1 -1
- package/dist/mock/msw.js +999 -1
- package/dist/mock/msw.mjs +999 -1
- package/dist/payment-Bse2XJ-c.d.mts +113 -0
- package/dist/payment-JcNqOf_T.d.ts +113 -0
- package/dist/{price-DMijJ6_3.d.mts → price-YBGk5seG.d.mts} +1 -1
- package/dist/{price-DmQTOnjj.d.ts → price-mHkRncgW.d.ts} +1 -1
- package/dist/{payment-4JSLNTVM.d.mts → product-DiX-HGkT.d.mts} +1 -111
- package/dist/{payment-4JSLNTVM.d.ts → product-DiX-HGkT.d.ts} +1 -111
- package/dist/react.d.mts +4 -3
- package/dist/react.d.ts +4 -3
- package/dist/{server-UARbamIZ.d.mts → server-Bg3VtA1D.d.ts} +10 -1
- package/dist/{server-Bs295U0t.d.mts → server-CzthOeYS.d.mts} +43 -1
- package/dist/{server-Bs295U0t.d.ts → server-CzthOeYS.d.ts} +43 -1
- package/dist/{server-UARbamIZ.d.ts → server-kakjHRgj.d.mts} +10 -1
- package/dist/server.d.mts +4 -3
- package/dist/server.d.ts +4 -3
- package/dist/testing/msw.d.mts +2 -1
- package/dist/testing/msw.d.ts +2 -1
- package/dist/testing/msw.js +2 -2
- package/dist/testing/msw.mjs +1 -1
- package/dist/testing/suite.d.mts +6 -5
- package/dist/testing/suite.d.ts +6 -5
- package/dist/testing/suite.js +21 -21
- package/dist/testing/suite.mjs +2 -2
- package/dist/testing.d.mts +5 -4
- package/dist/testing.d.ts +5 -4
- package/dist/testing.js +77 -77
- package/dist/testing.mjs +3 -3
- package/dist/utils.d.mts +4 -3
- package/dist/utils.d.ts +4 -3
- package/package.json +1 -1
|
@@ -3784,6 +3784,10 @@ function toApiProduct(p, ctx) {
|
|
|
3784
3784
|
duration_unit: p.duration_unit,
|
|
3785
3785
|
duration_minutes: p.duration_minutes,
|
|
3786
3786
|
billing_plans: p.billing_plans,
|
|
3787
|
+
/** Per-product customer inputs (prescription upload, consent
|
|
3788
|
+
* signature, etc.). The Rust backend emits this on ProductView; the
|
|
3789
|
+
* SDK's React components branch on its presence to render inputs. */
|
|
3790
|
+
input_fields: p.input_fields ?? [],
|
|
3787
3791
|
created_at: p.created_at,
|
|
3788
3792
|
updated_at: p.updated_at,
|
|
3789
3793
|
metadata: {
|
|
@@ -9029,6 +9033,998 @@ function seedFashion(registry) {
|
|
|
9029
9033
|
return { businessId };
|
|
9030
9034
|
}
|
|
9031
9035
|
|
|
9036
|
+
// src/mock/seeds/pharmacy.ts
|
|
9037
|
+
var ISO9 = "2026-01-01T00:00:00.000Z";
|
|
9038
|
+
var photoFor6 = (slug) => seedImage("pharmacy", slug);
|
|
9039
|
+
function seedPharmacy(registry) {
|
|
9040
|
+
const businessId = "bus_wellspring_pharmacy";
|
|
9041
|
+
const business = {
|
|
9042
|
+
id: businessId,
|
|
9043
|
+
name: "Wellspring Pharmacy",
|
|
9044
|
+
handle: "wellspring",
|
|
9045
|
+
business_type: "retail",
|
|
9046
|
+
email: "care@wellspringpharmacy.test",
|
|
9047
|
+
default_currency: "GHS",
|
|
9048
|
+
default_phone: "+233244778899",
|
|
9049
|
+
default_address: "5 Liberation Road, Ridge, Accra",
|
|
9050
|
+
default_offers_table_service: false,
|
|
9051
|
+
default_accepts_online_orders: true,
|
|
9052
|
+
image: photoFor6("business-hero"),
|
|
9053
|
+
status: "active",
|
|
9054
|
+
created_at: ISO9,
|
|
9055
|
+
updated_at: ISO9,
|
|
9056
|
+
created_by: "seed",
|
|
9057
|
+
preferences: {
|
|
9058
|
+
theme: "clinical",
|
|
9059
|
+
tagline: "Trusted care, delivered same-day",
|
|
9060
|
+
checkout: { allow_guest: true }
|
|
9061
|
+
},
|
|
9062
|
+
is_online_only: false,
|
|
9063
|
+
enabled_payment_types: ["card", "mobile_money", "cash"],
|
|
9064
|
+
default_location_settings: {},
|
|
9065
|
+
country_code: "GH",
|
|
9066
|
+
timezone: "Africa/Accra"
|
|
9067
|
+
};
|
|
9068
|
+
registry.businesses.put(businessId, business);
|
|
9069
|
+
const categories = [
|
|
9070
|
+
{ slug: "pain-relief", name: "Pain Relief" },
|
|
9071
|
+
{ slug: "cold-flu", name: "Cold & Flu" },
|
|
9072
|
+
{ slug: "vitamins", name: "Vitamins & Supplements" },
|
|
9073
|
+
{ slug: "first-aid", name: "First Aid" },
|
|
9074
|
+
{ slug: "personal-care", name: "Personal Care" },
|
|
9075
|
+
{ slug: "devices", name: "Medical Devices" },
|
|
9076
|
+
{ slug: "baby", name: "Baby & Mother" }
|
|
9077
|
+
];
|
|
9078
|
+
const catIds = /* @__PURE__ */ new Map();
|
|
9079
|
+
for (const c of categories) {
|
|
9080
|
+
const id = `cat_${c.slug}`;
|
|
9081
|
+
catIds.set(c.slug, id);
|
|
9082
|
+
const cat = {
|
|
9083
|
+
id,
|
|
9084
|
+
business_id: businessId,
|
|
9085
|
+
name: c.name,
|
|
9086
|
+
slug: c.slug,
|
|
9087
|
+
description: `Wellspring \u2014 ${c.name}`,
|
|
9088
|
+
product_ids: [],
|
|
9089
|
+
display_order: 0,
|
|
9090
|
+
is_active: true,
|
|
9091
|
+
created_at: ISO9,
|
|
9092
|
+
updated_at: ISO9
|
|
9093
|
+
};
|
|
9094
|
+
registry.categories.put(id, cat);
|
|
9095
|
+
}
|
|
9096
|
+
function field(productSlug, f) {
|
|
9097
|
+
return {
|
|
9098
|
+
id: f.id ?? `fld_${productSlug}_${f.slug}`,
|
|
9099
|
+
product_id: `prod_${productSlug}`,
|
|
9100
|
+
...f
|
|
9101
|
+
};
|
|
9102
|
+
}
|
|
9103
|
+
const products = [
|
|
9104
|
+
// Pain Relief
|
|
9105
|
+
{
|
|
9106
|
+
slug: "paracetamol",
|
|
9107
|
+
name: "Paracetamol 500mg (24 tablets)",
|
|
9108
|
+
price: "12.00",
|
|
9109
|
+
category: "pain-relief",
|
|
9110
|
+
description: "Fever and mild-to-moderate pain. Adults and children over 12.",
|
|
9111
|
+
tags: ["otc", "analgesic"],
|
|
9112
|
+
inputs: [
|
|
9113
|
+
field("paracetamol", {
|
|
9114
|
+
slug: "age_confirmation",
|
|
9115
|
+
name: "Age confirmation",
|
|
9116
|
+
field_type: "checkbox",
|
|
9117
|
+
is_required: true,
|
|
9118
|
+
display_order: 0,
|
|
9119
|
+
help_text: "I confirm this product is for someone aged 12 or over."
|
|
9120
|
+
})
|
|
9121
|
+
]
|
|
9122
|
+
},
|
|
9123
|
+
{ slug: "ibuprofen", name: "Ibuprofen 200mg (20 tablets)", price: "18.00", category: "pain-relief", description: "Anti-inflammatory for headaches, muscle pain, menstrual cramps.", tags: ["otc", "nsaid"] },
|
|
9124
|
+
{ slug: "aspirin", name: "Aspirin 300mg (30 tablets)", price: "15.00", category: "pain-relief", description: "Pain relief and low-dose daily cardiovascular protection.", tags: ["otc", "analgesic"] },
|
|
9125
|
+
{ slug: "allergy-relief", name: "Cetirizine 10mg (10 tablets)", price: "22.00", category: "pain-relief", description: "Non-drowsy antihistamine for seasonal allergies.", tags: ["otc", "antihistamine"] },
|
|
9126
|
+
// Cold & Flu
|
|
9127
|
+
{ slug: "cold-flu-syrup", name: "Cold & Flu Syrup (200ml)", price: "35.00", category: "cold-flu", description: "Multi-symptom relief: blocked nose, sore throat, dry cough.", tags: ["otc", "syrup"] },
|
|
9128
|
+
{ slug: "throat-lozenges", name: "Honey-Lemon Throat Lozenges (24)", price: "18.00", category: "cold-flu", description: "Soothes sore throat and irritation.", tags: ["otc", "lozenge"] },
|
|
9129
|
+
{ slug: "decongestant", name: "Nasal Decongestant Spray (10ml)", price: "28.00", category: "cold-flu", description: "Fast-acting relief for blocked nasal passages.", tags: ["otc", "spray"] },
|
|
9130
|
+
// Vitamins & Supplements
|
|
9131
|
+
{ slug: "multivitamin", name: "Daily Multivitamin (60 tablets)", price: "85.00", category: "vitamins", description: "Once-daily formula with 22 essential vitamins and minerals.", tags: ["supplement", "daily"] },
|
|
9132
|
+
{ slug: "vitamin-c", name: "Vitamin C 1000mg (90 tablets)", price: "65.00", category: "vitamins", description: "Immune-support antioxidant. Time-released.", tags: ["supplement", "immune"] },
|
|
9133
|
+
{ slug: "vitamin-d", name: "Vitamin D3 1000IU (120 capsules)", price: "55.00", category: "vitamins", description: "Bone and immune health. 4-month supply.", tags: ["supplement", "bone-health"] },
|
|
9134
|
+
{ slug: "omega-3", name: "Omega-3 Fish Oil (90 softgels)", price: "120.00", category: "vitamins", description: "1000mg EPA+DHA for heart and brain health.", tags: ["supplement", "heart-health"] },
|
|
9135
|
+
{ slug: "probiotics", name: "Probiotic 10-Strain (30 capsules)", price: "95.00", category: "vitamins", description: "Digestive and immune support.", tags: ["supplement", "digestive"] },
|
|
9136
|
+
// First Aid
|
|
9137
|
+
{ slug: "first-aid-kit", name: "Home First Aid Kit", price: "180.00", category: "first-aid", description: "60-piece kit with plasters, gauze, antiseptic, scissors, and quick-reference guide.", tags: ["kit", "essential"] },
|
|
9138
|
+
{ slug: "plasters", name: "Assorted Plasters (40 pack)", price: "22.00", category: "first-aid", description: "Waterproof adhesive bandages in five sizes.", tags: ["first-aid"] },
|
|
9139
|
+
{ slug: "antiseptic", name: "Antiseptic Cream (30g)", price: "18.00", category: "first-aid", description: "For cuts, grazes, and minor skin infections.", tags: ["first-aid", "cream"] },
|
|
9140
|
+
{ slug: "bandages", name: "Elastic Crepe Bandage (5cm x 4.5m)", price: "15.00", category: "first-aid", description: "Reusable compression bandage for sprains.", tags: ["first-aid"] },
|
|
9141
|
+
// Personal Care
|
|
9142
|
+
{ slug: "hand-sanitizer", name: "Hand Sanitizer 70% Alcohol (500ml)", price: "32.00", category: "personal-care", description: "Kills 99.9% of germs. Moisturising formula.", tags: ["hygiene"] },
|
|
9143
|
+
{ slug: "face-mask", name: "Surgical Face Masks (50 pack)", price: "45.00", category: "personal-care", description: "3-ply earloop masks. Disposable.", tags: ["hygiene", "ppe"] },
|
|
9144
|
+
{ slug: "lip-balm", name: "Medicated Lip Balm (4g)", price: "12.00", category: "personal-care", description: "SPF 15 with cocoa butter and beeswax.", tags: ["skin-care"] },
|
|
9145
|
+
// Medical Devices
|
|
9146
|
+
{ slug: "thermometer", name: "Digital Thermometer", price: "65.00", category: "devices", description: "Fast oral / underarm reading in 10 seconds. Auto-shutoff.", tags: ["device", "essential"] },
|
|
9147
|
+
{
|
|
9148
|
+
slug: "blood-pressure-monitor",
|
|
9149
|
+
name: "Automatic BP Monitor",
|
|
9150
|
+
price: "320.00",
|
|
9151
|
+
category: "devices",
|
|
9152
|
+
description: "Upper-arm cuff with memory for two users. Irregular heartbeat detection.",
|
|
9153
|
+
tags: ["device", "premium"],
|
|
9154
|
+
inputs: [
|
|
9155
|
+
field("blood-pressure-monitor", {
|
|
9156
|
+
slug: "arm_size",
|
|
9157
|
+
name: "Arm circumference",
|
|
9158
|
+
field_type: "select",
|
|
9159
|
+
options: ["Standard (22\u201332 cm)", "Large (32\u201342 cm)"],
|
|
9160
|
+
is_required: true,
|
|
9161
|
+
display_order: 0,
|
|
9162
|
+
help_text: "Pick the cuff that fits \u2014 wrong size gives inaccurate readings."
|
|
9163
|
+
})
|
|
9164
|
+
]
|
|
9165
|
+
},
|
|
9166
|
+
{ slug: "glucometer", name: "Blood Glucose Meter Starter Kit", price: "280.00", category: "devices", description: "Meter, 25 test strips, lancing device, 25 lancets, carry case.", tags: ["device", "diabetes"] },
|
|
9167
|
+
{ slug: "pulse-oximeter", name: "Fingertip Pulse Oximeter", price: "145.00", category: "devices", description: "SpO2 + heart-rate reading in under 10 seconds.", tags: ["device"] },
|
|
9168
|
+
// Baby & Mother
|
|
9169
|
+
{
|
|
9170
|
+
slug: "baby-formula",
|
|
9171
|
+
name: "Infant Formula Stage 1 (400g)",
|
|
9172
|
+
price: "150.00",
|
|
9173
|
+
category: "baby",
|
|
9174
|
+
description: "0\u20136 months. Iron-fortified, with prebiotics.",
|
|
9175
|
+
tags: ["baby", "nutrition"],
|
|
9176
|
+
inputs: [
|
|
9177
|
+
field("baby-formula", {
|
|
9178
|
+
slug: "baby_dob",
|
|
9179
|
+
name: "Baby's date of birth",
|
|
9180
|
+
field_type: "date",
|
|
9181
|
+
is_required: true,
|
|
9182
|
+
display_order: 0,
|
|
9183
|
+
help_text: "Confirms stage 1 is the right formula for your baby's age."
|
|
9184
|
+
}),
|
|
9185
|
+
field("baby-formula", {
|
|
9186
|
+
slug: "allergies",
|
|
9187
|
+
name: "Known allergies or intolerances",
|
|
9188
|
+
field_type: "textarea",
|
|
9189
|
+
is_required: false,
|
|
9190
|
+
display_order: 1,
|
|
9191
|
+
placeholder: "e.g. lactose, soy. Leave blank if none.",
|
|
9192
|
+
semantic_kind: "allergen"
|
|
9193
|
+
})
|
|
9194
|
+
]
|
|
9195
|
+
},
|
|
9196
|
+
{ slug: "baby-wipes", name: "Sensitive Baby Wipes (72 pack)", price: "28.00", category: "baby", description: "Alcohol-free, fragrance-free. Dermatologist-tested.", tags: ["baby", "hygiene"] },
|
|
9197
|
+
// ── Prescription medications (Rx; require a verified prescription) ─
|
|
9198
|
+
{
|
|
9199
|
+
slug: "amoxicillin-rx",
|
|
9200
|
+
name: "Amoxicillin 500mg (Rx)",
|
|
9201
|
+
price: "65.00",
|
|
9202
|
+
category: "pain-relief",
|
|
9203
|
+
description: "Broad-spectrum antibiotic. Prescription required \u2014 our pharmacist will verify before dispensing.",
|
|
9204
|
+
tags: ["prescription", "antibiotic"],
|
|
9205
|
+
requiresPrescription: true,
|
|
9206
|
+
inputs: [
|
|
9207
|
+
field("amoxicillin-rx", {
|
|
9208
|
+
slug: "prescription_upload",
|
|
9209
|
+
name: "Upload prescription",
|
|
9210
|
+
field_type: "file",
|
|
9211
|
+
is_required: true,
|
|
9212
|
+
display_order: 0,
|
|
9213
|
+
help_text: "PDF or photo of your doctor's prescription (max 10 MB).",
|
|
9214
|
+
validation: { accepted_formats: ["pdf", "jpg", "jpeg", "png", "heic"], max_size_mb: 10 }
|
|
9215
|
+
}),
|
|
9216
|
+
field("amoxicillin-rx", {
|
|
9217
|
+
slug: "patient_dob",
|
|
9218
|
+
name: "Patient date of birth",
|
|
9219
|
+
field_type: "date",
|
|
9220
|
+
is_required: true,
|
|
9221
|
+
display_order: 1
|
|
9222
|
+
}),
|
|
9223
|
+
field("amoxicillin-rx", {
|
|
9224
|
+
slug: "consent",
|
|
9225
|
+
name: "I confirm this prescription is genuine and issued for the named patient",
|
|
9226
|
+
field_type: "checkbox",
|
|
9227
|
+
is_required: true,
|
|
9228
|
+
display_order: 2,
|
|
9229
|
+
semantic_kind: "consent"
|
|
9230
|
+
})
|
|
9231
|
+
]
|
|
9232
|
+
},
|
|
9233
|
+
{
|
|
9234
|
+
slug: "insulin-rx",
|
|
9235
|
+
name: "Insulin Glargine 100u/ml (Rx)",
|
|
9236
|
+
price: "240.00",
|
|
9237
|
+
category: "devices",
|
|
9238
|
+
description: "Long-acting basal insulin. Cold-chain delivery; prescription required.",
|
|
9239
|
+
tags: ["prescription", "diabetes", "cold-chain"],
|
|
9240
|
+
requiresPrescription: true,
|
|
9241
|
+
inputs: [
|
|
9242
|
+
field("insulin-rx", {
|
|
9243
|
+
slug: "prescription_upload",
|
|
9244
|
+
name: "Upload prescription",
|
|
9245
|
+
field_type: "file",
|
|
9246
|
+
is_required: true,
|
|
9247
|
+
display_order: 0,
|
|
9248
|
+
help_text: "PDF or photo of your doctor's prescription (max 10 MB).",
|
|
9249
|
+
validation: { accepted_formats: ["pdf", "jpg", "jpeg", "png", "heic"], max_size_mb: 10 }
|
|
9250
|
+
}),
|
|
9251
|
+
field("insulin-rx", {
|
|
9252
|
+
slug: "delivery_temp_acknowledgement",
|
|
9253
|
+
name: "I'll be available to receive a cold-chain delivery",
|
|
9254
|
+
field_type: "checkbox",
|
|
9255
|
+
is_required: true,
|
|
9256
|
+
display_order: 1,
|
|
9257
|
+
help_text: "Insulin must be refrigerated. Delivery driver will hand over directly \u2014 not leave at door.",
|
|
9258
|
+
semantic_kind: "consent"
|
|
9259
|
+
})
|
|
9260
|
+
]
|
|
9261
|
+
},
|
|
9262
|
+
{
|
|
9263
|
+
slug: "vaccination-consent",
|
|
9264
|
+
name: "Flu Shot \u2014 At-Pharmacy",
|
|
9265
|
+
price: "80.00",
|
|
9266
|
+
category: "personal-care",
|
|
9267
|
+
description: "Pharmacist-administered seasonal influenza vaccine. Walk-in or book a slot.",
|
|
9268
|
+
tags: ["service", "vaccination"],
|
|
9269
|
+
inputs: [
|
|
9270
|
+
field("vaccination-consent", {
|
|
9271
|
+
slug: "patient_name",
|
|
9272
|
+
name: "Patient name",
|
|
9273
|
+
field_type: "text",
|
|
9274
|
+
is_required: true,
|
|
9275
|
+
display_order: 0
|
|
9276
|
+
}),
|
|
9277
|
+
field("vaccination-consent", {
|
|
9278
|
+
slug: "patient_dob",
|
|
9279
|
+
name: "Date of birth",
|
|
9280
|
+
field_type: "date",
|
|
9281
|
+
is_required: true,
|
|
9282
|
+
display_order: 1
|
|
9283
|
+
}),
|
|
9284
|
+
field("vaccination-consent", {
|
|
9285
|
+
slug: "allergies",
|
|
9286
|
+
name: "Known allergies or reactions to past vaccines",
|
|
9287
|
+
field_type: "textarea",
|
|
9288
|
+
is_required: false,
|
|
9289
|
+
display_order: 2,
|
|
9290
|
+
placeholder: "Egg, latex, prior vaccine reactions, etc. Leave blank if none.",
|
|
9291
|
+
semantic_kind: "allergen"
|
|
9292
|
+
}),
|
|
9293
|
+
field("vaccination-consent", {
|
|
9294
|
+
slug: "consent_signature",
|
|
9295
|
+
name: "Signed consent",
|
|
9296
|
+
field_type: "signature",
|
|
9297
|
+
is_required: true,
|
|
9298
|
+
display_order: 3,
|
|
9299
|
+
help_text: "Required by our administering pharmacist before vaccination.",
|
|
9300
|
+
semantic_kind: "consent"
|
|
9301
|
+
})
|
|
9302
|
+
]
|
|
9303
|
+
}
|
|
9304
|
+
];
|
|
9305
|
+
for (const p of products) {
|
|
9306
|
+
const id = `prod_${p.slug}`;
|
|
9307
|
+
const catId = catIds.get(p.category);
|
|
9308
|
+
const product = {
|
|
9309
|
+
id,
|
|
9310
|
+
business_id: businessId,
|
|
9311
|
+
name: p.name,
|
|
9312
|
+
slug: p.slug,
|
|
9313
|
+
description: p.description,
|
|
9314
|
+
product_type: "product",
|
|
9315
|
+
base_price: p.price,
|
|
9316
|
+
currency: "GHS",
|
|
9317
|
+
image: photoFor6(p.slug),
|
|
9318
|
+
images: [photoFor6(p.slug)],
|
|
9319
|
+
is_available: true,
|
|
9320
|
+
category_ids: [catId],
|
|
9321
|
+
collection_ids: [],
|
|
9322
|
+
add_on_ids: [],
|
|
9323
|
+
variant_ids: [],
|
|
9324
|
+
tags: p.tags ?? [],
|
|
9325
|
+
input_fields: p.inputs,
|
|
9326
|
+
metadata: p.requiresPrescription ? { requires_prescription: true } : void 0,
|
|
9327
|
+
created_at: ISO9,
|
|
9328
|
+
updated_at: ISO9
|
|
9329
|
+
};
|
|
9330
|
+
registry.products.put(id, product);
|
|
9331
|
+
const cat = registry.categories.get(catId);
|
|
9332
|
+
cat.product_ids.push(id);
|
|
9333
|
+
registry.categories.put(catId, cat);
|
|
9334
|
+
}
|
|
9335
|
+
const essentials = {
|
|
9336
|
+
id: "col_essentials",
|
|
9337
|
+
business_id: businessId,
|
|
9338
|
+
name: "Home Essentials",
|
|
9339
|
+
slug: "essentials",
|
|
9340
|
+
description: "Stock up your medicine cabinet.",
|
|
9341
|
+
product_ids: [
|
|
9342
|
+
"prod_paracetamol",
|
|
9343
|
+
"prod_first-aid-kit",
|
|
9344
|
+
"prod_thermometer",
|
|
9345
|
+
"prod_hand-sanitizer",
|
|
9346
|
+
"prod_multivitamin"
|
|
9347
|
+
],
|
|
9348
|
+
is_active: true,
|
|
9349
|
+
created_at: ISO9,
|
|
9350
|
+
updated_at: ISO9
|
|
9351
|
+
};
|
|
9352
|
+
registry.collections.put(essentials.id, essentials);
|
|
9353
|
+
for (const pid of essentials.product_ids) {
|
|
9354
|
+
const p = registry.products.get(pid);
|
|
9355
|
+
if (p) {
|
|
9356
|
+
p.collection_ids.push(essentials.id);
|
|
9357
|
+
registry.products.put(pid, p);
|
|
9358
|
+
}
|
|
9359
|
+
}
|
|
9360
|
+
const packAxis = {
|
|
9361
|
+
id: "axis_pack_size",
|
|
9362
|
+
business_id: businessId,
|
|
9363
|
+
product_id: "prod_paracetamol",
|
|
9364
|
+
name: "Pack size",
|
|
9365
|
+
display_order: 0,
|
|
9366
|
+
affects_recipe: false,
|
|
9367
|
+
values: [
|
|
9368
|
+
{ id: "axv_pack_24", name: "24 tablets", display: 0 },
|
|
9369
|
+
{ id: "axv_pack_48", name: "48 tablets", display: 1 },
|
|
9370
|
+
{ id: "axv_pack_100", name: "100 tablets (family)", display: 2 }
|
|
9371
|
+
].map((v) => ({
|
|
9372
|
+
id: v.id,
|
|
9373
|
+
business_id: businessId,
|
|
9374
|
+
axis_id: "axis_pack_size",
|
|
9375
|
+
name: v.name,
|
|
9376
|
+
display_order: v.display,
|
|
9377
|
+
created_at: ISO9,
|
|
9378
|
+
updated_at: ISO9
|
|
9379
|
+
})),
|
|
9380
|
+
created_at: ISO9,
|
|
9381
|
+
updated_at: ISO9
|
|
9382
|
+
};
|
|
9383
|
+
registry.variantAxes.put(packAxis.id, packAxis);
|
|
9384
|
+
const packAdj = { pack_24: "0.00", pack_48: "8.00", pack_100: "18.00" };
|
|
9385
|
+
const paracetamolVariantIds = [];
|
|
9386
|
+
let firstVariant = true;
|
|
9387
|
+
for (const pk of packAxis.values) {
|
|
9388
|
+
const key = pk.id.replace("axv_pack_", "pack_");
|
|
9389
|
+
const id = `var_paracetamol_${key.replace("pack_", "")}`;
|
|
9390
|
+
const variant = {
|
|
9391
|
+
id,
|
|
9392
|
+
product_id: "prod_paracetamol",
|
|
9393
|
+
business_id: businessId,
|
|
9394
|
+
name: pk.name,
|
|
9395
|
+
sku: `PCM-${key.toUpperCase()}`,
|
|
9396
|
+
price_adjustment: packAdj[key] ?? "0.00",
|
|
9397
|
+
component_multiplier: "1.00",
|
|
9398
|
+
is_default: firstVariant,
|
|
9399
|
+
is_active: true,
|
|
9400
|
+
axis_value_ids: [pk.id],
|
|
9401
|
+
created_at: ISO9,
|
|
9402
|
+
updated_at: ISO9
|
|
9403
|
+
};
|
|
9404
|
+
registry.variants.put(id, variant);
|
|
9405
|
+
paracetamolVariantIds.push(id);
|
|
9406
|
+
firstVariant = false;
|
|
9407
|
+
}
|
|
9408
|
+
const paracetamol = registry.products.get("prod_paracetamol");
|
|
9409
|
+
if (paracetamol) {
|
|
9410
|
+
paracetamol.variant_ids = paracetamolVariantIds;
|
|
9411
|
+
registry.products.put(paracetamol.id, paracetamol);
|
|
9412
|
+
}
|
|
9413
|
+
const formAddOn = {
|
|
9414
|
+
id: "addon_form",
|
|
9415
|
+
business_id: businessId,
|
|
9416
|
+
name: "Format",
|
|
9417
|
+
is_multiple_allowed: false,
|
|
9418
|
+
is_required: false,
|
|
9419
|
+
is_mutually_exclusive: true,
|
|
9420
|
+
min_selections: 0,
|
|
9421
|
+
max_selections: 1,
|
|
9422
|
+
created_at: ISO9,
|
|
9423
|
+
updated_at: ISO9,
|
|
9424
|
+
options: [
|
|
9425
|
+
{ id: "addopt_generic", add_on_id: "addon_form", business_id: businessId, name: "Generic (default)", default_price: "0.00", is_required: false, is_mutually_exclusive: true, created_at: ISO9, updated_at: ISO9 },
|
|
9426
|
+
{ id: "addopt_brand", add_on_id: "addon_form", business_id: businessId, name: "Brand-name (+30%)", default_price: "8.00", is_required: false, is_mutually_exclusive: true, created_at: ISO9, updated_at: ISO9 }
|
|
9427
|
+
]
|
|
9428
|
+
};
|
|
9429
|
+
registry.addOns.put(formAddOn.id, formAddOn);
|
|
9430
|
+
const medProductIds = ["prod_paracetamol", "prod_ibuprofen", "prod_aspirin", "prod_allergy-relief"];
|
|
9431
|
+
for (const pid of medProductIds) {
|
|
9432
|
+
registry.productAddOns.put(`${pid}:${formAddOn.id}`, { product_id: pid, add_on_id: formAddOn.id });
|
|
9433
|
+
const p = registry.products.get(pid);
|
|
9434
|
+
if (p) {
|
|
9435
|
+
p.add_on_ids.push(formAddOn.id);
|
|
9436
|
+
registry.products.put(pid, p);
|
|
9437
|
+
}
|
|
9438
|
+
}
|
|
9439
|
+
const services = [
|
|
9440
|
+
{
|
|
9441
|
+
id: "svc_bp_check",
|
|
9442
|
+
business_id: businessId,
|
|
9443
|
+
name: "Blood Pressure Check",
|
|
9444
|
+
description: "Free in-store BP reading with our pharmacist.",
|
|
9445
|
+
duration_minutes: 15,
|
|
9446
|
+
price: "0.00",
|
|
9447
|
+
is_available: true
|
|
9448
|
+
},
|
|
9449
|
+
{
|
|
9450
|
+
id: "svc_consultation",
|
|
9451
|
+
business_id: businessId,
|
|
9452
|
+
name: "Pharmacist Consultation",
|
|
9453
|
+
description: "15-minute one-on-one about medications, interactions, or symptoms.",
|
|
9454
|
+
duration_minutes: 15,
|
|
9455
|
+
price: "30.00",
|
|
9456
|
+
is_available: true
|
|
9457
|
+
},
|
|
9458
|
+
{
|
|
9459
|
+
id: "svc_prescription_refill",
|
|
9460
|
+
business_id: businessId,
|
|
9461
|
+
name: "Prescription Refill",
|
|
9462
|
+
description: "Upload your prescription; we prepare it for pickup or delivery same-day.",
|
|
9463
|
+
duration_minutes: 30,
|
|
9464
|
+
price: "0.00",
|
|
9465
|
+
is_available: true
|
|
9466
|
+
},
|
|
9467
|
+
{
|
|
9468
|
+
id: "svc_vaccination",
|
|
9469
|
+
business_id: businessId,
|
|
9470
|
+
name: "Vaccination (Flu, Tetanus)",
|
|
9471
|
+
description: "Walk-in or by appointment. Pharmacist-administered.",
|
|
9472
|
+
duration_minutes: 20,
|
|
9473
|
+
price: "80.00",
|
|
9474
|
+
is_available: true
|
|
9475
|
+
}
|
|
9476
|
+
];
|
|
9477
|
+
for (const s of services) registry.services.put(s.id, s);
|
|
9478
|
+
const tags = [
|
|
9479
|
+
{ id: "tag_otc", business_id: businessId, name: "OTC", slug: "otc", color: "#16a34a", sort_order: 0, usage_count: 11, created_at: ISO9, updated_at: ISO9 },
|
|
9480
|
+
{ id: "tag_essential", business_id: businessId, name: "Essential", slug: "essential", color: "#2563eb", sort_order: 1, usage_count: 2, created_at: ISO9, updated_at: ISO9 },
|
|
9481
|
+
{ id: "tag_prescription", business_id: businessId, name: "Prescription", slug: "prescription", color: "#dc2626", sort_order: 2, usage_count: 0, created_at: ISO9, updated_at: ISO9 }
|
|
9482
|
+
];
|
|
9483
|
+
for (const t of tags) registry.tags.put(t.id, t);
|
|
9484
|
+
const medication = {
|
|
9485
|
+
id: "tax_medication",
|
|
9486
|
+
business_id: businessId,
|
|
9487
|
+
name: "Medication",
|
|
9488
|
+
slug: "medication",
|
|
9489
|
+
path: ["Health", "Medication"],
|
|
9490
|
+
attribute_template_ids: ["attr_active_ingredient", "attr_dosage"],
|
|
9491
|
+
created_at: ISO9,
|
|
9492
|
+
updated_at: ISO9
|
|
9493
|
+
};
|
|
9494
|
+
registry.taxonomies.put(medication.id, medication);
|
|
9495
|
+
const attrs = [
|
|
9496
|
+
{
|
|
9497
|
+
id: "attr_active_ingredient",
|
|
9498
|
+
business_id: businessId,
|
|
9499
|
+
namespace: "core",
|
|
9500
|
+
name: "Active ingredient",
|
|
9501
|
+
slug: "active-ingredient",
|
|
9502
|
+
attribute_type: "text",
|
|
9503
|
+
is_required: false,
|
|
9504
|
+
is_filterable: true,
|
|
9505
|
+
visibility: "public",
|
|
9506
|
+
display_order: 0,
|
|
9507
|
+
applies_to: "product",
|
|
9508
|
+
created_at: ISO9,
|
|
9509
|
+
updated_at: ISO9
|
|
9510
|
+
},
|
|
9511
|
+
{
|
|
9512
|
+
id: "attr_dosage",
|
|
9513
|
+
business_id: businessId,
|
|
9514
|
+
namespace: "core",
|
|
9515
|
+
name: "Dosage form",
|
|
9516
|
+
slug: "dosage-form",
|
|
9517
|
+
attribute_type: "select",
|
|
9518
|
+
options: ["tablet", "capsule", "syrup", "spray", "cream", "drops"],
|
|
9519
|
+
is_required: false,
|
|
9520
|
+
is_filterable: true,
|
|
9521
|
+
visibility: "public",
|
|
9522
|
+
display_order: 1,
|
|
9523
|
+
applies_to: "product",
|
|
9524
|
+
created_at: ISO9,
|
|
9525
|
+
updated_at: ISO9
|
|
9526
|
+
},
|
|
9527
|
+
{
|
|
9528
|
+
id: "attr_prescription_required",
|
|
9529
|
+
business_id: businessId,
|
|
9530
|
+
namespace: "core",
|
|
9531
|
+
name: "Prescription required",
|
|
9532
|
+
slug: "prescription-required",
|
|
9533
|
+
attribute_type: "boolean",
|
|
9534
|
+
is_required: false,
|
|
9535
|
+
is_filterable: true,
|
|
9536
|
+
visibility: "public",
|
|
9537
|
+
display_order: 2,
|
|
9538
|
+
applies_to: "product",
|
|
9539
|
+
created_at: ISO9,
|
|
9540
|
+
updated_at: ISO9
|
|
9541
|
+
}
|
|
9542
|
+
];
|
|
9543
|
+
for (const a of attrs) registry.attributeDefs.put(a.id, a);
|
|
9544
|
+
const articles = [
|
|
9545
|
+
{
|
|
9546
|
+
id: "kb_prescription",
|
|
9547
|
+
business_id: businessId,
|
|
9548
|
+
title: "Prescription handling",
|
|
9549
|
+
slug: "prescription-handling",
|
|
9550
|
+
content: "Upload prescriptions through the prescription-refill service. Our pharmacist verifies before dispensing; same-day pickup or delivery within Accra.",
|
|
9551
|
+
category: "logistics",
|
|
9552
|
+
tags: ["prescription", "delivery"],
|
|
9553
|
+
created_at: ISO9,
|
|
9554
|
+
updated_at: ISO9
|
|
9555
|
+
},
|
|
9556
|
+
{
|
|
9557
|
+
id: "kb_returns",
|
|
9558
|
+
business_id: businessId,
|
|
9559
|
+
title: "Returns & exchanges",
|
|
9560
|
+
slug: "returns",
|
|
9561
|
+
content: "Sealed OTC products may be returned within 7 days with receipt. Opened products, prescriptions, and refrigerated items are non-returnable for safety reasons.",
|
|
9562
|
+
category: "policies",
|
|
9563
|
+
tags: ["returns"],
|
|
9564
|
+
created_at: ISO9,
|
|
9565
|
+
updated_at: ISO9
|
|
9566
|
+
},
|
|
9567
|
+
{
|
|
9568
|
+
id: "kb_consultation",
|
|
9569
|
+
business_id: businessId,
|
|
9570
|
+
title: "Pharmacist consultations",
|
|
9571
|
+
slug: "consultations",
|
|
9572
|
+
content: "15-minute pharmacist appointments cover medication review, side-effect questions, OTC selection, and symptom triage. Book through the services menu.",
|
|
9573
|
+
category: "services",
|
|
9574
|
+
tags: ["consultation"],
|
|
9575
|
+
created_at: ISO9,
|
|
9576
|
+
updated_at: ISO9
|
|
9577
|
+
}
|
|
9578
|
+
];
|
|
9579
|
+
for (const a of articles) registry.knowledgeArticles.put(a.id, a);
|
|
9580
|
+
return { businessId };
|
|
9581
|
+
}
|
|
9582
|
+
|
|
9583
|
+
// src/mock/seeds/auto.ts
|
|
9584
|
+
var ISO10 = "2026-01-01T00:00:00.000Z";
|
|
9585
|
+
var photoFor7 = (slug) => seedImage("auto", slug);
|
|
9586
|
+
function seedAuto(registry) {
|
|
9587
|
+
const businessId = "bus_driveline_auto";
|
|
9588
|
+
const business = {
|
|
9589
|
+
id: businessId,
|
|
9590
|
+
name: "Driveline Auto Parts",
|
|
9591
|
+
handle: "driveline",
|
|
9592
|
+
business_type: "retail",
|
|
9593
|
+
email: "parts@drivelineauto.test",
|
|
9594
|
+
default_currency: "GHS",
|
|
9595
|
+
default_phone: "+233244600600",
|
|
9596
|
+
default_address: "Spintex Road, Accra",
|
|
9597
|
+
default_offers_table_service: false,
|
|
9598
|
+
default_accepts_online_orders: true,
|
|
9599
|
+
image: photoFor7("business-hero"),
|
|
9600
|
+
status: "active",
|
|
9601
|
+
created_at: ISO10,
|
|
9602
|
+
updated_at: ISO10,
|
|
9603
|
+
created_by: "seed",
|
|
9604
|
+
preferences: {
|
|
9605
|
+
theme: "garage",
|
|
9606
|
+
tagline: "Genuine parts. Same-day. Across Ghana.",
|
|
9607
|
+
checkout: { allow_guest: true }
|
|
9608
|
+
},
|
|
9609
|
+
is_online_only: false,
|
|
9610
|
+
enabled_payment_types: ["card", "mobile_money", "cash"],
|
|
9611
|
+
default_location_settings: {},
|
|
9612
|
+
country_code: "GH",
|
|
9613
|
+
timezone: "Africa/Accra"
|
|
9614
|
+
};
|
|
9615
|
+
registry.businesses.put(businessId, business);
|
|
9616
|
+
const categories = [
|
|
9617
|
+
{ slug: "engine-oil", name: "Engine Oil & Fluids" },
|
|
9618
|
+
{ slug: "filters", name: "Filters" },
|
|
9619
|
+
{ slug: "brakes", name: "Brakes" },
|
|
9620
|
+
{ slug: "batteries", name: "Batteries" },
|
|
9621
|
+
{ slug: "tires", name: "Tires & Wheels" },
|
|
9622
|
+
{ slug: "bulbs", name: "Lights & Bulbs" },
|
|
9623
|
+
{ slug: "wipers", name: "Wipers & Exterior" },
|
|
9624
|
+
{ slug: "tools", name: "Tools & Accessories" }
|
|
9625
|
+
];
|
|
9626
|
+
const catIds = /* @__PURE__ */ new Map();
|
|
9627
|
+
for (const c of categories) {
|
|
9628
|
+
const id = `cat_${c.slug}`;
|
|
9629
|
+
catIds.set(c.slug, id);
|
|
9630
|
+
const cat = {
|
|
9631
|
+
id,
|
|
9632
|
+
business_id: businessId,
|
|
9633
|
+
name: c.name,
|
|
9634
|
+
slug: c.slug,
|
|
9635
|
+
description: `Driveline \u2014 ${c.name}`,
|
|
9636
|
+
product_ids: [],
|
|
9637
|
+
display_order: 0,
|
|
9638
|
+
is_active: true,
|
|
9639
|
+
created_at: ISO10,
|
|
9640
|
+
updated_at: ISO10
|
|
9641
|
+
};
|
|
9642
|
+
registry.categories.put(id, cat);
|
|
9643
|
+
}
|
|
9644
|
+
const products = [
|
|
9645
|
+
// Engine oil & fluids
|
|
9646
|
+
{
|
|
9647
|
+
slug: "engine-oil-5w30",
|
|
9648
|
+
name: "5W-30 Full Synthetic Motor Oil (5L)",
|
|
9649
|
+
price: "320.00",
|
|
9650
|
+
category: "engine-oil",
|
|
9651
|
+
description: "API SP / ILSAC GF-6A full synthetic. Recommended for most modern petrol engines.",
|
|
9652
|
+
tags: ["oil", "synthetic", "fits:universal"]
|
|
9653
|
+
},
|
|
9654
|
+
{
|
|
9655
|
+
slug: "engine-oil-5w40",
|
|
9656
|
+
name: "5W-40 Full Synthetic Motor Oil (5L)",
|
|
9657
|
+
price: "335.00",
|
|
9658
|
+
category: "engine-oil",
|
|
9659
|
+
description: "Higher viscosity for European petrol and diesel engines. API SN / ACEA C3.",
|
|
9660
|
+
tags: ["oil", "synthetic", "fits:universal"]
|
|
9661
|
+
},
|
|
9662
|
+
{
|
|
9663
|
+
slug: "engine-oil-10w40",
|
|
9664
|
+
name: "10W-40 Semi-Synthetic Motor Oil (5L)",
|
|
9665
|
+
price: "240.00",
|
|
9666
|
+
category: "engine-oil",
|
|
9667
|
+
description: "All-weather semi-synthetic. Ideal for older or high-mileage engines.",
|
|
9668
|
+
tags: ["oil", "semi-synthetic", "fits:universal"]
|
|
9669
|
+
},
|
|
9670
|
+
{
|
|
9671
|
+
slug: "brake-fluid",
|
|
9672
|
+
name: "DOT 4 Brake Fluid (500ml)",
|
|
9673
|
+
price: "55.00",
|
|
9674
|
+
category: "engine-oil",
|
|
9675
|
+
description: "High-boiling-point hydraulic brake fluid. Replace every 2 years.",
|
|
9676
|
+
tags: ["fluid", "fits:universal"]
|
|
9677
|
+
},
|
|
9678
|
+
{
|
|
9679
|
+
slug: "coolant",
|
|
9680
|
+
name: "Long-Life Coolant Concentrate (1L)",
|
|
9681
|
+
price: "75.00",
|
|
9682
|
+
category: "engine-oil",
|
|
9683
|
+
description: "Ethylene-glycol concentrate. Dilute 50/50 with distilled water.",
|
|
9684
|
+
tags: ["fluid", "fits:universal"]
|
|
9685
|
+
},
|
|
9686
|
+
{
|
|
9687
|
+
slug: "transmission-fluid",
|
|
9688
|
+
name: "ATF Dexron VI (1L)",
|
|
9689
|
+
price: "95.00",
|
|
9690
|
+
category: "engine-oil",
|
|
9691
|
+
description: "Full-synthetic automatic transmission fluid. Backwards-compatible with Dexron III/II.",
|
|
9692
|
+
tags: ["fluid", "fits:universal"]
|
|
9693
|
+
},
|
|
9694
|
+
// Filters
|
|
9695
|
+
{
|
|
9696
|
+
slug: "oil-filter",
|
|
9697
|
+
name: "Oil Filter \u2014 Toyota / Honda / Nissan 1.5L\u20132.5L",
|
|
9698
|
+
price: "55.00",
|
|
9699
|
+
category: "filters",
|
|
9700
|
+
description: "Spin-on oil filter. Fits most Japanese-make 4-cylinder engines.",
|
|
9701
|
+
tags: ["filter", "fits:toyota", "fits:honda", "fits:nissan"]
|
|
9702
|
+
},
|
|
9703
|
+
{
|
|
9704
|
+
slug: "air-filter",
|
|
9705
|
+
name: "Engine Air Filter \u2014 Toyota Corolla / Yaris (2014\u20132024)",
|
|
9706
|
+
price: "85.00",
|
|
9707
|
+
category: "filters",
|
|
9708
|
+
description: "Pleated paper element. Replace every 20,000 km.",
|
|
9709
|
+
tags: ["filter", "fits:toyota", "fits:toyota:corolla", "fits:toyota:yaris"]
|
|
9710
|
+
},
|
|
9711
|
+
{
|
|
9712
|
+
slug: "cabin-filter",
|
|
9713
|
+
name: "Cabin Air Filter \u2014 Honda Civic / CR-V (2016\u20132023)",
|
|
9714
|
+
price: "95.00",
|
|
9715
|
+
category: "filters",
|
|
9716
|
+
description: "Activated-charcoal cabin filter. Improves AC airflow and traps pollen.",
|
|
9717
|
+
tags: ["filter", "fits:honda", "fits:honda:civic", "fits:honda:cr-v"]
|
|
9718
|
+
},
|
|
9719
|
+
{
|
|
9720
|
+
slug: "fuel-filter",
|
|
9721
|
+
name: "Fuel Filter \u2014 Nissan Almera / Sentra (2015\u20132024)",
|
|
9722
|
+
price: "120.00",
|
|
9723
|
+
category: "filters",
|
|
9724
|
+
description: "In-line fuel filter. Replace every 40,000 km.",
|
|
9725
|
+
tags: ["filter", "fits:nissan", "fits:nissan:almera", "fits:nissan:sentra"]
|
|
9726
|
+
},
|
|
9727
|
+
// Brakes
|
|
9728
|
+
{
|
|
9729
|
+
slug: "brake-pads-front",
|
|
9730
|
+
name: "Front Brake Pads \u2014 Toyota Corolla (2014\u20132024)",
|
|
9731
|
+
price: "280.00",
|
|
9732
|
+
category: "brakes",
|
|
9733
|
+
description: "Low-dust ceramic compound. Includes anti-squeal shims.",
|
|
9734
|
+
tags: ["brakes", "ceramic", "fits:toyota", "fits:toyota:corolla"]
|
|
9735
|
+
},
|
|
9736
|
+
{
|
|
9737
|
+
slug: "brake-pads-rear",
|
|
9738
|
+
name: "Rear Brake Pads \u2014 Honda Civic (2016\u20132023)",
|
|
9739
|
+
price: "240.00",
|
|
9740
|
+
category: "brakes",
|
|
9741
|
+
description: "Semi-metallic compound. Quiet, low-dust.",
|
|
9742
|
+
tags: ["brakes", "fits:honda", "fits:honda:civic"]
|
|
9743
|
+
},
|
|
9744
|
+
{
|
|
9745
|
+
slug: "brake-discs",
|
|
9746
|
+
name: "Front Brake Discs (pair) \u2014 Hyundai Elantra (2017\u20132024)",
|
|
9747
|
+
price: "650.00",
|
|
9748
|
+
category: "brakes",
|
|
9749
|
+
description: "Vented rotors with anti-corrosion coating. Sold as a pair.",
|
|
9750
|
+
tags: ["brakes", "fits:hyundai", "fits:hyundai:elantra"]
|
|
9751
|
+
},
|
|
9752
|
+
{
|
|
9753
|
+
slug: "spark-plugs",
|
|
9754
|
+
name: "Iridium Spark Plugs (set of 4) \u2014 Toyota / Honda 1.5L\u20132.0L",
|
|
9755
|
+
price: "180.00",
|
|
9756
|
+
category: "brakes",
|
|
9757
|
+
description: "Long-life iridium spark plugs. Lasts 100,000 km.",
|
|
9758
|
+
tags: ["ignition", "fits:toyota", "fits:honda"]
|
|
9759
|
+
},
|
|
9760
|
+
// Batteries
|
|
9761
|
+
{
|
|
9762
|
+
slug: "battery-60ah",
|
|
9763
|
+
name: "60Ah Maintenance-Free Battery",
|
|
9764
|
+
price: "780.00",
|
|
9765
|
+
category: "batteries",
|
|
9766
|
+
description: "CCA 540A. Fits most Japanese saloons. 2-year warranty.",
|
|
9767
|
+
tags: ["battery", "fits:toyota", "fits:honda", "fits:nissan", "fits:hyundai"]
|
|
9768
|
+
},
|
|
9769
|
+
{
|
|
9770
|
+
slug: "battery-70ah",
|
|
9771
|
+
name: "70Ah Maintenance-Free Battery",
|
|
9772
|
+
price: "920.00",
|
|
9773
|
+
category: "batteries",
|
|
9774
|
+
description: "CCA 640A. Fits SUVs and European saloons. 2-year warranty.",
|
|
9775
|
+
tags: ["battery", "fits:toyota", "fits:hyundai", "fits:volkswagen"]
|
|
9776
|
+
},
|
|
9777
|
+
{
|
|
9778
|
+
slug: "battery-100ah",
|
|
9779
|
+
name: "100Ah Heavy-Duty Battery",
|
|
9780
|
+
price: "1450.00",
|
|
9781
|
+
category: "batteries",
|
|
9782
|
+
description: "CCA 850A. For 4x4s, diesel engines, and aftermarket audio. 2-year warranty.",
|
|
9783
|
+
tags: ["battery", "heavy-duty", "fits:toyota", "fits:nissan"]
|
|
9784
|
+
},
|
|
9785
|
+
// Tires & wheels
|
|
9786
|
+
{
|
|
9787
|
+
slug: "tire-195-65-r15",
|
|
9788
|
+
name: "Tire 195/65 R15 \u2014 All-Season",
|
|
9789
|
+
price: "620.00",
|
|
9790
|
+
category: "tires",
|
|
9791
|
+
description: "Fits Toyota Corolla, Yaris, and most compact saloons. Treadwear 480.",
|
|
9792
|
+
tags: ["tire", "fits:toyota", "fits:toyota:corolla", "fits:toyota:yaris"]
|
|
9793
|
+
},
|
|
9794
|
+
{
|
|
9795
|
+
slug: "tire-205-55-r16",
|
|
9796
|
+
name: "Tire 205/55 R16 \u2014 All-Season",
|
|
9797
|
+
price: "780.00",
|
|
9798
|
+
category: "tires",
|
|
9799
|
+
description: "Fits Honda Civic, Mazda 3, VW Jetta. Treadwear 500.",
|
|
9800
|
+
tags: ["tire", "fits:honda", "fits:honda:civic", "fits:mazda", "fits:volkswagen"]
|
|
9801
|
+
},
|
|
9802
|
+
{
|
|
9803
|
+
slug: "tire-all-terrain",
|
|
9804
|
+
name: "Tire 265/70 R17 \u2014 All-Terrain",
|
|
9805
|
+
price: "1280.00",
|
|
9806
|
+
category: "tires",
|
|
9807
|
+
description: "Fits Toyota Hilux, Ford Ranger, Mitsubishi L200. Aggressive mud-and-snow tread.",
|
|
9808
|
+
tags: ["tire", "all-terrain", "fits:toyota", "fits:toyota:hilux", "fits:ford"]
|
|
9809
|
+
},
|
|
9810
|
+
// Lights & bulbs
|
|
9811
|
+
{
|
|
9812
|
+
slug: "h4-bulb",
|
|
9813
|
+
name: "H4 Halogen Bulb (pair) \u2014 Universal",
|
|
9814
|
+
price: "85.00",
|
|
9815
|
+
category: "bulbs",
|
|
9816
|
+
description: "55/60W halogen headlight bulbs. Drop-in replacement.",
|
|
9817
|
+
tags: ["bulb", "halogen", "fits:universal"]
|
|
9818
|
+
},
|
|
9819
|
+
{
|
|
9820
|
+
slug: "h7-led-headlight",
|
|
9821
|
+
name: "H7 LED Headlight Conversion (pair)",
|
|
9822
|
+
price: "320.00",
|
|
9823
|
+
category: "bulbs",
|
|
9824
|
+
description: "6000K daylight white. CANbus-compatible; no dashboard error.",
|
|
9825
|
+
tags: ["bulb", "led", "fits:universal"]
|
|
9826
|
+
},
|
|
9827
|
+
{
|
|
9828
|
+
slug: "brake-light-bulb",
|
|
9829
|
+
name: "Brake / Tail Light Bulb (pair) \u2014 P21W",
|
|
9830
|
+
price: "35.00",
|
|
9831
|
+
category: "bulbs",
|
|
9832
|
+
description: "21W stop and tail light bulbs. Universal bayonet fit.",
|
|
9833
|
+
tags: ["bulb", "fits:universal"]
|
|
9834
|
+
},
|
|
9835
|
+
// Wipers & exterior
|
|
9836
|
+
{
|
|
9837
|
+
slug: "wiper-blades-22",
|
|
9838
|
+
name: 'Wiper Blades 22" (pair)',
|
|
9839
|
+
price: "95.00",
|
|
9840
|
+
category: "wipers",
|
|
9841
|
+
description: "Soft-rubber refill. Fits Toyota Corolla, Honda Civic, and most compact saloons.",
|
|
9842
|
+
tags: ["wiper", "fits:universal"]
|
|
9843
|
+
},
|
|
9844
|
+
{
|
|
9845
|
+
slug: "wiper-blades-24",
|
|
9846
|
+
name: 'Wiper Blades 24" (pair)',
|
|
9847
|
+
price: "110.00",
|
|
9848
|
+
category: "wipers",
|
|
9849
|
+
description: "Soft-rubber refill. Fits Toyota Camry, Honda Accord, Hyundai Sonata.",
|
|
9850
|
+
tags: ["wiper", "fits:universal"]
|
|
9851
|
+
},
|
|
9852
|
+
{
|
|
9853
|
+
slug: "washer-fluid",
|
|
9854
|
+
name: "Concentrated Washer Fluid (1L)",
|
|
9855
|
+
price: "25.00",
|
|
9856
|
+
category: "wipers",
|
|
9857
|
+
description: "Dilutes 1:10. Bug-and-tar cleaner, anti-streak.",
|
|
9858
|
+
tags: ["fluid", "fits:universal"]
|
|
9859
|
+
},
|
|
9860
|
+
{
|
|
9861
|
+
slug: "floor-mats",
|
|
9862
|
+
name: "All-Weather Floor Mats (set of 4)",
|
|
9863
|
+
price: "180.00",
|
|
9864
|
+
category: "wipers",
|
|
9865
|
+
description: "Heavy-duty rubber. Trimmable to fit any vehicle.",
|
|
9866
|
+
tags: ["interior", "fits:universal"]
|
|
9867
|
+
},
|
|
9868
|
+
// Tools & accessories
|
|
9869
|
+
{
|
|
9870
|
+
slug: "dashcam",
|
|
9871
|
+
name: "1080p Dashcam with GPS",
|
|
9872
|
+
price: "650.00",
|
|
9873
|
+
category: "tools",
|
|
9874
|
+
description: "Loop recording, G-sensor, 32GB card included. 12V cigarette-lighter plug.",
|
|
9875
|
+
tags: ["electronics", "fits:universal"]
|
|
9876
|
+
},
|
|
9877
|
+
{
|
|
9878
|
+
slug: "jumper-cables",
|
|
9879
|
+
name: "Heavy-Duty Jumper Cables (4m, 1000A)",
|
|
9880
|
+
price: "220.00",
|
|
9881
|
+
category: "tools",
|
|
9882
|
+
description: "4-gauge copper-clad cables. Suitable for cars, SUVs, and small trucks.",
|
|
9883
|
+
tags: ["tool", "fits:universal"]
|
|
9884
|
+
},
|
|
9885
|
+
{
|
|
9886
|
+
slug: "tire-inflator",
|
|
9887
|
+
name: "12V Portable Tire Inflator",
|
|
9888
|
+
price: "280.00",
|
|
9889
|
+
category: "tools",
|
|
9890
|
+
description: "150 PSI compressor with digital gauge and auto-shutoff. Cigarette-lighter plug.",
|
|
9891
|
+
tags: ["tool", "fits:universal"]
|
|
9892
|
+
},
|
|
9893
|
+
{
|
|
9894
|
+
slug: "microfiber-cloth",
|
|
9895
|
+
name: "Microfiber Detailing Cloth (6 pack)",
|
|
9896
|
+
price: "60.00",
|
|
9897
|
+
category: "tools",
|
|
9898
|
+
description: "Lint-free 40x40cm microfiber cloths. Wash-and-reuse.",
|
|
9899
|
+
tags: ["detailing", "fits:universal"]
|
|
9900
|
+
}
|
|
9901
|
+
];
|
|
9902
|
+
for (const p of products) {
|
|
9903
|
+
const id = `prod_${p.slug}`;
|
|
9904
|
+
const catId = catIds.get(p.category);
|
|
9905
|
+
const product = {
|
|
9906
|
+
id,
|
|
9907
|
+
business_id: businessId,
|
|
9908
|
+
name: p.name,
|
|
9909
|
+
slug: p.slug,
|
|
9910
|
+
description: p.description,
|
|
9911
|
+
product_type: "product",
|
|
9912
|
+
base_price: p.price,
|
|
9913
|
+
currency: "GHS",
|
|
9914
|
+
image: photoFor7(p.slug),
|
|
9915
|
+
images: [photoFor7(p.slug)],
|
|
9916
|
+
is_available: true,
|
|
9917
|
+
category_ids: [catId],
|
|
9918
|
+
collection_ids: [],
|
|
9919
|
+
add_on_ids: [],
|
|
9920
|
+
variant_ids: [],
|
|
9921
|
+
tags: p.tags ?? [],
|
|
9922
|
+
created_at: ISO10,
|
|
9923
|
+
updated_at: ISO10
|
|
9924
|
+
};
|
|
9925
|
+
registry.products.put(id, product);
|
|
9926
|
+
const cat = registry.categories.get(catId);
|
|
9927
|
+
cat.product_ids.push(id);
|
|
9928
|
+
registry.categories.put(catId, cat);
|
|
9929
|
+
}
|
|
9930
|
+
const serviceKit = {
|
|
9931
|
+
id: "col_service_kit",
|
|
9932
|
+
business_id: businessId,
|
|
9933
|
+
name: "Service-due kit",
|
|
9934
|
+
slug: "service-kit",
|
|
9935
|
+
description: "Everything for a routine oil-and-filter service.",
|
|
9936
|
+
product_ids: [
|
|
9937
|
+
"prod_engine-oil-5w30",
|
|
9938
|
+
"prod_oil-filter",
|
|
9939
|
+
"prod_air-filter",
|
|
9940
|
+
"prod_cabin-filter",
|
|
9941
|
+
"prod_spark-plugs"
|
|
9942
|
+
],
|
|
9943
|
+
is_active: true,
|
|
9944
|
+
created_at: ISO10,
|
|
9945
|
+
updated_at: ISO10
|
|
9946
|
+
};
|
|
9947
|
+
registry.collections.put(serviceKit.id, serviceKit);
|
|
9948
|
+
for (const pid of serviceKit.product_ids) {
|
|
9949
|
+
const p = registry.products.get(pid);
|
|
9950
|
+
if (p) {
|
|
9951
|
+
p.collection_ids.push(serviceKit.id);
|
|
9952
|
+
registry.products.put(pid, p);
|
|
9953
|
+
}
|
|
9954
|
+
}
|
|
9955
|
+
const tagDefs = [
|
|
9956
|
+
{ slug: "oil", name: "Oil" },
|
|
9957
|
+
{ slug: "filter", name: "Filter" },
|
|
9958
|
+
{ slug: "brakes", name: "Brakes" },
|
|
9959
|
+
{ slug: "battery", name: "Battery" },
|
|
9960
|
+
{ slug: "tire", name: "Tire" },
|
|
9961
|
+
{ slug: "fits:toyota", name: "Fits Toyota" },
|
|
9962
|
+
{ slug: "fits:honda", name: "Fits Honda" },
|
|
9963
|
+
{ slug: "fits:nissan", name: "Fits Nissan" },
|
|
9964
|
+
{ slug: "fits:hyundai", name: "Fits Hyundai" },
|
|
9965
|
+
{ slug: "fits:universal", name: "Fits Universal" }
|
|
9966
|
+
];
|
|
9967
|
+
const tags = tagDefs.map((t, i) => ({
|
|
9968
|
+
id: `tag_${t.slug.replace(/[:]/g, "_")}`,
|
|
9969
|
+
business_id: businessId,
|
|
9970
|
+
name: t.name,
|
|
9971
|
+
slug: t.slug,
|
|
9972
|
+
sort_order: i,
|
|
9973
|
+
usage_count: 0,
|
|
9974
|
+
created_at: ISO10,
|
|
9975
|
+
updated_at: ISO10
|
|
9976
|
+
}));
|
|
9977
|
+
for (const t of tags) registry.tags.put(t.id, t);
|
|
9978
|
+
const taxonomy = {
|
|
9979
|
+
id: "tax_driveline",
|
|
9980
|
+
business_id: businessId,
|
|
9981
|
+
name: "Driveline catalogue",
|
|
9982
|
+
slug: "catalogue",
|
|
9983
|
+
path: [],
|
|
9984
|
+
attribute_template_ids: [],
|
|
9985
|
+
created_at: ISO10,
|
|
9986
|
+
updated_at: ISO10
|
|
9987
|
+
};
|
|
9988
|
+
registry.taxonomies.put(taxonomy.id, taxonomy);
|
|
9989
|
+
const kb = [
|
|
9990
|
+
{
|
|
9991
|
+
id: "kb_fitment",
|
|
9992
|
+
business_id: businessId,
|
|
9993
|
+
title: "How fitment works",
|
|
9994
|
+
slug: "fitment",
|
|
9995
|
+
content: "Every Driveline part lists which makes and models it fits. Use the fitment finder on the home page to filter the whole catalogue to parts that match your vehicle. Universal parts (oil, wipers, tools) always appear regardless of your selection.",
|
|
9996
|
+
category: "fitment",
|
|
9997
|
+
tags: ["fitment"],
|
|
9998
|
+
created_at: ISO10,
|
|
9999
|
+
updated_at: ISO10
|
|
10000
|
+
},
|
|
10001
|
+
{
|
|
10002
|
+
id: "kb_returns",
|
|
10003
|
+
business_id: businessId,
|
|
10004
|
+
title: "Returns & exchanges",
|
|
10005
|
+
slug: "returns",
|
|
10006
|
+
content: "Wrong part? 30-day exchange on unopened items. Electrical parts (bulbs, batteries, dashcams) are exchange-only once installed.",
|
|
10007
|
+
category: "policies",
|
|
10008
|
+
tags: ["returns"],
|
|
10009
|
+
created_at: ISO10,
|
|
10010
|
+
updated_at: ISO10
|
|
10011
|
+
},
|
|
10012
|
+
{
|
|
10013
|
+
id: "kb_install",
|
|
10014
|
+
business_id: businessId,
|
|
10015
|
+
title: "Installation",
|
|
10016
|
+
slug: "installation",
|
|
10017
|
+
content: "Need help fitting a part? Our partner workshops on Spintex and Tema Industrial offer flat-rate fitting from GH\u20B580. Ask at checkout.",
|
|
10018
|
+
category: "service",
|
|
10019
|
+
tags: ["installation"],
|
|
10020
|
+
created_at: ISO10,
|
|
10021
|
+
updated_at: ISO10
|
|
10022
|
+
}
|
|
10023
|
+
];
|
|
10024
|
+
for (const a of kb) registry.knowledgeArticles.put(a.id, a);
|
|
10025
|
+
return { businessId };
|
|
10026
|
+
}
|
|
10027
|
+
|
|
9032
10028
|
// src/mock/seeds/registry.ts
|
|
9033
10029
|
var SEEDS = {
|
|
9034
10030
|
default: seedDefault,
|
|
@@ -9038,7 +10034,9 @@ var SEEDS = {
|
|
|
9038
10034
|
retail: seedRetail,
|
|
9039
10035
|
services: seedServices,
|
|
9040
10036
|
grocery: seedGrocery,
|
|
9041
|
-
fashion: seedFashion
|
|
10037
|
+
fashion: seedFashion,
|
|
10038
|
+
pharmacy: seedPharmacy,
|
|
10039
|
+
auto: seedAuto
|
|
9042
10040
|
};
|
|
9043
10041
|
function applySeed(registry, name) {
|
|
9044
10042
|
const fn = SEEDS[name];
|