package repository import ( "context" "time" dbgen "github.com/SamuelTariku/FortuneBet-Backend/gen/db" "github.com/SamuelTariku/FortuneBet-Backend/internal/domain" "github.com/jackc/pgx/v5/pgtype" ) type DirectDepositRepository interface { CreateDirectDeposit(ctx context.Context, deposit *domain.DirectDeposit) error GetDirectDepositsByStatus(ctx context.Context, status string, page int, pageSize int) ([]domain.DirectDeposit, int64, error) ApproveDirectDeposit(ctx context.Context, depositID int, adminID int) error RejectDirectDeposit(ctx context.Context, depositID int, adminID int, reason string) error DeleteDirectDeposit(ctx context.Context, id int) error GetDirectDepositByID(ctx context.Context, id int) (*domain.DirectDeposit, error) } type DirectDepositRepo struct { store *Store } func NewDirectDepositRepository(store *Store) DirectDepositRepository { return &DirectDepositRepo{store: store} } func (r *DirectDepositRepo) CreateDirectDeposit(ctx context.Context, deposit *domain.DirectDeposit) error { params := dbgen.CreateDirectDepositParams{ CustomerID: pgtype.Int8{Int64: int64(deposit.CustomerID)}, WalletID: pgtype.Int8{Int64: int64(deposit.WalletID)}, BankName: pgtype.Text{String: deposit.BankName}, AccountNumber: pgtype.Text{String: deposit.AccountNumber}, AccountHolder: pgtype.Text{String: deposit.AccountHolder}, Amount: pgtype.Numeric{Exp: int32(deposit.Amount)}, ReferenceNumber: pgtype.Text{String: deposit.ReferenceNumber}, TransferScreenshot: pgtype.Text{String: deposit.TransferScreenshot}, } dbDeposit, err := r.store.queries.CreateDirectDeposit(ctx, params) if err != nil { return err } // Map back to domain struct deposit.ID = int(dbDeposit.ID) deposit.Status = dbDeposit.Status.String deposit.CreatedAt = dbDeposit.CreatedAt.Time return nil } func (r *DirectDepositRepo) GetDirectDepositsByStatus( ctx context.Context, status string, page int, pageSize int, ) ([]domain.DirectDeposit, int64, error) { // Default pagination rules if page < 1 { page = 1 } if pageSize < 1 || pageSize > 100 { pageSize = 50 } offset := (page - 1) * pageSize params := dbgen.GetDirectDepositsByStatusParams{ Status: pgtype.Text{String: status}, Limit: int32(pageSize), Offset: int32(offset), } dbItems, err := r.store.queries.GetDirectDepositsByStatus(ctx, params) if err != nil { return nil, 0, err } total, err := r.store.queries.CountDirectDepositsByStatus(ctx, pgtype.Text{String: status}) if err != nil { return nil, 0, err } deposits := make([]domain.DirectDeposit, len(dbItems)) for i, d := range dbItems { deposits[i] = *mapDBDirectDepositToDomain(&d) } return deposits, total, nil } func (r *DirectDepositRepo) ApproveDirectDeposit( ctx context.Context, depositID int, adminID int, ) error { params := dbgen.ApproveDirectDepositParams{ ID: int64(depositID), ApprovedBy: pgtype.Int8{Int64: int64(adminID)}, } err := r.store.queries.ApproveDirectDeposit(ctx, params) if err != nil { return err } return nil } func (r *DirectDepositRepo) GetDirectDepositByID( ctx context.Context, id int, ) (*domain.DirectDeposit, error) { dbDeposit, err := r.store.queries.GetDirectDepositByID(ctx, int64(id)) if err != nil { return nil, err } deposit := mapDBDirectDepositToDomain(&dbDeposit) return deposit, nil } func (r *DirectDepositRepo) DeleteDirectDeposit( ctx context.Context, id int, ) error { err := r.store.queries.DeleteDirectDeposit(ctx, int64(id)) if err != nil { return err } return nil } func (r *DirectDepositRepo) RejectDirectDeposit( ctx context.Context, depositID int, adminID int, reason string, ) error { params := dbgen.RejectDirectDepositParams{ ID: int64(depositID), ApprovedBy: pgtype.Int8{Int64: int64(adminID)}, RejectionReason: pgtype.Text{String: reason}, } err := r.store.queries.RejectDirectDeposit(ctx, params) if err != nil { return err } return nil } func mapDBDirectDepositToDomain(d *dbgen.DirectDeposit) *domain.DirectDeposit { var approvedBy *int if d.ApprovedBy.Valid { v := int(d.ApprovedBy.Int64) approvedBy = &v } var approvedAt *time.Time if d.ApprovedAt.Valid { t := d.ApprovedAt.Time approvedAt = &t } var rejectionReason *string if d.RejectionReason.Valid { r := d.RejectionReason.String rejectionReason = &r } return &domain.DirectDeposit{ ID: int(d.ID), CustomerID: int(d.CustomerID.Int64), WalletID: int(d.WalletID.Int64), BankName: d.BankName.String, AccountNumber: d.AccountNumber.String, AccountHolder: d.AccountHolder.String, Amount: float64(d.Amount.Exp), ReferenceNumber: d.ReferenceNumber.String, TransferScreenshot: d.TransferScreenshot.String, Status: d.Status.String, CreatedAt: d.CreatedAt.Time, ApprovedBy: approvedBy, ApprovedAt: approvedAt, RejectionReason: rejectionReason, } }