@porulle/plugin-marketplace 0.1.0

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 (118) hide show
  1. package/README.md +479 -0
  2. package/dist/analytics-models.d.ts +13 -0
  3. package/dist/analytics-models.d.ts.map +1 -0
  4. package/dist/analytics-models.js +69 -0
  5. package/dist/hooks.d.ts +4 -0
  6. package/dist/hooks.d.ts.map +1 -0
  7. package/dist/hooks.js +187 -0
  8. package/dist/index.d.ts +4 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +97 -0
  11. package/dist/routes/b2b.d.ts +9 -0
  12. package/dist/routes/b2b.d.ts.map +1 -0
  13. package/dist/routes/b2b.js +156 -0
  14. package/dist/routes/commission.d.ts +6 -0
  15. package/dist/routes/commission.d.ts.map +1 -0
  16. package/dist/routes/commission.js +85 -0
  17. package/dist/routes/disputes-returns-reviews.d.ts +10 -0
  18. package/dist/routes/disputes-returns-reviews.d.ts.map +1 -0
  19. package/dist/routes/disputes-returns-reviews.js +179 -0
  20. package/dist/routes/payouts.d.ts +6 -0
  21. package/dist/routes/payouts.d.ts.map +1 -0
  22. package/dist/routes/payouts.js +40 -0
  23. package/dist/routes/sub-orders.d.ts +6 -0
  24. package/dist/routes/sub-orders.d.ts.map +1 -0
  25. package/dist/routes/sub-orders.js +44 -0
  26. package/dist/routes/util.d.ts +23 -0
  27. package/dist/routes/util.d.ts.map +1 -0
  28. package/dist/routes/util.js +41 -0
  29. package/dist/routes/vendor-portal.d.ts +14 -0
  30. package/dist/routes/vendor-portal.d.ts.map +1 -0
  31. package/dist/routes/vendor-portal.js +255 -0
  32. package/dist/routes/vendors.d.ts +11 -0
  33. package/dist/routes/vendors.d.ts.map +1 -0
  34. package/dist/routes/vendors.js +185 -0
  35. package/dist/schema.d.ts +3255 -0
  36. package/dist/schema.d.ts.map +1 -0
  37. package/dist/schema.js +225 -0
  38. package/dist/schemas/b2b.d.ts +1009 -0
  39. package/dist/schemas/b2b.d.ts.map +1 -0
  40. package/dist/schemas/b2b.js +208 -0
  41. package/dist/schemas/commission.d.ts +532 -0
  42. package/dist/schemas/commission.d.ts.map +1 -0
  43. package/dist/schemas/commission.js +113 -0
  44. package/dist/schemas/disputes-returns-reviews.d.ts +1405 -0
  45. package/dist/schemas/disputes-returns-reviews.d.ts.map +1 -0
  46. package/dist/schemas/disputes-returns-reviews.js +270 -0
  47. package/dist/schemas/payouts.d.ts +375 -0
  48. package/dist/schemas/payouts.d.ts.map +1 -0
  49. package/dist/schemas/payouts.js +78 -0
  50. package/dist/schemas/sub-orders.d.ts +303 -0
  51. package/dist/schemas/sub-orders.d.ts.map +1 -0
  52. package/dist/schemas/sub-orders.js +67 -0
  53. package/dist/schemas/vendor-portal.d.ts +1785 -0
  54. package/dist/schemas/vendor-portal.d.ts.map +1 -0
  55. package/dist/schemas/vendor-portal.js +294 -0
  56. package/dist/schemas/vendors.d.ts +1348 -0
  57. package/dist/schemas/vendors.d.ts.map +1 -0
  58. package/dist/schemas/vendors.js +245 -0
  59. package/dist/services/commission.d.ts +81 -0
  60. package/dist/services/commission.d.ts.map +1 -0
  61. package/dist/services/commission.js +98 -0
  62. package/dist/services/contract-price.d.ts +64 -0
  63. package/dist/services/contract-price.d.ts.map +1 -0
  64. package/dist/services/contract-price.js +57 -0
  65. package/dist/services/dispute.d.ts +156 -0
  66. package/dist/services/dispute.d.ts.map +1 -0
  67. package/dist/services/dispute.js +77 -0
  68. package/dist/services/payout.d.ts +126 -0
  69. package/dist/services/payout.d.ts.map +1 -0
  70. package/dist/services/payout.js +130 -0
  71. package/dist/services/return.d.ts +181 -0
  72. package/dist/services/return.d.ts.map +1 -0
  73. package/dist/services/return.js +80 -0
  74. package/dist/services/review.d.ts +70 -0
  75. package/dist/services/review.d.ts.map +1 -0
  76. package/dist/services/review.js +60 -0
  77. package/dist/services/rfq.d.ts +122 -0
  78. package/dist/services/rfq.d.ts.map +1 -0
  79. package/dist/services/rfq.js +60 -0
  80. package/dist/services/sub-order.d.ts +336 -0
  81. package/dist/services/sub-order.d.ts.map +1 -0
  82. package/dist/services/sub-order.js +121 -0
  83. package/dist/services/vendor.d.ts +528 -0
  84. package/dist/services/vendor.d.ts.map +1 -0
  85. package/dist/services/vendor.js +119 -0
  86. package/dist/types.d.ts +67 -0
  87. package/dist/types.d.ts.map +1 -0
  88. package/dist/types.js +13 -0
  89. package/package.json +58 -0
  90. package/src/analytics-models.ts +75 -0
  91. package/src/hooks.ts +215 -0
  92. package/src/index.ts +116 -0
  93. package/src/routes/b2b.ts +179 -0
  94. package/src/routes/commission.ts +95 -0
  95. package/src/routes/disputes-returns-reviews.ts +209 -0
  96. package/src/routes/payouts.ts +49 -0
  97. package/src/routes/sub-orders.ts +54 -0
  98. package/src/routes/util.ts +42 -0
  99. package/src/routes/vendor-portal.ts +277 -0
  100. package/src/routes/vendors.ts +201 -0
  101. package/src/schema.ts +260 -0
  102. package/src/schemas/b2b.ts +238 -0
  103. package/src/schemas/commission.ts +129 -0
  104. package/src/schemas/disputes-returns-reviews.ts +311 -0
  105. package/src/schemas/payouts.ts +90 -0
  106. package/src/schemas/sub-orders.ts +77 -0
  107. package/src/schemas/vendor-portal.ts +344 -0
  108. package/src/schemas/vendors.ts +281 -0
  109. package/src/services/commission.ts +120 -0
  110. package/src/services/contract-price.ts +80 -0
  111. package/src/services/dispute.ts +92 -0
  112. package/src/services/payout.ts +154 -0
  113. package/src/services/return.ts +92 -0
  114. package/src/services/review.ts +76 -0
  115. package/src/services/rfq.ts +82 -0
  116. package/src/services/sub-order.ts +136 -0
  117. package/src/services/vendor.ts +151 -0
  118. package/src/types.ts +164 -0
