@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
@@ -3786,6 +3786,10 @@ function toApiProduct(p, ctx) {
3786
3786
  duration_unit: p.duration_unit,
3787
3787
  duration_minutes: p.duration_minutes,
3788
3788
  billing_plans: p.billing_plans,
3789
+ /** Per-product customer inputs (prescription upload, consent
3790
+ * signature, etc.). The Rust backend emits this on ProductView; the
3791
+ * SDK's React components branch on its presence to render inputs. */
3792
+ input_fields: p.input_fields ?? [],
3789
3793
  created_at: p.created_at,
3790
3794
  updated_at: p.updated_at,
3791
3795
  metadata: {
@@ -5677,8 +5681,8 @@ function createLinkService({ clock, ids }) {
5677
5681
 
5678
5682
  // src/mock/seeds/image.ts
5679
5683
  var CDN_BASE_URL = "https://static-tmp.cimplify.io";
5680
- function seedImage(industry, photoId) {
5681
- return `${CDN_BASE_URL}/seed/${industry}/${photoId}.jpg`;
5684
+ function seedImage(industry, slug) {
5685
+ return `${CDN_BASE_URL}/seed/${industry}/${slug}.jpg`;
5682
5686
  }
5683
5687
 
5684
5688
  // src/mock/seeds/default.ts
@@ -5741,7 +5745,7 @@ function seedDefault(registry) {
5741
5745
  default_address: "12 Independence Ave, Accra",
5742
5746
  default_offers_table_service: true,
5743
5747
  default_accepts_online_orders: true,
5744
- image: img("1568254183919-78a4f43a2877"),
5748
+ image: img("business-hero"),
5745
5749
  status: "active",
5746
5750
  created_at: ISO,
5747
5751
  updated_at: ISO,
@@ -5796,8 +5800,8 @@ function seedDefault(registry) {
5796
5800
  price: "25.00",
5797
5801
  description: "24-hour fermented country loaf with our heritage starter \u2014 open crumb, blistered crust, naturally tangy. Baked fresh every morning.",
5798
5802
  category: "breads",
5799
- imageUrl: img("1509440159596-0249088772ff"),
5800
- images: [img("1509440159596-0249088772ff"), img("1486887396153-fa416526c108")],
5803
+ imageUrl: img("sourdough-loaf"),
5804
+ images: [img("sourdough-loaf"), img("whole-wheat")],
5801
5805
  tags: ["bread", "vegan", "signature"],
5802
5806
  isSignature: true,
5803
5807
  ingredients: ["Wheat flour", "Sourdough starter", "Sea salt", "Filtered water"],
@@ -5812,7 +5816,7 @@ function seedDefault(registry) {
5812
5816
  price: "20.00",
5813
5817
  description: "Hearty 100% whole wheat with sunflower, sesame, and pumpkin seeds. Slow-fermented for a soft crumb and nutty depth.",
5814
5818
  category: "breads",
5815
- imageUrl: img("1486887396153-fa416526c108"),
5819
+ imageUrl: img("whole-wheat"),
5816
5820
  tags: ["bread", "vegan", "high-fibre"],
5817
5821
  ingredients: ["Whole wheat flour", "Sunflower seeds", "Sesame", "Pumpkin seeds"],
5818
5822
  allergies: ["wheat", "gluten", "sesame"],
@@ -5825,7 +5829,7 @@ function seedDefault(registry) {
5825
5829
  price: "15.00",
5826
5830
  description: "Crackling crust, airy crumb. Best eaten warm, within an hour of baking.",
5827
5831
  category: "breads",
5828
- imageUrl: img("1568471173242-461f0a730452"),
5832
+ imageUrl: img("baguette"),
5829
5833
  tags: ["bread", "vegan"],
5830
5834
  ingredients: ["Wheat flour", "Yeast", "Sea salt", "Water"],
5831
5835
  allergies: ["wheat", "gluten"],
@@ -5838,7 +5842,7 @@ function seedDefault(registry) {
5838
5842
  price: "30.00",
5839
5843
  description: "High-hydration focaccia drenched in olive oil, scattered with sea salt and fresh rosemary. Sold whole or by the slab.",
5840
5844
  category: "breads",
5841
- imageUrl: img("1571167530149-c1105da4c2c7"),
5845
+ imageUrl: img("focaccia"),
5842
5846
  tags: ["bread", "vegetarian"],
5843
5847
  ingredients: ["00 flour", "Olive oil", "Rosemary", "Maldon salt"],
5844
5848
  pairings: ["Burrata", "Prosciutto", "Caponata"],
@@ -5852,7 +5856,7 @@ function seedDefault(registry) {
5852
5856
  price: "18.00",
5853
5857
  description: "Caramelised brown butter, three over-ripe bananas, walnuts, finished with a salted maple glaze.",
5854
5858
  category: "breads",
5855
- imageUrl: img("1632931057819-4eefffa8e007"),
5859
+ imageUrl: img("banana-bread"),
5856
5860
  tags: ["sweet", "comfort"],
5857
5861
  ingredients: ["Bananas", "Brown butter", "Walnuts", "Maple syrup"],
5858
5862
  allergies: ["wheat", "gluten", "dairy", "nuts", "eggs"],
@@ -5867,8 +5871,8 @@ function seedDefault(registry) {
5867
5871
  price: "12.00",
5868
5872
  description: "27 layers of laminated dough wrapped around French butter. Crisp, shattering crust and a tender honeycomb interior.",
5869
5873
  category: "pastries",
5870
- imageUrl: img("1555507036-ab1f4038808a"),
5871
- images: [img("1555507036-ab1f4038808a"), img("1530610476181-d83430b64dcd")],
5874
+ imageUrl: img("croissant"),
5875
+ images: [img("croissant"), img("pain-au-chocolat")],
5872
5876
  tags: ["pastry", "vegetarian", "signature"],
5873
5877
  isSignature: true,
5874
5878
  ingredients: ["French butter", "Wheat flour", "Milk", "Eggs"],
@@ -5882,7 +5886,7 @@ function seedDefault(registry) {
5882
5886
  price: "14.00",
5883
5887
  description: "Our croissant dough wrapped around two batons of 70% Valrhona dark chocolate.",
5884
5888
  category: "pastries",
5885
- imageUrl: img("1530610476181-d83430b64dcd"),
5889
+ imageUrl: img("pain-au-chocolat"),
5886
5890
  tags: ["pastry", "chocolate"],
5887
5891
  ingredients: ["Croissant dough", "Valrhona chocolate"],
5888
5892
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -5895,7 +5899,7 @@ function seedDefault(registry) {
5895
5899
  price: "16.00",
5896
5900
  description: "Flaky pastry filled with almond cream, dusted with toasted slivers and powdered sugar.",
5897
5901
  category: "pastries",
5898
- imageUrl: img("1517433367423-c7e5b0f35086"),
5902
+ imageUrl: img("almond-danish"),
5899
5903
  tags: ["pastry", "nuts"],
5900
5904
  ingredients: ["Pastry dough", "Almond cream", "Toasted almonds"],
5901
5905
  allergies: ["wheat", "gluten", "dairy", "eggs", "nuts"],
@@ -5908,7 +5912,7 @@ function seedDefault(registry) {
5908
5912
  price: "13.00",
5909
5913
  description: "Soft enriched dough swirled with butter and Ceylon cinnamon, finished with cream-cheese glaze.",
5910
5914
  category: "pastries",
5911
- imageUrl: img("1607920591413-4ec007e70023"),
5915
+ imageUrl: img("cinnamon-roll"),
5912
5916
  tags: ["pastry", "comfort"],
5913
5917
  ingredients: ["Enriched dough", "Cinnamon", "Brown sugar", "Cream cheese"],
5914
5918
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -5921,7 +5925,7 @@ function seedDefault(registry) {
5921
5925
  price: "12.00",
5922
5926
  description: "Dark, dense, fudgy brownie with a glossy shell. Chocolate four ways. Best slightly warm.",
5923
5927
  category: "pastries",
5924
- imageUrl: img("1606313564200-e75d5e30476c"),
5928
+ imageUrl: img("brownie"),
5925
5929
  tags: ["chocolate", "vegetarian"],
5926
5930
  ingredients: ["Dark chocolate", "Cocoa", "Brown butter", "Eggs"],
5927
5931
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -5934,7 +5938,7 @@ function seedDefault(registry) {
5934
5938
  price: "60.00",
5935
5939
  description: "Six French macarons \u2014 pistachio, raspberry, salted caramel, espresso, vanilla bean, and dark chocolate ganache.",
5936
5940
  category: "pastries",
5937
- imageUrl: img("1558326567-98ae2405596b"),
5941
+ imageUrl: img("macaron-box"),
5938
5942
  tags: ["pastry", "gift", "premium"],
5939
5943
  ingredients: ["Almond flour", "Egg whites", "Sugar", "Various fillings"],
5940
5944
  allergies: ["nuts", "eggs", "dairy"],
@@ -5948,7 +5952,7 @@ function seedDefault(registry) {
5948
5952
  price: "22.00",
5949
5953
  description: "Three layers of dark chocolate sponge with chocolate ganache and cr\xE8me p\xE2tissi\xE8re, finished with a mirror glaze. (Slice)",
5950
5954
  category: "cakes",
5951
- imageUrl: img("1565958011703-44f9829ba187"),
5955
+ imageUrl: img("chocolate-cake"),
5952
5956
  tags: ["cake", "chocolate", "signature"],
5953
5957
  isSignature: true,
5954
5958
  ingredients: ["Dark chocolate", "Cr\xE8me p\xE2tissi\xE8re", "Cocoa", "Eggs"],
@@ -5963,7 +5967,7 @@ function seedDefault(registry) {
5963
5967
  price: "22.00",
5964
5968
  description: "Classic red velvet with cream cheese frosting and white chocolate shavings.",
5965
5969
  category: "cakes",
5966
- imageUrl: img("1586788680434-30d324b2d46f"),
5970
+ imageUrl: img("red-velvet"),
5967
5971
  tags: ["cake"],
5968
5972
  ingredients: ["Buttermilk", "Cocoa", "Cream cheese", "Beetroot"],
5969
5973
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -5976,7 +5980,7 @@ function seedDefault(registry) {
5976
5980
  price: "20.00",
5977
5981
  description: "Spiced carrot cake with toasted walnuts, golden raisins, and cream-cheese frosting.",
5978
5982
  category: "cakes",
5979
- imageUrl: img("1568827999250-3f6afff96e66"),
5983
+ imageUrl: img("carrot-cake"),
5980
5984
  tags: ["cake", "spiced"],
5981
5985
  ingredients: ["Carrot", "Walnuts", "Cinnamon", "Cream cheese"],
5982
5986
  allergies: ["wheat", "gluten", "dairy", "eggs", "nuts"],
@@ -5989,7 +5993,7 @@ function seedDefault(registry) {
5989
5993
  price: "24.00",
5990
5994
  description: "Dense, creamy New York cheesecake on a butter graham crust. Topped with seasonal berry compote.",
5991
5995
  category: "cakes",
5992
- imageUrl: img("1567306226416-28f0efdc88ce"),
5996
+ imageUrl: img("cheesecake"),
5993
5997
  tags: ["cake", "premium"],
5994
5998
  ingredients: ["Cream cheese", "Sour cream", "Graham crust", "Vanilla"],
5995
5999
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6002,8 +6006,8 @@ function seedDefault(registry) {
6002
6006
  price: "250.00",
6003
6007
  description: "Made-to-order three-tier cake. Choose size, flavour, and frosting. 48-hour notice required for personalisation.",
6004
6008
  category: "cakes",
6005
- imageUrl: img("1535254973040-607b474cb50d"),
6006
- images: [img("1535254973040-607b474cb50d"), img("1565958011703-44f9829ba187")],
6009
+ imageUrl: img("birthday-cake"),
6010
+ images: [img("birthday-cake"), img("chocolate-cake")],
6007
6011
  tags: ["cake", "made-to-order", "premium"],
6008
6012
  ingredients: ["Sponge cake", "Buttercream", "Custom decoration"],
6009
6013
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6017,7 +6021,7 @@ function seedDefault(registry) {
6017
6021
  price: "10.00",
6018
6022
  description: "Locally roasted Arabica from Volta Region. Notes of cocoa, dark fruit, and brown sugar.",
6019
6023
  category: "drinks",
6020
- imageUrl: img("1495474472287-4d71bcdd2085"),
6024
+ imageUrl: img("coffee"),
6021
6025
  tags: ["drink", "coffee", "vegan"],
6022
6026
  ingredients: ["Single-origin Arabica beans"],
6023
6027
  pairings: ["Croissant", "Brownie"],
@@ -6030,7 +6034,7 @@ function seedDefault(registry) {
6030
6034
  price: "8.00",
6031
6035
  description: "Choice of English breakfast, Earl Grey, green sencha, or chamomile.",
6032
6036
  category: "drinks",
6033
- imageUrl: img("1576092768241-dec231879fc3"),
6037
+ imageUrl: img("tea"),
6034
6038
  tags: ["drink", "tea", "vegan"],
6035
6039
  calories: 0
6036
6040
  },
@@ -6041,7 +6045,7 @@ function seedDefault(registry) {
6041
6045
  price: "12.00",
6042
6046
  description: "Iced hibiscus tea with ginger, pineapple peel, and a hint of clove. Tart, refreshing, lightly sweet.",
6043
6047
  category: "drinks",
6044
- imageUrl: img("1556679343-c7306c1976bc"),
6048
+ imageUrl: img("sobolo"),
6045
6049
  tags: ["drink", "vegan", "ghana"],
6046
6050
  isSignature: true,
6047
6051
  ingredients: ["Hibiscus", "Ginger", "Pineapple", "Clove"],
@@ -6054,7 +6058,7 @@ function seedDefault(registry) {
6054
6058
  price: "15.00",
6055
6059
  description: "Hand-pressed at sunrise from Ghanaian Valencia oranges. No sugar, no concentrate.",
6056
6060
  category: "drinks",
6057
- imageUrl: img("1622597467836-f3285f2131b8"),
6061
+ imageUrl: img("orange-juice"),
6058
6062
  tags: ["drink", "vegan"],
6059
6063
  calories: 110
6060
6064
  },
@@ -6066,8 +6070,8 @@ function seedDefault(registry) {
6066
6070
  price: "30.00",
6067
6071
  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.",
6068
6072
  category: "boxes",
6069
- imageUrl: img("1533089860892-a7c6f0a88666"),
6070
- images: [img("1533089860892-a7c6f0a88666"), img("1495474472287-4d71bcdd2085")],
6073
+ imageUrl: img("breakfast-box"),
6074
+ images: [img("breakfast-box"), img("coffee")],
6071
6075
  tags: ["bundle", "breakfast"],
6072
6076
  productType: "bundle"
6073
6077
  },
@@ -6078,7 +6082,7 @@ function seedDefault(registry) {
6078
6082
  price: "60.00",
6079
6083
  description: "Pick 6 to 12 of our pastries \u2014 mix and match. Freshly boxed for sharing.",
6080
6084
  category: "boxes",
6081
- imageUrl: img("1486427944299-d1955d23e34d"),
6085
+ imageUrl: img("pastry-box"),
6082
6086
  tags: ["composite", "build-your-own", "gift"],
6083
6087
  productType: "composite"
6084
6088
  },
@@ -6090,7 +6094,7 @@ function seedDefault(registry) {
6090
6094
  price: "85.00",
6091
6095
  description: "Heavy-weight cotton-canvas apron with leather neck strap, embroidered logo, and two front pockets. Made in Accra.",
6092
6096
  category: "merch",
6093
- imageUrl: img("1556905055-8f358a7a47b2"),
6097
+ imageUrl: img("apron"),
6094
6098
  tags: ["merch", "physical"],
6095
6099
  renderHint: "physical"
6096
6100
  },
@@ -6101,7 +6105,7 @@ function seedDefault(registry) {
6101
6105
  price: "35.00",
6102
6106
  description: "12oz natural canvas tote, screen-printed with our wheat-stalk crest. Roomy enough for two loaves.",
6103
6107
  category: "merch",
6104
- imageUrl: img("1591561954557-26941169b49e"),
6108
+ imageUrl: img("tote-bag"),
6105
6109
  tags: ["merch", "physical", "gift"],
6106
6110
  renderHint: "physical",
6107
6111
  isNew: true
@@ -6114,7 +6118,7 @@ function seedDefault(registry) {
6114
6118
  price: "320.00",
6115
6119
  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.",
6116
6120
  category: "merch",
6117
- imageUrl: img("1568254183919-78a4f43a2877"),
6121
+ imageUrl: img("flour-25kg"),
6118
6122
  tags: ["wholesale", "physical", "trade"],
6119
6123
  renderHint: "physical",
6120
6124
  quantityPricing: [
@@ -6132,7 +6136,7 @@ function seedDefault(registry) {
6132
6136
  price: "45.00",
6133
6137
  description: "PDF + EPUB walkthrough of our sourdough programme \u2014 starter, levain, autolyse, bulk fermentation, shaping, scoring. Lifetime updates.",
6134
6138
  category: "merch",
6135
- imageUrl: img("1543002588-bfa74002ed7e"),
6139
+ imageUrl: img("sourdough-ebook"),
6136
6140
  tags: ["digital", "download"],
6137
6141
  productType: "digital",
6138
6142
  digitalProductType: "download"
@@ -6144,7 +6148,7 @@ function seedDefault(registry) {
6144
6148
  price: "100.00",
6145
6149
  description: "Send instantly. Redeemable in-store and online toward any product. Choose any amount from GH\u20B550 upward.",
6146
6150
  category: "merch",
6147
- imageUrl: img("1556905055-8f358a7a47b2"),
6151
+ imageUrl: img("gift-card"),
6148
6152
  tags: ["digital", "gift"],
6149
6153
  productType: "digital",
6150
6154
  digitalProductType: "gift_code",
@@ -6158,7 +6162,7 @@ function seedDefault(registry) {
6158
6162
  price: "320.00",
6159
6163
  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.",
6160
6164
  category: "classes",
6161
- imageUrl: img("1517686469429-8bdb88b9f907"),
6165
+ imageUrl: img("baking-class"),
6162
6166
  tags: ["class", "service", "hands-on"],
6163
6167
  productType: "service",
6164
6168
  durationMinutes: 120
@@ -6170,7 +6174,7 @@ function seedDefault(registry) {
6170
6174
  price: "480.00",
6171
6175
  description: "Three-hour deep-dive on laminated dough. We cover croissants, danishes, kouign-amann. Aprons supplied; pastries to take home.",
6172
6176
  category: "classes",
6173
- imageUrl: img("1517433367423-c7e5b0f35086"),
6177
+ imageUrl: img("pastry-workshop"),
6174
6178
  tags: ["class", "service", "advanced"],
6175
6179
  productType: "service",
6176
6180
  durationMinutes: 180,
@@ -6184,7 +6188,7 @@ function seedDefault(registry) {
6184
6188
  price: "180.00",
6185
6189
  description: "Rent our commercial bakery after hours. Deck oven, retarder-proofer, mixers, scales \u2014 bring your team or shoot your content. Hourly.",
6186
6190
  category: "classes",
6187
- imageUrl: img("1606755962773-d324e0a13086"),
6191
+ imageUrl: img("kitchen-rental"),
6188
6192
  tags: ["rental", "service", "commercial"],
6189
6193
  productType: "service",
6190
6194
  durationUnit: "hours"
@@ -6197,7 +6201,7 @@ function seedDefault(registry) {
6197
6201
  price: "650.00",
6198
6202
  description: "One-bedroom loft above the bakery. Wakes up to fresh croissants, ends with a private dinner. Ghana Tourism-licensed. Per night.",
6199
6203
  category: "classes",
6200
- imageUrl: img("1564013799919-ab600027ffc6"),
6204
+ imageUrl: img("loft-stay"),
6201
6205
  tags: ["stay", "service", "premium"],
6202
6206
  productType: "service",
6203
6207
  durationUnit: "nights"
@@ -6210,7 +6214,7 @@ function seedDefault(registry) {
6210
6214
  price: "0.00",
6211
6215
  description: "A fresh loaf delivered to your door every week. Pause or skip any time. Choose monthly or quarterly billing for a discount.",
6212
6216
  category: "classes",
6213
- imageUrl: img("1509440159596-0249088772ff"),
6217
+ imageUrl: img("loaf-subscription"),
6214
6218
  tags: ["subscription", "service", "delivery"],
6215
6219
  productType: "service",
6216
6220
  billingPlans: [
@@ -7038,31 +7042,7 @@ function seedReesa(registry) {
7038
7042
 
7039
7043
  // src/mock/seeds/restaurant.ts
7040
7044
  var ISO4 = "2026-01-01T00:00:00.000Z";
7041
- var PHOTO = {
7042
- "business-hero": "1414235077428-338989a2e8c0",
7043
- kelewele: "1599487488170-d11ec9c172f0",
7044
- "spring-rolls": "1559339352-11d035aa65de",
7045
- "soup-of-the-day": "1547592180-85f173990554",
7046
- "jollof-rice": "1546069901-d5bfd2cbfb1f",
7047
- "banku-tilapia": "1485921325833-c519f76c4927",
7048
- "fufu-light-soup": "1602253057119-44d745d9b860",
7049
- waakye: "1565299624946-b28f40a0ae38",
7050
- "grilled-chicken": "1598103442097-8b74394b95c6",
7051
- burger: "1568901346375-23c9450c58cd",
7052
- "yam-fries": "1576107232684-1279f390859f",
7053
- "fried-plantain": "1493770348161-369560ae357d",
7054
- salad: "1512621776951-a57141f2eefd",
7055
- "ice-cream": "1488900128323-21503983a07e",
7056
- "cake-slice": "1565958011703-44f9829ba187",
7057
- "fruit-bowl": "1490474418585-ba9bad8fd0ea",
7058
- "soft-drink": "1581636625402-29b2a704ef13",
7059
- sobolo: "1556679343-c7306c1976bc",
7060
- "fresh-juice": "1610970881699-44a5587cabec",
7061
- water: "1564325724739-bae0bd08762c",
7062
- feast: "1559847844-5315695dadae",
7063
- byo: "1551782450-a2132b4ba21d"
7064
- };
7065
- var photoFor = (slug) => seedImage("restaurant", PHOTO[slug] ?? "1414235077428-338989a2e8c0");
7045
+ var photoFor = (slug) => seedImage("restaurant", slug);
7066
7046
  function seedRestaurant(registry) {
7067
7047
  const businessId = "bus_mamas_kitchen";
7068
7048
  const business = {
@@ -7522,29 +7502,7 @@ function seedRestaurant(registry) {
7522
7502
 
7523
7503
  // src/mock/seeds/retail.ts
7524
7504
  var ISO5 = "2026-01-01T00:00:00.000Z";
7525
- var PHOTO2 = {
7526
- "android-flagship": "1592750475338-74b7b21085ab",
7527
- "android-mid": "1511707171634-5f897ff02aa9",
7528
- "phone-budget": "1574944985070-8f3ebc6b79d2",
7529
- "laptop-pro": "1517336714731-489689fd1ca8",
7530
- "laptop-air": "1496181133206-80ce9b88a853",
7531
- "laptop-budget": "1601784551446-20c9e07cdbdb",
7532
- "headphones-anc": "1505740420928-5e560c06d30e",
7533
- "earbuds-pro": "1572569511254-d8f925fe2cbb",
7534
- "speaker-bt": "1612287230202-1ff1d85d1bdf",
7535
- "phone-case": "1611532736597-de2d4265fba3",
7536
- "screen-protector": "1568952433726-3896e3881c65",
7537
- "fast-charger": "1620794108219-aedbaded4eea",
7538
- "laptop-sleeve": "1604671801908-6f0c6a092c05",
7539
- "wireless-mouse": "1594732832278-abd644401426",
7540
- "mech-keyboard": "1583394838336-acd977736f90",
7541
- "gaming-controller": "1542751371-adc38448a05e",
7542
- "gaming-headset": "1606220945770-b5b6c2c55bf1",
7543
- "console-handheld": "1593642634524-b40b5baae6bb",
7544
- wfh: "1605236453806-6ff36851218e",
7545
- "game-pack": "1606144042614-b2417e99c4e3"
7546
- };
7547
- var photoFor2 = (slug) => seedImage("retail", PHOTO2[slug] ?? "1517336714731-489689fd1ca8");
7505
+ var photoFor2 = (slug) => seedImage("retail", slug);
7548
7506
  function seedRetail(registry) {
7549
7507
  const businessId = "bus_currents_electronics";
7550
7508
  const business = {
@@ -8017,29 +7975,7 @@ function seedRetail(registry) {
8017
7975
 
8018
7976
  // src/mock/seeds/services.ts
8019
7977
  var ISO6 = "2026-01-01T00:00:00.000Z";
8020
- var PHOTO3 = {
8021
- "business-hero": "1540555700478-4be289fbecef",
8022
- "swedish-massage-60": "1544161515-4ab6ce6db874",
8023
- "swedish-massage-90": "1519823551278-64ac92734fb1",
8024
- "deep-tissue-60": "1571019613454-1cb2f99b2d8b",
8025
- "couples-massage": "1591343395082-e120087004b4",
8026
- "hot-stone-90": "1620733723572-11c53f73a416",
8027
- "facial-classic": "1487412947147-5cebf100ffc2",
8028
- "facial-anti-aging": "1487412947147-5cebf100ffc2",
8029
- "facial-acne": "1556228720-195a672e8a03",
8030
- manicure: "1604654894610-df63bc536371",
8031
- pedicure: "1519415943484-9fa1873496d4",
8032
- "gel-manicure": "1607779097040-26e80aa78e66",
8033
- haircut: "1622286342621-4bd786c2447c",
8034
- "hair-treatment": "1633681926022-84c23e8cb2d6",
8035
- color: "1560066984-138dadb4c035",
8036
- "yoga-session": "1545205597-3d9d02c29597",
8037
- meditation: "1506126613408-eca07ce68773",
8038
- "spa-day": "1571019613454-1cb2f99b2d8b",
8039
- couples: "1591343395082-e120087004b4",
8040
- custom: "1540555700478-4be289fbecef"
8041
- };
8042
- var photoFor3 = (slug) => seedImage("services", PHOTO3[slug] ?? "1540555700478-4be289fbecef");
7978
+ var photoFor3 = (slug) => seedImage("services", slug);
8043
7979
  function seedServices(registry) {
8044
7980
  const businessId = "bus_serene_spa";
8045
7981
  const business = {
@@ -8419,35 +8355,7 @@ function seedServices(registry) {
8419
8355
 
8420
8356
  // src/mock/seeds/grocery.ts
8421
8357
  var ISO7 = "2026-01-01T00:00:00.000Z";
8422
- var PHOTO4 = {
8423
- "business-hero": "1542838132-92c53300491e",
8424
- "tomatoes-1kg": "1592924357228-91a4daadcfea",
8425
- "onions-1kg": "1620574387735-3624d75b2dbc",
8426
- "ginger-200g": "1594631252845-29fc4cc8cde9",
8427
- "bananas-bunch": "1571771019784-3ff35f4f4277",
8428
- pineapple: "1550258987-190a2d41a8ba",
8429
- "spinach-bunch": "1576045057995-568f588f82fb",
8430
- "milk-1l": "1563636619-e9143da7973b",
8431
- "yogurt-500g": "1488477181946-6428a0291777",
8432
- "eggs-12": "1582722872445-44dc5f7e3c8f",
8433
- "cheese-200g": "1486297678162-eb2a19b0a32d",
8434
- "chicken-1kg": "1604503468506-a8da13d82791",
8435
- "beef-mince-500g": "1607623814075-e51df1bdc82f",
8436
- "tilapia-each": "1535473895227-bdecb20fb157",
8437
- "rice-5kg": "1586201375761-83865001e31c",
8438
- "garri-2kg": "1582284540020-8acbe03f4924",
8439
- "palm-oil-1l": "1611078489935-0cb964de46d6",
8440
- "vegetable-oil-1l": "1474979266404-7eaacbcd87c5",
8441
- "salt-1kg": "1607301406259-dfb186e15de8",
8442
- "sugar-1kg": "1610725664285-7c57e6eeac3f",
8443
- "tomato-paste": "1561136594-7f68413baa99",
8444
- "soap-bar": "1600857062241-98e5dba7f214",
8445
- "detergent-1kg": "1582735689369-4fe89db7114c",
8446
- "tissue-pack": "1583947215259-38e31be8751f",
8447
- "trash-bags": "1605600659908-0ef719419d41",
8448
- essentials: "1542838132-92c53300491e"
8449
- };
8450
- var photoFor4 = (slug) => seedImage("grocery", PHOTO4[slug] ?? "1542838132-92c53300491e");
8358
+ var photoFor4 = (slug) => seedImage("grocery", slug);
8451
8359
  function seedGrocery(registry) {
8452
8360
  const businessId = "bus_freshmart";
8453
8361
  const business = {
@@ -8710,23 +8618,7 @@ function seedGrocery(registry) {
8710
8618
 
8711
8619
  // src/mock/seeds/fashion.ts
8712
8620
  var ISO8 = "2026-01-01T00:00:00.000Z";
8713
- var PHOTO5 = {
8714
- "heavyweight-hoodie-charcoal": "1556905055-8f358a7a47b2",
8715
- "heavyweight-hoodie-cream": "1576566588028-4147f3842f27",
8716
- "heavyweight-hoodie-cobalt": "1542838686-37da4a9fd1b3",
8717
- "studio-tee-black": "1521572163474-6864f9cf17ab",
8718
- "studio-tee-natural": "1485518882345-15568b007407",
8719
- "graphic-tee-frx-mark": "1521223890158-f9f7c3d5d504",
8720
- "carbon-bomber": "1591047139829-d91aecb6caea",
8721
- "field-jacket-olive": "1564859228273-274232fdb516",
8722
- "wide-leg-trouser": "1542272604-787c3835535d",
8723
- "track-pant-charcoal": "1604176354204-9268737828e4",
8724
- "studio-cap": "1620799140408-edc6dcb6d633",
8725
- "tote-natural": "1591195853828-11db59a44f6b",
8726
- "knit-beanie": "1542838132-92c53300491e",
8727
- "studio-sock-3pack": "1602810318383-e386cc2a3ccf"
8728
- };
8729
- var photoFor5 = (slug) => seedImage("fashion", PHOTO5[slug] ?? "1556905055-8f358a7a47b2");
8621
+ var photoFor5 = (slug) => seedImage("fashion", slug);
8730
8622
  var SIZES = ["XS", "S", "M", "L", "XL", "2XL"];
8731
8623
  function seedFashion(registry) {
8732
8624
  const businessId = "bus_studio_frx";
@@ -8741,7 +8633,7 @@ function seedFashion(registry) {
8741
8633
  default_address: "Osu Oxford Street, Accra",
8742
8634
  default_offers_table_service: false,
8743
8635
  default_accepts_online_orders: true,
8744
- image: seedImage("fashion", "1490481651871-ab68de25d43d"),
8636
+ image: seedImage("fashion", "business-hero"),
8745
8637
  status: "active",
8746
8638
  created_at: ISO8,
8747
8639
  updated_at: ISO8,
@@ -9143,6 +9035,553 @@ function seedFashion(registry) {
9143
9035
  return { businessId };
9144
9036
  }
9145
9037
 
9038
+ // src/mock/seeds/pharmacy.ts
9039
+ var ISO9 = "2026-01-01T00:00:00.000Z";
9040
+ var photoFor6 = (slug) => seedImage("pharmacy", slug);
9041
+ function seedPharmacy(registry) {
9042
+ const businessId = "bus_wellspring_pharmacy";
9043
+ const business = {
9044
+ id: businessId,
9045
+ name: "Wellspring Pharmacy",
9046
+ handle: "wellspring",
9047
+ business_type: "retail",
9048
+ email: "care@wellspringpharmacy.test",
9049
+ default_currency: "GHS",
9050
+ default_phone: "+233244778899",
9051
+ default_address: "5 Liberation Road, Ridge, Accra",
9052
+ default_offers_table_service: false,
9053
+ default_accepts_online_orders: true,
9054
+ image: photoFor6("business-hero"),
9055
+ status: "active",
9056
+ created_at: ISO9,
9057
+ updated_at: ISO9,
9058
+ created_by: "seed",
9059
+ preferences: {
9060
+ theme: "clinical",
9061
+ tagline: "Trusted care, delivered same-day",
9062
+ checkout: { allow_guest: true }
9063
+ },
9064
+ is_online_only: false,
9065
+ enabled_payment_types: ["card", "mobile_money", "cash"],
9066
+ default_location_settings: {},
9067
+ country_code: "GH",
9068
+ timezone: "Africa/Accra"
9069
+ };
9070
+ registry.businesses.put(businessId, business);
9071
+ const categories = [
9072
+ { slug: "pain-relief", name: "Pain Relief" },
9073
+ { slug: "cold-flu", name: "Cold & Flu" },
9074
+ { slug: "vitamins", name: "Vitamins & Supplements" },
9075
+ { slug: "first-aid", name: "First Aid" },
9076
+ { slug: "personal-care", name: "Personal Care" },
9077
+ { slug: "devices", name: "Medical Devices" },
9078
+ { slug: "baby", name: "Baby & Mother" }
9079
+ ];
9080
+ const catIds = /* @__PURE__ */ new Map();
9081
+ for (const c of categories) {
9082
+ const id = `cat_${c.slug}`;
9083
+ catIds.set(c.slug, id);
9084
+ const cat = {
9085
+ id,
9086
+ business_id: businessId,
9087
+ name: c.name,
9088
+ slug: c.slug,
9089
+ description: `Wellspring \u2014 ${c.name}`,
9090
+ product_ids: [],
9091
+ display_order: 0,
9092
+ is_active: true,
9093
+ created_at: ISO9,
9094
+ updated_at: ISO9
9095
+ };
9096
+ registry.categories.put(id, cat);
9097
+ }
9098
+ function field(productSlug, f) {
9099
+ return {
9100
+ id: f.id ?? `fld_${productSlug}_${f.slug}`,
9101
+ product_id: `prod_${productSlug}`,
9102
+ ...f
9103
+ };
9104
+ }
9105
+ const products = [
9106
+ // Pain Relief
9107
+ {
9108
+ slug: "paracetamol",
9109
+ name: "Paracetamol 500mg (24 tablets)",
9110
+ price: "12.00",
9111
+ category: "pain-relief",
9112
+ description: "Fever and mild-to-moderate pain. Adults and children over 12.",
9113
+ tags: ["otc", "analgesic"],
9114
+ inputs: [
9115
+ field("paracetamol", {
9116
+ slug: "age_confirmation",
9117
+ name: "Age confirmation",
9118
+ field_type: "checkbox",
9119
+ is_required: true,
9120
+ display_order: 0,
9121
+ help_text: "I confirm this product is for someone aged 12 or over."
9122
+ })
9123
+ ]
9124
+ },
9125
+ { 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"] },
9126
+ { 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"] },
9127
+ { slug: "allergy-relief", name: "Cetirizine 10mg (10 tablets)", price: "22.00", category: "pain-relief", description: "Non-drowsy antihistamine for seasonal allergies.", tags: ["otc", "antihistamine"] },
9128
+ // Cold & Flu
9129
+ { 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"] },
9130
+ { slug: "throat-lozenges", name: "Honey-Lemon Throat Lozenges (24)", price: "18.00", category: "cold-flu", description: "Soothes sore throat and irritation.", tags: ["otc", "lozenge"] },
9131
+ { slug: "decongestant", name: "Nasal Decongestant Spray (10ml)", price: "28.00", category: "cold-flu", description: "Fast-acting relief for blocked nasal passages.", tags: ["otc", "spray"] },
9132
+ // Vitamins & Supplements
9133
+ { 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"] },
9134
+ { slug: "vitamin-c", name: "Vitamin C 1000mg (90 tablets)", price: "65.00", category: "vitamins", description: "Immune-support antioxidant. Time-released.", tags: ["supplement", "immune"] },
9135
+ { 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"] },
9136
+ { 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"] },
9137
+ { slug: "probiotics", name: "Probiotic 10-Strain (30 capsules)", price: "95.00", category: "vitamins", description: "Digestive and immune support.", tags: ["supplement", "digestive"] },
9138
+ // First Aid
9139
+ { 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"] },
9140
+ { slug: "plasters", name: "Assorted Plasters (40 pack)", price: "22.00", category: "first-aid", description: "Waterproof adhesive bandages in five sizes.", tags: ["first-aid"] },
9141
+ { slug: "antiseptic", name: "Antiseptic Cream (30g)", price: "18.00", category: "first-aid", description: "For cuts, grazes, and minor skin infections.", tags: ["first-aid", "cream"] },
9142
+ { 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"] },
9143
+ // Personal Care
9144
+ { 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"] },
9145
+ { slug: "face-mask", name: "Surgical Face Masks (50 pack)", price: "45.00", category: "personal-care", description: "3-ply earloop masks. Disposable.", tags: ["hygiene", "ppe"] },
9146
+ { 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"] },
9147
+ // Medical Devices
9148
+ { slug: "thermometer", name: "Digital Thermometer", price: "65.00", category: "devices", description: "Fast oral / underarm reading in 10 seconds. Auto-shutoff.", tags: ["device", "essential"] },
9149
+ {
9150
+ slug: "blood-pressure-monitor",
9151
+ name: "Automatic BP Monitor",
9152
+ price: "320.00",
9153
+ category: "devices",
9154
+ description: "Upper-arm cuff with memory for two users. Irregular heartbeat detection.",
9155
+ tags: ["device", "premium"],
9156
+ inputs: [
9157
+ field("blood-pressure-monitor", {
9158
+ slug: "arm_size",
9159
+ name: "Arm circumference",
9160
+ field_type: "select",
9161
+ options: ["Standard (22\u201332 cm)", "Large (32\u201342 cm)"],
9162
+ is_required: true,
9163
+ display_order: 0,
9164
+ help_text: "Pick the cuff that fits \u2014 wrong size gives inaccurate readings."
9165
+ })
9166
+ ]
9167
+ },
9168
+ { 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"] },
9169
+ { slug: "pulse-oximeter", name: "Fingertip Pulse Oximeter", price: "145.00", category: "devices", description: "SpO2 + heart-rate reading in under 10 seconds.", tags: ["device"] },
9170
+ // Baby & Mother
9171
+ {
9172
+ slug: "baby-formula",
9173
+ name: "Infant Formula Stage 1 (400g)",
9174
+ price: "150.00",
9175
+ category: "baby",
9176
+ description: "0\u20136 months. Iron-fortified, with prebiotics.",
9177
+ tags: ["baby", "nutrition"],
9178
+ inputs: [
9179
+ field("baby-formula", {
9180
+ slug: "baby_dob",
9181
+ name: "Baby's date of birth",
9182
+ field_type: "date",
9183
+ is_required: true,
9184
+ display_order: 0,
9185
+ help_text: "Confirms stage 1 is the right formula for your baby's age."
9186
+ }),
9187
+ field("baby-formula", {
9188
+ slug: "allergies",
9189
+ name: "Known allergies or intolerances",
9190
+ field_type: "textarea",
9191
+ is_required: false,
9192
+ display_order: 1,
9193
+ placeholder: "e.g. lactose, soy. Leave blank if none.",
9194
+ semantic_kind: "allergen"
9195
+ })
9196
+ ]
9197
+ },
9198
+ { slug: "baby-wipes", name: "Sensitive Baby Wipes (72 pack)", price: "28.00", category: "baby", description: "Alcohol-free, fragrance-free. Dermatologist-tested.", tags: ["baby", "hygiene"] },
9199
+ // ── Prescription medications (Rx; require a verified prescription) ─
9200
+ {
9201
+ slug: "amoxicillin-rx",
9202
+ name: "Amoxicillin 500mg (Rx)",
9203
+ price: "65.00",
9204
+ category: "pain-relief",
9205
+ description: "Broad-spectrum antibiotic. Prescription required \u2014 our pharmacist will verify before dispensing.",
9206
+ tags: ["prescription", "antibiotic"],
9207
+ requiresPrescription: true,
9208
+ inputs: [
9209
+ field("amoxicillin-rx", {
9210
+ slug: "prescription_upload",
9211
+ name: "Upload prescription",
9212
+ field_type: "file",
9213
+ is_required: true,
9214
+ display_order: 0,
9215
+ help_text: "PDF or photo of your doctor's prescription (max 10 MB).",
9216
+ validation: { accepted_formats: ["pdf", "jpg", "jpeg", "png", "heic"], max_size_mb: 10 }
9217
+ }),
9218
+ field("amoxicillin-rx", {
9219
+ slug: "patient_dob",
9220
+ name: "Patient date of birth",
9221
+ field_type: "date",
9222
+ is_required: true,
9223
+ display_order: 1
9224
+ }),
9225
+ field("amoxicillin-rx", {
9226
+ slug: "consent",
9227
+ name: "I confirm this prescription is genuine and issued for the named patient",
9228
+ field_type: "checkbox",
9229
+ is_required: true,
9230
+ display_order: 2,
9231
+ semantic_kind: "consent"
9232
+ })
9233
+ ]
9234
+ },
9235
+ {
9236
+ slug: "insulin-rx",
9237
+ name: "Insulin Glargine 100u/ml (Rx)",
9238
+ price: "240.00",
9239
+ category: "devices",
9240
+ description: "Long-acting basal insulin. Cold-chain delivery; prescription required.",
9241
+ tags: ["prescription", "diabetes", "cold-chain"],
9242
+ requiresPrescription: true,
9243
+ inputs: [
9244
+ field("insulin-rx", {
9245
+ slug: "prescription_upload",
9246
+ name: "Upload prescription",
9247
+ field_type: "file",
9248
+ is_required: true,
9249
+ display_order: 0,
9250
+ help_text: "PDF or photo of your doctor's prescription (max 10 MB).",
9251
+ validation: { accepted_formats: ["pdf", "jpg", "jpeg", "png", "heic"], max_size_mb: 10 }
9252
+ }),
9253
+ field("insulin-rx", {
9254
+ slug: "delivery_temp_acknowledgement",
9255
+ name: "I'll be available to receive a cold-chain delivery",
9256
+ field_type: "checkbox",
9257
+ is_required: true,
9258
+ display_order: 1,
9259
+ help_text: "Insulin must be refrigerated. Delivery driver will hand over directly \u2014 not leave at door.",
9260
+ semantic_kind: "consent"
9261
+ })
9262
+ ]
9263
+ },
9264
+ {
9265
+ slug: "vaccination-consent",
9266
+ name: "Flu Shot \u2014 At-Pharmacy",
9267
+ price: "80.00",
9268
+ category: "personal-care",
9269
+ description: "Pharmacist-administered seasonal influenza vaccine. Walk-in or book a slot.",
9270
+ tags: ["service", "vaccination"],
9271
+ inputs: [
9272
+ field("vaccination-consent", {
9273
+ slug: "patient_name",
9274
+ name: "Patient name",
9275
+ field_type: "text",
9276
+ is_required: true,
9277
+ display_order: 0
9278
+ }),
9279
+ field("vaccination-consent", {
9280
+ slug: "patient_dob",
9281
+ name: "Date of birth",
9282
+ field_type: "date",
9283
+ is_required: true,
9284
+ display_order: 1
9285
+ }),
9286
+ field("vaccination-consent", {
9287
+ slug: "allergies",
9288
+ name: "Known allergies or reactions to past vaccines",
9289
+ field_type: "textarea",
9290
+ is_required: false,
9291
+ display_order: 2,
9292
+ placeholder: "Egg, latex, prior vaccine reactions, etc. Leave blank if none.",
9293
+ semantic_kind: "allergen"
9294
+ }),
9295
+ field("vaccination-consent", {
9296
+ slug: "consent_signature",
9297
+ name: "Signed consent",
9298
+ field_type: "signature",
9299
+ is_required: true,
9300
+ display_order: 3,
9301
+ help_text: "Required by our administering pharmacist before vaccination.",
9302
+ semantic_kind: "consent"
9303
+ })
9304
+ ]
9305
+ }
9306
+ ];
9307
+ for (const p of products) {
9308
+ const id = `prod_${p.slug}`;
9309
+ const catId = catIds.get(p.category);
9310
+ const product = {
9311
+ id,
9312
+ business_id: businessId,
9313
+ name: p.name,
9314
+ slug: p.slug,
9315
+ description: p.description,
9316
+ product_type: "product",
9317
+ base_price: p.price,
9318
+ currency: "GHS",
9319
+ image: photoFor6(p.slug),
9320
+ images: [photoFor6(p.slug)],
9321
+ is_available: true,
9322
+ category_ids: [catId],
9323
+ collection_ids: [],
9324
+ add_on_ids: [],
9325
+ variant_ids: [],
9326
+ tags: p.tags ?? [],
9327
+ input_fields: p.inputs,
9328
+ metadata: p.requiresPrescription ? { requires_prescription: true } : void 0,
9329
+ created_at: ISO9,
9330
+ updated_at: ISO9
9331
+ };
9332
+ registry.products.put(id, product);
9333
+ const cat = registry.categories.get(catId);
9334
+ cat.product_ids.push(id);
9335
+ registry.categories.put(catId, cat);
9336
+ }
9337
+ const essentials = {
9338
+ id: "col_essentials",
9339
+ business_id: businessId,
9340
+ name: "Home Essentials",
9341
+ slug: "essentials",
9342
+ description: "Stock up your medicine cabinet.",
9343
+ product_ids: [
9344
+ "prod_paracetamol",
9345
+ "prod_first-aid-kit",
9346
+ "prod_thermometer",
9347
+ "prod_hand-sanitizer",
9348
+ "prod_multivitamin"
9349
+ ],
9350
+ is_active: true,
9351
+ created_at: ISO9,
9352
+ updated_at: ISO9
9353
+ };
9354
+ registry.collections.put(essentials.id, essentials);
9355
+ for (const pid of essentials.product_ids) {
9356
+ const p = registry.products.get(pid);
9357
+ if (p) {
9358
+ p.collection_ids.push(essentials.id);
9359
+ registry.products.put(pid, p);
9360
+ }
9361
+ }
9362
+ const packAxis = {
9363
+ id: "axis_pack_size",
9364
+ business_id: businessId,
9365
+ product_id: "prod_paracetamol",
9366
+ name: "Pack size",
9367
+ display_order: 0,
9368
+ affects_recipe: false,
9369
+ values: [
9370
+ { id: "axv_pack_24", name: "24 tablets", display: 0 },
9371
+ { id: "axv_pack_48", name: "48 tablets", display: 1 },
9372
+ { id: "axv_pack_100", name: "100 tablets (family)", display: 2 }
9373
+ ].map((v) => ({
9374
+ id: v.id,
9375
+ business_id: businessId,
9376
+ axis_id: "axis_pack_size",
9377
+ name: v.name,
9378
+ display_order: v.display,
9379
+ created_at: ISO9,
9380
+ updated_at: ISO9
9381
+ })),
9382
+ created_at: ISO9,
9383
+ updated_at: ISO9
9384
+ };
9385
+ registry.variantAxes.put(packAxis.id, packAxis);
9386
+ const packAdj = { pack_24: "0.00", pack_48: "8.00", pack_100: "18.00" };
9387
+ const paracetamolVariantIds = [];
9388
+ let firstVariant = true;
9389
+ for (const pk of packAxis.values) {
9390
+ const key = pk.id.replace("axv_pack_", "pack_");
9391
+ const id = `var_paracetamol_${key.replace("pack_", "")}`;
9392
+ const variant = {
9393
+ id,
9394
+ product_id: "prod_paracetamol",
9395
+ business_id: businessId,
9396
+ name: pk.name,
9397
+ sku: `PCM-${key.toUpperCase()}`,
9398
+ price_adjustment: packAdj[key] ?? "0.00",
9399
+ component_multiplier: "1.00",
9400
+ is_default: firstVariant,
9401
+ is_active: true,
9402
+ axis_value_ids: [pk.id],
9403
+ created_at: ISO9,
9404
+ updated_at: ISO9
9405
+ };
9406
+ registry.variants.put(id, variant);
9407
+ paracetamolVariantIds.push(id);
9408
+ firstVariant = false;
9409
+ }
9410
+ const paracetamol = registry.products.get("prod_paracetamol");
9411
+ if (paracetamol) {
9412
+ paracetamol.variant_ids = paracetamolVariantIds;
9413
+ registry.products.put(paracetamol.id, paracetamol);
9414
+ }
9415
+ const formAddOn = {
9416
+ id: "addon_form",
9417
+ business_id: businessId,
9418
+ name: "Format",
9419
+ is_multiple_allowed: false,
9420
+ is_required: false,
9421
+ is_mutually_exclusive: true,
9422
+ min_selections: 0,
9423
+ max_selections: 1,
9424
+ created_at: ISO9,
9425
+ updated_at: ISO9,
9426
+ options: [
9427
+ { 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 },
9428
+ { 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 }
9429
+ ]
9430
+ };
9431
+ registry.addOns.put(formAddOn.id, formAddOn);
9432
+ const medProductIds = ["prod_paracetamol", "prod_ibuprofen", "prod_aspirin", "prod_allergy-relief"];
9433
+ for (const pid of medProductIds) {
9434
+ registry.productAddOns.put(`${pid}:${formAddOn.id}`, { product_id: pid, add_on_id: formAddOn.id });
9435
+ const p = registry.products.get(pid);
9436
+ if (p) {
9437
+ p.add_on_ids.push(formAddOn.id);
9438
+ registry.products.put(pid, p);
9439
+ }
9440
+ }
9441
+ const services = [
9442
+ {
9443
+ id: "svc_bp_check",
9444
+ business_id: businessId,
9445
+ name: "Blood Pressure Check",
9446
+ description: "Free in-store BP reading with our pharmacist.",
9447
+ duration_minutes: 15,
9448
+ price: "0.00",
9449
+ is_available: true
9450
+ },
9451
+ {
9452
+ id: "svc_consultation",
9453
+ business_id: businessId,
9454
+ name: "Pharmacist Consultation",
9455
+ description: "15-minute one-on-one about medications, interactions, or symptoms.",
9456
+ duration_minutes: 15,
9457
+ price: "30.00",
9458
+ is_available: true
9459
+ },
9460
+ {
9461
+ id: "svc_prescription_refill",
9462
+ business_id: businessId,
9463
+ name: "Prescription Refill",
9464
+ description: "Upload your prescription; we prepare it for pickup or delivery same-day.",
9465
+ duration_minutes: 30,
9466
+ price: "0.00",
9467
+ is_available: true
9468
+ },
9469
+ {
9470
+ id: "svc_vaccination",
9471
+ business_id: businessId,
9472
+ name: "Vaccination (Flu, Tetanus)",
9473
+ description: "Walk-in or by appointment. Pharmacist-administered.",
9474
+ duration_minutes: 20,
9475
+ price: "80.00",
9476
+ is_available: true
9477
+ }
9478
+ ];
9479
+ for (const s of services) registry.services.put(s.id, s);
9480
+ const tags = [
9481
+ { id: "tag_otc", business_id: businessId, name: "OTC", slug: "otc", color: "#16a34a", sort_order: 0, usage_count: 11, created_at: ISO9, updated_at: ISO9 },
9482
+ { id: "tag_essential", business_id: businessId, name: "Essential", slug: "essential", color: "#2563eb", sort_order: 1, usage_count: 2, created_at: ISO9, updated_at: ISO9 },
9483
+ { id: "tag_prescription", business_id: businessId, name: "Prescription", slug: "prescription", color: "#dc2626", sort_order: 2, usage_count: 0, created_at: ISO9, updated_at: ISO9 }
9484
+ ];
9485
+ for (const t of tags) registry.tags.put(t.id, t);
9486
+ const medication = {
9487
+ id: "tax_medication",
9488
+ business_id: businessId,
9489
+ name: "Medication",
9490
+ slug: "medication",
9491
+ path: ["Health", "Medication"],
9492
+ attribute_template_ids: ["attr_active_ingredient", "attr_dosage"],
9493
+ created_at: ISO9,
9494
+ updated_at: ISO9
9495
+ };
9496
+ registry.taxonomies.put(medication.id, medication);
9497
+ const attrs = [
9498
+ {
9499
+ id: "attr_active_ingredient",
9500
+ business_id: businessId,
9501
+ namespace: "core",
9502
+ name: "Active ingredient",
9503
+ slug: "active-ingredient",
9504
+ attribute_type: "text",
9505
+ is_required: false,
9506
+ is_filterable: true,
9507
+ visibility: "public",
9508
+ display_order: 0,
9509
+ applies_to: "product",
9510
+ created_at: ISO9,
9511
+ updated_at: ISO9
9512
+ },
9513
+ {
9514
+ id: "attr_dosage",
9515
+ business_id: businessId,
9516
+ namespace: "core",
9517
+ name: "Dosage form",
9518
+ slug: "dosage-form",
9519
+ attribute_type: "select",
9520
+ options: ["tablet", "capsule", "syrup", "spray", "cream", "drops"],
9521
+ is_required: false,
9522
+ is_filterable: true,
9523
+ visibility: "public",
9524
+ display_order: 1,
9525
+ applies_to: "product",
9526
+ created_at: ISO9,
9527
+ updated_at: ISO9
9528
+ },
9529
+ {
9530
+ id: "attr_prescription_required",
9531
+ business_id: businessId,
9532
+ namespace: "core",
9533
+ name: "Prescription required",
9534
+ slug: "prescription-required",
9535
+ attribute_type: "boolean",
9536
+ is_required: false,
9537
+ is_filterable: true,
9538
+ visibility: "public",
9539
+ display_order: 2,
9540
+ applies_to: "product",
9541
+ created_at: ISO9,
9542
+ updated_at: ISO9
9543
+ }
9544
+ ];
9545
+ for (const a of attrs) registry.attributeDefs.put(a.id, a);
9546
+ const articles = [
9547
+ {
9548
+ id: "kb_prescription",
9549
+ business_id: businessId,
9550
+ title: "Prescription handling",
9551
+ slug: "prescription-handling",
9552
+ content: "Upload prescriptions through the prescription-refill service. Our pharmacist verifies before dispensing; same-day pickup or delivery within Accra.",
9553
+ category: "logistics",
9554
+ tags: ["prescription", "delivery"],
9555
+ created_at: ISO9,
9556
+ updated_at: ISO9
9557
+ },
9558
+ {
9559
+ id: "kb_returns",
9560
+ business_id: businessId,
9561
+ title: "Returns & exchanges",
9562
+ slug: "returns",
9563
+ content: "Sealed OTC products may be returned within 7 days with receipt. Opened products, prescriptions, and refrigerated items are non-returnable for safety reasons.",
9564
+ category: "policies",
9565
+ tags: ["returns"],
9566
+ created_at: ISO9,
9567
+ updated_at: ISO9
9568
+ },
9569
+ {
9570
+ id: "kb_consultation",
9571
+ business_id: businessId,
9572
+ title: "Pharmacist consultations",
9573
+ slug: "consultations",
9574
+ content: "15-minute pharmacist appointments cover medication review, side-effect questions, OTC selection, and symptom triage. Book through the services menu.",
9575
+ category: "services",
9576
+ tags: ["consultation"],
9577
+ created_at: ISO9,
9578
+ updated_at: ISO9
9579
+ }
9580
+ ];
9581
+ for (const a of articles) registry.knowledgeArticles.put(a.id, a);
9582
+ return { businessId };
9583
+ }
9584
+
9146
9585
  // src/mock/seeds/registry.ts
9147
9586
  var SEEDS = {
9148
9587
  default: seedDefault,
@@ -9152,7 +9591,8 @@ var SEEDS = {
9152
9591
  retail: seedRetail,
9153
9592
  services: seedServices,
9154
9593
  grocery: seedGrocery,
9155
- fashion: seedFashion
9594
+ fashion: seedFashion,
9595
+ pharmacy: seedPharmacy
9156
9596
  };
9157
9597
  function applySeed(registry, name) {
9158
9598
  const fn = SEEDS[name];