From 8cdc9ee0759b233c18a9386e8a74742810f568b3 Mon Sep 17 00:00:00 2001 From: Nandgopal-R Date: Sat, 3 Jan 2026 23:14:30 +0530 Subject: [PATCH] fix: repair CreateDispute and UpdateDispute --- api/dispute/controllers.go | 35 ++++++++++++++++++---- db/gen/dispute-for-admin.sql.go | 51 +++++++++++++++++++++++++------- db/queries/dispute-for-admin.sql | 22 ++++++++++---- models/dispute.go | 5 +--- 4 files changed, 88 insertions(+), 25 deletions(-) diff --git a/api/dispute/controllers.go b/api/dispute/controllers.go index 43073f25..4bb9584d 100644 --- a/api/dispute/controllers.go +++ b/api/dispute/controllers.go @@ -63,11 +63,37 @@ func CreateDispute(c *gin.Context) { return } + disputeCount, err := q.CheckDisputeExistsByTxnIdQuery(ctx, tx, txnId) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": "Oops! Something happened. Please try again later", + }) + pkg.Log.ErrorCtx(c, "[DISPUTE-ERROR]: Failed to check if dispute exists by transaction ID", err) + return + } + if disputeCount > 0 { + c.JSON(http.StatusBadRequest, gin.H{ + "message": "Dispute already exists for this transaction", + }) + pkg.Log.ErrorCtx(c, "[DISPUTE-ERROR]: Attempted to create duplicate dispute for transaction ID", nil) + return + } + + studentEmail, err := q.GetEmailByTxnIdQuery(ctx, tx, txnId) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "message": "Oops! Something happened. Please try again later", + }) + pkg.Log.ErrorCtx(c, "[DISPUTE-ERROR]: Failed to fetch student email by transaction ID", err) + return + } + if event.EventStatus == "ACTIVE" { err = q.CreateDisputeQuery(ctx, tx, db.CreateDisputeQueryParams{ - EventID: event.EventID, - TxnID: txnId, + EventID: event.EventID, + TxnID: txnId, + StudentEmail: pkg.ToPgText(studentEmail), }) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ @@ -136,9 +162,8 @@ func UpdateDispute(c *gin.Context) { q := db.New() row, err := q.UpdateDisputeQuery(ctx, conn, db.UpdateDisputeQueryParams{ - ID: disputeId, - StudentEmail: pkg.ToPgText(req.StudentEmail), - Description: pkg.ToPgText(req.Description), + ID: disputeId, + Description: pkg.ToPgText(req.Description), }) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{ diff --git a/db/gen/dispute-for-admin.sql.go b/db/gen/dispute-for-admin.sql.go index b7431eb4..330fa4e8 100644 --- a/db/gen/dispute-for-admin.sql.go +++ b/db/gen/dispute-for-admin.sql.go @@ -12,6 +12,20 @@ import ( "github.com/jackc/pgx/v5/pgtype" ) +const checkDisputeExistsByTxnIdQuery = `-- name: CheckDisputeExistsByTxnIdQuery :one +SELECT COUNT(*) AS count +FROM dispute +WHERE txn_id = $1 +AND dispute_status = 'OPEN' +` + +func (q *Queries) CheckDisputeExistsByTxnIdQuery(ctx context.Context, db DBTX, txnID string) (int64, error) { + row := db.QueryRow(ctx, checkDisputeExistsByTxnIdQuery, txnID) + var count int64 + err := row.Scan(&count) + return count, err +} + const closeAsFalseDisputeQuery = `-- name: CloseAsFalseDisputeQuery :execrows UPDATE dispute SET dispute_status = 'CLOSED_AS_FALSE', @@ -45,17 +59,19 @@ func (q *Queries) CloseAsTrueDisputeQuery(ctx context.Context, db DBTX, id uuid. const createDisputeQuery = `-- name: CreateDisputeQuery :exec INSERT INTO dispute ( txn_id, - event_id -) VALUES ($1, $2) + event_id, + student_email +) VALUES ($1, $2, $3) ` type CreateDisputeQueryParams struct { - TxnID string `json:"txn_id"` - EventID uuid.UUID `json:"event_id"` + TxnID string `json:"txn_id"` + EventID uuid.UUID `json:"event_id"` + StudentEmail pgtype.Text `json:"student_email"` } func (q *Queries) CreateDisputeQuery(ctx context.Context, db DBTX, arg CreateDisputeQueryParams) error { - _, err := db.Exec(ctx, createDisputeQuery, arg.TxnID, arg.EventID) + _, err := db.Exec(ctx, createDisputeQuery, arg.TxnID, arg.EventID, arg.StudentEmail) return err } @@ -153,6 +169,21 @@ func (q *Queries) GetDisputeByIDQuery(ctx context.Context, db DBTX, id uuid.UUID return i, err } +const getEmailByTxnIdQuery = `-- name: GetEmailByTxnIdQuery :one +SELECT s.email +FROM student s +INNER JOIN bookings b + ON s.id = b.student_id +WHERE b.txn_id = $1 +` + +func (q *Queries) GetEmailByTxnIdQuery(ctx context.Context, db DBTX, txnID string) (string, error) { + row := db.QueryRow(ctx, getEmailByTxnIdQuery, txnID) + var email string + err := row.Scan(&email) + return email, err +} + const getEventIdByDisputeIDQuery = `-- name: GetEventIdByDisputeIDQuery :one SELECT d.event_id AS event_id @@ -204,20 +235,18 @@ func (q *Queries) IncrementSeatFilledCountQuery(ctx context.Context, db DBTX, id const updateDisputeQuery = `-- name: UpdateDisputeQuery :execrows UPDATE dispute -SET student_email = $2, - description = $3, +SET description = $2, updated_at = NOW() WHERE id = $1 ` type UpdateDisputeQueryParams struct { - ID uuid.UUID `json:"id"` - StudentEmail pgtype.Text `json:"student_email"` - Description pgtype.Text `json:"description"` + ID uuid.UUID `json:"id"` + Description pgtype.Text `json:"description"` } func (q *Queries) UpdateDisputeQuery(ctx context.Context, db DBTX, arg UpdateDisputeQueryParams) (int64, error) { - result, err := db.Exec(ctx, updateDisputeQuery, arg.ID, arg.StudentEmail, arg.Description) + result, err := db.Exec(ctx, updateDisputeQuery, arg.ID, arg.Description) if err != nil { return 0, err } diff --git a/db/queries/dispute-for-admin.sql b/db/queries/dispute-for-admin.sql index 0e4967fa..264edee9 100644 --- a/db/queries/dispute-for-admin.sql +++ b/db/queries/dispute-for-admin.sql @@ -17,11 +17,19 @@ SELECT id, FROM dispute WHERE id = $1; +-- name: CheckDisputeExistsByTxnIdQuery :one +SELECT COUNT(*) AS count +FROM dispute +WHERE txn_id = $1 +AND dispute_status = 'OPEN'; + + -- name: CreateDisputeQuery :exec INSERT INTO dispute ( txn_id, - event_id -) VALUES ($1, $2); + event_id, + student_email +) VALUES ($1, $2, $3); -- name: GetEventIdByTxnIdQuery :one SELECT @@ -49,8 +57,7 @@ WHERE id = $1; -- name: UpdateDisputeQuery :execrows UPDATE dispute -SET student_email = $2, - description = $3, +SET description = $2, updated_at = NOW() WHERE id = $1; @@ -66,4 +73,9 @@ SET dispute_status = 'CLOSED_AS_FALSE', updated_at = NOW() WHERE id = $1; - +-- name: GetEmailByTxnIdQuery :one +SELECT s.email +FROM student s +INNER JOIN bookings b + ON s.id = b.student_id +WHERE b.txn_id = $1; diff --git a/models/dispute.go b/models/dispute.go index 008193c0..ad1ca3ab 100644 --- a/models/dispute.go +++ b/models/dispute.go @@ -2,17 +2,14 @@ package models import ( v "github.com/go-ozzo/ozzo-validation/v4" - "github.com/go-ozzo/ozzo-validation/v4/is" ) type UpdateDisputeStatusInput struct { - StudentEmail string `json:"student_email"` - Description string `json:"description"` + Description string `json:"description"` } func (u UpdateDisputeStatusInput) Validate() error { if err := v.ValidateStruct(&u, - v.Field(&u.StudentEmail, is.Email), v.Field(&u.Description), ); err != nil { return err