CREATE TABLE user_cards ( id SERIAL PRIMARY KEY, user_id INT NOT NULL, card_number_hash VARCHAR(255) NOT NULL, -- hashed for security last_four VARCHAR(4) NOT NULL, card_network VARCHAR(20) DEFAULT 'Visa', card_type VARCHAR(20) DEFAULT 'Credit', expiry_month INT NOT NULL, expiry_year INT NOT NULL, is_active BOOLEAN DEFAULT true, is_permanently_blocked BOOLEAN DEFAULT false, block_reason VARCHAR(255), blocked_at TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE card_block_requests ( id SERIAL PRIMARY KEY, card_id INT REFERENCES user_cards(id), request_reason VARCHAR(100) NOT NULL, -- 'lost', 'stolen', 'fraud', 'other' description TEXT, status VARCHAR(20) DEFAULT 'pending', -- pending, processed, failed hdfc_reference_id VARCHAR(100), error_message TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, processed_at TIMESTAMP ); 1. Card Model ( models/Card.js ) const pool = require('../db'); class Card static async findActiveCardByUserAndLastFour(userId, lastFour) const result = await pool.query( SELECT * FROM user_cards WHERE user_id = $1 AND last_four = $2 AND is_active = true AND is_permanently_blocked = false , [userId, lastFour] ); return result.rows[0];
input, select, textarea width: 100%; padding: 10px; border: 1px solid #ccc; border-radius: 8px; font-size: 1rem; box-sizing: border-box;
await client.query('COMMIT'); return blockReq.rows[0]; catch (err) await client.query('ROLLBACK'); throw err; finally client.release();