@86d-app/reviews 0.0.3

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 (53) hide show
  1. package/AGENTS.md +41 -0
  2. package/COMPONENTS.md +34 -0
  3. package/README.md +192 -0
  4. package/package.json +46 -0
  5. package/src/__tests__/service-impl.test.ts +1436 -0
  6. package/src/admin/components/index.ts +3 -0
  7. package/src/admin/components/index.tsx +3 -0
  8. package/src/admin/components/review-analytics.mdx +3 -0
  9. package/src/admin/components/review-analytics.tsx +221 -0
  10. package/src/admin/components/review-list.mdx +89 -0
  11. package/src/admin/components/review-list.tsx +308 -0
  12. package/src/admin/components/review-moderation.mdx +3 -0
  13. package/src/admin/components/review-moderation.tsx +447 -0
  14. package/src/admin/endpoints/approve-review.ts +19 -0
  15. package/src/admin/endpoints/delete-review.ts +17 -0
  16. package/src/admin/endpoints/get-review.ts +16 -0
  17. package/src/admin/endpoints/index.ts +23 -0
  18. package/src/admin/endpoints/list-review-requests.ts +23 -0
  19. package/src/admin/endpoints/list-reviews.ts +25 -0
  20. package/src/admin/endpoints/reject-review.ts +19 -0
  21. package/src/admin/endpoints/respond-review.ts +22 -0
  22. package/src/admin/endpoints/review-analytics.ts +14 -0
  23. package/src/admin/endpoints/review-request-stats.ts +12 -0
  24. package/src/admin/endpoints/send-review-request.ts +41 -0
  25. package/src/index.ts +73 -0
  26. package/src/mdx.d.ts +5 -0
  27. package/src/schema.ts +37 -0
  28. package/src/service-impl.ts +263 -0
  29. package/src/service.ts +126 -0
  30. package/src/store/components/_hooks.ts +13 -0
  31. package/src/store/components/_utils.ts +16 -0
  32. package/src/store/components/distribution-bars.mdx +21 -0
  33. package/src/store/components/distribution-bars.tsx +13 -0
  34. package/src/store/components/index.tsx +20 -0
  35. package/src/store/components/product-reviews.mdx +52 -0
  36. package/src/store/components/product-reviews.tsx +172 -0
  37. package/src/store/components/review-card.mdx +32 -0
  38. package/src/store/components/review-card.tsx +87 -0
  39. package/src/store/components/review-form.mdx +111 -0
  40. package/src/store/components/review-form.tsx +68 -0
  41. package/src/store/components/reviews-summary.mdx +6 -0
  42. package/src/store/components/reviews-summary.tsx +30 -0
  43. package/src/store/components/star-display.mdx +18 -0
  44. package/src/store/components/star-display.tsx +28 -0
  45. package/src/store/components/star-picker.mdx +21 -0
  46. package/src/store/components/star-picker.tsx +23 -0
  47. package/src/store/endpoints/index.ts +11 -0
  48. package/src/store/endpoints/list-my-reviews.ts +38 -0
  49. package/src/store/endpoints/list-product-reviews.ts +26 -0
  50. package/src/store/endpoints/mark-helpful.ts +16 -0
  51. package/src/store/endpoints/submit-review.ts +33 -0
  52. package/tsconfig.json +9 -0
  53. package/vitest.config.ts +2 -0
