@mac777/project-pinecone-models 1.1.21 → 1.1.23

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.
package/dist/AuditLog.js CHANGED
@@ -22,7 +22,7 @@ var AuditStatus;
22
22
  AuditStatus["FAILURE"] = "FAILURE";
23
23
  })(AuditStatus || (exports.AuditStatus = AuditStatus = {}));
24
24
  const auditLogSchema = new mongoose_1.Schema({
25
- userId: { type: String, index: true },
25
+ userId: { type: String, ref: 'User', index: true },
26
26
  action: { type: String, required: true, index: true },
27
27
  category: {
28
28
  type: String,
@@ -0,0 +1,38 @@
1
+ import mongoose from 'mongoose';
2
+ export interface IReview {
3
+ eventId: mongoose.Types.ObjectId;
4
+ userId: mongoose.Types.ObjectId;
5
+ ticketId: mongoose.Types.ObjectId;
6
+ rating: number;
7
+ title: string;
8
+ comment: string;
9
+ reviewContext: {
10
+ hasCheckedIn: boolean;
11
+ checkInTime?: Date;
12
+ ticketTier: string;
13
+ ticketType: string;
14
+ };
15
+ status: 'pending' | 'approved' | 'hidden' | 'flagged';
16
+ isVisible: boolean;
17
+ moderationNotes?: string;
18
+ submittedAt: Date;
19
+ moderatedAt?: Date;
20
+ moderatorId?: mongoose.Types.ObjectId;
21
+ helpfulVotes: number;
22
+ reportedCount: number;
23
+ reports: Array<{
24
+ userId: mongoose.Types.ObjectId;
25
+ reason: string;
26
+ reportedAt: Date;
27
+ }>;
28
+ }
29
+ declare const reviewSchema: mongoose.Schema<IReview, mongoose.Model<IReview, any, any, any, mongoose.Document<unknown, any, IReview, any, {}> & IReview & {
30
+ _id: mongoose.Types.ObjectId;
31
+ } & {
32
+ __v: number;
33
+ }, any>, {}, {}, {}, {}, mongoose.DefaultSchemaOptions, IReview, mongoose.Document<unknown, {}, mongoose.FlatRecord<IReview>, {}, mongoose.ResolveSchemaOptions<mongoose.DefaultSchemaOptions>> & mongoose.FlatRecord<IReview> & {
34
+ _id: mongoose.Types.ObjectId;
35
+ } & {
36
+ __v: number;
37
+ }>;
38
+ export default reviewSchema;
package/dist/Review.js ADDED
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const mongoose_1 = __importDefault(require("mongoose"));
7
+ const reviewSchema = new mongoose_1.default.Schema({
8
+ eventId: {
9
+ type: mongoose_1.default.Schema.Types.ObjectId,
10
+ ref: 'Event',
11
+ required: true,
12
+ index: true
13
+ },
14
+ userId: {
15
+ type: mongoose_1.default.Schema.Types.ObjectId,
16
+ ref: 'User',
17
+ required: true,
18
+ index: true
19
+ },
20
+ ticketId: {
21
+ type: mongoose_1.default.Schema.Types.ObjectId,
22
+ ref: 'Ticket',
23
+ required: true,
24
+ index: true
25
+ },
26
+ // Review Content
27
+ rating: {
28
+ type: Number,
29
+ required: true,
30
+ min: 1,
31
+ max: 5,
32
+ validate: {
33
+ validator: Number.isInteger,
34
+ message: 'Rating must be a whole number'
35
+ }
36
+ },
37
+ title: {
38
+ type: String,
39
+ required: true,
40
+ trim: true,
41
+ maxlength: 100
42
+ },
43
+ comment: {
44
+ type: String,
45
+ required: true,
46
+ trim: true,
47
+ maxlength: 1000
48
+ },
49
+ // Context Metadata
50
+ reviewContext: {
51
+ hasCheckedIn: {
52
+ type: Boolean,
53
+ required: true
54
+ },
55
+ checkInTime: Date,
56
+ ticketTier: {
57
+ type: String,
58
+ required: true
59
+ },
60
+ ticketType: {
61
+ type: String,
62
+ required: true
63
+ }
64
+ },
65
+ // Status & Moderation
66
+ status: {
67
+ type: String,
68
+ enum: ['pending', 'approved', 'hidden', 'flagged'],
69
+ default: 'pending',
70
+ index: true
71
+ },
72
+ isVisible: {
73
+ type: Boolean,
74
+ default: true
75
+ },
76
+ moderationNotes: {
77
+ type: String,
78
+ trim: true,
79
+ maxlength: 500
80
+ },
81
+ // Timestamps
82
+ submittedAt: {
83
+ type: Date,
84
+ default: Date.now,
85
+ index: true
86
+ },
87
+ moderatedAt: Date,
88
+ moderatorId: {
89
+ type: mongoose_1.default.Schema.Types.ObjectId,
90
+ ref: 'User'
91
+ },
92
+ // Community Features
93
+ helpfulVotes: {
94
+ type: Number,
95
+ default: 0,
96
+ min: 0
97
+ },
98
+ reportedCount: {
99
+ type: Number,
100
+ default: 0,
101
+ min: 0
102
+ },
103
+ reports: [{
104
+ userId: {
105
+ type: mongoose_1.default.Schema.Types.ObjectId,
106
+ ref: 'User',
107
+ required: true
108
+ },
109
+ reason: {
110
+ type: String,
111
+ required: true,
112
+ enum: ['spam', 'abusive', 'fake', 'irrelevant', 'other']
113
+ },
114
+ reportedAt: {
115
+ type: Date,
116
+ default: Date.now
117
+ }
118
+ }]
119
+ });
120
+ // Compound indexes for efficient queries
121
+ reviewSchema.index({ eventId: 1, status: 1, isVisible: 1 });
122
+ reviewSchema.index({ userId: 1, eventId: 1 }, { unique: true }); // One review per user per event
123
+ reviewSchema.index({ submittedAt: -1 });
124
+ reviewSchema.index({ 'reviewContext.hasCheckedIn': 1 });
125
+ // Virtual for review type classification
126
+ reviewSchema.virtual('reviewType').get(function () {
127
+ return this.reviewContext.hasCheckedIn ? 'attended' : 'entry_access';
128
+ });
129
+ // Method to mark as helpful
130
+ reviewSchema.methods.markHelpful = function () {
131
+ this.helpfulVotes += 1;
132
+ return this.save();
133
+ };
134
+ // Method to report review
135
+ reviewSchema.methods.report = function (userId, reason) {
136
+ // Check if user already reported
137
+ const existingReport = this.reports.find((report) => report.userId.toString() === userId);
138
+ if (!existingReport) {
139
+ this.reports.push({
140
+ userId: new mongoose_1.default.Types.ObjectId(userId),
141
+ reason,
142
+ reportedAt: new Date()
143
+ });
144
+ this.reportedCount += 1;
145
+ // Auto-flag if too many reports
146
+ if (this.reportedCount >= 3) {
147
+ this.status = 'flagged';
148
+ }
149
+ }
150
+ return this.save();
151
+ };
152
+ // Method for admin moderation
153
+ reviewSchema.methods.moderate = function (moderatorId, action, notes) {
154
+ this.moderatorId = new mongoose_1.default.Types.ObjectId(moderatorId);
155
+ this.moderatedAt = new Date();
156
+ switch (action) {
157
+ case 'approve':
158
+ this.status = 'approved';
159
+ this.isVisible = true;
160
+ break;
161
+ case 'hide':
162
+ this.status = 'hidden';
163
+ this.isVisible = false;
164
+ break;
165
+ case 'flag':
166
+ this.status = 'flagged';
167
+ this.isVisible = false;
168
+ break;
169
+ }
170
+ if (notes) {
171
+ this.moderationNotes = notes;
172
+ }
173
+ return this.save();
174
+ };
175
+ // Static method to calculate weighted rating for an event
176
+ reviewSchema.statics.calculateWeightedRating = async function (eventId) {
177
+ const reviews = await this.find({
178
+ eventId: new mongoose_1.default.Types.ObjectId(eventId),
179
+ status: 'approved',
180
+ isVisible: true
181
+ });
182
+ if (reviews.length === 0)
183
+ return 0;
184
+ let totalWeightedRating = 0;
185
+ let totalWeight = 0;
186
+ reviews.forEach((review) => {
187
+ const weight = review.reviewContext.hasCheckedIn ? 1.0 : 0.6;
188
+ totalWeightedRating += review.rating * weight;
189
+ totalWeight += weight;
190
+ });
191
+ return totalWeight > 0 ? totalWeightedRating / totalWeight : 0;
192
+ };
193
+ // Pre-save middleware to set default status
194
+ reviewSchema.pre('save', function (next) {
195
+ if (this.isNew && !this.status) {
196
+ this.status = 'pending';
197
+ }
198
+ next();
199
+ });
200
+ exports.default = reviewSchema;
package/dist/Ticket.d.ts CHANGED
@@ -6,11 +6,11 @@ declare const ticketSchema: mongoose.Schema<any, mongoose.Model<any, any, any, a
6
6
  eventId: mongoose.Types.ObjectId;
7
7
  ticketVariantId: mongoose.Types.ObjectId;
8
8
  orderId: mongoose.Types.ObjectId;
9
+ ticketType: string;
9
10
  ticketNumber: string;
10
11
  eventTitle: string;
11
12
  eventDate: NativeDate;
12
13
  eventVenue: string;
13
- ticketType: string;
14
14
  qrCode: string;
15
15
  qrCodeUrl: string;
16
16
  checkInStatus: "not_checked_in" | "checked_in";
@@ -28,11 +28,11 @@ declare const ticketSchema: mongoose.Schema<any, mongoose.Model<any, any, any, a
28
28
  eventId: mongoose.Types.ObjectId;
29
29
  ticketVariantId: mongoose.Types.ObjectId;
30
30
  orderId: mongoose.Types.ObjectId;
31
+ ticketType: string;
31
32
  ticketNumber: string;
32
33
  eventTitle: string;
33
34
  eventDate: NativeDate;
34
35
  eventVenue: string;
35
- ticketType: string;
36
36
  qrCode: string;
37
37
  qrCodeUrl: string;
38
38
  checkInStatus: "not_checked_in" | "checked_in";
@@ -50,11 +50,11 @@ declare const ticketSchema: mongoose.Schema<any, mongoose.Model<any, any, any, a
50
50
  eventId: mongoose.Types.ObjectId;
51
51
  ticketVariantId: mongoose.Types.ObjectId;
52
52
  orderId: mongoose.Types.ObjectId;
53
+ ticketType: string;
53
54
  ticketNumber: string;
54
55
  eventTitle: string;
55
56
  eventDate: NativeDate;
56
57
  eventVenue: string;
57
- ticketType: string;
58
58
  qrCode: string;
59
59
  qrCodeUrl: string;
60
60
  checkInStatus: "not_checked_in" | "checked_in";
package/dist/index.d.ts CHANGED
@@ -8,5 +8,7 @@ export { default as userSchema } from './User';
8
8
  export { default as eventViewsSchema } from './Event.views';
9
9
  export { default as payoutSchema } from './Payout';
10
10
  export { default as auditLogSchema } from './AuditLog';
11
+ export { default as reviewSchema } from './Review';
11
12
  export type { IAuditLog } from './AuditLog';
13
+ export type { IReview } from './Review';
12
14
  export { AuditSeverity, AuditCategory, AuditStatus } from './AuditLog';
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.AuditStatus = exports.AuditCategory = exports.AuditSeverity = exports.auditLogSchema = exports.payoutSchema = exports.eventViewsSchema = exports.userSchema = exports.orderSchema = exports.paymentSchema = exports.bkashSchema = exports.mediaSchema = exports.ticketSchema = exports.eventSchema = void 0;
6
+ exports.AuditStatus = exports.AuditCategory = exports.AuditSeverity = exports.reviewSchema = exports.auditLogSchema = exports.payoutSchema = exports.eventViewsSchema = exports.userSchema = exports.orderSchema = exports.paymentSchema = exports.bkashSchema = exports.mediaSchema = exports.ticketSchema = exports.eventSchema = void 0;
7
7
  // Shared database models for Pinecone microservices
8
8
  var Event_1 = require("./Event");
9
9
  Object.defineProperty(exports, "eventSchema", { enumerable: true, get: function () { return __importDefault(Event_1).default; } });
@@ -25,6 +25,8 @@ var Payout_1 = require("./Payout");
25
25
  Object.defineProperty(exports, "payoutSchema", { enumerable: true, get: function () { return __importDefault(Payout_1).default; } });
26
26
  var AuditLog_1 = require("./AuditLog");
27
27
  Object.defineProperty(exports, "auditLogSchema", { enumerable: true, get: function () { return __importDefault(AuditLog_1).default; } });
28
+ var Review_1 = require("./Review");
29
+ Object.defineProperty(exports, "reviewSchema", { enumerable: true, get: function () { return __importDefault(Review_1).default; } });
28
30
  var AuditLog_2 = require("./AuditLog");
29
31
  Object.defineProperty(exports, "AuditSeverity", { enumerable: true, get: function () { return AuditLog_2.AuditSeverity; } });
30
32
  Object.defineProperty(exports, "AuditCategory", { enumerable: true, get: function () { return AuditLog_2.AuditCategory; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mac777/project-pinecone-models",
3
- "version": "1.1.21",
3
+ "version": "1.1.23",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
package/src/AuditLog.ts CHANGED
@@ -42,7 +42,7 @@ export interface IAuditLog extends Document {
42
42
  }
43
43
 
44
44
  const auditLogSchema = new Schema<IAuditLog>({
45
- userId: { type: String, index: true },
45
+ userId: { type: String, ref: 'User', index: true },
46
46
  action: { type: String, required: true, index: true },
47
47
  category: {
48
48
  type: String,
package/src/Review.ts ADDED
@@ -0,0 +1,268 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ export interface IReview {
4
+ eventId: mongoose.Types.ObjectId;
5
+ userId: mongoose.Types.ObjectId;
6
+ ticketId: mongoose.Types.ObjectId;
7
+
8
+ // Review Content
9
+ rating: number; // 1-5 stars
10
+ title: string;
11
+ comment: string;
12
+
13
+ // Context Metadata (smart dual-context approach)
14
+ reviewContext: {
15
+ hasCheckedIn: boolean;
16
+ checkInTime?: Date;
17
+ ticketTier: string;
18
+ ticketType: string;
19
+ };
20
+
21
+ // Status & Moderation
22
+ status: 'pending' | 'approved' | 'hidden' | 'flagged';
23
+ isVisible: boolean;
24
+ moderationNotes?: string;
25
+
26
+ // Timestamps
27
+ submittedAt: Date;
28
+ moderatedAt?: Date;
29
+ moderatorId?: mongoose.Types.ObjectId;
30
+
31
+ // Community Features
32
+ helpfulVotes: number;
33
+ reportedCount: number;
34
+ reports: Array<{
35
+ userId: mongoose.Types.ObjectId;
36
+ reason: string;
37
+ reportedAt: Date;
38
+ }>;
39
+ }
40
+
41
+ const reviewSchema = new mongoose.Schema<IReview>({
42
+ eventId: {
43
+ type: mongoose.Schema.Types.ObjectId,
44
+ ref: 'Event',
45
+ required: true,
46
+ index: true
47
+ },
48
+
49
+ userId: {
50
+ type: mongoose.Schema.Types.ObjectId,
51
+ ref: 'User',
52
+ required: true,
53
+ index: true
54
+ },
55
+
56
+ ticketId: {
57
+ type: mongoose.Schema.Types.ObjectId,
58
+ ref: 'Ticket',
59
+ required: true,
60
+ index: true
61
+ },
62
+
63
+ // Review Content
64
+ rating: {
65
+ type: Number,
66
+ required: true,
67
+ min: 1,
68
+ max: 5,
69
+ validate: {
70
+ validator: Number.isInteger,
71
+ message: 'Rating must be a whole number'
72
+ }
73
+ },
74
+
75
+ title: {
76
+ type: String,
77
+ required: true,
78
+ trim: true,
79
+ maxlength: 100
80
+ },
81
+
82
+ comment: {
83
+ type: String,
84
+ required: true,
85
+ trim: true,
86
+ maxlength: 1000
87
+ },
88
+
89
+ // Context Metadata
90
+ reviewContext: {
91
+ hasCheckedIn: {
92
+ type: Boolean,
93
+ required: true
94
+ },
95
+ checkInTime: Date,
96
+ ticketTier: {
97
+ type: String,
98
+ required: true
99
+ },
100
+ ticketType: {
101
+ type: String,
102
+ required: true
103
+ }
104
+ },
105
+
106
+ // Status & Moderation
107
+ status: {
108
+ type: String,
109
+ enum: ['pending', 'approved', 'hidden', 'flagged'],
110
+ default: 'pending',
111
+ index: true
112
+ },
113
+
114
+ isVisible: {
115
+ type: Boolean,
116
+ default: true
117
+ },
118
+
119
+ moderationNotes: {
120
+ type: String,
121
+ trim: true,
122
+ maxlength: 500
123
+ },
124
+
125
+ // Timestamps
126
+ submittedAt: {
127
+ type: Date,
128
+ default: Date.now,
129
+ index: true
130
+ },
131
+
132
+ moderatedAt: Date,
133
+
134
+ moderatorId: {
135
+ type: mongoose.Schema.Types.ObjectId,
136
+ ref: 'User'
137
+ },
138
+
139
+ // Community Features
140
+ helpfulVotes: {
141
+ type: Number,
142
+ default: 0,
143
+ min: 0
144
+ },
145
+
146
+ reportedCount: {
147
+ type: Number,
148
+ default: 0,
149
+ min: 0
150
+ },
151
+
152
+ reports: [{
153
+ userId: {
154
+ type: mongoose.Schema.Types.ObjectId,
155
+ ref: 'User',
156
+ required: true
157
+ },
158
+ reason: {
159
+ type: String,
160
+ required: true,
161
+ enum: ['spam', 'abusive', 'fake', 'irrelevant', 'other']
162
+ },
163
+ reportedAt: {
164
+ type: Date,
165
+ default: Date.now
166
+ }
167
+ }]
168
+ });
169
+
170
+ // Compound indexes for efficient queries
171
+ reviewSchema.index({ eventId: 1, status: 1, isVisible: 1 });
172
+ reviewSchema.index({ userId: 1, eventId: 1 }, { unique: true }); // One review per user per event
173
+ reviewSchema.index({ submittedAt: -1 });
174
+ reviewSchema.index({ 'reviewContext.hasCheckedIn': 1 });
175
+
176
+ // Virtual for review type classification
177
+ reviewSchema.virtual('reviewType').get(function() {
178
+ return this.reviewContext.hasCheckedIn ? 'attended' : 'entry_access';
179
+ });
180
+
181
+ // Method to mark as helpful
182
+ reviewSchema.methods.markHelpful = function() {
183
+ this.helpfulVotes += 1;
184
+ return this.save();
185
+ };
186
+
187
+ // Method to report review
188
+ reviewSchema.methods.report = function(userId: string, reason: string) {
189
+ // Check if user already reported
190
+ const existingReport = this.reports.find((report: any) =>
191
+ report.userId.toString() === userId
192
+ );
193
+
194
+ if (!existingReport) {
195
+ this.reports.push({
196
+ userId: new mongoose.Types.ObjectId(userId),
197
+ reason,
198
+ reportedAt: new Date()
199
+ });
200
+ this.reportedCount += 1;
201
+
202
+ // Auto-flag if too many reports
203
+ if (this.reportedCount >= 3) {
204
+ this.status = 'flagged';
205
+ }
206
+ }
207
+
208
+ return this.save();
209
+ };
210
+
211
+ // Method for admin moderation
212
+ reviewSchema.methods.moderate = function(moderatorId: string, action: 'approve' | 'hide' | 'flag', notes?: string) {
213
+ this.moderatorId = new mongoose.Types.ObjectId(moderatorId);
214
+ this.moderatedAt = new Date();
215
+
216
+ switch (action) {
217
+ case 'approve':
218
+ this.status = 'approved';
219
+ this.isVisible = true;
220
+ break;
221
+ case 'hide':
222
+ this.status = 'hidden';
223
+ this.isVisible = false;
224
+ break;
225
+ case 'flag':
226
+ this.status = 'flagged';
227
+ this.isVisible = false;
228
+ break;
229
+ }
230
+
231
+ if (notes) {
232
+ this.moderationNotes = notes;
233
+ }
234
+
235
+ return this.save();
236
+ };
237
+
238
+ // Static method to calculate weighted rating for an event
239
+ reviewSchema.statics.calculateWeightedRating = async function(eventId: string) {
240
+ const reviews = await this.find({
241
+ eventId: new mongoose.Types.ObjectId(eventId),
242
+ status: 'approved',
243
+ isVisible: true
244
+ });
245
+
246
+ if (reviews.length === 0) return 0;
247
+
248
+ let totalWeightedRating = 0;
249
+ let totalWeight = 0;
250
+
251
+ reviews.forEach((review: any) => {
252
+ const weight = review.reviewContext.hasCheckedIn ? 1.0 : 0.6;
253
+ totalWeightedRating += review.rating * weight;
254
+ totalWeight += weight;
255
+ });
256
+
257
+ return totalWeight > 0 ? totalWeightedRating / totalWeight : 0;
258
+ };
259
+
260
+ // Pre-save middleware to set default status
261
+ reviewSchema.pre('save', function(next) {
262
+ if (this.isNew && !this.status) {
263
+ this.status = 'pending';
264
+ }
265
+ next();
266
+ });
267
+
268
+ export default reviewSchema;
package/src/index.ts CHANGED
@@ -9,5 +9,7 @@ export { default as userSchema } from './User';
9
9
  export { default as eventViewsSchema } from './Event.views';
10
10
  export { default as payoutSchema } from './Payout';
11
11
  export { default as auditLogSchema } from './AuditLog';
12
+ export { default as reviewSchema } from './Review';
12
13
  export type { IAuditLog } from './AuditLog';
13
- export { AuditSeverity, AuditCategory, AuditStatus } from './AuditLog';
14
+ export type { IReview } from './Review';
15
+ export { AuditSeverity, AuditCategory, AuditStatus } from './AuditLog';