@@ -0,0 +1,185 @@
1
+ import { router, resolveOrgId } from "@porulle/core";
2
+ import { CreateVendorBodySchema, UpdateVendorBodySchema, RejectVendorBodySchema, SuspendVendorBodySchema, UploadDocumentBodySchema, } from "../schemas/vendors.js";
3
+ import { stripUndefined, stripVendorSecrets } from "./util.js";
4
+ export function buildVendorRoutes(services, options) {
5
+ const r = router("Marketplace - Vendors", "/marketplace/vendors");
6
+ // ─── List vendors ──────────────────────────────────────────────────────────
7
+ r.get("/")
8
+ .summary("List all vendors")
9
+ .permission("marketplace:admin")
10
+ .handler(async ({ query }) => {
11
+ const vendors = await services.vendor.list(stripUndefined({
12
+ status: query.status,
13
+ tier: query.tier,
14
+ search: query.search,
15
+ }));
16
+ return vendors.map(stripVendorSecrets);
17
+ });
18
+ // ─── Create vendor ─────────────────────────────────────────────────────────
19
+ r.post("/")
20
+ .summary("Create a vendor")
21
+ .permission("marketplace:admin")
22
+ .input(CreateVendorBodySchema)
23
+ .handler(async ({ input, actor }) => {
24
+ const body = input;
25
+ const defaultBps = options?.defaultCommissionRateBps ?? 1000;
26
+ return services.vendor.create(resolveOrgId(actor), stripUndefined({
27
+ ...body,
28
+ commissionRateBps: body.commissionRateBps ?? defaultBps,
29
+ }));
30
+ });
31
+ // ─── Get vendor detail ─────────────────────────────────────────────────────
32
+ r.get("/{id}")
33
+ .summary("Get vendor detail")
34
+ .permission("marketplace:admin")
35
+ .handler(async ({ params }) => {
36
+ const vendor = await services.vendor.getById(params.id);
37
+ if (!vendor)
38
+ throw new Error("Vendor not found");
39
+ return stripVendorSecrets(vendor);
40
+ });
41
+ // ─── Update vendor ─────────────────────────────────────────────────────────
42
+ r.patch("/{id}")
43
+ .summary("Update a vendor")
44
+ .permission("marketplace:admin")
45
+ .input(UpdateVendorBodySchema)
46
+ .handler(async ({ params, input }) => {
47
+ const body = input;
48
+ const updated = await services.vendor.update(params.id, stripUndefined(body));
49
+ if (!updated)
50
+ throw new Error("Vendor not found");
51
+ return stripVendorSecrets(updated);
52
+ });
53
+ // ─── Approve vendor ────────────────────────────────────────────────────────
54
+ r.post("/{id}/approve")
55
+ .summary("Approve a vendor application")
56
+ .permission("marketplace:admin")
57
+ .handler(async ({ params }) => {
58
+ const vendor = await services.vendor.getById(params.id);
59
+ if (!vendor)
60
+ throw new Error("Vendor not found");
61
+ const approved = await services.vendor.approve(params.id);
62
+ if (!approved)
63
+ throw new Error("Vendor not found");
64
+ return stripVendorSecrets(approved);
65
+ });
66
+ // ─── Reject vendor ─────────────────────────────────────────────────────────
67
+ r.post("/{id}/reject")
68
+ .summary("Reject a vendor application")
69
+ .permission("marketplace:admin")
70
+ .input(RejectVendorBodySchema)
71
+ .handler(async ({ params, input }) => {
72
+ const body = input;
73
+ const vendor = await services.vendor.getById(params.id);
74
+ if (!vendor)
75
+ throw new Error("Vendor not found");
76
+ const rejected = await services.vendor.reject(params.id, body.reason);
77
+ if (!rejected)
78
+ throw new Error("Vendor not found");
79
+ return stripVendorSecrets(rejected);
80
+ });
81
+ // ─── Suspend vendor ────────────────────────────────────────────────────────
82
+ r.post("/{id}/suspend")
83
+ .summary("Suspend a vendor")
84
+ .permission("marketplace:admin")
85
+ .input(SuspendVendorBodySchema)
86
+ .handler(async ({ params, input }) => {
87
+ const body = input;
88
+ const vendor = await services.vendor.getById(params.id);
89
+ if (!vendor)
90
+ throw new Error("Vendor not found");
91
+ const suspended = await services.vendor.suspend(params.id, body.reason);
92
+ if (!suspended)
93
+ throw new Error("Vendor not found");
94
+ return stripVendorSecrets(suspended);
95
+ });
96
+ // ─── Reinstate vendor ──────────────────────────────────────────────────────
97
+ r.post("/{id}/reinstate")
98
+ .summary("Reinstate a suspended vendor")
99
+ .permission("marketplace:admin")
100
+ .handler(async ({ params }) => {
101
+ const vendor = await services.vendor.getById(params.id);
102
+ if (!vendor)
103
+ throw new Error("Vendor not found");
104
+ const reinstated = await services.vendor.reinstate(params.id);
105
+ if (!reinstated)
106
+ throw new Error("Vendor not found");
107
+ return stripVendorSecrets(reinstated);
108
+ });
109
+ // ─── Upload vendor document ────────────────────────────────────────────────
110
+ r.post("/{id}/documents")
111
+ .summary("Upload a vendor document")
112
+ .permission("marketplace:admin")
113
+ .input(UploadDocumentBodySchema)
114
+ .handler(async ({ params, input }) => {
115
+ const body = input;
116
+ const vendor = await services.vendor.getById(params.id);
117
+ if (!vendor)
118
+ throw new Error("Vendor not found");
119
+ return services.vendor.uploadDocument(params.id, {
120
+ type: body.type,
121
+ fileUrl: body.fileUrl,
122
+ });
123
+ });
124
+ // ─── List vendor documents ─────────────────────────────────────────────────
125
+ r.get("/{id}/documents")
126
+ .summary("List vendor documents")
127
+ .permission("marketplace:admin")
128
+ .handler(async ({ params }) => {
129
+ const vendor = await services.vendor.getById(params.id);
130
+ if (!vendor)
131
+ throw new Error("Vendor not found");
132
+ return services.vendor.listDocuments(params.id);
133
+ });
134
+ // ─── Approve document ──────────────────────────────────────────────────────
135
+ r.post("/{id}/documents/{docId}/approve")
136
+ .summary("Approve a vendor document")
137
+ .permission("marketplace:admin")
138
+ .handler(async ({ params }) => {
139
+ const updated = await services.vendor.approveDocument(params.docId);
140
+ if (!updated)
141
+ throw new Error("Document not found");
142
+ return updated;
143
+ });
144
+ // ─── Reject document ───────────────────────────────────────────────────────
145
+ r.post("/{id}/documents/{docId}/reject")
146
+ .summary("Reject a vendor document")
147
+ .permission("marketplace:admin")
148
+ .handler(async ({ params }) => {
149
+ const updated = await services.vendor.rejectDocument(params.docId);
150
+ if (!updated)
151
+ throw new Error("Document not found");
152
+ return updated;
153
+ });
154
+ // ─── Vendor balance ────────────────────────────────────────────────────────
155
+ r.get("/{id}/balance")
156
+ .summary("Get vendor balance")
157
+ .permission("marketplace:admin")
158
+ .handler(async ({ params }) => {
159
+ const vendor = await services.vendor.getById(params.id);
160
+ if (!vendor)
161
+ throw new Error("Vendor not found");
162
+ const balance = await services.payout.getBalance(params.id);
163
+ const ledger = await services.payout.getLedger(params.id);
164
+ return { balanceCents: balance, ledger };
165
+ });
166
+ // ─── Vendor performance ────────────────────────────────────────────────────
167
+ r.get("/{id}/performance")
168
+ .summary("Get vendor performance metrics")
169
+ .permission("marketplace:admin")
170
+ .handler(async ({ params }) => {
171
+ const vendor = await services.vendor.getById(params.id);
172
+ if (!vendor)
173
+ throw new Error("Vendor not found");
174
+ const rating = await services.review.getAggregateRating(params.id);
175
+ const balance = await services.payout.getBalance(params.id);
176
+ return {
177
+ vendorId: params.id,
178
+ performanceScore: vendor.performanceScore,
179
+ tier: vendor.tier,
180
+ rating,
181
+ balanceCents: balance,
182
+ };
183
+ });
184
+ return r.routes();
185
+ }