initial commit
This commit is contained in:
121
models/transaction.ts
Normal file
121
models/transaction.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import mongoose, { Document, Model } from 'mongoose'
|
||||
import { z } from 'zod'
|
||||
|
||||
// Zod schema for validation
|
||||
export const TransactionSchema = z.object({
|
||||
transactionId: z.string().min(1, 'Transaction ID is required'),
|
||||
userId: z.string().min(1, 'User ID is required'),
|
||||
email: z.string().email('Invalid email format'),
|
||||
type: z.enum(['debit', 'credit']),
|
||||
amount: z.number().positive('Amount must be positive'),
|
||||
service: z.string().min(1, 'Service name is required'),
|
||||
serviceId: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
status: z.enum(['pending', 'completed', 'failed']).default('completed'),
|
||||
previousBalance: z.number().min(0, 'Previous balance cannot be negative'),
|
||||
newBalance: z.number().min(0, 'New balance cannot be negative'),
|
||||
metadata: z.record(z.string(), z.any()).optional(),
|
||||
})
|
||||
|
||||
export type TransactionType = z.infer<typeof TransactionSchema>
|
||||
|
||||
// Mongoose interface
|
||||
export interface ITransaction extends Document {
|
||||
transactionId: string
|
||||
userId: string
|
||||
email: string
|
||||
type: 'debit' | 'credit'
|
||||
amount: number
|
||||
service: string
|
||||
serviceId?: string
|
||||
description?: string
|
||||
status: 'pending' | 'completed' | 'failed'
|
||||
previousBalance: number
|
||||
newBalance: number
|
||||
metadata?: Record<string, any>
|
||||
createdAt: Date
|
||||
updatedAt: Date
|
||||
}
|
||||
|
||||
// Mongoose schema
|
||||
const transactionSchema = new mongoose.Schema<ITransaction>(
|
||||
{
|
||||
transactionId: {
|
||||
type: String,
|
||||
required: true,
|
||||
unique: true,
|
||||
index: true,
|
||||
},
|
||||
userId: {
|
||||
type: String,
|
||||
required: true,
|
||||
index: true,
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
required: true,
|
||||
lowercase: true,
|
||||
trim: true,
|
||||
index: true,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
enum: ['debit', 'credit'],
|
||||
required: true,
|
||||
},
|
||||
amount: {
|
||||
type: Number,
|
||||
required: true,
|
||||
min: 0,
|
||||
},
|
||||
service: {
|
||||
type: String,
|
||||
required: true,
|
||||
trim: true,
|
||||
},
|
||||
serviceId: {
|
||||
type: String,
|
||||
trim: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
trim: true,
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
enum: ['pending', 'completed', 'failed'],
|
||||
default: 'completed',
|
||||
},
|
||||
previousBalance: {
|
||||
type: Number,
|
||||
required: true,
|
||||
min: 0,
|
||||
},
|
||||
newBalance: {
|
||||
type: Number,
|
||||
required: true,
|
||||
min: 0,
|
||||
},
|
||||
metadata: {
|
||||
type: mongoose.Schema.Types.Mixed,
|
||||
},
|
||||
},
|
||||
{
|
||||
timestamps: true,
|
||||
}
|
||||
)
|
||||
|
||||
// Indexes for performance
|
||||
transactionSchema.index({ userId: 1, createdAt: -1 })
|
||||
transactionSchema.index({ email: 1, createdAt: -1 })
|
||||
transactionSchema.index({ service: 1, createdAt: -1 })
|
||||
transactionSchema.index({ type: 1, createdAt: -1 })
|
||||
|
||||
// Transform method to format response
|
||||
transactionSchema.methods.toJSON = function () {
|
||||
const transaction = this.toObject()
|
||||
return transaction
|
||||
}
|
||||
|
||||
export const Transaction: Model<ITransaction> =
|
||||
mongoose.models.Transaction || mongoose.model<ITransaction>('Transaction', transactionSchema)
|
||||
Reference in New Issue
Block a user