@cimplify/sdk 0.45.2 → 0.45.4

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.
Files changed (52) hide show
  1. package/dist/advanced.d.mts +3 -2
  2. package/dist/advanced.d.ts +3 -2
  3. package/dist/{chunk-JNXCY43J.js → chunk-3OPVWRIP.js} +2 -2
  4. package/dist/{chunk-F4CGIOIJ.js → chunk-CJN5SPXN.js} +598 -158
  5. package/dist/{chunk-EMEUSFSR.mjs → chunk-DZGOF7CA.mjs} +598 -158
  6. package/dist/{chunk-YVIIBCJR.mjs → chunk-GDGDDGAE.mjs} +1 -1
  7. package/dist/{client-DjzIoewX.d.ts → client-B0RPhAvp.d.ts} +2 -2
  8. package/dist/{client-EM8xKCPO.d.mts → client-BUtbmHv-.d.mts} +2 -2
  9. package/dist/{client-C5LcbNxL.d.mts → client-CDUY-6nC.d.mts} +2 -1
  10. package/dist/{client-Bsd4Vi_y.d.ts → client-aZInadOY.d.ts} +2 -1
  11. package/dist/{index-yMe4VZqR.d.mts → index-3C9J8Wb-.d.mts} +3 -2
  12. package/dist/{index-PbBuEWp7.d.ts → index-DC_ZcSgO.d.ts} +3 -2
  13. package/dist/index.d.mts +6 -5
  14. package/dist/index.d.ts +6 -5
  15. package/dist/mock/cli.mjs +598 -158
  16. package/dist/mock/library.d.mts +2 -2
  17. package/dist/mock/library.d.ts +2 -2
  18. package/dist/mock/library.js +598 -158
  19. package/dist/mock/library.mjs +598 -158
  20. package/dist/mock/msw.d.mts +1 -1
  21. package/dist/mock/msw.d.ts +1 -1
  22. package/dist/mock/msw.js +598 -158
  23. package/dist/mock/msw.mjs +598 -158
  24. package/dist/payment-Bse2XJ-c.d.mts +113 -0
  25. package/dist/payment-JcNqOf_T.d.ts +113 -0
  26. package/dist/{price-DMijJ6_3.d.mts → price-YBGk5seG.d.mts} +1 -1
  27. package/dist/{price-DmQTOnjj.d.ts → price-mHkRncgW.d.ts} +1 -1
  28. package/dist/{payment-4JSLNTVM.d.ts → product-DiX-HGkT.d.mts} +1 -111
  29. package/dist/{payment-4JSLNTVM.d.mts → product-DiX-HGkT.d.ts} +1 -111
  30. package/dist/react.d.mts +4 -3
  31. package/dist/react.d.ts +4 -3
  32. package/dist/{server-UARbamIZ.d.ts → server-BY-DDUM0.d.mts} +10 -1
  33. package/dist/{server-Bs295U0t.d.ts → server-CiUhgjZA.d.mts} +43 -1
  34. package/dist/{server-Bs295U0t.d.mts → server-CiUhgjZA.d.ts} +43 -1
  35. package/dist/{server-UARbamIZ.d.mts → server-DkrQ4Idn.d.ts} +10 -1
  36. package/dist/server.d.mts +4 -3
  37. package/dist/server.d.ts +4 -3
  38. package/dist/testing/msw.d.mts +2 -1
  39. package/dist/testing/msw.d.ts +2 -1
  40. package/dist/testing/msw.js +2 -2
  41. package/dist/testing/msw.mjs +1 -1
  42. package/dist/testing/suite.d.mts +6 -5
  43. package/dist/testing/suite.d.ts +6 -5
  44. package/dist/testing/suite.js +21 -21
  45. package/dist/testing/suite.mjs +2 -2
  46. package/dist/testing.d.mts +5 -4
  47. package/dist/testing.d.ts +5 -4
  48. package/dist/testing.js +77 -77
  49. package/dist/testing.mjs +3 -3
  50. package/dist/utils.d.mts +4 -3
  51. package/dist/utils.d.ts +4 -3
  52. package/package.json +1 -1
