package repositories import ( "FamilyHub/src/domain" "context" "database/sql" "errors" ) type OTPRepository interface { Create(ctx context.Context, otp *domain.OTP) error Get(ctx context.Context, userID int64, code string) (*domain.OTP, error) } type OTPSQLRepository struct { db *sql.DB } func NewOTPSQLRepository(db *sql.DB) *OTPSQLRepository { return &OTPSQLRepository{db: db} } func (r *OTPSQLRepository) Create(ctx context.Context, otp *domain.OTP) error { query := ` INSERT INTO otp (user_id, otp, expired_at) VALUES ($1, $2, $3) ` _, err := r.db.ExecContext(ctx, query, otp.UserID, otp.Code, otp.ExpiredAt) return err } func (r *OTPSQLRepository) Get(ctx context.Context, userID int64, code string) (*domain.OTP, error) { query := ` DELETE FROM otp WHERE ctid IN ( SELECT ctid FROM otp WHERE user_id = $1 AND otp = $2 AND expired_at > NOW() ORDER BY expired_at LIMIT 1 ) RETURNING user_id, otp, expired_at ` var otp domain.OTP err := r.db.QueryRowContext(ctx, query, userID, code).Scan( &otp.UserID, &otp.Code, &otp.ExpiredAt, ) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, nil } return nil, err } return &otp, nil }