@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/cli.mjs CHANGED
@@ -4488,6 +4488,10 @@ function toApiProduct(p, ctx) {
4488
4488
  duration_unit: p.duration_unit,
4489
4489
  duration_minutes: p.duration_minutes,
4490
4490
  billing_plans: p.billing_plans,
4491
+ /** Per-product customer inputs (prescription upload, consent
4492
+ * signature, etc.). The Rust backend emits this on ProductView; the
4493
+ * SDK's React components branch on its presence to render inputs. */
4494
+ input_fields: p.input_fields ?? [],
4491
4495
  created_at: p.created_at,
4492
4496
  updated_at: p.updated_at,
4493
4497
  metadata: {
@@ -6379,8 +6383,8 @@ function createLinkService({ clock, ids }) {
6379
6383
 
6380
6384
  // src/mock/seeds/image.ts
6381
6385
  var CDN_BASE_URL = "https://static-tmp.cimplify.io";
6382
- function seedImage(industry, photoId) {
6383
- return `${CDN_BASE_URL}/seed/${industry}/${photoId}.jpg`;
6386
+ function seedImage(industry, slug) {
6387
+ return `${CDN_BASE_URL}/seed/${industry}/${slug}.jpg`;
6384
6388
  }
6385
6389
 
6386
6390
  // src/mock/seeds/default.ts
@@ -6443,7 +6447,7 @@ function seedDefault(registry) {
6443
6447
  default_address: "12 Independence Ave, Accra",
6444
6448
  default_offers_table_service: true,
6445
6449
  default_accepts_online_orders: true,
6446
- image: img("1568254183919-78a4f43a2877"),
6450
+ image: img("business-hero"),
6447
6451
  status: "active",
6448
6452
  created_at: ISO,
6449
6453
  updated_at: ISO,
@@ -6498,8 +6502,8 @@ function seedDefault(registry) {
6498
6502
  price: "25.00",
6499
6503
  description: "24-hour fermented country loaf with our heritage starter \u2014 open crumb, blistered crust, naturally tangy. Baked fresh every morning.",
6500
6504
  category: "breads",
6501
- imageUrl: img("1509440159596-0249088772ff"),
6502
- images: [img("1509440159596-0249088772ff"), img("1486887396153-fa416526c108")],
6505
+ imageUrl: img("sourdough-loaf"),
6506
+ images: [img("sourdough-loaf"), img("whole-wheat")],
6503
6507
  tags: ["bread", "vegan", "signature"],
6504
6508
  isSignature: true,
6505
6509
  ingredients: ["Wheat flour", "Sourdough starter", "Sea salt", "Filtered water"],
@@ -6514,7 +6518,7 @@ function seedDefault(registry) {
6514
6518
  price: "20.00",
6515
6519
  description: "Hearty 100% whole wheat with sunflower, sesame, and pumpkin seeds. Slow-fermented for a soft crumb and nutty depth.",
6516
6520
  category: "breads",
6517
- imageUrl: img("1486887396153-fa416526c108"),
6521
+ imageUrl: img("whole-wheat"),
6518
6522
  tags: ["bread", "vegan", "high-fibre"],
6519
6523
  ingredients: ["Whole wheat flour", "Sunflower seeds", "Sesame", "Pumpkin seeds"],
6520
6524
  allergies: ["wheat", "gluten", "sesame"],
@@ -6527,7 +6531,7 @@ function seedDefault(registry) {
6527
6531
  price: "15.00",
6528
6532
  description: "Crackling crust, airy crumb. Best eaten warm, within an hour of baking.",
6529
6533
  category: "breads",
6530
- imageUrl: img("1568471173242-461f0a730452"),
6534
+ imageUrl: img("baguette"),
6531
6535
  tags: ["bread", "vegan"],
6532
6536
  ingredients: ["Wheat flour", "Yeast", "Sea salt", "Water"],
6533
6537
  allergies: ["wheat", "gluten"],
@@ -6540,7 +6544,7 @@ function seedDefault(registry) {
6540
6544
  price: "30.00",
6541
6545
  description: "High-hydration focaccia drenched in olive oil, scattered with sea salt and fresh rosemary. Sold whole or by the slab.",
6542
6546
  category: "breads",
6543
- imageUrl: img("1571167530149-c1105da4c2c7"),
6547
+ imageUrl: img("focaccia"),
6544
6548
  tags: ["bread", "vegetarian"],
6545
6549
  ingredients: ["00 flour", "Olive oil", "Rosemary", "Maldon salt"],
6546
6550
  pairings: ["Burrata", "Prosciutto", "Caponata"],
@@ -6554,7 +6558,7 @@ function seedDefault(registry) {
6554
6558
  price: "18.00",
6555
6559
  description: "Caramelised brown butter, three over-ripe bananas, walnuts, finished with a salted maple glaze.",
6556
6560
  category: "breads",
6557
- imageUrl: img("1632931057819-4eefffa8e007"),
6561
+ imageUrl: img("banana-bread"),
6558
6562
  tags: ["sweet", "comfort"],
6559
6563
  ingredients: ["Bananas", "Brown butter", "Walnuts", "Maple syrup"],
6560
6564
  allergies: ["wheat", "gluten", "dairy", "nuts", "eggs"],
@@ -6569,8 +6573,8 @@ function seedDefault(registry) {
6569
6573
  price: "12.00",
6570
6574
  description: "27 layers of laminated dough wrapped around French butter. Crisp, shattering crust and a tender honeycomb interior.",
6571
6575
  category: "pastries",
6572
- imageUrl: img("1555507036-ab1f4038808a"),
6573
- images: [img("1555507036-ab1f4038808a"), img("1530610476181-d83430b64dcd")],
6576
+ imageUrl: img("croissant"),
6577
+ images: [img("croissant"), img("pain-au-chocolat")],
6574
6578
  tags: ["pastry", "vegetarian", "signature"],
6575
6579
  isSignature: true,
6576
6580
  ingredients: ["French butter", "Wheat flour", "Milk", "Eggs"],
@@ -6584,7 +6588,7 @@ function seedDefault(registry) {
6584
6588
  price: "14.00",
6585
6589
  description: "Our croissant dough wrapped around two batons of 70% Valrhona dark chocolate.",
6586
6590
  category: "pastries",
6587
- imageUrl: img("1530610476181-d83430b64dcd"),
6591
+ imageUrl: img("pain-au-chocolat"),
6588
6592
  tags: ["pastry", "chocolate"],
6589
6593
  ingredients: ["Croissant dough", "Valrhona chocolate"],
6590
6594
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6597,7 +6601,7 @@ function seedDefault(registry) {
6597
6601
  price: "16.00",
6598
6602
  description: "Flaky pastry filled with almond cream, dusted with toasted slivers and powdered sugar.",
6599
6603
  category: "pastries",
6600
- imageUrl: img("1517433367423-c7e5b0f35086"),
6604
+ imageUrl: img("almond-danish"),
6601
6605
  tags: ["pastry", "nuts"],
6602
6606
  ingredients: ["Pastry dough", "Almond cream", "Toasted almonds"],
6603
6607
  allergies: ["wheat", "gluten", "dairy", "eggs", "nuts"],
@@ -6610,7 +6614,7 @@ function seedDefault(registry) {
6610
6614
  price: "13.00",
6611
6615
  description: "Soft enriched dough swirled with butter and Ceylon cinnamon, finished with cream-cheese glaze.",
6612
6616
  category: "pastries",
6613
- imageUrl: img("1607920591413-4ec007e70023"),
6617
+ imageUrl: img("cinnamon-roll"),
6614
6618
  tags: ["pastry", "comfort"],
6615
6619
  ingredients: ["Enriched dough", "Cinnamon", "Brown sugar", "Cream cheese"],
6616
6620
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6623,7 +6627,7 @@ function seedDefault(registry) {
6623
6627
  price: "12.00",
6624
6628
  description: "Dark, dense, fudgy brownie with a glossy shell. Chocolate four ways. Best slightly warm.",
6625
6629
  category: "pastries",
6626
- imageUrl: img("1606313564200-e75d5e30476c"),
6630
+ imageUrl: img("brownie"),
6627
6631
  tags: ["chocolate", "vegetarian"],
6628
6632
  ingredients: ["Dark chocolate", "Cocoa", "Brown butter", "Eggs"],
6629
6633
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6636,7 +6640,7 @@ function seedDefault(registry) {
6636
6640
  price: "60.00",
6637
6641
  description: "Six French macarons \u2014 pistachio, raspberry, salted caramel, espresso, vanilla bean, and dark chocolate ganache.",
6638
6642
  category: "pastries",
6639
- imageUrl: img("1558326567-98ae2405596b"),
6643
+ imageUrl: img("macaron-box"),
6640
6644
  tags: ["pastry", "gift", "premium"],
6641
6645
  ingredients: ["Almond flour", "Egg whites", "Sugar", "Various fillings"],
6642
6646
  allergies: ["nuts", "eggs", "dairy"],
@@ -6650,7 +6654,7 @@ function seedDefault(registry) {
6650
6654
  price: "22.00",
6651
6655
  description: "Three layers of dark chocolate sponge with chocolate ganache and cr\xE8me p\xE2tissi\xE8re, finished with a mirror glaze. (Slice)",
6652
6656
  category: "cakes",
6653
- imageUrl: img("1565958011703-44f9829ba187"),
6657
+ imageUrl: img("chocolate-cake"),
6654
6658
  tags: ["cake", "chocolate", "signature"],
6655
6659
  isSignature: true,
6656
6660
  ingredients: ["Dark chocolate", "Cr\xE8me p\xE2tissi\xE8re", "Cocoa", "Eggs"],
@@ -6665,7 +6669,7 @@ function seedDefault(registry) {
6665
6669
  price: "22.00",
6666
6670
  description: "Classic red velvet with cream cheese frosting and white chocolate shavings.",
6667
6671
  category: "cakes",
6668
- imageUrl: img("1586788680434-30d324b2d46f"),
6672
+ imageUrl: img("red-velvet"),
6669
6673
  tags: ["cake"],
6670
6674
  ingredients: ["Buttermilk", "Cocoa", "Cream cheese", "Beetroot"],
6671
6675
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6678,7 +6682,7 @@ function seedDefault(registry) {
6678
6682
  price: "20.00",
6679
6683
  description: "Spiced carrot cake with toasted walnuts, golden raisins, and cream-cheese frosting.",
6680
6684
  category: "cakes",
6681
- imageUrl: img("1568827999250-3f6afff96e66"),
6685
+ imageUrl: img("carrot-cake"),
6682
6686
  tags: ["cake", "spiced"],
6683
6687
  ingredients: ["Carrot", "Walnuts", "Cinnamon", "Cream cheese"],
6684
6688
  allergies: ["wheat", "gluten", "dairy", "eggs", "nuts"],
@@ -6691,7 +6695,7 @@ function seedDefault(registry) {
6691
6695
  price: "24.00",
6692
6696
  description: "Dense, creamy New York cheesecake on a butter graham crust. Topped with seasonal berry compote.",
6693
6697
  category: "cakes",
6694
- imageUrl: img("1567306226416-28f0efdc88ce"),
6698
+ imageUrl: img("cheesecake"),
6695
6699
  tags: ["cake", "premium"],
6696
6700
  ingredients: ["Cream cheese", "Sour cream", "Graham crust", "Vanilla"],
6697
6701
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6704,8 +6708,8 @@ function seedDefault(registry) {
6704
6708
  price: "250.00",
6705
6709
  description: "Made-to-order three-tier cake. Choose size, flavour, and frosting. 48-hour notice required for personalisation.",
6706
6710
  category: "cakes",
6707
- imageUrl: img("1535254973040-607b474cb50d"),
6708
- images: [img("1535254973040-607b474cb50d"), img("1565958011703-44f9829ba187")],
6711
+ imageUrl: img("birthday-cake"),
6712
+ images: [img("birthday-cake"), img("chocolate-cake")],
6709
6713
  tags: ["cake", "made-to-order", "premium"],
6710
6714
  ingredients: ["Sponge cake", "Buttercream", "Custom decoration"],
6711
6715
  allergies: ["wheat", "gluten", "dairy", "eggs"],
@@ -6719,7 +6723,7 @@ function seedDefault(registry) {
6719
6723
  price: "10.00",
6720
6724
  description: "Locally roasted Arabica from Volta Region. Notes of cocoa, dark fruit, and brown sugar.",
6721
6725
  category: "drinks",
6722
- imageUrl: img("1495474472287-4d71bcdd2085"),
6726
+ imageUrl: img("coffee"),
6723
6727
  tags: ["drink", "coffee", "vegan"],
6724
6728
  ingredients: ["Single-origin Arabica beans"],
6725
6729
  pairings: ["Croissant", "Brownie"],
@@ -6732,7 +6736,7 @@ function seedDefault(registry) {
6732
6736
  price: "8.00",
6733
6737
  description: "Choice of English breakfast, Earl Grey, green sencha, or chamomile.",
6734
6738
  category: "drinks",
6735
- imageUrl: img("1576092768241-dec231879fc3"),
6739
+ imageUrl: img("tea"),
6736
6740
  tags: ["drink", "tea", "vegan"],
6737
6741
  calories: 0
6738
6742
  },
@@ -6743,7 +6747,7 @@ function seedDefault(registry) {
6743
6747
  price: "12.00",
6744
6748
  description: "Iced hibiscus tea with ginger, pineapple peel, and a hint of clove. Tart, refreshing, lightly sweet.",
6745
6749
  category: "drinks",
6746
- imageUrl: img("1556679343-c7306c1976bc"),
6750
+ imageUrl: img("sobolo"),
6747
6751
  tags: ["drink", "vegan", "ghana"],
6748
6752
  isSignature: true,
6749
6753
  ingredients: ["Hibiscus", "Ginger", "Pineapple", "Clove"],
@@ -6756,7 +6760,7 @@ function seedDefault(registry) {
6756
6760
  price: "15.00",
6757
6761
  description: "Hand-pressed at sunrise from Ghanaian Valencia oranges. No sugar, no concentrate.",
6758
6762
  category: "drinks",
6759
- imageUrl: img("1622597467836-f3285f2131b8"),
6763
+ imageUrl: img("orange-juice"),
6760
6764
  tags: ["drink", "vegan"],
6761
6765
  calories: 110
6762
6766
  },
@@ -6768,8 +6772,8 @@ function seedDefault(registry) {
6768
6772
  price: "30.00",
6769
6773
  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.",
6770
6774
  category: "boxes",
6771
- imageUrl: img("1533089860892-a7c6f0a88666"),
6772
- images: [img("1533089860892-a7c6f0a88666"), img("1495474472287-4d71bcdd2085")],
6775
+ imageUrl: img("breakfast-box"),
6776
+ images: [img("breakfast-box"), img("coffee")],
6773
6777
  tags: ["bundle", "breakfast"],
6774
6778
  productType: "bundle"
6775
6779
  },
@@ -6780,7 +6784,7 @@ function seedDefault(registry) {
6780
6784
  price: "60.00",
6781
6785
  description: "Pick 6 to 12 of our pastries \u2014 mix and match. Freshly boxed for sharing.",
6782
6786
  category: "boxes",
6783
- imageUrl: img("1486427944299-d1955d23e34d"),
6787
+ imageUrl: img("pastry-box"),
6784
6788
  tags: ["composite", "build-your-own", "gift"],
6785
6789
  productType: "composite"
6786
6790
  },
@@ -6792,7 +6796,7 @@ function seedDefault(registry) {
6792
6796
  price: "85.00",
6793
6797
  description: "Heavy-weight cotton-canvas apron with leather neck strap, embroidered logo, and two front pockets. Made in Accra.",
6794
6798
  category: "merch",
6795
- imageUrl: img("1556905055-8f358a7a47b2"),
6799
+ imageUrl: img("apron"),
6796
6800
  tags: ["merch", "physical"],
6797
6801
  renderHint: "physical"
6798
6802
  },
@@ -6803,7 +6807,7 @@ function seedDefault(registry) {
6803
6807
  price: "35.00",
6804
6808
  description: "12oz natural canvas tote, screen-printed with our wheat-stalk crest. Roomy enough for two loaves.",
6805
6809
  category: "merch",
6806
- imageUrl: img("1591561954557-26941169b49e"),
6810
+ imageUrl: img("tote-bag"),
6807
6811
  tags: ["merch", "physical", "gift"],
6808
6812
  renderHint: "physical",
6809
6813
  isNew: true
@@ -6816,7 +6820,7 @@ function seedDefault(registry) {
6816
6820
  price: "320.00",
6817
6821
  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.",
6818
6822
  category: "merch",
6819
- imageUrl: img("1568254183919-78a4f43a2877"),
6823
+ imageUrl: img("flour-25kg"),
6820
6824
  tags: ["wholesale", "physical", "trade"],
6821
6825
  renderHint: "physical",
6822
6826
  quantityPricing: [
@@ -6834,7 +6838,7 @@ function seedDefault(registry) {
6834
6838
  price: "45.00",
6835
6839
  description: "PDF + EPUB walkthrough of our sourdough programme \u2014 starter, levain, autolyse, bulk fermentation, shaping, scoring. Lifetime updates.",
6836
6840
  category: "merch",
6837
- imageUrl: img("1543002588-bfa74002ed7e"),
6841
+ imageUrl: img("sourdough-ebook"),
6838
6842
  tags: ["digital", "download"],
6839
6843
  productType: "digital",
6840
6844
  digitalProductType: "download"
@@ -6846,7 +6850,7 @@ function seedDefault(registry) {
6846
6850
  price: "100.00",
6847
6851
  description: "Send instantly. Redeemable in-store and online toward any product. Choose any amount from GH\u20B550 upward.",
6848
6852
  category: "merch",
6849
- imageUrl: img("1556905055-8f358a7a47b2"),
6853
+ imageUrl: img("gift-card"),
6850
6854
  tags: ["digital", "gift"],
6851
6855
  productType: "digital",
6852
6856
  digitalProductType: "gift_code",
@@ -6860,7 +6864,7 @@ function seedDefault(registry) {
6860
6864
  price: "320.00",
6861
6865
  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.",
6862
6866
  category: "classes",
6863
- imageUrl: img("1517686469429-8bdb88b9f907"),
6867
+ imageUrl: img("baking-class"),
6864
6868
  tags: ["class", "service", "hands-on"],
6865
6869
  productType: "service",
6866
6870
  durationMinutes: 120
@@ -6872,7 +6876,7 @@ function seedDefault(registry) {
6872
6876
  price: "480.00",
6873
6877
  description: "Three-hour deep-dive on laminated dough. We cover croissants, danishes, kouign-amann. Aprons supplied; pastries to take home.",
6874
6878
  category: "classes",
6875
- imageUrl: img("1517433367423-c7e5b0f35086"),
6879
+ imageUrl: img("pastry-workshop"),
6876
6880
  tags: ["class", "service", "advanced"],
6877
6881
  productType: "service",
6878
6882
  durationMinutes: 180,
@@ -6886,7 +6890,7 @@ function seedDefault(registry) {
6886
6890
  price: "180.00",
6887
6891
  description: "Rent our commercial bakery after hours. Deck oven, retarder-proofer, mixers, scales \u2014 bring your team or shoot your content. Hourly.",
6888
6892
  category: "classes",
6889
- imageUrl: img("1606755962773-d324e0a13086"),
6893
+ imageUrl: img("kitchen-rental"),
6890
6894
  tags: ["rental", "service", "commercial"],
6891
6895
  productType: "service",
6892
6896
  durationUnit: "hours"
@@ -6899,7 +6903,7 @@ function seedDefault(registry) {
6899
6903
  price: "650.00",
6900
6904
  description: "One-bedroom loft above the bakery. Wakes up to fresh croissants, ends with a private dinner. Ghana Tourism-licensed. Per night.",
6901
6905
  category: "classes",
6902
- imageUrl: img("1564013799919-ab600027ffc6"),
6906
+ imageUrl: img("loft-stay"),
6903
6907
  tags: ["stay", "service", "premium"],
6904
6908
  productType: "service",
6905
6909
  durationUnit: "nights"
@@ -6912,7 +6916,7 @@ function seedDefault(registry) {
6912
6916
  price: "0.00",
6913
6917
  description: "A fresh loaf delivered to your door every week. Pause or skip any time. Choose monthly or quarterly billing for a discount.",
6914
6918
  category: "classes",
6915
- imageUrl: img("1509440159596-0249088772ff"),
6919
+ imageUrl: img("loaf-subscription"),
6916
6920
  tags: ["subscription", "service", "delivery"],
6917
6921
  productType: "service",
6918
6922
  billingPlans: [
@@ -7740,31 +7744,7 @@ function seedReesa(registry) {
7740
7744
 
7741
7745
  // src/mock/seeds/restaurant.ts
7742
7746
  var ISO4 = "2026-01-01T00:00:00.000Z";
7743
- var PHOTO = {
7744
- "business-hero": "1414235077428-338989a2e8c0",
7745
- kelewele: "1599487488170-d11ec9c172f0",
7746
- "spring-rolls": "1559339352-11d035aa65de",
7747
- "soup-of-the-day": "1547592180-85f173990554",
7748
- "jollof-rice": "1546069901-d5bfd2cbfb1f",
7749
- "banku-tilapia": "1485921325833-c519f76c4927",
7750
- "fufu-light-soup": "1602253057119-44d745d9b860",
7751
- waakye: "1565299624946-b28f40a0ae38",
7752
- "grilled-chicken": "1598103442097-8b74394b95c6",
7753
- burger: "1568901346375-23c9450c58cd",
7754
- "yam-fries": "1576107232684-1279f390859f",
7755
- "fried-plantain": "1493770348161-369560ae357d",
7756
- salad: "1512621776951-a57141f2eefd",
7757
- "ice-cream": "1488900128323-21503983a07e",
7758
- "cake-slice": "1565958011703-44f9829ba187",
7759
- "fruit-bowl": "1490474418585-ba9bad8fd0ea",
7760
- "soft-drink": "1581636625402-29b2a704ef13",
7761
- sobolo: "1556679343-c7306c1976bc",
7762
- "fresh-juice": "1610970881699-44a5587cabec",
7763
- water: "1564325724739-bae0bd08762c",
7764
- feast: "1559847844-5315695dadae",
7765
- byo: "1551782450-a2132b4ba21d"
7766
- };
7767
- var photoFor = (slug) => seedImage("restaurant", PHOTO[slug] ?? "1414235077428-338989a2e8c0");
7747
+ var photoFor = (slug) => seedImage("restaurant", slug);
7768
7748
  function seedRestaurant(registry) {
7769
7749
  const businessId = "bus_mamas_kitchen";
7770
7750
  const business = {
@@ -8224,29 +8204,7 @@ function seedRestaurant(registry) {
8224
8204
 
8225
8205
  // src/mock/seeds/retail.ts
8226
8206
  var ISO5 = "2026-01-01T00:00:00.000Z";
8227
- var PHOTO2 = {
8228
- "android-flagship": "1592750475338-74b7b21085ab",
8229
- "android-mid": "1511707171634-5f897ff02aa9",
8230
- "phone-budget": "1574944985070-8f3ebc6b79d2",
8231
- "laptop-pro": "1517336714731-489689fd1ca8",
8232
- "laptop-air": "1496181133206-80ce9b88a853",
8233
- "laptop-budget": "1601784551446-20c9e07cdbdb",
8234
- "headphones-anc": "1505740420928-5e560c06d30e",
8235
- "earbuds-pro": "1572569511254-d8f925fe2cbb",
8236
- "speaker-bt": "1612287230202-1ff1d85d1bdf",
8237
- "phone-case": "1611532736597-de2d4265fba3",
8238
- "screen-protector": "1568952433726-3896e3881c65",
8239
- "fast-charger": "1620794108219-aedbaded4eea",
8240
- "laptop-sleeve": "1604671801908-6f0c6a092c05",
8241
- "wireless-mouse": "1594732832278-abd644401426",
8242
- "mech-keyboard": "1583394838336-acd977736f90",
8243
- "gaming-controller": "1542751371-adc38448a05e",
8244
- "gaming-headset": "1606220945770-b5b6c2c55bf1",
8245
- "console-handheld": "1593642634524-b40b5baae6bb",
8246
- wfh: "1605236453806-6ff36851218e",
8247
- "game-pack": "1606144042614-b2417e99c4e3"
8248
- };
8249
- var photoFor2 = (slug) => seedImage("retail", PHOTO2[slug] ?? "1517336714731-489689fd1ca8");
8207
+ var photoFor2 = (slug) => seedImage("retail", slug);
8250
8208
  function seedRetail(registry) {
8251
8209
  const businessId = "bus_currents_electronics";
8252
8210
  const business = {
@@ -8719,29 +8677,7 @@ function seedRetail(registry) {
8719
8677
 
8720
8678
  // src/mock/seeds/services.ts
8721
8679
  var ISO6 = "2026-01-01T00:00:00.000Z";
8722
- var PHOTO3 = {
8723
- "business-hero": "1540555700478-4be289fbecef",
8724
- "swedish-massage-60": "1544161515-4ab6ce6db874",
8725
- "swedish-massage-90": "1519823551278-64ac92734fb1",
8726
- "deep-tissue-60": "1571019613454-1cb2f99b2d8b",
8727
- "couples-massage": "1591343395082-e120087004b4",
8728
- "hot-stone-90": "1620733723572-11c53f73a416",
8729
- "facial-classic": "1487412947147-5cebf100ffc2",
8730
- "facial-anti-aging": "1487412947147-5cebf100ffc2",
8731
- "facial-acne": "1556228720-195a672e8a03",
8732
- manicure: "1604654894610-df63bc536371",
8733
- pedicure: "1519415943484-9fa1873496d4",
8734
- "gel-manicure": "1607779097040-26e80aa78e66",
8735
- haircut: "1622286342621-4bd786c2447c",
8736
- "hair-treatment": "1633681926022-84c23e8cb2d6",
8737
- color: "1560066984-138dadb4c035",
8738
- "yoga-session": "1545205597-3d9d02c29597",
8739
- meditation: "1506126613408-eca07ce68773",
8740
- "spa-day": "1571019613454-1cb2f99b2d8b",
8741
- couples: "1591343395082-e120087004b4",
8742
- custom: "1540555700478-4be289fbecef"
8743
- };
8744
- var photoFor3 = (slug) => seedImage("services", PHOTO3[slug] ?? "1540555700478-4be289fbecef");
8680
+ var photoFor3 = (slug) => seedImage("services", slug);
8745
8681
  function seedServices(registry) {
8746
8682
  const businessId = "bus_serene_spa";
8747
8683
  const business = {
@@ -9121,35 +9057,7 @@ function seedServices(registry) {
9121
9057
 
9122
9058
  // src/mock/seeds/grocery.ts
9123
9059
  var ISO7 = "2026-01-01T00:00:00.000Z";
9124
- var PHOTO4 = {
9125
- "business-hero": "1542838132-92c53300491e",
9126
- "tomatoes-1kg": "1592924357228-91a4daadcfea",
9127
- "onions-1kg": "1620574387735-3624d75b2dbc",
9128
- "ginger-200g": "1594631252845-29fc4cc8cde9",
9129
- "bananas-bunch": "1571771019784-3ff35f4f4277",
9130
- pineapple: "1550258987-190a2d41a8ba",
9131
- "spinach-bunch": "1576045057995-568f588f82fb",
9132
- "milk-1l": "1563636619-e9143da7973b",
9133
- "yogurt-500g": "1488477181946-6428a0291777",
9134
- "eggs-12": "1582722872445-44dc5f7e3c8f",
9135
- "cheese-200g": "1486297678162-eb2a19b0a32d",
9136
- "chicken-1kg": "1604503468506-a8da13d82791",
9137
- "beef-mince-500g": "1607623814075-e51df1bdc82f",
9138
- "tilapia-each": "1535473895227-bdecb20fb157",
9139
- "rice-5kg": "1586201375761-83865001e31c",
9140
- "garri-2kg": "1582284540020-8acbe03f4924",
9141
- "palm-oil-1l": "1611078489935-0cb964de46d6",
9142
- "vegetable-oil-1l": "1474979266404-7eaacbcd87c5",
9143
- "salt-1kg": "1607301406259-dfb186e15de8",
9144
- "sugar-1kg": "1610725664285-7c57e6eeac3f",
9145
- "tomato-paste": "1561136594-7f68413baa99",
9146
- "soap-bar": "1600857062241-98e5dba7f214",
9147
- "detergent-1kg": "1582735689369-4fe89db7114c",
9148
- "tissue-pack": "1583947215259-38e31be8751f",
9149
- "trash-bags": "1605600659908-0ef719419d41",
9150
- essentials: "1542838132-92c53300491e"
9151
- };
9152
- var photoFor4 = (slug) => seedImage("grocery", PHOTO4[slug] ?? "1542838132-92c53300491e");
9060
+ var photoFor4 = (slug) => seedImage("grocery", slug);
9153
9061
  function seedGrocery(registry) {
9154
9062
  const businessId = "bus_freshmart";
9155
9063
  const business = {
@@ -9412,23 +9320,7 @@ function seedGrocery(registry) {
9412
9320
 
9413
9321
  // src/mock/seeds/fashion.ts
9414
9322
  var ISO8 = "2026-01-01T00:00:00.000Z";
9415
- var PHOTO5 = {
9416
- "heavyweight-hoodie-charcoal": "1556905055-8f358a7a47b2",
9417
- "heavyweight-hoodie-cream": "1576566588028-4147f3842f27",
9418
- "heavyweight-hoodie-cobalt": "1542838686-37da4a9fd1b3",
9419
- "studio-tee-black": "1521572163474-6864f9cf17ab",
9420
- "studio-tee-natural": "1485518882345-15568b007407",
9421
- "graphic-tee-frx-mark": "1521223890158-f9f7c3d5d504",
9422
- "carbon-bomber": "1591047139829-d91aecb6caea",
9423
- "field-jacket-olive": "1564859228273-274232fdb516",
9424
- "wide-leg-trouser": "1542272604-787c3835535d",
9425
- "track-pant-charcoal": "1604176354204-9268737828e4",
9426
- "studio-cap": "1620799140408-edc6dcb6d633",
9427
- "tote-natural": "1591195853828-11db59a44f6b",
9428
- "knit-beanie": "1542838132-92c53300491e",
9429
- "studio-sock-3pack": "1602810318383-e386cc2a3ccf"
9430
- };
9431
- var photoFor5 = (slug) => seedImage("fashion", PHOTO5[slug] ?? "1556905055-8f358a7a47b2");
9323
+ var photoFor5 = (slug) => seedImage("fashion", slug);
9432
9324
  var SIZES = ["XS", "S", "M", "L", "XL", "2XL"];
9433
9325
  function seedFashion(registry) {
9434
9326
  const businessId = "bus_studio_frx";
@@ -9443,7 +9335,7 @@ function seedFashion(registry) {
9443
9335
  default_address: "Osu Oxford Street, Accra",
9444
9336
  default_offers_table_service: false,
9445
9337
  default_accepts_online_orders: true,
9446
- image: seedImage("fashion", "1490481651871-ab68de25d43d"),
9338
+ image: seedImage("fashion", "business-hero"),
9447
9339
  status: "active",
9448
9340
  created_at: ISO8,
9449
9341
  updated_at: ISO8,
@@ -9845,6 +9737,553 @@ function seedFashion(registry) {
9845
9737
  return { businessId };
9846
9738
  }
9847
9739
 
9740
+ // src/mock/seeds/pharmacy.ts
9741
+ var ISO9 = "2026-01-01T00:00:00.000Z";
9742
+ var photoFor6 = (slug) => seedImage("pharmacy", slug);
9743
+ function seedPharmacy(registry) {
9744
+ const businessId = "bus_wellspring_pharmacy";
9745
+ const business = {
9746
+ id: businessId,
9747
+ name: "Wellspring Pharmacy",
9748
+ handle: "wellspring",
9749
+ business_type: "retail",
9750
+ email: "care@wellspringpharmacy.test",
9751
+ default_currency: "GHS",
9752
+ default_phone: "+233244778899",
9753
+ default_address: "5 Liberation Road, Ridge, Accra",
9754
+ default_offers_table_service: false,
9755
+ default_accepts_online_orders: true,
9756
+ image: photoFor6("business-hero"),
9757
+ status: "active",
9758
+ created_at: ISO9,
9759
+ updated_at: ISO9,
9760
+ created_by: "seed",
9761
+ preferences: {
9762
+ theme: "clinical",
9763
+ tagline: "Trusted care, delivered same-day",
9764
+ checkout: { allow_guest: true }
9765
+ },
9766
+ is_online_only: false,
9767
+ enabled_payment_types: ["card", "mobile_money", "cash"],
9768
+ default_location_settings: {},
9769
+ country_code: "GH",
9770
+ timezone: "Africa/Accra"
9771
+ };
9772
+ registry.businesses.put(businessId, business);
9773
+ const categories = [
9774
+ { slug: "pain-relief", name: "Pain Relief" },
9775
+ { slug: "cold-flu", name: "Cold & Flu" },
9776
+ { slug: "vitamins", name: "Vitamins & Supplements" },
9777
+ { slug: "first-aid", name: "First Aid" },
9778
+ { slug: "personal-care", name: "Personal Care" },
9779
+ { slug: "devices", name: "Medical Devices" },
9780
+ { slug: "baby", name: "Baby & Mother" }
9781
+ ];
9782
+ const catIds = /* @__PURE__ */ new Map();
9783
+ for (const c of categories) {
9784
+ const id = `cat_${c.slug}`;
9785
+ catIds.set(c.slug, id);
9786
+ const cat = {
9787
+ id,
9788
+ business_id: businessId,
9789
+ name: c.name,
9790
+ slug: c.slug,
9791
+ description: `Wellspring \u2014 ${c.name}`,
9792
+ product_ids: [],
9793
+ display_order: 0,
9794
+ is_active: true,
9795
+ created_at: ISO9,
9796
+ updated_at: ISO9
9797
+ };
9798
+ registry.categories.put(id, cat);
9799
+ }
9800
+ function field(productSlug, f) {
9801
+ return {
9802
+ id: f.id ?? `fld_${productSlug}_${f.slug}`,
9803
+ product_id: `prod_${productSlug}`,
9804
+ ...f
9805
+ };
9806
+ }
9807
+ const products = [
9808
+ // Pain Relief
9809
+ {
9810
+ slug: "paracetamol",
9811
+ name: "Paracetamol 500mg (24 tablets)",
9812
+ price: "12.00",
9813
+ category: "pain-relief",
9814
+ description: "Fever and mild-to-moderate pain. Adults and children over 12.",
9815
+ tags: ["otc", "analgesic"],
9816
+ inputs: [
9817
+ field("paracetamol", {
9818
+ slug: "age_confirmation",
9819
+ name: "Age confirmation",
9820
+ field_type: "checkbox",
9821
+ is_required: true,
9822
+ display_order: 0,
9823
+ help_text: "I confirm this product is for someone aged 12 or over."
9824
+ })
9825
+ ]
9826
+ },
9827
+ { 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"] },
9828
+ { 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"] },
9829
+ { slug: "allergy-relief", name: "Cetirizine 10mg (10 tablets)", price: "22.00", category: "pain-relief", description: "Non-drowsy antihistamine for seasonal allergies.", tags: ["otc", "antihistamine"] },
9830
+ // Cold & Flu
9831
+ { 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"] },
9832
+ { slug: "throat-lozenges", name: "Honey-Lemon Throat Lozenges (24)", price: "18.00", category: "cold-flu", description: "Soothes sore throat and irritation.", tags: ["otc", "lozenge"] },
9833
+ { slug: "decongestant", name: "Nasal Decongestant Spray (10ml)", price: "28.00", category: "cold-flu", description: "Fast-acting relief for blocked nasal passages.", tags: ["otc", "spray"] },
9834
+ // Vitamins & Supplements
9835
+ { 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"] },
9836
+ { slug: "vitamin-c", name: "Vitamin C 1000mg (90 tablets)", price: "65.00", category: "vitamins", description: "Immune-support antioxidant. Time-released.", tags: ["supplement", "immune"] },
9837
+ { 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"] },
9838
+ { 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"] },
9839
+ { slug: "probiotics", name: "Probiotic 10-Strain (30 capsules)", price: "95.00", category: "vitamins", description: "Digestive and immune support.", tags: ["supplement", "digestive"] },
9840
+ // First Aid
9841
+ { 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"] },
9842
+ { slug: "plasters", name: "Assorted Plasters (40 pack)", price: "22.00", category: "first-aid", description: "Waterproof adhesive bandages in five sizes.", tags: ["first-aid"] },
9843
+ { slug: "antiseptic", name: "Antiseptic Cream (30g)", price: "18.00", category: "first-aid", description: "For cuts, grazes, and minor skin infections.", tags: ["first-aid", "cream"] },
9844
+ { 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"] },
9845
+ // Personal Care
9846
+ { 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"] },
9847
+ { slug: "face-mask", name: "Surgical Face Masks (50 pack)", price: "45.00", category: "personal-care", description: "3-ply earloop masks. Disposable.", tags: ["hygiene", "ppe"] },
9848
+ { 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"] },
9849
+ // Medical Devices
9850
+ { slug: "thermometer", name: "Digital Thermometer", price: "65.00", category: "devices", description: "Fast oral / underarm reading in 10 seconds. Auto-shutoff.", tags: ["device", "essential"] },
9851
+ {
9852
+ slug: "blood-pressure-monitor",
9853
+ name: "Automatic BP Monitor",
9854
+ price: "320.00",
9855
+ category: "devices",
9856
+ description: "Upper-arm cuff with memory for two users. Irregular heartbeat detection.",
9857
+ tags: ["device", "premium"],
9858
+ inputs: [
9859
+ field("blood-pressure-monitor", {
9860
+ slug: "arm_size",
9861
+ name: "Arm circumference",
9862
+ field_type: "select",
9863
+ options: ["Standard (22\u201332 cm)", "Large (32\u201342 cm)"],
9864
+ is_required: true,
9865
+ display_order: 0,
9866
+ help_text: "Pick the cuff that fits \u2014 wrong size gives inaccurate readings."
9867
+ })
9868
+ ]
9869
+ },
9870
+ { 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"] },
9871
+ { slug: "pulse-oximeter", name: "Fingertip Pulse Oximeter", price: "145.00", category: "devices", description: "SpO2 + heart-rate reading in under 10 seconds.", tags: ["device"] },
9872
+ // Baby & Mother
9873
+ {
9874
+ slug: "baby-formula",
9875
+ name: "Infant Formula Stage 1 (400g)",
9876
+ price: "150.00",
9877
+ category: "baby",
9878
+ description: "0\u20136 months. Iron-fortified, with prebiotics.",
9879
+ tags: ["baby", "nutrition"],
9880
+ inputs: [
9881
+ field("baby-formula", {
9882
+ slug: "baby_dob",
9883
+ name: "Baby's date of birth",
9884
+ field_type: "date",
9885
+ is_required: true,
9886
+ display_order: 0,
9887
+ help_text: "Confirms stage 1 is the right formula for your baby's age."
9888
+ }),
9889
+ field("baby-formula", {
9890
+ slug: "allergies",
9891
+ name: "Known allergies or intolerances",
9892
+ field_type: "textarea",
9893
+ is_required: false,
9894
+ display_order: 1,
9895
+ placeholder: "e.g. lactose, soy. Leave blank if none.",
9896
+ semantic_kind: "allergen"
9897
+ })
9898
+ ]
9899
+ },
9900
+ { slug: "baby-wipes", name: "Sensitive Baby Wipes (72 pack)", price: "28.00", category: "baby", description: "Alcohol-free, fragrance-free. Dermatologist-tested.", tags: ["baby", "hygiene"] },
9901
+ // ── Prescription medications (Rx; require a verified prescription) ─
9902
+ {
9903
+ slug: "amoxicillin-rx",
9904
+ name: "Amoxicillin 500mg (Rx)",
9905
+ price: "65.00",
9906
+ category: "pain-relief",
9907
+ description: "Broad-spectrum antibiotic. Prescription required \u2014 our pharmacist will verify before dispensing.",
9908
+ tags: ["prescription", "antibiotic"],
9909
+ requiresPrescription: true,
9910
+ inputs: [
9911
+ field("amoxicillin-rx", {
9912
+ slug: "prescription_upload",
9913
+ name: "Upload prescription",
9914
+ field_type: "file",
9915
+ is_required: true,
9916
+ display_order: 0,
9917
+ help_text: "PDF or photo of your doctor's prescription (max 10 MB).",
9918
+ validation: { accepted_formats: ["pdf", "jpg", "jpeg", "png", "heic"], max_size_mb: 10 }
9919
+ }),
9920
+ field("amoxicillin-rx", {
9921
+ slug: "patient_dob",
9922
+ name: "Patient date of birth",
9923
+ field_type: "date",
9924
+ is_required: true,
9925
+ display_order: 1
9926
+ }),
9927
+ field("amoxicillin-rx", {
9928
+ slug: "consent",
9929
+ name: "I confirm this prescription is genuine and issued for the named patient",
9930
+ field_type: "checkbox",
9931
+ is_required: true,
9932
+ display_order: 2,
9933
+ semantic_kind: "consent"
9934
+ })
9935
+ ]
9936
+ },
9937
+ {
9938
+ slug: "insulin-rx",
9939
+ name: "Insulin Glargine 100u/ml (Rx)",
9940
+ price: "240.00",
9941
+ category: "devices",
9942
+ description: "Long-acting basal insulin. Cold-chain delivery; prescription required.",
9943
+ tags: ["prescription", "diabetes", "cold-chain"],
9944
+ requiresPrescription: true,
9945
+ inputs: [
9946
+ field("insulin-rx", {
9947
+ slug: "prescription_upload",
9948
+ name: "Upload prescription",
9949
+ field_type: "file",
9950
+ is_required: true,
9951
+ display_order: 0,
9952
+ help_text: "PDF or photo of your doctor's prescription (max 10 MB).",
9953
+ validation: { accepted_formats: ["pdf", "jpg", "jpeg", "png", "heic"], max_size_mb: 10 }
9954
+ }),
9955
+ field("insulin-rx", {
9956
+ slug: "delivery_temp_acknowledgement",
9957
+ name: "I'll be available to receive a cold-chain delivery",
9958
+ field_type: "checkbox",
9959
+ is_required: true,
9960
+ display_order: 1,
9961
+ help_text: "Insulin must be refrigerated. Delivery driver will hand over directly \u2014 not leave at door.",
9962
+ semantic_kind: "consent"
9963
+ })
9964
+ ]
9965
+ },
9966
+ {
9967
+ slug: "vaccination-consent",
9968
+ name: "Flu Shot \u2014 At-Pharmacy",
9969
+ price: "80.00",
9970
+ category: "personal-care",
9971
+ description: "Pharmacist-administered seasonal influenza vaccine. Walk-in or book a slot.",
9972
+ tags: ["service", "vaccination"],
9973
+ inputs: [
9974
+ field("vaccination-consent", {
9975
+ slug: "patient_name",
9976
+ name: "Patient name",
9977
+ field_type: "text",
9978
+ is_required: true,
9979
+ display_order: 0
9980
+ }),
9981
+ field("vaccination-consent", {
9982
+ slug: "patient_dob",
9983
+ name: "Date of birth",
9984
+ field_type: "date",
9985
+ is_required: true,
9986
+ display_order: 1
9987
+ }),
9988
+ field("vaccination-consent", {
9989
+ slug: "allergies",
9990
+ name: "Known allergies or reactions to past vaccines",
9991
+ field_type: "textarea",
9992
+ is_required: false,
9993
+ display_order: 2,
9994
+ placeholder: "Egg, latex, prior vaccine reactions, etc. Leave blank if none.",
9995
+ semantic_kind: "allergen"
9996
+ }),
9997
+ field("vaccination-consent", {
9998
+ slug: "consent_signature",
9999
+ name: "Signed consent",
10000
+ field_type: "signature",
10001
+ is_required: true,
10002
+ display_order: 3,
10003
+ help_text: "Required by our administering pharmacist before vaccination.",
10004
+ semantic_kind: "consent"
10005
+ })
10006
+ ]
10007
+ }
10008
+ ];
10009
+ for (const p of products) {
10010
+ const id = `prod_${p.slug}`;
10011
+ const catId = catIds.get(p.category);
10012
+ const product = {
10013
+ id,
10014
+ business_id: businessId,
10015
+ name: p.name,
10016
+ slug: p.slug,
10017
+ description: p.description,
10018
+ product_type: "product",
10019
+ base_price: p.price,
10020
+ currency: "GHS",
10021
+ image: photoFor6(p.slug),
10022
+ images: [photoFor6(p.slug)],
10023
+ is_available: true,
10024
+ category_ids: [catId],
10025
+ collection_ids: [],
10026
+ add_on_ids: [],
10027
+ variant_ids: [],
10028
+ tags: p.tags ?? [],
10029
+ input_fields: p.inputs,
10030
+ metadata: p.requiresPrescription ? { requires_prescription: true } : void 0,
10031
+ created_at: ISO9,
10032
+ updated_at: ISO9
10033
+ };
10034
+ registry.products.put(id, product);
10035
+ const cat = registry.categories.get(catId);
10036
+ cat.product_ids.push(id);
10037
+ registry.categories.put(catId, cat);
10038
+ }
10039
+ const essentials = {
10040
+ id: "col_essentials",
10041
+ business_id: businessId,
10042
+ name: "Home Essentials",
10043
+ slug: "essentials",
10044
+ description: "Stock up your medicine cabinet.",
10045
+ product_ids: [
10046
+ "prod_paracetamol",
10047
+ "prod_first-aid-kit",
10048
+ "prod_thermometer",
10049
+ "prod_hand-sanitizer",
10050
+ "prod_multivitamin"
10051
+ ],
10052
+ is_active: true,
10053
+ created_at: ISO9,
10054
+ updated_at: ISO9
10055
+ };
10056
+ registry.collections.put(essentials.id, essentials);
10057
+ for (const pid of essentials.product_ids) {
10058
+ const p = registry.products.get(pid);
10059
+ if (p) {
10060
+ p.collection_ids.push(essentials.id);
10061
+ registry.products.put(pid, p);
10062
+ }
10063
+ }
10064
+ const packAxis = {
10065
+ id: "axis_pack_size",
10066
+ business_id: businessId,
10067
+ product_id: "prod_paracetamol",
10068
+ name: "Pack size",
10069
+ display_order: 0,
10070
+ affects_recipe: false,
10071
+ values: [
10072
+ { id: "axv_pack_24", name: "24 tablets", display: 0 },
10073
+ { id: "axv_pack_48", name: "48 tablets", display: 1 },
10074
+ { id: "axv_pack_100", name: "100 tablets (family)", display: 2 }
10075
+ ].map((v) => ({
10076
+ id: v.id,
10077
+ business_id: businessId,
10078
+ axis_id: "axis_pack_size",
10079
+ name: v.name,
10080
+ display_order: v.display,
10081
+ created_at: ISO9,
10082
+ updated_at: ISO9
10083
+ })),
10084
+ created_at: ISO9,
10085
+ updated_at: ISO9
10086
+ };
10087
+ registry.variantAxes.put(packAxis.id, packAxis);
10088
+ const packAdj = { pack_24: "0.00", pack_48: "8.00", pack_100: "18.00" };
10089
+ const paracetamolVariantIds = [];
10090
+ let firstVariant = true;
10091
+ for (const pk of packAxis.values) {
10092
+ const key = pk.id.replace("axv_pack_", "pack_");
10093
+ const id = `var_paracetamol_${key.replace("pack_", "")}`;
10094
+ const variant = {
10095
+ id,
10096
+ product_id: "prod_paracetamol",
10097
+ business_id: businessId,
10098
+ name: pk.name,
10099
+ sku: `PCM-${key.toUpperCase()}`,
10100
+ price_adjustment: packAdj[key] ?? "0.00",
10101
+ component_multiplier: "1.00",
10102
+ is_default: firstVariant,
10103
+ is_active: true,
10104
+ axis_value_ids: [pk.id],
10105
+ created_at: ISO9,
10106
+ updated_at: ISO9
10107
+ };
10108
+ registry.variants.put(id, variant);
10109
+ paracetamolVariantIds.push(id);
10110
+ firstVariant = false;
10111
+ }
10112
+ const paracetamol = registry.products.get("prod_paracetamol");
10113
+ if (paracetamol) {
10114
+ paracetamol.variant_ids = paracetamolVariantIds;
10115
+ registry.products.put(paracetamol.id, paracetamol);
10116
+ }
10117
+ const formAddOn = {
10118
+ id: "addon_form",
10119
+ business_id: businessId,
10120
+ name: "Format",
10121
+ is_multiple_allowed: false,
10122
+ is_required: false,
10123
+ is_mutually_exclusive: true,
10124
+ min_selections: 0,
10125
+ max_selections: 1,
10126
+ created_at: ISO9,
10127
+ updated_at: ISO9,
10128
+ options: [
10129
+ { 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 },
10130
+ { 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 }
10131
+ ]
10132
+ };
10133
+ registry.addOns.put(formAddOn.id, formAddOn);
10134
+ const medProductIds = ["prod_paracetamol", "prod_ibuprofen", "prod_aspirin", "prod_allergy-relief"];
10135
+ for (const pid of medProductIds) {
10136
+ registry.productAddOns.put(`${pid}:${formAddOn.id}`, { product_id: pid, add_on_id: formAddOn.id });
10137
+ const p = registry.products.get(pid);
10138
+ if (p) {
10139
+ p.add_on_ids.push(formAddOn.id);
10140
+ registry.products.put(pid, p);
10141
+ }
10142
+ }
10143
+ const services = [
10144
+ {
10145
+ id: "svc_bp_check",
10146
+ business_id: businessId,
10147
+ name: "Blood Pressure Check",
10148
+ description: "Free in-store BP reading with our pharmacist.",
10149
+ duration_minutes: 15,
10150
+ price: "0.00",
10151
+ is_available: true
10152
+ },
10153
+ {
10154
+ id: "svc_consultation",
10155
+ business_id: businessId,
10156
+ name: "Pharmacist Consultation",
10157
+ description: "15-minute one-on-one about medications, interactions, or symptoms.",
10158
+ duration_minutes: 15,
10159
+ price: "30.00",
10160
+ is_available: true
10161
+ },
10162
+ {
10163
+ id: "svc_prescription_refill",
10164
+ business_id: businessId,
10165
+ name: "Prescription Refill",
10166
+ description: "Upload your prescription; we prepare it for pickup or delivery same-day.",
10167
+ duration_minutes: 30,
10168
+ price: "0.00",
10169
+ is_available: true
10170
+ },
10171
+ {
10172
+ id: "svc_vaccination",
10173
+ business_id: businessId,
10174
+ name: "Vaccination (Flu, Tetanus)",
10175
+ description: "Walk-in or by appointment. Pharmacist-administered.",
10176
+ duration_minutes: 20,
10177
+ price: "80.00",
10178
+ is_available: true
10179
+ }
10180
+ ];
10181
+ for (const s of services) registry.services.put(s.id, s);
10182
+ const tags = [
10183
+ { id: "tag_otc", business_id: businessId, name: "OTC", slug: "otc", color: "#16a34a", sort_order: 0, usage_count: 11, created_at: ISO9, updated_at: ISO9 },
10184
+ { id: "tag_essential", business_id: businessId, name: "Essential", slug: "essential", color: "#2563eb", sort_order: 1, usage_count: 2, created_at: ISO9, updated_at: ISO9 },
10185
+ { id: "tag_prescription", business_id: businessId, name: "Prescription", slug: "prescription", color: "#dc2626", sort_order: 2, usage_count: 0, created_at: ISO9, updated_at: ISO9 }
10186
+ ];
10187
+ for (const t of tags) registry.tags.put(t.id, t);
10188
+ const medication = {
10189
+ id: "tax_medication",
10190
+ business_id: businessId,
10191
+ name: "Medication",
10192
+ slug: "medication",
10193
+ path: ["Health", "Medication"],
10194
+ attribute_template_ids: ["attr_active_ingredient", "attr_dosage"],
10195
+ created_at: ISO9,
10196
+ updated_at: ISO9
10197
+ };
10198
+ registry.taxonomies.put(medication.id, medication);
10199
+ const attrs = [
10200
+ {
10201
+ id: "attr_active_ingredient",
10202
+ business_id: businessId,
10203
+ namespace: "core",
10204
+ name: "Active ingredient",
10205
+ slug: "active-ingredient",
10206
+ attribute_type: "text",
10207
+ is_required: false,
10208
+ is_filterable: true,
10209
+ visibility: "public",
10210
+ display_order: 0,
10211
+ applies_to: "product",
10212
+ created_at: ISO9,
10213
+ updated_at: ISO9
10214
+ },
10215
+ {
10216
+ id: "attr_dosage",
10217
+ business_id: businessId,
10218
+ namespace: "core",
10219
+ name: "Dosage form",
10220
+ slug: "dosage-form",
10221
+ attribute_type: "select",
10222
+ options: ["tablet", "capsule", "syrup", "spray", "cream", "drops"],
10223
+ is_required: false,
10224
+ is_filterable: true,
10225
+ visibility: "public",
10226
+ display_order: 1,
10227
+ applies_to: "product",
10228
+ created_at: ISO9,
10229
+ updated_at: ISO9
10230
+ },
10231
+ {
10232
+ id: "attr_prescription_required",
10233
+ business_id: businessId,
10234
+ namespace: "core",
10235
+ name: "Prescription required",
10236
+ slug: "prescription-required",
10237
+ attribute_type: "boolean",
10238
+ is_required: false,
10239
+ is_filterable: true,
10240
+ visibility: "public",
10241
+ display_order: 2,
10242
+ applies_to: "product",
10243
+ created_at: ISO9,
10244
+ updated_at: ISO9
10245
+ }
10246
+ ];
10247
+ for (const a of attrs) registry.attributeDefs.put(a.id, a);
10248
+ const articles = [
10249
+ {
10250
+ id: "kb_prescription",
10251
+ business_id: businessId,
10252
+ title: "Prescription handling",
10253
+ slug: "prescription-handling",
10254
+ content: "Upload prescriptions through the prescription-refill service. Our pharmacist verifies before dispensing; same-day pickup or delivery within Accra.",
10255
+ category: "logistics",
10256
+ tags: ["prescription", "delivery"],
10257
+ created_at: ISO9,
10258
+ updated_at: ISO9
10259
+ },
10260
+ {
10261
+ id: "kb_returns",
10262
+ business_id: businessId,
10263
+ title: "Returns & exchanges",
10264
+ slug: "returns",
10265
+ content: "Sealed OTC products may be returned within 7 days with receipt. Opened products, prescriptions, and refrigerated items are non-returnable for safety reasons.",
10266
+ category: "policies",
10267
+ tags: ["returns"],
10268
+ created_at: ISO9,
10269
+ updated_at: ISO9
10270
+ },
10271
+ {
10272
+ id: "kb_consultation",
10273
+ business_id: businessId,
10274
+ title: "Pharmacist consultations",
10275
+ slug: "consultations",
10276
+ content: "15-minute pharmacist appointments cover medication review, side-effect questions, OTC selection, and symptom triage. Book through the services menu.",
10277
+ category: "services",
10278
+ tags: ["consultation"],
10279
+ created_at: ISO9,
10280
+ updated_at: ISO9
10281
+ }
10282
+ ];
10283
+ for (const a of articles) registry.knowledgeArticles.put(a.id, a);
10284
+ return { businessId };
10285
+ }
10286
+
9848
10287
  // src/mock/seeds/registry.ts
9849
10288
  var SEEDS = {
9850
10289
  default: seedDefault,
@@ -9854,7 +10293,8 @@ var SEEDS = {
9854
10293
  retail: seedRetail,
9855
10294
  services: seedServices,
9856
10295
  grocery: seedGrocery,
9857
- fashion: seedFashion
10296
+ fashion: seedFashion,
10297
+ pharmacy: seedPharmacy
9858
10298
  };
9859
10299
  function applySeed(registry, name) {
9860
10300
  const fn = SEEDS[name];