Files
boc/services/frilans-payout/db.mjs
T

127 lines
4.5 KiB
JavaScript
Raw Normal View History

/**
* quiXzoom Frilans Payout — Database Layer
* Raw SQL via pg (no ORM per REXO standards)
*/
import pg from 'pg';
const { Pool } = pg;
const pool = new Pool({
connectionString: process.env.DATABASE_URL || 'postgresql://wavult_admin:EgoVVPQuVSioCiMgJWmMoVvnjgiJPaD6hPR8xkZo@wavult-identity-core.cvi0qcksmsfj.eu-north-1.rds.amazonaws.com:5432/wavult_identity',
ssl: { rejectUnauthorized: false },
});
// ── Frilans Accounts ────────────────────────────────────────────────────────
export async function createAccount(data) {
const { userId, country, currency, taxHandling, personalNumber, payoutMethod } = data;
const result = await pool.query(`
INSERT INTO frilans_accounts (user_id, country, currency, tax_handling, personal_number, payout_method)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING *
`, [userId, country, currency, taxHandling, personalNumber, payoutMethod]);
return result.rows[0];
}
export async function getAccountByUserId(userId) {
const result = await pool.query(
'SELECT * FROM frilans_accounts WHERE user_id = $1 AND status = $2',
[userId, 'active']
);
return result.rows[0] || null;
}
export async function updateAccount(accountId, updates) {
const fields = Object.keys(updates);
const values = Object.values(updates);
const setClause = fields.map((f, i) => `${f} = $${i + 2}`).join(', ');
const result = await pool.query(`
UPDATE frilans_accounts
SET ${setClause}, updated_at = NOW()
WHERE id = $1
RETURNING *
`, [accountId, ...values]);
return result.rows[0];
}
// ── Payouts ─────────────────────────────────────────────────────────────────
export async function createPayout(data) {
const { accountId, amount, netAmount, currency, platformFee, processingFee, taxAmount, method, scheduledDate } = data;
const result = await pool.query(`
INSERT INTO frilans_payouts (account_id, amount, net_amount, currency, platform_fee, processing_fee, tax_amount, method, scheduled_date)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
RETURNING *
`, [accountId, amount, netAmount, currency, platformFee, processingFee, taxAmount, method, scheduledDate]);
return result.rows[0];
}
export async function listPayouts(accountId) {
const result = await pool.query(
'SELECT * FROM frilans_payouts WHERE account_id = $1 ORDER BY created_at DESC',
[accountId]
);
return result.rows;
}
export async function getPayoutById(payoutId) {
const result = await pool.query(
'SELECT * FROM frilans_payouts WHERE id = $1',
[payoutId]
);
return result.rows[0] || null;
}
// ── Documents ───────────────────────────────────────────────────────────────
export async function createDocument(data) {
const { accountId, type, s3Url } = data;
const result = await pool.query(`
INSERT INTO frilans_documents (account_id, type, s3_url, status)
VALUES ($1, $2, $3, $4)
RETURNING *
`, [accountId, type, s3Url, 'verified']);
return result.rows[0];
}
export async function listDocuments(accountId) {
const result = await pool.query(
'SELECT * FROM frilans_documents WHERE account_id = $1 ORDER BY uploaded_at DESC',
[accountId]
);
return result.rows;
}
// ── Tax Summary ─────────────────────────────────────────────────────────────
export async function getTaxSummary(accountId, year) {
const result = await pool.query(`
SELECT
COALESCE(SUM(amount), 0) as total_earnings,
COALESCE(SUM(tax_amount), 0) as total_tax_paid,
COALESCE(SUM(platform_fee + processing_fee), 0) as total_fees_paid,
COALESCE(SUM(net_amount), 0) as net_earnings
FROM frilans_payouts
WHERE account_id = $1
AND EXTRACT(YEAR FROM created_at) = $2
AND status = 'completed'
`, [accountId, year]);
return result.rows[0];
}
// ── Health Check ────────────────────────────────────────────────────────────
export async function healthCheck() {
const result = await pool.query('SELECT NOW()');
return result.rows[0];
}