package/dist/mock/msw.mjs CHANGED
@@ -3852,6 +3852,10 @@ function toApiProduct(p, ctx) {
3852
3852
  duration_unit: p.duration_unit,
3853
3853
  duration_minutes: p.duration_minutes,
3854
3854
  billing_plans: p.billing_plans,
3855
+ /** Per-product customer inputs (prescription upload, consent
3856
+ * signature, etc.). The Rust backend emits this on ProductView; the
3857
+ * SDK's React components branch on its presence to render inputs. */
3858
+ input_fields: p.input_fields ?? [],
3855
3859
  created_at: p.created_at,
3856
3860
  updated_at: p.updated_at,
3857
3861
  metadata: {
@@ -5743,8 +5747,8 @@ function createLinkService({ clock, ids }) {
5743
5747
 
5744
5748
  // src/mock/seeds/image.ts
5745
5749
  var CDN_BASE_URL = "https://static-tmp.cimplify.io";
5746
- function seedImage(industry, photoId) {
5747
- return `${CDN_BASE_URL}/seed/${industry}/${photoId}.jpg`;
5750
+ function seedImage(industry, slug) {
5751
+ return `${CDN_BASE_URL}/seed/${industry}/${slug}.jpg`;
5748
5752
  }
5749
5753
 
5750
5754
  // src/mock/seeds/default.ts
@@ -5807,7 +5811,7 @@ function seedDefault(registry) {
5807
5811
  default_address: "12 Independence Ave, Accra",
5808
5812
  default_offers_table_service: true,
5809
5813
  default_accepts_online_orders: true,
5810
- image: img("1568254183919-78a4f43a2877"),
5814
+ image: img("business-hero"),
5811
5815
  status: "active",
5812
5816
  created_at: ISO,
5813
5817
  updated_at: ISO,
@@ -5862,8 +5866,8 @@ function seedDefault(registry) {
5862
5866
  price: "25.00",
5863
5867
  description: "24-hour fermented country loaf with our heritage starter \u2014 open crumb, blistered crust, naturally tangy. Baked fresh every morning.",
5864
5868
  category: "breads",
5865
- imageUrl: img("1509440159596-0249088772ff"),
5866
- images: [img("1509440159596-0249088772ff"), img("1486887396153-fa416526c108")],
5869
+ imageUrl: img("sourdough-loaf"),
5870
+ images: [img("sourdough-loaf"), img("whole-wheat")],
5867
5871
  tags: ["bread", "vegan", "signature"],
5868
5872
  isSignature: true,
5869
5873
  ingredients: ["Wheat flour", "Sourdough starter", "Sea salt", "Filtered water"],
@@ -5878,7 +5882,7 @@ function seedDefault(registry) {
5878
5882
  price: "20.00",
5879
5883
  description: "Hearty 100% whole wheat with sunflower, sesame, and pumpkin seeds. Slow-fermented for a soft crumb and nutty depth.",
5880
5884
  category: "breads",
5881
- imageUrl: img("1486887396153-fa416526c108"),
5885
+ imageUrl: img("whole-wheat"),
5882
5886
  tags: ["bread", "vegan", "high-fibre"],
5883
5887
  ingredients: ["Whole wheat flour", "Sunflower seeds", "Sesame", "Pumpkin seeds"],
5884
5888
  allergies: ["wheat", "gluten", "sesame"],
@@ -5891,7 +5895,7 @@ function seedDefault(registry) {
5891
5895
  price: "15.00",
5892
5896
  description: "Crackling crust, airy crumb. Best eaten warm, within an hour of baking.",
5893
5897
  category: "breads",
5894
- imageUrl: img("1568471173242-461f0a730452"),
5898
+ imageUrl: img("baguette"),
5895
5899
  tags: ["bread", "vegan"],
5896
5900
  ingredients: ["Wheat flour", "Yeast", "Sea salt", "Water"],
5897
5901
  allergies: ["wheat", "gluten"],
@@ -5904,7 +5908,7 @@ function seedDefault(registry) {
5904
5908
  price: "30.00",
5905
5909
  description: "High-hydration focaccia drenched in olive oil, scattered with sea salt and fresh rosemary. Sold whole or by the slab.",
5906
5910
  category: "breads",
5907
- imageUrl: img("1571167530149-c1105da4c2c7"),
5911
+ imageUrl: img("focaccia"),
5908
5912
  tags: ["bread", "vegetarian"],
5909
5913
  ingredients: ["00 flour", "Olive oil", "Rosemary", "Maldon salt"],
5910
5914
  pairings: ["Burrata", "Prosciutto", "Caponata"],
@@ -5918,7 +5922,7 @@ function seedDefault(registry) {
5918
5922
  price: "18.00",
5919
5923
  description: "Caramelised brown butter, three over-ripe bananas, walnuts, finished with a salted maple glaze.",
5920
5924
  category: "breads",
5921
- imageUrl: img("1632931057819-4eefffa8e007"),
5925
+ imageUrl: img("banana-bread"),
5922
5926
  tags: ["sweet", "comfort"],
5923
5927
  ingredients: ["Bananas", "Brown butter", "Walnuts", "Maple syrup"],
5924
5928
  allergies: ["wheat", "gluten", "dairy", "nuts", "eggs"],
@@ -5933,8 +5937,8 @@ function seedDefault(registry) {
5933
5937
  price: "12.00",
5934
5938
  description: "27 layers of laminated dough wrapped around French butter. Crisp, shattering crust and a tender honeycomb interior.",
5935
5939
  category: "pastries",
5936
- imageUrl: img("1555507036-ab1f4038808a"),
5937
- images: [img("1555507036-ab1f4038808a"), img("1530610476181-d83430b64dcd")],
5940
+ imageUrl: img("croissant"),
5941
+ images: [img("croissant"), img("pain-au-chocolat")],
5938
5942
  tags: ["pastry", "vegetarian", "signature"],
5939
5943
  isSignature: true,
5940
5944
  ingredients: ["French butter", "Wheat flour", "Milk", "Eggs"],
@@ -5948,7 +5952,7 @@ function seedDefault(registry) {
5948
5952
  price: "14.00",
5949
5953
  description: "Our croissant dough wrapped around two batons of 70% Valrhona dark chocolate.",
5950
5954
  category: "pastries",
5951
- imageUrl: img("1530610476181-d83430b64dcd"),
5955
+ imageUrl: img("pain-au-chocolat"),
5952
5956
  tags: ["pastry", "chocolate"],
5953
5957
  ingredients: ["Croissant dough", "Valrhona chocolate"],
5954
5958
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -5961,7 +5965,7 @@ function seedDefault(registry) {
5961
5965
  price: "16.00",
5962
5966
  description: "Flaky pastry filled with almond cream, dusted with toasted slivers and powdered sugar.",
5963
5967
  category: "pastries",
5964
- imageUrl: img("1517433367423-c7e5b0f35086"),
5968
+ imageUrl: img("almond-danish"),
5965
5969
  tags: ["pastry", "nuts"],
5966
5970
  ingredients: ["Pastry dough", "Almond cream", "Toasted almonds"],
5967
5971
  allergies: ["wheat", "gluten", "dairy", "eggs", "nuts"],
@@ -5974,7 +5978,7 @@ function seedDefault(registry) {
5974
5978
  price: "13.00",
5975
5979
  description: "Soft enriched dough swirled with butter and Ceylon cinnamon, finished with cream-cheese glaze.",
5976
5980
  category: "pastries",
5977
- imageUrl: img("1607920591413-4ec007e70023"),
5981
+ imageUrl: img("cinnamon-roll"),
5978
5982
  tags: ["pastry", "comfort"],
5979
5983
  ingredients: ["Enriched dough", "Cinnamon", "Brown sugar", "Cream cheese"],
5980
5984
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -5987,7 +5991,7 @@ function seedDefault(registry) {
5987
5991
  price: "12.00",
5988
5992
  description: "Dark, dense, fudgy brownie with a glossy shell. Chocolate four ways. Best slightly warm.",
5989
5993
  category: "pastries",
5990
- imageUrl: img("1606313564200-e75d5e30476c"),
5994
+ imageUrl: img("brownie"),
5991
5995
  tags: ["chocolate", "vegetarian"],
5992
5996
  ingredients: ["Dark chocolate", "Cocoa", "Brown butter", "Eggs"],
5993
5997
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6000,7 +6004,7 @@ function seedDefault(registry) {
6000
6004
  price: "60.00",
6001
6005
  description: "Six French macarons \u2014 pistachio, raspberry, salted caramel, espresso, vanilla bean, and dark chocolate ganache.",
6002
6006
  category: "pastries",
6003
- imageUrl: img("1558326567-98ae2405596b"),
6007
+ imageUrl: img("macaron-box"),
6004
6008
  tags: ["pastry", "gift", "premium"],
6005
6009
  ingredients: ["Almond flour", "Egg whites", "Sugar", "Various fillings"],
6006
6010
  allergies: ["nuts", "eggs", "dairy"],
@@ -6014,7 +6018,7 @@ function seedDefault(registry) {
6014
6018
  price: "22.00",
6015
6019
  description: "Three layers of dark chocolate sponge with chocolate ganache and cr\xE8me p\xE2tissi\xE8re, finished with a mirror glaze. (Slice)",
6016
6020
  category: "cakes",
6017
- imageUrl: img("1565958011703-44f9829ba187"),
6021
+ imageUrl: img("chocolate-cake"),
6018
6022
  tags: ["cake", "chocolate", "signature"],
6019
6023
  isSignature: true,
6020
6024
  ingredients: ["Dark chocolate", "Cr\xE8me p\xE2tissi\xE8re", "Cocoa", "Eggs"],
@@ -6029,7 +6033,7 @@ function seedDefault(registry) {
6029
6033
  price: "22.00",
6030
6034
  description: "Classic red velvet with cream cheese frosting and white chocolate shavings.",
6031
6035
  category: "cakes",
6032
- imageUrl: img("1586788680434-30d324b2d46f"),
6036
+ imageUrl: img("red-velvet"),
6033
6037
  tags: ["cake"],
6034
6038
  ingredients: ["Buttermilk", "Cocoa", "Cream cheese", "Beetroot"],
6035
6039
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6042,7 +6046,7 @@ function seedDefault(registry) {
6042
6046
  price: "20.00",
6043
6047
  description: "Spiced carrot cake with toasted walnuts, golden raisins, and cream-cheese frosting.",
6044
6048
  category: "cakes",
6045
- imageUrl: img("1568827999250-3f6afff96e66"),
6049
+ imageUrl: img("carrot-cake"),
6046
6050
  tags: ["cake", "spiced"],
6047
6051
  ingredients: ["Carrot", "Walnuts", "Cinnamon", "Cream cheese"],
6048
6052
  allergies: ["wheat", "gluten", "dairy", "eggs", "nuts"],
@@ -6055,7 +6059,7 @@ function seedDefault(registry) {
6055
6059
  price: "24.00",
6056
6060
  description: "Dense, creamy New York cheesecake on a butter graham crust. Topped with seasonal berry compote.",
6057
6061
  category: "cakes",
6058
- imageUrl: img("1567306226416-28f0efdc88ce"),
6062
+ imageUrl: img("cheesecake"),
6059
6063
  tags: ["cake", "premium"],
6060
6064
  ingredients: ["Cream cheese", "Sour cream", "Graham crust", "Vanilla"],
6061
6065
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6068,8 +6072,8 @@ function seedDefault(registry) {
6068
6072
  price: "250.00",
6069
6073
  description: "Made-to-order three-tier cake. Choose size, flavour, and frosting. 48-hour notice required for personalisation.",
6070
6074
  category: "cakes",
6071
- imageUrl: img("1535254973040-607b474cb50d"),
6072
- images: [img("1535254973040-607b474cb50d"), img("1565958011703-44f9829ba187")],
6075
+ imageUrl: img("birthday-cake"),
6076
+ images: [img("birthday-cake"), img("chocolate-cake")],
6073
6077
  tags: ["cake", "made-to-order", "premium"],
6074
6078
  ingredients: ["Sponge cake", "Buttercream", "Custom decoration"],
6075
6079
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6083,7 +6087,7 @@ function seedDefault(registry) {
6083
6087
  price: "10.00",
6084
6088
  description: "Locally roasted Arabica from Volta Region. Notes of cocoa, dark fruit, and brown sugar.",
6085
6089
  category: "drinks",
6086
- imageUrl: img("1495474472287-4d71bcdd2085"),
6090
+ imageUrl: img("coffee"),
6087
6091
  tags: ["drink", "coffee", "vegan"],
6088
6092
  ingredients: ["Single-origin Arabica beans"],
6089
6093
  pairings: ["Croissant", "Brownie"],
@@ -6096,7 +6100,7 @@ function seedDefault(registry) {
6096
6100
  price: "8.00",
6097
6101
  description: "Choice of English breakfast, Earl Grey, green sencha, or chamomile.",
6098
6102
  category: "drinks",
6099
- imageUrl: img("1576092768241-dec231879fc3"),
6103
+ imageUrl: img("tea"),
6100
6104
  tags: ["drink", "tea", "vegan"],
6101
6105
  calories: 0
6102
6106
  },
@@ -6107,7 +6111,7 @@ function seedDefault(registry) {
6107
6111
  price: "12.00",
6108
6112
  description: "Iced hibiscus tea with ginger, pineapple peel, and a hint of clove. Tart, refreshing, lightly sweet.",
6109
6113
  category: "drinks",
6110
- imageUrl: img("1556679343-c7306c1976bc"),
6114
+ imageUrl: img("sobolo"),
6111
6115
  tags: ["drink", "vegan", "ghana"],
6112
6116
  isSignature: true,
6113
6117
  ingredients: ["Hibiscus", "Ginger", "Pineapple", "Clove"],
@@ -6120,7 +6124,7 @@ function seedDefault(registry) {
6120
6124
  price: "15.00",
6121
6125
  description: "Hand-pressed at sunrise from Ghanaian Valencia oranges. No sugar, no concentrate.",
6122
6126
  category: "drinks",
6123
- imageUrl: img("1622597467836-f3285f2131b8"),
6127
+ imageUrl: img("orange-juice"),
6124
6128
  tags: ["drink", "vegan"],
6125
6129
  calories: 110
6126
6130
  },
@@ -6132,8 +6136,8 @@ function seedDefault(registry) {
6132
6136
  price: "30.00",
6133
6137
  description: "A buttery croissant, a single-origin coffee, and a fresh-pressed orange juice. Everything you need to start the day. Save GH\u20B57 vs buying separately.",
6134
6138
  category: "boxes",
6135
- imageUrl: img("1533089860892-a7c6f0a88666"),
6136
- images: [img("1533089860892-a7c6f0a88666"), img("1495474472287-4d71bcdd2085")],
6139
+ imageUrl: img("breakfast-box"),
6140
+ images: [img("breakfast-box"), img("coffee")],
6137
6141
  tags: ["bundle", "breakfast"],
6138
6142
  productType: "bundle"
6139
6143
  },
@@ -6144,7 +6148,7 @@ function seedDefault(registry) {
6144
6148
  price: "60.00",
6145
6149
  description: "Pick 6 to 12 of our pastries \u2014 mix and match. Freshly boxed for sharing.",
6146
6150
  category: "boxes",
6147
- imageUrl: img("1486427944299-d1955d23e34d"),
6151
+ imageUrl: img("pastry-box"),
6148
6152
  tags: ["composite", "build-your-own", "gift"],
6149
6153
  productType: "composite"
6150
6154
  },
@@ -6156,7 +6160,7 @@ function seedDefault(registry) {
6156
6160
  price: "85.00",
6157
6161
  description: "Heavy-weight cotton-canvas apron with leather neck strap, embroidered logo, and two front pockets. Made in Accra.",
6158
6162
  category: "merch",
6159
- imageUrl: img("1556905055-8f358a7a47b2"),
6163
+ imageUrl: img("apron"),
6160
6164
  tags: ["merch", "physical"],
6161
6165
  renderHint: "physical"
6162
6166
  },
@@ -6167,7 +6171,7 @@ function seedDefault(registry) {
6167
6171
  price: "35.00",
6168
6172
  description: "12oz natural canvas tote, screen-printed with our wheat-stalk crest. Roomy enough for two loaves.",
6169
6173
  category: "merch",
6170
- imageUrl: img("1591561954557-26941169b49e"),
6174
+ imageUrl: img("tote-bag"),
6171
6175
  tags: ["merch", "physical", "gift"],
6172
6176
  renderHint: "physical",
6173
6177
  isNew: true
@@ -6180,7 +6184,7 @@ function seedDefault(registry) {
6180
6184
  price: "320.00",
6181
6185
  description: "Stone-milled heritage wheat flour, the same we use in our country sourdough. Tiered pricing for caf\xE9s, restaurants, and home-baking co-ops.",
6182
6186
  category: "merch",
6183
- imageUrl: img("1568254183919-78a4f43a2877"),
6187
+ imageUrl: img("flour-25kg"),
6184
6188
  tags: ["wholesale", "physical", "trade"],
6185
6189
  renderHint: "physical",
6186
6190
  quantityPricing: [
@@ -6198,7 +6202,7 @@ function seedDefault(registry) {
6198
6202
  price: "45.00",
6199
6203
  description: "PDF + EPUB walkthrough of our sourdough programme \u2014 starter, levain, autolyse, bulk fermentation, shaping, scoring. Lifetime updates.",
6200
6204
  category: "merch",
6201
- imageUrl: img("1543002588-bfa74002ed7e"),
6205
+ imageUrl: img("sourdough-ebook"),
6202
6206
  tags: ["digital", "download"],
6203
6207
  productType: "digital",
6204
6208
  digitalProductType: "download"
@@ -6210,7 +6214,7 @@ function seedDefault(registry) {
6210
6214
  price: "100.00",
6211
6215
  description: "Send instantly. Redeemable in-store and online toward any product. Choose any amount from GH\u20B550 upward.",
6212
6216
  category: "merch",
6213
- imageUrl: img("1556905055-8f358a7a47b2"),
6217
+ imageUrl: img("gift-card"),
6214
6218
  tags: ["digital", "gift"],
6215
6219
  productType: "digital",
6216
6220
  digitalProductType: "gift_code",
@@ -6224,7 +6228,7 @@ function seedDefault(registry) {
6224
6228
  price: "320.00",
6225
6229
  description: "Two-hour hands-on class: shape your own boule, score it, and take home a baked loaf and a starter jar. Held Saturdays, 10am\u201312pm.",
6226
6230
  category: "classes",
6227
- imageUrl: img("1517686469429-8bdb88b9f907"),
6231
+ imageUrl: img("baking-class"),
6228
6232
  tags: ["class", "service", "hands-on"],
6229
6233
  productType: "service",
6230
6234
  durationMinutes: 120
@@ -6236,7 +6240,7 @@ function seedDefault(registry) {
6236
6240
  price: "480.00",
6237
6241
  description: "Three-hour deep-dive on laminated dough. We cover croissants, danishes, kouign-amann. Aprons supplied; pastries to take home.",
6238
6242
  category: "classes",
6239
- imageUrl: img("1517433367423-c7e5b0f35086"),
6243
+ imageUrl: img("pastry-workshop"),
6240
6244
  tags: ["class", "service", "advanced"],
6241
6245
  productType: "service",
6242
6246
  durationMinutes: 180,
@@ -6250,7 +6254,7 @@ function seedDefault(registry) {
6250
6254
  price: "180.00",
6251
6255
  description: "Rent our commercial bakery after hours. Deck oven, retarder-proofer, mixers, scales \u2014 bring your team or shoot your content. Hourly.",
6252
6256
  category: "classes",
6253
- imageUrl: img("1606755962773-d324e0a13086"),
6257
+ imageUrl: img("kitchen-rental"),
6254
6258
  tags: ["rental", "service", "commercial"],
6255
6259
  productType: "service",
6256
6260
  durationUnit: "hours"
@@ -6263,7 +6267,7 @@ function seedDefault(registry) {
6263
6267
  price: "650.00",
6264
6268
  description: "One-bedroom loft above the bakery. Wakes up to fresh croissants, ends with a private dinner. Ghana Tourism-licensed. Per night.",
6265
6269
  category: "classes",
6266
- imageUrl: img("1564013799919-ab600027ffc6"),
6270
+ imageUrl: img("loft-stay"),
6267
6271
  tags: ["stay", "service", "premium"],
6268
6272
  productType: "service",
6269
6273
  durationUnit: "nights"
@@ -6276,7 +6280,7 @@ function seedDefault(registry) {
6276
6280
  price: "0.00",
6277
6281
  description: "A fresh loaf delivered to your door every week. Pause or skip any time. Choose monthly or quarterly billing for a discount.",
6278
6282
  category: "classes",
6279
- imageUrl: img("1509440159596-0249088772ff"),
6283
+ imageUrl: img("loaf-subscription"),
6280
6284
  tags: ["subscription", "service", "delivery"],
6281
6285
  productType: "service",
6282
6286
  billingPlans: [
@@ -7104,31 +7108,7 @@ function seedReesa(registry) {
7104
7108
 
7105
7109
  // src/mock/seeds/restaurant.ts
7106
7110
  var ISO4 = "2026-01-01T00:00:00.000Z";
7107
- var PHOTO = {
7108
- "business-hero": "1414235077428-338989a2e8c0",
7109
- kelewele: "1599487488170-d11ec9c172f0",
7110
- "spring-rolls": "1559339352-11d035aa65de",
7111
- "soup-of-the-day": "1547592180-85f173990554",
7112
- "jollof-rice": "1546069901-d5bfd2cbfb1f",
7113
- "banku-tilapia": "1485921325833-c519f76c4927",
7114
- "fufu-light-soup": "1602253057119-44d745d9b860",
7115
- waakye: "1565299624946-b28f40a0ae38",
7116
- "grilled-chicken": "1598103442097-8b74394b95c6",
7117
- burger: "1568901346375-23c9450c58cd",
7118
- "yam-fries": "1576107232684-1279f390859f",
7119
- "fried-plantain": "1493770348161-369560ae357d",
7120
- salad: "1512621776951-a57141f2eefd",
7121
- "ice-cream": "1488900128323-21503983a07e",
7122
- "cake-slice": "1565958011703-44f9829ba187",
7123
- "fruit-bowl": "1490474418585-ba9bad8fd0ea",
7124
- "soft-drink": "1581636625402-29b2a704ef13",
7125
- sobolo: "1556679343-c7306c1976bc",
7126
- "fresh-juice": "1610970881699-44a5587cabec",
7127
- water: "1564325724739-bae0bd08762c",
7128
- feast: "1559847844-5315695dadae",
7129
- byo: "1551782450-a2132b4ba21d"
7130
- };
7131
- var photoFor = (slug) => seedImage("restaurant", PHOTO[slug] ?? "1414235077428-338989a2e8c0");
7111
+ var photoFor = (slug) => seedImage("restaurant", slug);
7132
7112
  function seedRestaurant(registry) {
7133
7113
  const businessId = "bus_mamas_kitchen";
7134
7114
  const business = {
@@ -7588,29 +7568,7 @@ function seedRestaurant(registry) {
7588
7568
 
7589
7569
  // src/mock/seeds/retail.ts
7590
7570
  var ISO5 = "2026-01-01T00:00:00.000Z";
7591
- var PHOTO2 = {
7592
- "android-flagship": "1592750475338-74b7b21085ab",
7593
- "android-mid": "1511707171634-5f897ff02aa9",
7594
- "phone-budget": "1574944985070-8f3ebc6b79d2",
7595
- "laptop-pro": "1517336714731-489689fd1ca8",
7596
- "laptop-air": "1496181133206-80ce9b88a853",
7597
- "laptop-budget": "1601784551446-20c9e07cdbdb",
7598
- "headphones-anc": "1505740420928-5e560c06d30e",
7599
- "earbuds-pro": "1572569511254-d8f925fe2cbb",
7600
- "speaker-bt": "1612287230202-1ff1d85d1bdf",
7601
- "phone-case": "1611532736597-de2d4265fba3",
7602
- "screen-protector": "1568952433726-3896e3881c65",
7603
- "fast-charger": "1620794108219-aedbaded4eea",
7604
- "laptop-sleeve": "1604671801908-6f0c6a092c05",
7605
- "wireless-mouse": "1594732832278-abd644401426",
7606
- "mech-keyboard": "1583394838336-acd977736f90",
7607
- "gaming-controller": "1542751371-adc38448a05e",
7608
- "gaming-headset": "1606220945770-b5b6c2c55bf1",
7609
- "console-handheld": "1593642634524-b40b5baae6bb",
7610
- wfh: "1605236453806-6ff36851218e",
7611
- "game-pack": "1606144042614-b2417e99c4e3"
7612
- };
7613
- var photoFor2 = (slug) => seedImage("retail", PHOTO2[slug] ?? "1517336714731-489689fd1ca8");
7571
+ var photoFor2 = (slug) => seedImage("retail", slug);
7614
7572
  function seedRetail(registry) {
7615
7573
  const businessId = "bus_currents_electronics";
7616
7574
  const business = {
@@ -8083,29 +8041,7 @@ function seedRetail(registry) {
8083
8041
 
8084
8042
  // src/mock/seeds/services.ts
8085
8043
  var ISO6 = "2026-01-01T00:00:00.000Z";
8086
- var PHOTO3 = {
8087
- "business-hero": "1540555700478-4be289fbecef",
8088
- "swedish-massage-60": "1544161515-4ab6ce6db874",
8089
- "swedish-massage-90": "1519823551278-64ac92734fb1",
8090
- "deep-tissue-60": "1571019613454-1cb2f99b2d8b",
8091
- "couples-massage": "1591343395082-e120087004b4",
8092
- "hot-stone-90": "1620733723572-11c53f73a416",
8093
- "facial-classic": "1487412947147-5cebf100ffc2",
8094
- "facial-anti-aging": "1487412947147-5cebf100ffc2",
8095
- "facial-acne": "1556228720-195a672e8a03",
8096
- manicure: "1604654894610-df63bc536371",
8097
- pedicure: "1519415943484-9fa1873496d4",
8098
- "gel-manicure": "1607779097040-26e80aa78e66",
8099
- haircut: "1622286342621-4bd786c2447c",
8100
- "hair-treatment": "1633681926022-84c23e8cb2d6",
8101
- color: "1560066984-138dadb4c035",
8102
- "yoga-session": "1545205597-3d9d02c29597",
8103
- meditation: "1506126613408-eca07ce68773",
8104
- "spa-day": "1571019613454-1cb2f99b2d8b",
8105
- couples: "1591343395082-e120087004b4",
8106
- custom: "1540555700478-4be289fbecef"
8107
- };
8108
- var photoFor3 = (slug) => seedImage("services", PHOTO3[slug] ?? "1540555700478-4be289fbecef");
8044
+ var photoFor3 = (slug) => seedImage("services", slug);
8109
8045
  function seedServices(registry) {
8110
8046
  const businessId = "bus_serene_spa";
8111
8047
  const business = {
@@ -8485,35 +8421,7 @@ function seedServices(registry) {
8485
8421
 
8486
8422
  // src/mock/seeds/grocery.ts
8487
8423
  var ISO7 = "2026-01-01T00:00:00.000Z";
8488
- var PHOTO4 = {
8489
- "business-hero": "1542838132-92c53300491e",
8490
- "tomatoes-1kg": "1592924357228-91a4daadcfea",
8491
- "onions-1kg": "1620574387735-3624d75b2dbc",
8492
- "ginger-200g": "1594631252845-29fc4cc8cde9",
8493
- "bananas-bunch": "1571771019784-3ff35f4f4277",
8494
- pineapple: "1550258987-190a2d41a8ba",
8495
- "spinach-bunch": "1576045057995-568f588f82fb",
8496
- "milk-1l": "1563636619-e9143da7973b",
8497
- "yogurt-500g": "1488477181946-6428a0291777",
8498
- "eggs-12": "1582722872445-44dc5f7e3c8f",
8499
- "cheese-200g": "1486297678162-eb2a19b0a32d",
8500
- "chicken-1kg": "1604503468506-a8da13d82791",
8501
- "beef-mince-500g": "1607623814075-e51df1bdc82f",
8502
- "tilapia-each": "1535473895227-bdecb20fb157",
8503
- "rice-5kg": "1586201375761-83865001e31c",
8504
- "garri-2kg": "1582284540020-8acbe03f4924",
8505
- "palm-oil-1l": "1611078489935-0cb964de46d6",
8506
- "vegetable-oil-1l": "1474979266404-7eaacbcd87c5",
8507
- "salt-1kg": "1607301406259-dfb186e15de8",
8508
- "sugar-1kg": "1610725664285-7c57e6eeac3f",
8509
- "tomato-paste": "1561136594-7f68413baa99",
8510
- "soap-bar": "1600857062241-98e5dba7f214",
8511
- "detergent-1kg": "1582735689369-4fe89db7114c",
8512
- "tissue-pack": "1583947215259-38e31be8751f",
8513
- "trash-bags": "1605600659908-0ef719419d41",
8514
- essentials: "1542838132-92c53300491e"
8515
- };
8516
- var photoFor4 = (slug) => seedImage("grocery", PHOTO4[slug] ?? "1542838132-92c53300491e");
8424
+ var photoFor4 = (slug) => seedImage("grocery", slug);
8517
8425
  function seedGrocery(registry) {
8518
8426
  const businessId = "bus_freshmart";
8519
8427
  const business = {
@@ -8776,23 +8684,7 @@ function seedGrocery(registry) {
8776
8684
 
8777
8685
  // src/mock/seeds/fashion.ts
8778
8686
  var ISO8 = "2026-01-01T00:00:00.000Z";
8779
- var PHOTO5 = {
8780
- "heavyweight-hoodie-charcoal": "1556905055-8f358a7a47b2",
8781
- "heavyweight-hoodie-cream": "1576566588028-4147f3842f27",
8782
- "heavyweight-hoodie-cobalt": "1542838686-37da4a9fd1b3",
8783
- "studio-tee-black": "1521572163474-6864f9cf17ab",
8784
- "studio-tee-natural": "1485518882345-15568b007407",
8785
- "graphic-tee-frx-mark": "1521223890158-f9f7c3d5d504",
8786
- "carbon-bomber": "1591047139829-d91aecb6caea",
8787
- "field-jacket-olive": "1564859228273-274232fdb516",
8788
- "wide-leg-trouser": "1542272604-787c3835535d",
8789
- "track-pant-charcoal": "1604176354204-9268737828e4",
8790
- "studio-cap": "1620799140408-edc6dcb6d633",
8791
- "tote-natural": "1591195853828-11db59a44f6b",
8792
- "knit-beanie": "1542838132-92c53300491e",
8793
- "studio-sock-3pack": "1602810318383-e386cc2a3ccf"
8794
- };
8795
- var photoFor5 = (slug) => seedImage("fashion", PHOTO5[slug] ?? "1556905055-8f358a7a47b2");
8687
+ var photoFor5 = (slug) => seedImage("fashion", slug);
8796
8688
  var SIZES = ["XS", "S", "M", "L", "XL", "2XL"];
8797
8689
  function seedFashion(registry) {
8798
8690
  const businessId = "bus_studio_frx";
@@ -8807,7 +8699,7 @@ function seedFashion(registry) {
8807
8699
  default_address: "Osu Oxford Street, Accra",
8808
8700
  default_offers_table_service: false,
8809
8701
  default_accepts_online_orders: true,
8810
- image: seedImage("fashion", "1490481651871-ab68de25d43d"),
8702
+ image: seedImage("fashion", "business-hero"),
8811
8703
  status: "active",
8812
8704
  created_at: ISO8,
8813
8705
  updated_at: ISO8,
@@ -9209,6 +9101,553 @@ function seedFashion(registry) {
9209
9101
  return { businessId };
9210
9102
  }
9211
9103
 
9104
+ // src/mock/seeds/pharmacy.ts
9105
+ var ISO9 = "2026-01-01T00:00:00.000Z";
9106
+ var photoFor6 = (slug) => seedImage("pharmacy", slug);
9107
+ function seedPharmacy(registry) {
9108
+ const businessId = "bus_wellspring_pharmacy";
9109
+ const business = {
9110
+ id: businessId,
9111
+ name: "Wellspring Pharmacy",
9112
+ handle: "wellspring",
9113
+ business_type: "retail",
9114
+ email: "care@wellspringpharmacy.test",
9115
+ default_currency: "GHS",
9116
+ default_phone: "+233244778899",
9117
+ default_address: "5 Liberation Road, Ridge, Accra",
9118
+ default_offers_table_service: false,
9119
+ default_accepts_online_orders: true,
9120
+ image: photoFor6("business-hero"),
9121
+ status: "active",
9122
+ created_at: ISO9,
9123
+ updated_at: ISO9,
9124
+ created_by: "seed",
9125
+ preferences: {
9126
+ theme: "clinical",
9127
+ tagline: "Trusted care, delivered same-day",
9128
+ checkout: { allow_guest: true }
9129
+ },
9130
+ is_online_only: false,
9131
+ enabled_payment_types: ["card", "mobile_money", "cash"],
9132
+ default_location_settings: {},
9133
+ country_code: "GH",
9134
+ timezone: "Africa/Accra"
9135
+ };
9136
+ registry.businesses.put(businessId, business);
9137
+ const categories = [
9138
+ { slug: "pain-relief", name: "Pain Relief" },
9139
+ { slug: "cold-flu", name: "Cold & Flu" },
9140
+ { slug: "vitamins", name: "Vitamins & Supplements" },
9141
+ { slug: "first-aid", name: "First Aid" },
9142
+ { slug: "personal-care", name: "Personal Care" },
9143
+ { slug: "devices", name: "Medical Devices" },
9144
+ { slug: "baby", name: "Baby & Mother" }
9145
+ ];
9146
+ const catIds = /* @__PURE__ */ new Map();
9147
+ for (const c of categories) {
9148
+ const id = `cat_${c.slug}`;
9149
+ catIds.set(c.slug, id);
9150
+ const cat = {
9151
+ id,
9152
+ business_id: businessId,
9153
+ name: c.name,
9154
+ slug: c.slug,
9155
+ description: `Wellspring \u2014 ${c.name}`,
9156
+ product_ids: [],
9157
+ display_order: 0,
9158
+ is_active: true,
9159
+ created_at: ISO9,
9160
+ updated_at: ISO9
9161
+ };
9162
+ registry.categories.put(id, cat);
9163
+ }
9164
+ function field(productSlug, f) {
9165
+ return {
9166
+ id: f.id ?? `fld_${productSlug}_${f.slug}`,
9167
+ product_id: `prod_${productSlug}`,
9168
+ ...f
9169
+ };
9170
+ }
9171
+ const products = [
9172
+ // Pain Relief
9173
+ {
9174
+ slug: "paracetamol",
9175
+ name: "Paracetamol 500mg (24 tablets)",
9176
+ price: "12.00",
9177
+ category: "pain-relief",
9178
+ description: "Fever and mild-to-moderate pain. Adults and children over 12.",
9179
+ tags: ["otc", "analgesic"],
9180
+ inputs: [
9181
+ field("paracetamol", {
9182
+ slug: "age_confirmation",
9183
+ name: "Age confirmation",
9184
+ field_type: "checkbox",
9185
+ is_required: true,
9186
+ display_order: 0,
9187
+ help_text: "I confirm this product is for someone aged 12 or over."
9188
+ })
9189
+ ]
9190
+ },
9191
+ { 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"] },
9192
+ { 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"] },
9193
+ { slug: "allergy-relief", name: "Cetirizine 10mg (10 tablets)", price: "22.00", category: "pain-relief", description: "Non-drowsy antihistamine for seasonal allergies.", tags: ["otc", "antihistamine"] },
9194
+ // Cold & Flu
9195
+ { 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"] },
9196
+ { slug: "throat-lozenges", name: "Honey-Lemon Throat Lozenges (24)", price: "18.00", category: "cold-flu", description: "Soothes sore throat and irritation.", tags: ["otc", "lozenge"] },
9197
+ { slug: "decongestant", name: "Nasal Decongestant Spray (10ml)", price: "28.00", category: "cold-flu", description: "Fast-acting relief for blocked nasal passages.", tags: ["otc", "spray"] },
9198
+ // Vitamins & Supplements
9199
+ { 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"] },
9200
+ { slug: "vitamin-c", name: "Vitamin C 1000mg (90 tablets)", price: "65.00", category: "vitamins", description: "Immune-support antioxidant. Time-released.", tags: ["supplement", "immune"] },
9201
+ { 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"] },
9202
+ { 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"] },
9203
+ { slug: "probiotics", name: "Probiotic 10-Strain (30 capsules)", price: "95.00", category: "vitamins", description: "Digestive and immune support.", tags: ["supplement", "digestive"] },
9204
+ // First Aid
9205
+ { 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"] },
9206
+ { slug: "plasters", name: "Assorted Plasters (40 pack)", price: "22.00", category: "first-aid", description: "Waterproof adhesive bandages in five sizes.", tags: ["first-aid"] },
9207
+ { slug: "antiseptic", name: "Antiseptic Cream (30g)", price: "18.00", category: "first-aid", description: "For cuts, grazes, and minor skin infections.", tags: ["first-aid", "cream"] },
9208
+ { 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"] },
9209
+ // Personal Care
9210
+ { 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"] },
9211
+ { slug: "face-mask", name: "Surgical Face Masks (50 pack)", price: "45.00", category: "personal-care", description: "3-ply earloop masks. Disposable.", tags: ["hygiene", "ppe"] },
9212
+ { 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"] },
9213
+ // Medical Devices
9214
+ { slug: "thermometer", name: "Digital Thermometer", price: "65.00", category: "devices", description: "Fast oral / underarm reading in 10 seconds. Auto-shutoff.", tags: ["device", "essential"] },
9215
+ {
9216
+ slug: "blood-pressure-monitor",
9217
+ name: "Automatic BP Monitor",
9218
+ price: "320.00",
9219
+ category: "devices",
9220
+ description: "Upper-arm cuff with memory for two users. Irregular heartbeat detection.",
9221
+ tags: ["device", "premium"],
9222
+ inputs: [
9223
+ field("blood-pressure-monitor", {
9224
+ slug: "arm_size",
9225
+ name: "Arm circumference",
9226
+ field_type: "select",
9227
+ options: ["Standard (22\u201332 cm)", "Large (32\u201342 cm)"],
9228
+ is_required: true,
9229
+ display_order: 0,
9230
+ help_text: "Pick the cuff that fits \u2014 wrong size gives inaccurate readings."
9231
+ })
9232
+ ]
9233
+ },
9234
+ { 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"] },
9235
+ { slug: "pulse-oximeter", name: "Fingertip Pulse Oximeter", price: "145.00", category: "devices", description: "SpO2 + heart-rate reading in under 10 seconds.", tags: ["device"] },
9236
+ // Baby & Mother
9237
+ {
9238
+ slug: "baby-formula",
9239
+ name: "Infant Formula Stage 1 (400g)",
9240
+ price: "150.00",
9241
+ category: "baby",
9242
+ description: "0\u20136 months. Iron-fortified, with prebiotics.",
9243
+ tags: ["baby", "nutrition"],
9244
+ inputs: [
9245
+ field("baby-formula", {
9246
+ slug: "baby_dob",
9247
+ name: "Baby's date of birth",
9248
+ field_type: "date",
9249
+ is_required: true,
9250
+ display_order: 0,
9251
+ help_text: "Confirms stage 1 is the right formula for your baby's age."
9252
+ }),
9253
+ field("baby-formula", {
9254
+ slug: "allergies",
9255
+ name: "Known allergies or intolerances",
9256
+ field_type: "textarea",
9257
+ is_required: false,
9258
+ display_order: 1,
9259
+ placeholder: "e.g. lactose, soy. Leave blank if none.",
9260
+ semantic_kind: "allergen"
9261
+ })
9262
+ ]
9263
+ },
9264
+ { slug: "baby-wipes", name: "Sensitive Baby Wipes (72 pack)", price: "28.00", category: "baby", description: "Alcohol-free, fragrance-free. Dermatologist-tested.", tags: ["baby", "hygiene"] },
9265
+ // ── Prescription medications (Rx; require a verified prescription) ─
9266
+ {
9267
+ slug: "amoxicillin-rx",
9268
+ name: "Amoxicillin 500mg (Rx)",
9269
+ price: "65.00",
9270
+ category: "pain-relief",
9271
+ description: "Broad-spectrum antibiotic. Prescription required \u2014 our pharmacist will verify before dispensing.",
9272
+ tags: ["prescription", "antibiotic"],
9273
+ requiresPrescription: true,
9274
+ inputs: [
9275
+ field("amoxicillin-rx", {
9276
+ slug: "prescription_upload",
9277
+ name: "Upload prescription",
9278
+ field_type: "file",
9279
+ is_required: true,
9280
+ display_order: 0,
9281
+ help_text: "PDF or photo of your doctor's prescription (max 10 MB).",
9282
+ validation: { accepted_formats: ["pdf", "jpg", "jpeg", "png", "heic"], max_size_mb: 10 }
9283
+ }),
9284
+ field("amoxicillin-rx", {
9285
+ slug: "patient_dob",
9286
+ name: "Patient date of birth",
9287
+ field_type: "date",
9288
+ is_required: true,
9289
+ display_order: 1
9290
+ }),
9291
+ field("amoxicillin-rx", {
9292
+ slug: "consent",
9293
+ name: "I confirm this prescription is genuine and issued for the named patient",
9294
+ field_type: "checkbox",
9295
+ is_required: true,
9296
+ display_order: 2,
9297
+ semantic_kind: "consent"
9298
+ })
9299
+ ]
9300
+ },
9301
+ {
9302
+ slug: "insulin-rx",
9303
+ name: "Insulin Glargine 100u/ml (Rx)",
9304
+ price: "240.00",
9305
+ category: "devices",
9306
+ description: "Long-acting basal insulin. Cold-chain delivery; prescription required.",
9307
+ tags: ["prescription", "diabetes", "cold-chain"],
9308
+ requiresPrescription: true,
9309
+ inputs: [
9310
+ field("insulin-rx", {
9311
+ slug: "prescription_upload",
9312
+ name: "Upload prescription",
9313
+ field_type: "file",
9314
+ is_required: true,
9315
+ display_order: 0,
9316
+ help_text: "PDF or photo of your doctor's prescription (max 10 MB).",
9317
+ validation: { accepted_formats: ["pdf", "jpg", "jpeg", "png", "heic"], max_size_mb: 10 }
9318
+ }),
9319
+ field("insulin-rx", {
9320
+ slug: "delivery_temp_acknowledgement",
9321
+ name: "I'll be available to receive a cold-chain delivery",
9322
+ field_type: "checkbox",
9323
+ is_required: true,
9324
+ display_order: 1,
9325
+ help_text: "Insulin must be refrigerated. Delivery driver will hand over directly \u2014 not leave at door.",
9326
+ semantic_kind: "consent"
9327
+ })
9328
+ ]
9329
+ },
9330
+ {
9331
+ slug: "vaccination-consent",
9332
+ name: "Flu Shot \u2014 At-Pharmacy",
9333
+ price: "80.00",
9334
+ category: "personal-care",
9335
+ description: "Pharmacist-administered seasonal influenza vaccine. Walk-in or book a slot.",
9336
+ tags: ["service", "vaccination"],
9337
+ inputs: [
9338
+ field("vaccination-consent", {
9339
+ slug: "patient_name",
9340
+ name: "Patient name",
9341
+ field_type: "text",
9342
+ is_required: true,
9343
+ display_order: 0
9344
+ }),
9345
+ field("vaccination-consent", {
9346
+ slug: "patient_dob",
9347
+ name: "Date of birth",
9348
+ field_type: "date",
9349
+ is_required: true,
9350
+ display_order: 1
9351
+ }),
9352
+ field("vaccination-consent", {
9353
+ slug: "allergies",
9354
+ name: "Known allergies or reactions to past vaccines",
9355
+ field_type: "textarea",
9356
+ is_required: false,
9357
+ display_order: 2,
9358
+ placeholder: "Egg, latex, prior vaccine reactions, etc. Leave blank if none.",
9359
+ semantic_kind: "allergen"
9360
+ }),
9361
+ field("vaccination-consent", {
9362
+ slug: "consent_signature",
9363
+ name: "Signed consent",
9364
+ field_type: "signature",
9365
+ is_required: true,
9366
+ display_order: 3,
9367
+ help_text: "Required by our administering pharmacist before vaccination.",
9368
+ semantic_kind: "consent"
9369
+ })
9370
+ ]
9371
+ }
9372
+ ];
9373
+ for (const p of products) {
9374
+ const id = `prod_${p.slug}`;
9375
+ const catId = catIds.get(p.category);
9376
+ const product = {
9377
+ id,
9378
+ business_id: businessId,
9379
+ name: p.name,
9380
+ slug: p.slug,
9381
+ description: p.description,
9382
+ product_type: "product",
9383
+ base_price: p.price,
9384
+ currency: "GHS",
9385
+ image: photoFor6(p.slug),
9386
+ images: [photoFor6(p.slug)],
9387
+ is_available: true,
9388
+ category_ids: [catId],
9389
+ collection_ids: [],
9390
+ add_on_ids: [],
9391
+ variant_ids: [],
9392
+ tags: p.tags ?? [],
9393
+ input_fields: p.inputs,
9394
+ metadata: p.requiresPrescription ? { requires_prescription: true } : void 0,
9395
+ created_at: ISO9,
9396
+ updated_at: ISO9
9397
+ };
9398
+ registry.products.put(id, product);
9399
+ const cat = registry.categories.get(catId);
9400
+ cat.product_ids.push(id);
9401
+ registry.categories.put(catId, cat);
9402
+ }
9403
+ const essentials = {
9404
+ id: "col_essentials",
9405
+ business_id: businessId,
9406
+ name: "Home Essentials",
9407
+ slug: "essentials",
9408
+ description: "Stock up your medicine cabinet.",
9409
+ product_ids: [
9410
+ "prod_paracetamol",
9411
+ "prod_first-aid-kit",
9412
+ "prod_thermometer",
9413
+ "prod_hand-sanitizer",
9414
+ "prod_multivitamin"
9415
+ ],
9416
+ is_active: true,
9417
+ created_at: ISO9,
9418
+ updated_at: ISO9
9419
+ };
9420
+ registry.collections.put(essentials.id, essentials);
9421
+ for (const pid of essentials.product_ids) {
9422
+ const p = registry.products.get(pid);
9423
+ if (p) {
9424
+ p.collection_ids.push(essentials.id);
9425
+ registry.products.put(pid, p);
9426
+ }
9427
+ }
9428
+ const packAxis = {
9429
+ id: "axis_pack_size",
9430
+ business_id: businessId,
9431
+ product_id: "prod_paracetamol",
9432
+ name: "Pack size",
9433
+ display_order: 0,
9434
+ affects_recipe: false,
9435
+ values: [
9436
+ { id: "axv_pack_24", name: "24 tablets", display: 0 },
9437
+ { id: "axv_pack_48", name: "48 tablets", display: 1 },
9438
+ { id: "axv_pack_100", name: "100 tablets (family)", display: 2 }
9439
+ ].map((v) => ({
9440
+ id: v.id,
9441
+ business_id: businessId,
9442
+ axis_id: "axis_pack_size",
9443
+ name: v.name,
9444
+ display_order: v.display,
9445
+ created_at: ISO9,
9446
+ updated_at: ISO9
9447
+ })),
9448
+ created_at: ISO9,
9449
+ updated_at: ISO9
9450
+ };
9451
+ registry.variantAxes.put(packAxis.id, packAxis);
9452
+ const packAdj = { pack_24: "0.00", pack_48: "8.00", pack_100: "18.00" };
9453
+ const paracetamolVariantIds = [];
9454
+ let firstVariant = true;
9455
+ for (const pk of packAxis.values) {
9456
+ const key = pk.id.replace("axv_pack_", "pack_");
9457
+ const id = `var_paracetamol_${key.replace("pack_", "")}`;
9458
+ const variant = {
9459
+ id,
9460
+ product_id: "prod_paracetamol",
9461
+ business_id: businessId,
9462
+ name: pk.name,
9463
+ sku: `PCM-${key.toUpperCase()}`,
9464
+ price_adjustment: packAdj[key] ?? "0.00",
9465
+ component_multiplier: "1.00",
9466
+ is_default: firstVariant,
9467
+ is_active: true,
9468
+ axis_value_ids: [pk.id],
9469
+ created_at: ISO9,
9470
+ updated_at: ISO9
9471
+ };
9472
+ registry.variants.put(id, variant);
9473
+ paracetamolVariantIds.push(id);
9474
+ firstVariant = false;
9475
+ }
9476
+ const paracetamol = registry.products.get("prod_paracetamol");
9477
+ if (paracetamol) {
9478
+ paracetamol.variant_ids = paracetamolVariantIds;
9479
+ registry.products.put(paracetamol.id, paracetamol);
9480
+ }
9481
+ const formAddOn = {
9482
+ id: "addon_form",
9483
+ business_id: businessId,
9484
+ name: "Format",
9485
+ is_multiple_allowed: false,
9486
+ is_required: false,
9487
+ is_mutually_exclusive: true,
9488
+ min_selections: 0,
9489
+ max_selections: 1,
9490
+ created_at: ISO9,
9491
+ updated_at: ISO9,
9492
+ options: [
9493
+ { 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 },
9494
+ { 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 }
9495
+ ]
9496
+ };
9497
+ registry.addOns.put(formAddOn.id, formAddOn);
9498
+ const medProductIds = ["prod_paracetamol", "prod_ibuprofen", "prod_aspirin", "prod_allergy-relief"];
9499
+ for (const pid of medProductIds) {
9500
+ registry.productAddOns.put(`${pid}:${formAddOn.id}`, { product_id: pid, add_on_id: formAddOn.id });
9501
+ const p = registry.products.get(pid);
9502
+ if (p) {
9503
+ p.add_on_ids.push(formAddOn.id);
9504
+ registry.products.put(pid, p);
9505
+ }
9506
+ }
9507
+ const services = [
9508
+ {
9509
+ id: "svc_bp_check",
9510
+ business_id: businessId,
9511
+ name: "Blood Pressure Check",
9512
+ description: "Free in-store BP reading with our pharmacist.",
9513
+ duration_minutes: 15,
9514
+ price: "0.00",
9515
+ is_available: true
9516
+ },
9517
+ {
9518
+ id: "svc_consultation",
9519
+ business_id: businessId,
9520
+ name: "Pharmacist Consultation",
9521
+ description: "15-minute one-on-one about medications, interactions, or symptoms.",
9522
+ duration_minutes: 15,
9523
+ price: "30.00",
9524
+ is_available: true
9525
+ },
9526
+ {
9527
+ id: "svc_prescription_refill",
9528
+ business_id: businessId,
9529
+ name: "Prescription Refill",
9530
+ description: "Upload your prescription; we prepare it for pickup or delivery same-day.",
9531
+ duration_minutes: 30,
9532
+ price: "0.00",
9533
+ is_available: true
9534
+ },
9535
+ {
9536
+ id: "svc_vaccination",
9537
+ business_id: businessId,
9538
+ name: "Vaccination (Flu, Tetanus)",
9539
+ description: "Walk-in or by appointment. Pharmacist-administered.",
9540
+ duration_minutes: 20,
9541
+ price: "80.00",
9542
+ is_available: true
9543
+ }
9544
+ ];
9545
+ for (const s of services) registry.services.put(s.id, s);
9546
+ const tags = [
9547
+ { id: "tag_otc", business_id: businessId, name: "OTC", slug: "otc", color: "#16a34a", sort_order: 0, usage_count: 11, created_at: ISO9, updated_at: ISO9 },
9548
+ { id: "tag_essential", business_id: businessId, name: "Essential", slug: "essential", color: "#2563eb", sort_order: 1, usage_count: 2, created_at: ISO9, updated_at: ISO9 },
9549
+ { id: "tag_prescription", business_id: businessId, name: "Prescription", slug: "prescription", color: "#dc2626", sort_order: 2, usage_count: 0, created_at: ISO9, updated_at: ISO9 }
9550
+ ];
9551
+ for (const t of tags) registry.tags.put(t.id, t);
9552
+ const medication = {
9553
+ id: "tax_medication",
9554
+ business_id: businessId,
9555
+ name: "Medication",
9556
+ slug: "medication",
9557
+ path: ["Health", "Medication"],
9558
+ attribute_template_ids: ["attr_active_ingredient", "attr_dosage"],
9559
+ created_at: ISO9,
9560
+ updated_at: ISO9
9561
+ };
9562
+ registry.taxonomies.put(medication.id, medication);
9563
+ const attrs = [
9564
+ {
9565
+ id: "attr_active_ingredient",
9566
+ business_id: businessId,
9567
+ namespace: "core",
9568
+ name: "Active ingredient",
9569
+ slug: "active-ingredient",
9570
+ attribute_type: "text",
9571
+ is_required: false,
9572
+ is_filterable: true,
9573
+ visibility: "public",
9574
+ display_order: 0,
9575
+ applies_to: "product",
9576
+ created_at: ISO9,
9577
+ updated_at: ISO9
9578
+ },
9579
+ {
9580
+ id: "attr_dosage",
9581
+ business_id: businessId,
9582
+ namespace: "core",
9583
+ name: "Dosage form",
9584
+ slug: "dosage-form",
9585
+ attribute_type: "select",
9586
+ options: ["tablet", "capsule", "syrup", "spray", "cream", "drops"],
9587
+ is_required: false,
9588
+ is_filterable: true,
9589
+ visibility: "public",
9590
+ display_order: 1,
9591
+ applies_to: "product",
9592
+ created_at: ISO9,
9593
+ updated_at: ISO9
9594
+ },
9595
+ {
9596
+ id: "attr_prescription_required",
9597
+ business_id: businessId,
9598
+ namespace: "core",
9599
+ name: "Prescription required",
9600
+ slug: "prescription-required",
9601
+ attribute_type: "boolean",
9602
+ is_required: false,
9603
+ is_filterable: true,
9604
+ visibility: "public",
9605
+ display_order: 2,
9606
+ applies_to: "product",
9607
+ created_at: ISO9,
9608
+ updated_at: ISO9
9609
+ }
9610
+ ];
9611
+ for (const a of attrs) registry.attributeDefs.put(a.id, a);
9612
+ const articles = [
9613
+ {
9614
+ id: "kb_prescription",
9615
+ business_id: businessId,
9616
+ title: "Prescription handling",
9617
+ slug: "prescription-handling",
9618
+ content: "Upload prescriptions through the prescription-refill service. Our pharmacist verifies before dispensing; same-day pickup or delivery within Accra.",
9619
+ category: "logistics",
9620
+ tags: ["prescription", "delivery"],
9621
+ created_at: ISO9,
9622
+ updated_at: ISO9
9623
+ },
9624
+ {
9625
+ id: "kb_returns",
9626
+ business_id: businessId,
9627
+ title: "Returns & exchanges",
9628
+ slug: "returns",
9629
+ content: "Sealed OTC products may be returned within 7 days with receipt. Opened products, prescriptions, and refrigerated items are non-returnable for safety reasons.",
9630
+ category: "policies",
9631
+ tags: ["returns"],
9632
+ created_at: ISO9,
9633
+ updated_at: ISO9
9634
+ },
9635
+ {
9636
+ id: "kb_consultation",
9637
+ business_id: businessId,
9638
+ title: "Pharmacist consultations",
9639
+ slug: "consultations",
9640
+ content: "15-minute pharmacist appointments cover medication review, side-effect questions, OTC selection, and symptom triage. Book through the services menu.",
9641
+ category: "services",
9642
+ tags: ["consultation"],
9643
+ created_at: ISO9,
9644
+ updated_at: ISO9
9645
+ }
9646
+ ];
9647
+ for (const a of articles) registry.knowledgeArticles.put(a.id, a);
9648
+ return { businessId };
9649
+ }
9650
+
9212
9651
  // src/mock/seeds/registry.ts
9213
9652
  var SEEDS = {
9214
9653
  default: seedDefault,
@@ -9218,7 +9657,8 @@ var SEEDS = {
9218
9657
  retail: seedRetail,
9219
9658
  services: seedServices,
9220
9659
  grocery: seedGrocery,
9221
- fashion: seedFashion
9660
+ fashion: seedFashion,
9661
+ pharmacy: seedPharmacy
9222
9662
  };
9223
9663
  function applySeed(registry, name) {
9224
9664
  const fn = SEEDS[name];