clhq-postgres-module 1.1.0-alpha.97 → 1.1.0-alpha.99
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/entities/credit-allocation.entity.d.ts +23 -0
- package/dist/entities/credit-allocation.entity.js +91 -0
- package/dist/entities/credit-consumption-log.entity.d.ts +32 -0
- package/dist/entities/credit-consumption-log.entity.js +127 -0
- package/dist/entities/credit-transaction.entity.d.ts +7 -0
- package/dist/entities/credit-transaction.entity.js +28 -0
- package/dist/entities/index.d.ts +3 -0
- package/dist/entities/index.js +3 -0
- package/dist/entities/referral-event.entity.d.ts +41 -0
- package/dist/entities/referral-event.entity.js +170 -0
- package/dist/postgres.module.js +1 -0
- package/dist/repositories/index.d.ts +1 -0
- package/dist/repositories/index.js +3 -1
- package/dist/repositories/referral-event.repository.d.ts +37 -0
- package/dist/repositories/referral-event.repository.js +154 -0
- package/dist/repositories/repository.module.js +2 -0
- package/package.json +7 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { User } from './user.entity';
|
|
2
|
+
export declare enum CreditAllocationStatus {
|
|
3
|
+
ACTIVE = "active",
|
|
4
|
+
EXPIRED = "expired",
|
|
5
|
+
UPGRADED = "upgraded",
|
|
6
|
+
CANCELLED = "cancelled"
|
|
7
|
+
}
|
|
8
|
+
export declare class CreditAllocation {
|
|
9
|
+
id: string;
|
|
10
|
+
userId: string;
|
|
11
|
+
user: User;
|
|
12
|
+
planId: string;
|
|
13
|
+
creditsAllocated: number;
|
|
14
|
+
creditsRemaining: number;
|
|
15
|
+
aiCreditsAllocated: number;
|
|
16
|
+
aiCreditsRemaining: number;
|
|
17
|
+
periodStart: Date;
|
|
18
|
+
periodEnd: Date;
|
|
19
|
+
rolloverCredits: number;
|
|
20
|
+
status: CreditAllocationStatus;
|
|
21
|
+
createdAt: Date;
|
|
22
|
+
updatedAt: Date;
|
|
23
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CreditAllocation = exports.CreditAllocationStatus = void 0;
|
|
13
|
+
const typeorm_1 = require("typeorm");
|
|
14
|
+
const user_entity_1 = require("./user.entity");
|
|
15
|
+
var CreditAllocationStatus;
|
|
16
|
+
(function (CreditAllocationStatus) {
|
|
17
|
+
CreditAllocationStatus["ACTIVE"] = "active";
|
|
18
|
+
CreditAllocationStatus["EXPIRED"] = "expired";
|
|
19
|
+
CreditAllocationStatus["UPGRADED"] = "upgraded";
|
|
20
|
+
CreditAllocationStatus["CANCELLED"] = "cancelled";
|
|
21
|
+
})(CreditAllocationStatus || (exports.CreditAllocationStatus = CreditAllocationStatus = {}));
|
|
22
|
+
let CreditAllocation = class CreditAllocation {
|
|
23
|
+
};
|
|
24
|
+
exports.CreditAllocation = CreditAllocation;
|
|
25
|
+
__decorate([
|
|
26
|
+
(0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
|
|
27
|
+
__metadata("design:type", String)
|
|
28
|
+
], CreditAllocation.prototype, "id", void 0);
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, typeorm_1.Column)({ name: 'user_id' }),
|
|
31
|
+
__metadata("design:type", String)
|
|
32
|
+
], CreditAllocation.prototype, "userId", void 0);
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, typeorm_1.ManyToOne)(() => user_entity_1.User),
|
|
35
|
+
(0, typeorm_1.JoinColumn)({ name: 'user_id' }),
|
|
36
|
+
__metadata("design:type", user_entity_1.User)
|
|
37
|
+
], CreditAllocation.prototype, "user", void 0);
|
|
38
|
+
__decorate([
|
|
39
|
+
(0, typeorm_1.Column)({ name: 'plan_id', length: 50 }),
|
|
40
|
+
__metadata("design:type", String)
|
|
41
|
+
], CreditAllocation.prototype, "planId", void 0);
|
|
42
|
+
__decorate([
|
|
43
|
+
(0, typeorm_1.Column)({ name: 'credits_allocated' }),
|
|
44
|
+
__metadata("design:type", Number)
|
|
45
|
+
], CreditAllocation.prototype, "creditsAllocated", void 0);
|
|
46
|
+
__decorate([
|
|
47
|
+
(0, typeorm_1.Column)({ name: 'credits_remaining' }),
|
|
48
|
+
__metadata("design:type", Number)
|
|
49
|
+
], CreditAllocation.prototype, "creditsRemaining", void 0);
|
|
50
|
+
__decorate([
|
|
51
|
+
(0, typeorm_1.Column)({ name: 'ai_credits_allocated', default: 0 }),
|
|
52
|
+
__metadata("design:type", Number)
|
|
53
|
+
], CreditAllocation.prototype, "aiCreditsAllocated", void 0);
|
|
54
|
+
__decorate([
|
|
55
|
+
(0, typeorm_1.Column)({ name: 'ai_credits_remaining', default: 0 }),
|
|
56
|
+
__metadata("design:type", Number)
|
|
57
|
+
], CreditAllocation.prototype, "aiCreditsRemaining", void 0);
|
|
58
|
+
__decorate([
|
|
59
|
+
(0, typeorm_1.Column)({ name: 'period_start' }),
|
|
60
|
+
__metadata("design:type", Date)
|
|
61
|
+
], CreditAllocation.prototype, "periodStart", void 0);
|
|
62
|
+
__decorate([
|
|
63
|
+
(0, typeorm_1.Column)({ name: 'period_end' }),
|
|
64
|
+
__metadata("design:type", Date)
|
|
65
|
+
], CreditAllocation.prototype, "periodEnd", void 0);
|
|
66
|
+
__decorate([
|
|
67
|
+
(0, typeorm_1.Column)({ name: 'rollover_credits', default: 0 }),
|
|
68
|
+
__metadata("design:type", Number)
|
|
69
|
+
], CreditAllocation.prototype, "rolloverCredits", void 0);
|
|
70
|
+
__decorate([
|
|
71
|
+
(0, typeorm_1.Column)({
|
|
72
|
+
type: 'enum',
|
|
73
|
+
enum: CreditAllocationStatus,
|
|
74
|
+
default: CreditAllocationStatus.ACTIVE,
|
|
75
|
+
}),
|
|
76
|
+
__metadata("design:type", String)
|
|
77
|
+
], CreditAllocation.prototype, "status", void 0);
|
|
78
|
+
__decorate([
|
|
79
|
+
(0, typeorm_1.CreateDateColumn)({ name: 'created_at' }),
|
|
80
|
+
__metadata("design:type", Date)
|
|
81
|
+
], CreditAllocation.prototype, "createdAt", void 0);
|
|
82
|
+
__decorate([
|
|
83
|
+
(0, typeorm_1.UpdateDateColumn)({ name: 'updated_at' }),
|
|
84
|
+
__metadata("design:type", Date)
|
|
85
|
+
], CreditAllocation.prototype, "updatedAt", void 0);
|
|
86
|
+
exports.CreditAllocation = CreditAllocation = __decorate([
|
|
87
|
+
(0, typeorm_1.Entity)('credit_allocations'),
|
|
88
|
+
(0, typeorm_1.Index)(['userId'], { unique: false }),
|
|
89
|
+
(0, typeorm_1.Index)(['periodStart', 'periodEnd'], { unique: false }),
|
|
90
|
+
(0, typeorm_1.Index)(['status'], { unique: false })
|
|
91
|
+
], CreditAllocation);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { User } from './user.entity';
|
|
2
|
+
import { CreditAllocation } from './credit-allocation.entity';
|
|
3
|
+
import { CreditTransaction } from './credit-transaction.entity';
|
|
4
|
+
export declare enum ConsumptionStatus {
|
|
5
|
+
PENDING = "pending",
|
|
6
|
+
RESERVED = "reserved",
|
|
7
|
+
COMPLETED = "completed",
|
|
8
|
+
FAILED = "failed",
|
|
9
|
+
REFUNDED = "refunded"
|
|
10
|
+
}
|
|
11
|
+
export declare class CreditConsumptionLog {
|
|
12
|
+
id: string;
|
|
13
|
+
userId: string;
|
|
14
|
+
user: User;
|
|
15
|
+
allocationId?: string;
|
|
16
|
+
allocation?: CreditAllocation;
|
|
17
|
+
transactionId?: string;
|
|
18
|
+
transaction?: CreditTransaction;
|
|
19
|
+
operationType: string;
|
|
20
|
+
operationId?: string;
|
|
21
|
+
baseCredits: number;
|
|
22
|
+
modifierCredits: number;
|
|
23
|
+
totalCredits: number;
|
|
24
|
+
operationParams: Record<string, any>;
|
|
25
|
+
status: ConsumptionStatus;
|
|
26
|
+
startedAt: Date;
|
|
27
|
+
completedAt?: Date;
|
|
28
|
+
resultUrl?: string;
|
|
29
|
+
errorMessage?: string;
|
|
30
|
+
createdAt: Date;
|
|
31
|
+
updatedAt: Date;
|
|
32
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CreditConsumptionLog = exports.ConsumptionStatus = void 0;
|
|
13
|
+
const typeorm_1 = require("typeorm");
|
|
14
|
+
const user_entity_1 = require("./user.entity");
|
|
15
|
+
const credit_allocation_entity_1 = require("./credit-allocation.entity");
|
|
16
|
+
const credit_transaction_entity_1 = require("./credit-transaction.entity");
|
|
17
|
+
var ConsumptionStatus;
|
|
18
|
+
(function (ConsumptionStatus) {
|
|
19
|
+
ConsumptionStatus["PENDING"] = "pending";
|
|
20
|
+
ConsumptionStatus["RESERVED"] = "reserved";
|
|
21
|
+
ConsumptionStatus["COMPLETED"] = "completed";
|
|
22
|
+
ConsumptionStatus["FAILED"] = "failed";
|
|
23
|
+
ConsumptionStatus["REFUNDED"] = "refunded";
|
|
24
|
+
})(ConsumptionStatus || (exports.ConsumptionStatus = ConsumptionStatus = {}));
|
|
25
|
+
let CreditConsumptionLog = class CreditConsumptionLog {
|
|
26
|
+
};
|
|
27
|
+
exports.CreditConsumptionLog = CreditConsumptionLog;
|
|
28
|
+
__decorate([
|
|
29
|
+
(0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
|
|
30
|
+
__metadata("design:type", String)
|
|
31
|
+
], CreditConsumptionLog.prototype, "id", void 0);
|
|
32
|
+
__decorate([
|
|
33
|
+
(0, typeorm_1.Column)({ name: 'user_id' }),
|
|
34
|
+
__metadata("design:type", String)
|
|
35
|
+
], CreditConsumptionLog.prototype, "userId", void 0);
|
|
36
|
+
__decorate([
|
|
37
|
+
(0, typeorm_1.ManyToOne)(() => user_entity_1.User),
|
|
38
|
+
(0, typeorm_1.JoinColumn)({ name: 'user_id' }),
|
|
39
|
+
__metadata("design:type", user_entity_1.User)
|
|
40
|
+
], CreditConsumptionLog.prototype, "user", void 0);
|
|
41
|
+
__decorate([
|
|
42
|
+
(0, typeorm_1.Column)({ name: 'allocation_id', nullable: true }),
|
|
43
|
+
__metadata("design:type", String)
|
|
44
|
+
], CreditConsumptionLog.prototype, "allocationId", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
(0, typeorm_1.ManyToOne)(() => credit_allocation_entity_1.CreditAllocation, { nullable: true }),
|
|
47
|
+
(0, typeorm_1.JoinColumn)({ name: 'allocation_id' }),
|
|
48
|
+
__metadata("design:type", credit_allocation_entity_1.CreditAllocation)
|
|
49
|
+
], CreditConsumptionLog.prototype, "allocation", void 0);
|
|
50
|
+
__decorate([
|
|
51
|
+
(0, typeorm_1.Column)({ name: 'transaction_id', nullable: true }),
|
|
52
|
+
__metadata("design:type", String)
|
|
53
|
+
], CreditConsumptionLog.prototype, "transactionId", void 0);
|
|
54
|
+
__decorate([
|
|
55
|
+
(0, typeorm_1.ManyToOne)(() => credit_transaction_entity_1.CreditTransaction, { nullable: true }),
|
|
56
|
+
(0, typeorm_1.JoinColumn)({ name: 'transaction_id' }),
|
|
57
|
+
__metadata("design:type", credit_transaction_entity_1.CreditTransaction)
|
|
58
|
+
], CreditConsumptionLog.prototype, "transaction", void 0);
|
|
59
|
+
__decorate([
|
|
60
|
+
(0, typeorm_1.Column)({ name: 'operation_type', length: 50 }),
|
|
61
|
+
__metadata("design:type", String)
|
|
62
|
+
], CreditConsumptionLog.prototype, "operationType", void 0);
|
|
63
|
+
__decorate([
|
|
64
|
+
(0, typeorm_1.Column)({ name: 'operation_id', length: 100, nullable: true }),
|
|
65
|
+
__metadata("design:type", String)
|
|
66
|
+
], CreditConsumptionLog.prototype, "operationId", void 0);
|
|
67
|
+
__decorate([
|
|
68
|
+
(0, typeorm_1.Column)({ name: 'base_credits', type: 'decimal', precision: 10, scale: 2 }),
|
|
69
|
+
__metadata("design:type", Number)
|
|
70
|
+
], CreditConsumptionLog.prototype, "baseCredits", void 0);
|
|
71
|
+
__decorate([
|
|
72
|
+
(0, typeorm_1.Column)({
|
|
73
|
+
name: 'modifier_credits',
|
|
74
|
+
type: 'decimal',
|
|
75
|
+
precision: 10,
|
|
76
|
+
scale: 2,
|
|
77
|
+
default: 0,
|
|
78
|
+
}),
|
|
79
|
+
__metadata("design:type", Number)
|
|
80
|
+
], CreditConsumptionLog.prototype, "modifierCredits", void 0);
|
|
81
|
+
__decorate([
|
|
82
|
+
(0, typeorm_1.Column)({ name: 'total_credits', type: 'decimal', precision: 10, scale: 2 }),
|
|
83
|
+
__metadata("design:type", Number)
|
|
84
|
+
], CreditConsumptionLog.prototype, "totalCredits", void 0);
|
|
85
|
+
__decorate([
|
|
86
|
+
(0, typeorm_1.Column)({ name: 'operation_params', type: 'jsonb', default: {} }),
|
|
87
|
+
__metadata("design:type", Object)
|
|
88
|
+
], CreditConsumptionLog.prototype, "operationParams", void 0);
|
|
89
|
+
__decorate([
|
|
90
|
+
(0, typeorm_1.Column)({
|
|
91
|
+
type: 'enum',
|
|
92
|
+
enum: ConsumptionStatus,
|
|
93
|
+
default: ConsumptionStatus.PENDING,
|
|
94
|
+
}),
|
|
95
|
+
__metadata("design:type", String)
|
|
96
|
+
], CreditConsumptionLog.prototype, "status", void 0);
|
|
97
|
+
__decorate([
|
|
98
|
+
(0, typeorm_1.Column)({ name: 'started_at', default: () => 'NOW()' }),
|
|
99
|
+
__metadata("design:type", Date)
|
|
100
|
+
], CreditConsumptionLog.prototype, "startedAt", void 0);
|
|
101
|
+
__decorate([
|
|
102
|
+
(0, typeorm_1.Column)({ name: 'completed_at', nullable: true }),
|
|
103
|
+
__metadata("design:type", Date)
|
|
104
|
+
], CreditConsumptionLog.prototype, "completedAt", void 0);
|
|
105
|
+
__decorate([
|
|
106
|
+
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
107
|
+
__metadata("design:type", String)
|
|
108
|
+
], CreditConsumptionLog.prototype, "resultUrl", void 0);
|
|
109
|
+
__decorate([
|
|
110
|
+
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
111
|
+
__metadata("design:type", String)
|
|
112
|
+
], CreditConsumptionLog.prototype, "errorMessage", void 0);
|
|
113
|
+
__decorate([
|
|
114
|
+
(0, typeorm_1.CreateDateColumn)({ name: 'created_at' }),
|
|
115
|
+
__metadata("design:type", Date)
|
|
116
|
+
], CreditConsumptionLog.prototype, "createdAt", void 0);
|
|
117
|
+
__decorate([
|
|
118
|
+
(0, typeorm_1.UpdateDateColumn)({ name: 'updated_at' }),
|
|
119
|
+
__metadata("design:type", Date)
|
|
120
|
+
], CreditConsumptionLog.prototype, "updatedAt", void 0);
|
|
121
|
+
exports.CreditConsumptionLog = CreditConsumptionLog = __decorate([
|
|
122
|
+
(0, typeorm_1.Entity)('credit_consumption_log'),
|
|
123
|
+
(0, typeorm_1.Index)(['userId'], { unique: false }),
|
|
124
|
+
(0, typeorm_1.Index)(['operationType'], { unique: false }),
|
|
125
|
+
(0, typeorm_1.Index)(['status'], { unique: false }),
|
|
126
|
+
(0, typeorm_1.Index)(['createdAt'], { unique: false })
|
|
127
|
+
], CreditConsumptionLog);
|
|
@@ -7,6 +7,13 @@ export declare class CreditTransaction {
|
|
|
7
7
|
type: string;
|
|
8
8
|
description?: string;
|
|
9
9
|
stripePaymentIntentId?: string;
|
|
10
|
+
source?: string;
|
|
11
|
+
referenceId?: string;
|
|
12
|
+
expiresAt?: Date;
|
|
13
|
+
operationType?: string;
|
|
14
|
+
operationId?: string;
|
|
15
|
+
reservationId?: string;
|
|
16
|
+
status: string;
|
|
10
17
|
metadata: Record<string, any>;
|
|
11
18
|
createdAt: Date;
|
|
12
19
|
updatedAt: Date;
|
|
@@ -44,6 +44,34 @@ __decorate([
|
|
|
44
44
|
(0, typeorm_1.Column)({ name: 'stripe_payment_intent_id', nullable: true }),
|
|
45
45
|
__metadata("design:type", String)
|
|
46
46
|
], CreditTransaction.prototype, "stripePaymentIntentId", void 0);
|
|
47
|
+
__decorate([
|
|
48
|
+
(0, typeorm_1.Column)({ length: 50, nullable: true }),
|
|
49
|
+
__metadata("design:type", String)
|
|
50
|
+
], CreditTransaction.prototype, "source", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
(0, typeorm_1.Column)({ name: 'reference_id', type: 'uuid', nullable: true }),
|
|
53
|
+
__metadata("design:type", String)
|
|
54
|
+
], CreditTransaction.prototype, "referenceId", void 0);
|
|
55
|
+
__decorate([
|
|
56
|
+
(0, typeorm_1.Column)({ name: 'expires_at', type: 'timestamp', nullable: true }),
|
|
57
|
+
__metadata("design:type", Date)
|
|
58
|
+
], CreditTransaction.prototype, "expiresAt", void 0);
|
|
59
|
+
__decorate([
|
|
60
|
+
(0, typeorm_1.Column)({ name: 'operation_type', length: 50, nullable: true }),
|
|
61
|
+
__metadata("design:type", String)
|
|
62
|
+
], CreditTransaction.prototype, "operationType", void 0);
|
|
63
|
+
__decorate([
|
|
64
|
+
(0, typeorm_1.Column)({ name: 'operation_id', length: 100, nullable: true }),
|
|
65
|
+
__metadata("design:type", String)
|
|
66
|
+
], CreditTransaction.prototype, "operationId", void 0);
|
|
67
|
+
__decorate([
|
|
68
|
+
(0, typeorm_1.Column)({ name: 'reservation_id', type: 'uuid', nullable: true }),
|
|
69
|
+
__metadata("design:type", String)
|
|
70
|
+
], CreditTransaction.prototype, "reservationId", void 0);
|
|
71
|
+
__decorate([
|
|
72
|
+
(0, typeorm_1.Column)({ length: 20, default: 'completed' }),
|
|
73
|
+
__metadata("design:type", String)
|
|
74
|
+
], CreditTransaction.prototype, "status", void 0);
|
|
47
75
|
__decorate([
|
|
48
76
|
(0, typeorm_1.Column)({ type: 'jsonb', default: {} }),
|
|
49
77
|
__metadata("design:type", Object)
|
package/dist/entities/index.d.ts
CHANGED
|
@@ -14,7 +14,10 @@ export * from './subscription-usage.entity';
|
|
|
14
14
|
export * from './payment-transaction.entity';
|
|
15
15
|
export * from './stripe-webhook.entity';
|
|
16
16
|
export * from './credit-transaction.entity';
|
|
17
|
+
export * from './credit-allocation.entity';
|
|
18
|
+
export * from './credit-consumption-log.entity';
|
|
17
19
|
export * from './reward-rule.entity';
|
|
20
|
+
export * from './referral-event.entity';
|
|
18
21
|
export { AiUsage as AIUsage } from './ai-usage.entity';
|
|
19
22
|
export * from './asset.entity';
|
|
20
23
|
export * from './effect.entity';
|
package/dist/entities/index.js
CHANGED
|
@@ -31,7 +31,10 @@ __exportStar(require("./subscription-usage.entity"), exports);
|
|
|
31
31
|
__exportStar(require("./payment-transaction.entity"), exports);
|
|
32
32
|
__exportStar(require("./stripe-webhook.entity"), exports);
|
|
33
33
|
__exportStar(require("./credit-transaction.entity"), exports);
|
|
34
|
+
__exportStar(require("./credit-allocation.entity"), exports);
|
|
35
|
+
__exportStar(require("./credit-consumption-log.entity"), exports);
|
|
34
36
|
__exportStar(require("./reward-rule.entity"), exports);
|
|
37
|
+
__exportStar(require("./referral-event.entity"), exports);
|
|
35
38
|
var ai_usage_entity_1 = require("./ai-usage.entity");
|
|
36
39
|
Object.defineProperty(exports, "AIUsage", { enumerable: true, get: function () { return ai_usage_entity_1.AiUsage; } });
|
|
37
40
|
__exportStar(require("./asset.entity"), exports);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { User } from './user.entity';
|
|
2
|
+
export declare enum ReferralStatus {
|
|
3
|
+
SIGNUP = "signup",
|
|
4
|
+
EMAIL_VERIFIED = "email_verified",
|
|
5
|
+
FIRST_PROJECT = "first_project",
|
|
6
|
+
CONVERTED = "converted",
|
|
7
|
+
CHURNED = "churned"
|
|
8
|
+
}
|
|
9
|
+
export declare enum RewardStatus {
|
|
10
|
+
PENDING = "pending",
|
|
11
|
+
PROCESSING = "processing",
|
|
12
|
+
COMPLETED = "completed",
|
|
13
|
+
FAILED = "failed",
|
|
14
|
+
EXPIRED = "expired"
|
|
15
|
+
}
|
|
16
|
+
export declare class ReferralEvent {
|
|
17
|
+
id: string;
|
|
18
|
+
referrerId: string;
|
|
19
|
+
referrer: User;
|
|
20
|
+
referredId: string;
|
|
21
|
+
referred: User;
|
|
22
|
+
referralCode: string;
|
|
23
|
+
status: ReferralStatus;
|
|
24
|
+
conversionType?: string;
|
|
25
|
+
conversionValue: number;
|
|
26
|
+
referrerRewardAmount: number;
|
|
27
|
+
referredRewardAmount: number;
|
|
28
|
+
rewardStatus: RewardStatus;
|
|
29
|
+
rewardProcessedAt?: Date;
|
|
30
|
+
attributionSource?: string;
|
|
31
|
+
utmSource?: string;
|
|
32
|
+
utmMedium?: string;
|
|
33
|
+
utmCampaign?: string;
|
|
34
|
+
metadata: Record<string, any>;
|
|
35
|
+
ipAddress?: string;
|
|
36
|
+
userAgent?: string;
|
|
37
|
+
signupAt: Date;
|
|
38
|
+
convertedAt?: Date;
|
|
39
|
+
createdAt: Date;
|
|
40
|
+
updatedAt: Date;
|
|
41
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ReferralEvent = exports.RewardStatus = exports.ReferralStatus = void 0;
|
|
13
|
+
const typeorm_1 = require("typeorm");
|
|
14
|
+
const user_entity_1 = require("./user.entity");
|
|
15
|
+
var ReferralStatus;
|
|
16
|
+
(function (ReferralStatus) {
|
|
17
|
+
ReferralStatus["SIGNUP"] = "signup";
|
|
18
|
+
ReferralStatus["EMAIL_VERIFIED"] = "email_verified";
|
|
19
|
+
ReferralStatus["FIRST_PROJECT"] = "first_project";
|
|
20
|
+
ReferralStatus["CONVERTED"] = "converted";
|
|
21
|
+
ReferralStatus["CHURNED"] = "churned";
|
|
22
|
+
})(ReferralStatus || (exports.ReferralStatus = ReferralStatus = {}));
|
|
23
|
+
var RewardStatus;
|
|
24
|
+
(function (RewardStatus) {
|
|
25
|
+
RewardStatus["PENDING"] = "pending";
|
|
26
|
+
RewardStatus["PROCESSING"] = "processing";
|
|
27
|
+
RewardStatus["COMPLETED"] = "completed";
|
|
28
|
+
RewardStatus["FAILED"] = "failed";
|
|
29
|
+
RewardStatus["EXPIRED"] = "expired";
|
|
30
|
+
})(RewardStatus || (exports.RewardStatus = RewardStatus = {}));
|
|
31
|
+
let ReferralEvent = class ReferralEvent {
|
|
32
|
+
};
|
|
33
|
+
exports.ReferralEvent = ReferralEvent;
|
|
34
|
+
__decorate([
|
|
35
|
+
(0, typeorm_1.PrimaryGeneratedColumn)('uuid'),
|
|
36
|
+
__metadata("design:type", String)
|
|
37
|
+
], ReferralEvent.prototype, "id", void 0);
|
|
38
|
+
__decorate([
|
|
39
|
+
(0, typeorm_1.Column)({ name: 'referrer_id' }),
|
|
40
|
+
__metadata("design:type", String)
|
|
41
|
+
], ReferralEvent.prototype, "referrerId", void 0);
|
|
42
|
+
__decorate([
|
|
43
|
+
(0, typeorm_1.ManyToOne)(() => user_entity_1.User),
|
|
44
|
+
(0, typeorm_1.JoinColumn)({ name: 'referrer_id' }),
|
|
45
|
+
__metadata("design:type", user_entity_1.User)
|
|
46
|
+
], ReferralEvent.prototype, "referrer", void 0);
|
|
47
|
+
__decorate([
|
|
48
|
+
(0, typeorm_1.Column)({ name: 'referred_id' }),
|
|
49
|
+
__metadata("design:type", String)
|
|
50
|
+
], ReferralEvent.prototype, "referredId", void 0);
|
|
51
|
+
__decorate([
|
|
52
|
+
(0, typeorm_1.ManyToOne)(() => user_entity_1.User),
|
|
53
|
+
(0, typeorm_1.JoinColumn)({ name: 'referred_id' }),
|
|
54
|
+
__metadata("design:type", user_entity_1.User)
|
|
55
|
+
], ReferralEvent.prototype, "referred", void 0);
|
|
56
|
+
__decorate([
|
|
57
|
+
(0, typeorm_1.Column)({ name: 'referral_code', length: 50 }),
|
|
58
|
+
__metadata("design:type", String)
|
|
59
|
+
], ReferralEvent.prototype, "referralCode", void 0);
|
|
60
|
+
__decorate([
|
|
61
|
+
(0, typeorm_1.Column)({
|
|
62
|
+
type: 'enum',
|
|
63
|
+
enum: ReferralStatus,
|
|
64
|
+
default: ReferralStatus.SIGNUP,
|
|
65
|
+
}),
|
|
66
|
+
__metadata("design:type", String)
|
|
67
|
+
], ReferralEvent.prototype, "status", void 0);
|
|
68
|
+
__decorate([
|
|
69
|
+
(0, typeorm_1.Column)({ name: 'conversion_type', length: 50, nullable: true }),
|
|
70
|
+
__metadata("design:type", String)
|
|
71
|
+
], ReferralEvent.prototype, "conversionType", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
(0, typeorm_1.Column)({
|
|
74
|
+
name: 'conversion_value',
|
|
75
|
+
type: 'decimal',
|
|
76
|
+
precision: 10,
|
|
77
|
+
scale: 2,
|
|
78
|
+
default: 0,
|
|
79
|
+
}),
|
|
80
|
+
__metadata("design:type", Number)
|
|
81
|
+
], ReferralEvent.prototype, "conversionValue", void 0);
|
|
82
|
+
__decorate([
|
|
83
|
+
(0, typeorm_1.Column)({
|
|
84
|
+
name: 'referrer_reward_amount',
|
|
85
|
+
type: 'decimal',
|
|
86
|
+
precision: 10,
|
|
87
|
+
scale: 2,
|
|
88
|
+
default: 0,
|
|
89
|
+
}),
|
|
90
|
+
__metadata("design:type", Number)
|
|
91
|
+
], ReferralEvent.prototype, "referrerRewardAmount", void 0);
|
|
92
|
+
__decorate([
|
|
93
|
+
(0, typeorm_1.Column)({
|
|
94
|
+
name: 'referred_reward_amount',
|
|
95
|
+
type: 'decimal',
|
|
96
|
+
precision: 10,
|
|
97
|
+
scale: 2,
|
|
98
|
+
default: 0,
|
|
99
|
+
}),
|
|
100
|
+
__metadata("design:type", Number)
|
|
101
|
+
], ReferralEvent.prototype, "referredRewardAmount", void 0);
|
|
102
|
+
__decorate([
|
|
103
|
+
(0, typeorm_1.Column)({
|
|
104
|
+
name: 'reward_status',
|
|
105
|
+
type: 'enum',
|
|
106
|
+
enum: RewardStatus,
|
|
107
|
+
default: RewardStatus.PENDING,
|
|
108
|
+
}),
|
|
109
|
+
__metadata("design:type", String)
|
|
110
|
+
], ReferralEvent.prototype, "rewardStatus", void 0);
|
|
111
|
+
__decorate([
|
|
112
|
+
(0, typeorm_1.Column)({ name: 'reward_processed_at', nullable: true }),
|
|
113
|
+
__metadata("design:type", Date)
|
|
114
|
+
], ReferralEvent.prototype, "rewardProcessedAt", void 0);
|
|
115
|
+
__decorate([
|
|
116
|
+
(0, typeorm_1.Column)({ name: 'attribution_source', length: 100, nullable: true }),
|
|
117
|
+
__metadata("design:type", String)
|
|
118
|
+
], ReferralEvent.prototype, "attributionSource", void 0);
|
|
119
|
+
__decorate([
|
|
120
|
+
(0, typeorm_1.Column)({ name: 'utm_source', length: 100, nullable: true }),
|
|
121
|
+
__metadata("design:type", String)
|
|
122
|
+
], ReferralEvent.prototype, "utmSource", void 0);
|
|
123
|
+
__decorate([
|
|
124
|
+
(0, typeorm_1.Column)({ name: 'utm_medium', length: 100, nullable: true }),
|
|
125
|
+
__metadata("design:type", String)
|
|
126
|
+
], ReferralEvent.prototype, "utmMedium", void 0);
|
|
127
|
+
__decorate([
|
|
128
|
+
(0, typeorm_1.Column)({ name: 'utm_campaign', length: 100, nullable: true }),
|
|
129
|
+
__metadata("design:type", String)
|
|
130
|
+
], ReferralEvent.prototype, "utmCampaign", void 0);
|
|
131
|
+
__decorate([
|
|
132
|
+
(0, typeorm_1.Column)({ type: 'jsonb', default: {} }),
|
|
133
|
+
__metadata("design:type", Object)
|
|
134
|
+
], ReferralEvent.prototype, "metadata", void 0);
|
|
135
|
+
__decorate([
|
|
136
|
+
(0, typeorm_1.Column)({ name: 'ip_address', type: 'inet', nullable: true }),
|
|
137
|
+
__metadata("design:type", String)
|
|
138
|
+
], ReferralEvent.prototype, "ipAddress", void 0);
|
|
139
|
+
__decorate([
|
|
140
|
+
(0, typeorm_1.Column)({ type: 'text', nullable: true }),
|
|
141
|
+
__metadata("design:type", String)
|
|
142
|
+
], ReferralEvent.prototype, "userAgent", void 0);
|
|
143
|
+
__decorate([
|
|
144
|
+
(0, typeorm_1.Column)({ name: 'signup_at' }),
|
|
145
|
+
__metadata("design:type", Date)
|
|
146
|
+
], ReferralEvent.prototype, "signupAt", void 0);
|
|
147
|
+
__decorate([
|
|
148
|
+
(0, typeorm_1.Column)({ name: 'converted_at', nullable: true }),
|
|
149
|
+
__metadata("design:type", Date)
|
|
150
|
+
], ReferralEvent.prototype, "convertedAt", void 0);
|
|
151
|
+
__decorate([
|
|
152
|
+
(0, typeorm_1.CreateDateColumn)({ name: 'created_at' }),
|
|
153
|
+
__metadata("design:type", Date)
|
|
154
|
+
], ReferralEvent.prototype, "createdAt", void 0);
|
|
155
|
+
__decorate([
|
|
156
|
+
(0, typeorm_1.UpdateDateColumn)({ name: 'updated_at' }),
|
|
157
|
+
__metadata("design:type", Date)
|
|
158
|
+
], ReferralEvent.prototype, "updatedAt", void 0);
|
|
159
|
+
exports.ReferralEvent = ReferralEvent = __decorate([
|
|
160
|
+
(0, typeorm_1.Entity)('referral_events'),
|
|
161
|
+
(0, typeorm_1.Index)(['referrerId'], { unique: false }),
|
|
162
|
+
(0, typeorm_1.Index)(['referredId'], { unique: false }),
|
|
163
|
+
(0, typeorm_1.Index)(['referralCode'], { unique: false }),
|
|
164
|
+
(0, typeorm_1.Index)(['status'], { unique: false }),
|
|
165
|
+
(0, typeorm_1.Index)(['createdAt'], { unique: false }),
|
|
166
|
+
(0, typeorm_1.Index)(['conversionType'], {
|
|
167
|
+
unique: false,
|
|
168
|
+
where: 'conversion_type IS NOT NULL',
|
|
169
|
+
})
|
|
170
|
+
], ReferralEvent);
|
package/dist/postgres.module.js
CHANGED
|
@@ -16,6 +16,7 @@ export { PaymentTransactionRepository } from './payment-transaction.repository';
|
|
|
16
16
|
export { StripeWebhookRepository } from './stripe-webhook.repository';
|
|
17
17
|
export { CreditTransactionRepository } from './credit-transaction.repository';
|
|
18
18
|
export { RewardRuleRepository } from './reward-rule.repository';
|
|
19
|
+
export { ReferralEventRepository } from './referral-event.repository';
|
|
19
20
|
export { AiUsageRepository } from './ai-usage.repository';
|
|
20
21
|
export { AssetRepository } from './asset.repository';
|
|
21
22
|
export { EffectRepository } from './effect.repository';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AudioWaveformRepository = exports.VideoFilmstripRepository = exports.VideoRenderRepository = exports.VideoTranscodeRepository = exports.EffectRepository = exports.AssetRepository = exports.AiUsageRepository = exports.RewardRuleRepository = exports.CreditTransactionRepository = exports.StripeWebhookRepository = exports.PaymentTransactionRepository = exports.SubscriptionUsageRepository = exports.UserSubscriptionRepository = exports.PlanRepository = exports.SubscriptionPlanRepository = exports.CommentRepository = exports.EditorProjectRepository = exports.InviteRepository = exports.WorkspaceMemberRepository = exports.WorkspaceRepository = exports.AuthSessionRepository = exports.UserOnboardingRepository = exports.UserProfileRepository = exports.UserRepository = exports.BaseRepository = void 0;
|
|
3
|
+
exports.AudioWaveformRepository = exports.VideoFilmstripRepository = exports.VideoRenderRepository = exports.VideoTranscodeRepository = exports.EffectRepository = exports.AssetRepository = exports.AiUsageRepository = exports.ReferralEventRepository = exports.RewardRuleRepository = exports.CreditTransactionRepository = exports.StripeWebhookRepository = exports.PaymentTransactionRepository = exports.SubscriptionUsageRepository = exports.UserSubscriptionRepository = exports.PlanRepository = exports.SubscriptionPlanRepository = exports.CommentRepository = exports.EditorProjectRepository = exports.InviteRepository = exports.WorkspaceMemberRepository = exports.WorkspaceRepository = exports.AuthSessionRepository = exports.UserOnboardingRepository = exports.UserProfileRepository = exports.UserRepository = exports.BaseRepository = void 0;
|
|
4
4
|
var base_repository_1 = require("./base.repository");
|
|
5
5
|
Object.defineProperty(exports, "BaseRepository", { enumerable: true, get: function () { return base_repository_1.BaseRepository; } });
|
|
6
6
|
var user_repository_1 = require("./user.repository");
|
|
@@ -37,6 +37,8 @@ var credit_transaction_repository_1 = require("./credit-transaction.repository")
|
|
|
37
37
|
Object.defineProperty(exports, "CreditTransactionRepository", { enumerable: true, get: function () { return credit_transaction_repository_1.CreditTransactionRepository; } });
|
|
38
38
|
var reward_rule_repository_1 = require("./reward-rule.repository");
|
|
39
39
|
Object.defineProperty(exports, "RewardRuleRepository", { enumerable: true, get: function () { return reward_rule_repository_1.RewardRuleRepository; } });
|
|
40
|
+
var referral_event_repository_1 = require("./referral-event.repository");
|
|
41
|
+
Object.defineProperty(exports, "ReferralEventRepository", { enumerable: true, get: function () { return referral_event_repository_1.ReferralEventRepository; } });
|
|
40
42
|
var ai_usage_repository_1 = require("./ai-usage.repository");
|
|
41
43
|
Object.defineProperty(exports, "AiUsageRepository", { enumerable: true, get: function () { return ai_usage_repository_1.AiUsageRepository; } });
|
|
42
44
|
var asset_repository_1 = require("./asset.repository");
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Repository } from 'typeorm';
|
|
2
|
+
import { BaseRepository } from './base.repository';
|
|
3
|
+
import { ReferralEvent, ReferralStatus, RewardStatus } from '../entities/referral-event.entity';
|
|
4
|
+
export declare class ReferralEventRepository extends BaseRepository<ReferralEvent> {
|
|
5
|
+
protected repository: Repository<ReferralEvent>;
|
|
6
|
+
constructor(repository: Repository<ReferralEvent>);
|
|
7
|
+
findByReferrerId(referrerId: string, options?: {
|
|
8
|
+
status?: ReferralStatus;
|
|
9
|
+
limit?: number;
|
|
10
|
+
offset?: number;
|
|
11
|
+
}): Promise<ReferralEvent[]>;
|
|
12
|
+
findByReferredId(referredId: string): Promise<ReferralEvent[]>;
|
|
13
|
+
findByReferralPair(referrerId: string, referredId: string): Promise<ReferralEvent | null>;
|
|
14
|
+
findByReferralCode(referralCode: string): Promise<ReferralEvent[]>;
|
|
15
|
+
countConversionsByReferrer(referrerId: string): Promise<number>;
|
|
16
|
+
countSignupsByReferrer(referrerId: string): Promise<number>;
|
|
17
|
+
getReferralStats(referrerId: string): Promise<{
|
|
18
|
+
totalSignups: number;
|
|
19
|
+
totalConversions: number;
|
|
20
|
+
conversionRate: number;
|
|
21
|
+
totalRewardAmount: number;
|
|
22
|
+
}>;
|
|
23
|
+
updateStatus(id: string, status: ReferralStatus, additionalData?: {
|
|
24
|
+
conversionType?: string;
|
|
25
|
+
conversionValue?: number;
|
|
26
|
+
convertedAt?: Date;
|
|
27
|
+
}): Promise<ReferralEvent | null>;
|
|
28
|
+
updateRewardStatus(id: string, rewardStatus: RewardStatus, rewardAmount?: number, rewardProcessedAt?: Date): Promise<ReferralEvent | null>;
|
|
29
|
+
getPendingRewards(): Promise<ReferralEvent[]>;
|
|
30
|
+
getConversionFunnel(startDate: Date, endDate: Date): Promise<{
|
|
31
|
+
signup: number;
|
|
32
|
+
emailVerified: number;
|
|
33
|
+
firstProject: number;
|
|
34
|
+
converted: number;
|
|
35
|
+
}>;
|
|
36
|
+
getAttributionBreakdown(startDate: Date, endDate: Date): Promise<Record<string, number>>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ReferralEventRepository = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const typeorm_1 = require("@nestjs/typeorm");
|
|
18
|
+
const typeorm_2 = require("typeorm");
|
|
19
|
+
const base_repository_1 = require("./base.repository");
|
|
20
|
+
const referral_event_entity_1 = require("../entities/referral-event.entity");
|
|
21
|
+
let ReferralEventRepository = class ReferralEventRepository extends base_repository_1.BaseRepository {
|
|
22
|
+
constructor(repository) {
|
|
23
|
+
super(repository);
|
|
24
|
+
this.repository = repository;
|
|
25
|
+
}
|
|
26
|
+
async findByReferrerId(referrerId, options) {
|
|
27
|
+
const query = this.repository
|
|
28
|
+
.createQueryBuilder('re')
|
|
29
|
+
.where('re.referrer_id = :referrerId', { referrerId })
|
|
30
|
+
.leftJoinAndSelect('re.referred', 'referred')
|
|
31
|
+
.orderBy('re.signup_at', 'DESC');
|
|
32
|
+
if (options?.status) {
|
|
33
|
+
query.andWhere('re.status = :status', { status: options.status });
|
|
34
|
+
}
|
|
35
|
+
if (options?.limit) {
|
|
36
|
+
query.take(options.limit);
|
|
37
|
+
}
|
|
38
|
+
if (options?.offset) {
|
|
39
|
+
query.skip(options.offset);
|
|
40
|
+
}
|
|
41
|
+
return query.getMany();
|
|
42
|
+
}
|
|
43
|
+
async findByReferredId(referredId) {
|
|
44
|
+
return this.repository.find({
|
|
45
|
+
where: { referredId },
|
|
46
|
+
relations: ['referrer'],
|
|
47
|
+
order: { signupAt: 'DESC' },
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async findByReferralPair(referrerId, referredId) {
|
|
51
|
+
return this.repository.findOne({
|
|
52
|
+
where: { referrerId, referredId },
|
|
53
|
+
relations: ['referrer', 'referred'],
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async findByReferralCode(referralCode) {
|
|
57
|
+
return this.repository.find({
|
|
58
|
+
where: { referralCode },
|
|
59
|
+
relations: ['referrer', 'referred'],
|
|
60
|
+
order: { signupAt: 'DESC' },
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async countConversionsByReferrer(referrerId) {
|
|
64
|
+
return this.repository.count({
|
|
65
|
+
where: {
|
|
66
|
+
referrerId,
|
|
67
|
+
status: referral_event_entity_1.ReferralStatus.CONVERTED,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
async countSignupsByReferrer(referrerId) {
|
|
72
|
+
return this.repository.count({
|
|
73
|
+
where: { referrerId },
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async getReferralStats(referrerId) {
|
|
77
|
+
const stats = await this.repository
|
|
78
|
+
.createQueryBuilder('re')
|
|
79
|
+
.select([
|
|
80
|
+
'COUNT(*) as totalSignups',
|
|
81
|
+
'COUNT(CASE WHEN re.status = :converted THEN 1 END) as totalConversions',
|
|
82
|
+
'SUM(re.referrer_reward_amount) as totalRewardAmount',
|
|
83
|
+
])
|
|
84
|
+
.where('re.referrer_id = :referrerId', { referrerId })
|
|
85
|
+
.setParameters({ converted: referral_event_entity_1.ReferralStatus.CONVERTED })
|
|
86
|
+
.getRawOne();
|
|
87
|
+
const totalSignups = Number(stats.totalSignups) || 0;
|
|
88
|
+
const totalConversions = Number(stats.totalConversions) || 0;
|
|
89
|
+
const conversionRate = totalSignups > 0 ? (totalConversions / totalSignups) * 100 : 0;
|
|
90
|
+
const totalRewardAmount = Number(stats.totalRewardAmount) || 0;
|
|
91
|
+
return {
|
|
92
|
+
totalSignups,
|
|
93
|
+
totalConversions,
|
|
94
|
+
conversionRate,
|
|
95
|
+
totalRewardAmount,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
async updateStatus(id, status, additionalData) {
|
|
99
|
+
const updateData = { status };
|
|
100
|
+
if (additionalData) {
|
|
101
|
+
Object.assign(updateData, additionalData);
|
|
102
|
+
}
|
|
103
|
+
return this.update(id, updateData);
|
|
104
|
+
}
|
|
105
|
+
async updateRewardStatus(id, rewardStatus, rewardAmount, rewardProcessedAt) {
|
|
106
|
+
const updateData = { rewardStatus };
|
|
107
|
+
if (rewardAmount !== undefined) {
|
|
108
|
+
updateData.referrerRewardAmount = rewardAmount;
|
|
109
|
+
}
|
|
110
|
+
if (rewardProcessedAt) {
|
|
111
|
+
updateData.rewardProcessedAt = rewardProcessedAt;
|
|
112
|
+
}
|
|
113
|
+
return this.update(id, updateData);
|
|
114
|
+
}
|
|
115
|
+
async getPendingRewards() {
|
|
116
|
+
return this.repository.find({
|
|
117
|
+
where: { rewardStatus: referral_event_entity_1.RewardStatus.PENDING },
|
|
118
|
+
relations: ['referrer', 'referred'],
|
|
119
|
+
order: { signupAt: 'ASC' },
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
async getConversionFunnel(startDate, endDate) {
|
|
123
|
+
const funnelData = await this.repository
|
|
124
|
+
.createQueryBuilder('re')
|
|
125
|
+
.select('re.status', 'status')
|
|
126
|
+
.addSelect('COUNT(*)', 'count')
|
|
127
|
+
.where('re.signup_at BETWEEN :start AND :end', { start: startDate, end: endDate })
|
|
128
|
+
.groupBy('re.status')
|
|
129
|
+
.getRawMany();
|
|
130
|
+
const counts = Object.fromEntries(funnelData.map((f) => [f.status, Number(f.count)]));
|
|
131
|
+
return {
|
|
132
|
+
signup: counts[referral_event_entity_1.ReferralStatus.SIGNUP] || 0,
|
|
133
|
+
emailVerified: counts[referral_event_entity_1.ReferralStatus.EMAIL_VERIFIED] || 0,
|
|
134
|
+
firstProject: counts[referral_event_entity_1.ReferralStatus.FIRST_PROJECT] || 0,
|
|
135
|
+
converted: counts[referral_event_entity_1.ReferralStatus.CONVERTED] || 0,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
async getAttributionBreakdown(startDate, endDate) {
|
|
139
|
+
const attributionData = await this.repository
|
|
140
|
+
.createQueryBuilder('re')
|
|
141
|
+
.select('COALESCE(re.attribution_source, \'unknown\')', 'source')
|
|
142
|
+
.addSelect('COUNT(*)', 'count')
|
|
143
|
+
.where('re.signup_at BETWEEN :start AND :end', { start: startDate, end: endDate })
|
|
144
|
+
.groupBy('re.attribution_source')
|
|
145
|
+
.getRawMany();
|
|
146
|
+
return Object.fromEntries(attributionData.map((a) => [a.source, Number(a.count)]));
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
exports.ReferralEventRepository = ReferralEventRepository;
|
|
150
|
+
exports.ReferralEventRepository = ReferralEventRepository = __decorate([
|
|
151
|
+
(0, common_1.Injectable)(),
|
|
152
|
+
__param(0, (0, typeorm_1.InjectRepository)(referral_event_entity_1.ReferralEvent)),
|
|
153
|
+
__metadata("design:paramtypes", [typeorm_2.Repository])
|
|
154
|
+
], ReferralEventRepository);
|
|
@@ -29,6 +29,7 @@ const repositories = [
|
|
|
29
29
|
_1.StripeWebhookRepository,
|
|
30
30
|
_1.CreditTransactionRepository,
|
|
31
31
|
_1.RewardRuleRepository,
|
|
32
|
+
_1.ReferralEventRepository,
|
|
32
33
|
_1.AiUsageRepository,
|
|
33
34
|
_1.AssetRepository,
|
|
34
35
|
_1.EffectRepository,
|
|
@@ -55,6 +56,7 @@ const entities = [
|
|
|
55
56
|
entities_1.StripeWebhookEvent,
|
|
56
57
|
entities_1.CreditTransaction,
|
|
57
58
|
entities_1.RewardRule,
|
|
59
|
+
entities_1.ReferralEvent,
|
|
58
60
|
entities_1.AIUsage,
|
|
59
61
|
entities_1.Asset,
|
|
60
62
|
entities_1.Effect,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clhq-postgres-module",
|
|
3
|
-
"version": "1.1.0-alpha.
|
|
3
|
+
"version": "1.1.0-alpha.99",
|
|
4
4
|
"description": "PostgreSQL module using TypeORM for Clippy",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -30,6 +30,12 @@
|
|
|
30
30
|
"db:migrate:004": "npx ts-node scripts/run-migrations.ts 004",
|
|
31
31
|
"db:migrate:008": "npx ts-node scripts/run-migrations.ts 008",
|
|
32
32
|
"db:migrate:009": "npx ts-node scripts/run-migrations.ts 009",
|
|
33
|
+
"db:migrate:011": "npx ts-node scripts/run-migrations.ts 011",
|
|
34
|
+
"db:migrate:012": "npx ts-node scripts/run-migrations.ts 012",
|
|
35
|
+
"db:migrate:013": "npx ts-node scripts/run-migrations.ts 013",
|
|
36
|
+
"db:migrate:014": "npx ts-node scripts/run-migrations.ts 014",
|
|
37
|
+
"db:migrate:015": "npx ts-node scripts/run-migrations.ts 015",
|
|
38
|
+
"db:migrate:016": "npx ts-node scripts/run-migrations.ts 016",
|
|
33
39
|
"db:verify": "env-cmd -f ../../.env.dev npx ts-node scripts/verify-tables.ts",
|
|
34
40
|
"db:test": "env-cmd -f ../../.env.dev npx ts-node scripts/test-connections.ts",
|
|
35
41
|
"db:sync": "env-cmd -f ../../.env.dev npm run typeorm schema:sync -- -d src/config/data-source.ts",
|