92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
import { Coupon, CouponStatus } from '../entities/coupon.entity';
|
|
|
|
export const COUPON_REPOSITORY = Symbol('ICouponRepository');
|
|
|
|
export interface CouponListFilters {
|
|
category?: string;
|
|
status?: string;
|
|
search?: string;
|
|
issuerId?: string;
|
|
page: number;
|
|
limit: number;
|
|
}
|
|
|
|
export interface CouponAggregateResult {
|
|
totalCoupons: number;
|
|
totalSupply: number;
|
|
totalSold: number;
|
|
totalRemaining: number;
|
|
}
|
|
|
|
export interface CouponStatusCount {
|
|
status: string;
|
|
count: number;
|
|
}
|
|
|
|
export interface CouponsByIssuerRow {
|
|
issuerId: string;
|
|
couponCount: number;
|
|
totalSupply: number;
|
|
totalSold: number;
|
|
totalFaceValue: number;
|
|
}
|
|
|
|
export interface CouponsByCategoryRow {
|
|
category: string;
|
|
couponCount: number;
|
|
totalSupply: number;
|
|
totalSold: number;
|
|
avgPrice: number;
|
|
}
|
|
|
|
export interface CouponSoldAggregateRow {
|
|
issuerId: string;
|
|
totalSold: number;
|
|
}
|
|
|
|
export interface DiscountDistributionRow {
|
|
range: string;
|
|
count: number;
|
|
avgDiscount: number;
|
|
}
|
|
|
|
export interface RedemptionRateRow {
|
|
month: string;
|
|
totalIssued: number;
|
|
totalSold: number;
|
|
}
|
|
|
|
export interface OwnerSummary {
|
|
count: number;
|
|
totalFaceValue: number;
|
|
totalSaved: number;
|
|
}
|
|
|
|
export interface ICouponRepository {
|
|
findById(id: string): Promise<Coupon | null>;
|
|
create(data: Partial<Coupon>): Promise<Coupon>;
|
|
save(coupon: Coupon): Promise<Coupon>;
|
|
findAndCount(filters: CouponListFilters): Promise<[Coupon[], number]>;
|
|
findAndCountWithIssuerJoin(filters: CouponListFilters): Promise<[Coupon[], number]>;
|
|
findByOwnerWithIssuerJoin(userId: string, filters: CouponListFilters): Promise<[Coupon[], number]>;
|
|
getOwnerSummary(userId: string): Promise<OwnerSummary>;
|
|
updateStatus(id: string, status: string): Promise<Coupon>;
|
|
purchaseWithLock(couponId: string, quantity: number): Promise<Coupon>;
|
|
count(where?: Partial<Record<string, any>>): Promise<number>;
|
|
|
|
// Analytics aggregates
|
|
getAggregateStats(): Promise<CouponAggregateResult>;
|
|
getStatusCounts(): Promise<CouponStatusCount[]>;
|
|
getCouponsByIssuer(): Promise<CouponsByIssuerRow[]>;
|
|
getCouponsByCategory(): Promise<CouponsByCategoryRow[]>;
|
|
getTotalSold(): Promise<number>;
|
|
getTotalSoldByStatuses(statuses: CouponStatus[]): Promise<number>;
|
|
getRedemptionRateTrend(): Promise<RedemptionRateRow[]>;
|
|
getDiscountDistribution(): Promise<DiscountDistributionRow[]>;
|
|
|
|
// Merchant analytics
|
|
getCouponSupplyAggregate(): Promise<{ totalCouponsIssued: number; totalCouponsSold: number }>;
|
|
getSoldPerIssuer(issuerIds: string[]): Promise<CouponSoldAggregateRow[]>;
|
|
getRecentlySoldCoupons(limit: number): Promise<Coupon[]>;
|
|
}
|