File size: 1,878 Bytes
b5e5eac
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4a31a72
b5e5eac
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4a285d2
 
b5e5eac
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  ManyToOne,
  Index,
} from 'typeorm';
import { Wallet } from './Wallet';
import { Agent } from './Agent';
import { User } from './User';

export enum TransactionType {
  PURCHASE = 'purchase', // Buying points
  CHARGE = 'charge', // Charged for agent task
  REFUND = 'refund', // Refunded points
  FREE = 'free', // Free task
  ADMIN_TEST = 'admin_test', // Admin testing unapproved agents (no charge)
}

export enum TransactionStatus {
  PENDING = 'pending',
  COMPLETED = 'completed',
  FAILED = 'failed',
}

@Entity('transactions')
@Index(['walletId', 'createdAt'])
@Index(['userId', 'agentId'])
export class Transaction {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToOne(() => Wallet, (wallet) => wallet.transactions)
  wallet: Wallet;

  @Column()
  walletId: string;

  @ManyToOne(() => User, { nullable: true })
  user: User;

  @Column({ nullable: true })
  userId?: string;

  @ManyToOne(() => Agent, { nullable: true })
  agent: Agent;

  @Column({ nullable: true })
  agentId?: string;

  @Column({
    type: 'enum',
    enum: TransactionType,
  })
  type: TransactionType;

  @Column({
    type: 'enum',
    enum: TransactionStatus,
    default: TransactionStatus.PENDING,
  })
  status: TransactionStatus;

  @Column('decimal', { precision: 15, scale: 2 })
  amount: number; // Points amount (positive for purchases, negative for charges)

  @Column('decimal', { precision: 15, scale: 2, nullable: true })
  balanceAfter: number; // Wallet balance after transaction

  @Column({ nullable: true })
  description?: string;

  @Column({ nullable: true, unique: true })
  paymentReference?: string; // Paystack reference for purchases (unique for idempotency)

  @Column('jsonb', { nullable: true })
  metadata?: Record<string, any>;

  @CreateDateColumn()
  createdAt: Date;
}