package/AGENTS.md ADDED
@@ -0,0 +1,41 @@
1
+ # reviews module
2
+
3
+ Handles product reviews and ratings. Reviews start as `pending` and require admin approval before being publicly visible.
4
+
5
+ ## Schema
6
+
7
+ - `review` — stores a single product review with rating (1–5), author info, body, moderation status, and helpfulness count.
8
+
9
+ ## Service
10
+
11
+ `ReviewController` exposes:
12
+
13
+ - `createReview` — submit a new review (always `pending`)
14
+ - `getReview` — fetch a review by id
15
+ - `listReviewsByProduct` — get reviews for a product (optionally only approved)
16
+ - `listReviews` — admin listing with filters (status, productId, pagination)
17
+ - `updateReviewStatus` — approve or reject a review
18
+ - `deleteReview` — hard delete
19
+ - `getProductRatingSummary` — average rating + distribution (approved reviews only)
20
+
21
+ ## Endpoints
22
+
23
+ ### Store
24
+ - `POST /reviews` — submit a review
25
+ - `GET /reviews/products/:productId` — list approved reviews + summary
26
+
27
+ ### Admin
28
+ - `GET /admin/reviews` — list all reviews (status/productId filters)
29
+ - `PUT /admin/reviews/:id/approve` — approve
30
+ - `PUT /admin/reviews/:id/reject` — reject
31
+ - `DELETE /admin/reviews/:id/delete` — delete
32
+
33
+ ## Options
34
+
35
+ | Key | Type | Description |
36
+ |-----|------|-------------|
37
+ | `autoApprove` | `"true" \| "false"` | Skip moderation queue |
38
+
39
+ ## Tests
40
+
41
+ 28 tests in `tests/service-impl.test.ts` covering all controller methods.
package/COMPONENTS.md ADDED
@@ -0,0 +1,34 @@
1
+ # Reviews Module — Store Components
2
+
3
+ ## ReviewsSummary
4
+
5
+ Compact star rating and count for product cards.
6
+
7
+ ### Props
8
+
9
+ | Prop | Type | Description |
10
+ |------|------|-------------|
11
+ | `productId` | `string` | Product ID to fetch review summary for |
12
+
13
+ ### Usage in MDX
14
+
15
+ ```mdx
16
+ <ReviewsSummary productId={product.id} />
17
+ ```
18
+
19
+ ## ProductReviews
20
+
21
+ Full reviews section with summary, distribution bars, review list, and submit form.
22
+
23
+ ### Props
24
+
25
+ | Prop | Type | Default | Description |
26
+ |------|------|---------|-------------|
27
+ | `productId` | `string` | — | Product ID |
28
+ | `title` | `string` | `"Customer Reviews"` | Section heading |
29
+
30
+ ### Usage in MDX
31
+
32
+ ```mdx
33
+ <ProductReviews productId={product.id} />
34
+ ```
package/README.md ADDED
@@ -0,0 +1,192 @@
1
+ <p align="center">
2
+ <a href="https://86d.app">
3
+ <img src="https://86d.app/logo" height="96" alt="86d" />
4
+ </a>
5
+ </p>
6
+
7
+ <p align="center">
8
+ Dynamic Commerce
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://vercel.com/changelog"><strong>npm</strong></a> ·
13
+ <a href="https://x.com/86d_app"><strong>X</strong></a> ·
14
+ <a href="https://vercel.com/templates"><strong>LinkedIn</strong></a>
15
+ </p>
16
+ <br/>
17
+
18
+ > [!WARNING]
19
+ > This project is under active development and is not ready for production use. Please proceed with caution. Use at your own risk.
20
+
21
+ # @86d-app/reviews
22
+
23
+ Product reviews and ratings for the 86d commerce platform. Manages a moderation queue so store owners can approve or reject reviews before they appear publicly.
24
+
25
+ ![version](https://img.shields.io/badge/version-0.0.1-blue) ![license](https://img.shields.io/badge/license-MIT-green)
26
+
27
+ ## Installation
28
+
29
+ ```sh
30
+ npm install @86d-app/reviews
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ```ts
36
+ import reviews from "@86d-app/reviews";
37
+ import { createModuleClient } from "@86d-app/core";
38
+
39
+ const client = createModuleClient([
40
+ reviews({
41
+ autoApprove: "false", // default: requires moderation
42
+ }),
43
+ ]);
44
+ ```
45
+
46
+ ## Configuration
47
+
48
+ | Option | Type | Default | Description |
49
+ |---|---|---|---|
50
+ | `autoApprove` | `"true" \| "false"` | `"false"` | Auto-approve reviews without moderation |
51
+
52
+ ## Review Lifecycle
53
+
54
+ ```
55
+ createReview() → pending
56
+ updateReviewStatus() → approved (publicly visible)
57
+ updateReviewStatus() → rejected (hidden from store)
58
+ ```
59
+
60
+ When `autoApprove: "true"`, new reviews skip the pending state and go directly to `approved`.
61
+
62
+ ## Store Endpoints
63
+
64
+ | Method | Path | Description |
65
+ |---|---|---|
66
+ | `POST` | `/reviews` | Submit a review (status: pending) |
67
+ | `GET` | `/reviews/products/:productId` | List approved reviews + rating summary |
68
+
69
+ **Response for `GET /reviews/products/:productId`:**
70
+ ```json
71
+ {
72
+ "reviews": [...],
73
+ "summary": {
74
+ "average": 4.3,
75
+ "count": 12,
76
+ "distribution": { "1": 0, "2": 1, "3": 2, "4": 4, "5": 5 }
77
+ }
78
+ }
79
+ ```
80
+
81
+ ## Admin Endpoints
82
+
83
+ | Method | Path | Description |
84
+ |---|---|---|
85
+ | `GET` | `/admin/reviews` | List all reviews (filter: `status`, `productId`) |
86
+ | `PUT` | `/admin/reviews/:id/approve` | Approve a review |
87
+ | `PUT` | `/admin/reviews/:id/reject` | Reject a review |
88
+ | `DELETE` | `/admin/reviews/:id/delete` | Delete a review permanently |
89
+
90
+ ## Controller API
91
+
92
+ ```ts
93
+ controller.createReview(params: {
94
+ productId: string;
95
+ authorName: string;
96
+ authorEmail: string;
97
+ rating: number; // 1–5
98
+ title?: string;
99
+ body: string;
100
+ customerId?: string;
101
+ isVerifiedPurchase?: boolean;
102
+ }): Promise<Review>
103
+
104
+ controller.getReview(id: string): Promise<Review | null>
105
+
106
+ // Returns only approved reviews by default (set approvedOnly: false for all)
107
+ controller.listReviewsByProduct(productId: string, params?: {
108
+ approvedOnly?: boolean;
109
+ take?: number;
110
+ skip?: number;
111
+ }): Promise<Review[]>
112
+
113
+ controller.listReviews(params?: {
114
+ productId?: string;
115
+ status?: ReviewStatus;
116
+ take?: number;
117
+ skip?: number;
118
+ }): Promise<Review[]>
119
+
120
+ controller.updateReviewStatus(id: string, status: ReviewStatus): Promise<Review | null>
121
+
122
+ controller.deleteReview(id: string): Promise<boolean>
123
+
124
+ // Calculates stats from approved reviews only
125
+ controller.getProductRatingSummary(productId: string): Promise<RatingSummary>
126
+ ```
127
+
128
+ ## Rating Summary
129
+
130
+ `getProductRatingSummary` only counts **approved** reviews. The `count` is the number of approved reviews, `average` is rounded to 1 decimal place, and `distribution` maps each star rating (1–5) to its count.
131
+
132
+ ```ts
133
+ interface RatingSummary {
134
+ average: number; // e.g. 4.3
135
+ count: number; // number of approved reviews
136
+ distribution: Record<string, number>; // { "1": 0, "2": 1, "3": 2, "4": 4, "5": 5 }
137
+ }
138
+ ```
139
+
140
+ ## Example: Moderation Flow
141
+
142
+ ```ts
143
+ // Customer submits a review
144
+ const review = await controller.createReview({
145
+ productId: "prod_abc",
146
+ authorName: "Jane Doe",
147
+ authorEmail: "jane@example.com",
148
+ rating: 5,
149
+ title: "Excellent product!",
150
+ body: "Exactly what I needed. Fast shipping too.",
151
+ isVerifiedPurchase: true,
152
+ });
153
+ // review.status === "pending"
154
+
155
+ // Admin approves it
156
+ await controller.updateReviewStatus(review.id, "approved");
157
+
158
+ // Fetch public ratings for a product page
159
+ const summary = await controller.getProductRatingSummary("prod_abc");
160
+ // { average: 5.0, count: 1, distribution: { "5": 1, "4": 0, ... } }
161
+
162
+ // Fetch approved reviews for display
163
+ const reviews = await controller.listReviewsByProduct("prod_abc");
164
+ ```
165
+
166
+ ## Types
167
+
168
+ ```ts
169
+ type ReviewStatus = "pending" | "approved" | "rejected";
170
+
171
+ interface Review {
172
+ id: string;
173
+ productId: string;
174
+ customerId?: string;
175
+ authorName: string;
176
+ authorEmail: string;
177
+ rating: number; // 1–5
178
+ title?: string;
179
+ body: string;
180
+ status: ReviewStatus;
181
+ isVerifiedPurchase: boolean;
182
+ helpfulCount: number;
183
+ createdAt: Date;
184
+ updatedAt: Date;
185
+ }
186
+
187
+ interface RatingSummary {
188
+ average: number;
189
+ count: number;
190
+ distribution: Record<string, number>;
191
+ }
192
+ ```
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@86d-app/reviews",
3
+ "version": "0.0.3",
4
+ "description": "Product reviews and ratings module for 86d commerce platform",
5
+ "keywords": [
6
+ "commerce",
7
+ "reviews",
8
+ "ratings",
9
+ "moderation",
10
+ "86d"
11
+ ],
12
+ "license": "MIT",
13
+ "author": "86d <chat@86d.app>",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/86d-app/86d.git",
17
+ "directory": "modules/reviews"
18
+ },
19
+ "homepage": "https://github.com/86d-app/86d/tree/main/modules/reviews",
20
+ "type": "module",
21
+ "exports": {
22
+ "./components": "./src/store/components",
23
+ "./admin-components": "./src/admin/components",
24
+ "./*": "./src/*"
25
+ },
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "check": "biome check src",
29
+ "check:fix": "biome check --write src",
30
+ "clean": "git clean -xdf .cache .turbo dist node_modules",
31
+ "dev": "tsc",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest watch",
34
+ "typecheck": "tsc --noEmit --emitDeclarationOnly false"
35
+ },
36
+ "dependencies": {
37
+ "@86d-app/core": "workspace:*"
38
+ },
39
+ "devDependencies": {
40
+ "@biomejs/biome": "catalog:",
41
+ "@types/mdx": "catalog:mdx",
42
+ "@types/react": "catalog:react",
43
+ "typescript": "catalog:",
44
+ "vitest": "catalog:vite"
45
+ }
46
+ }