const pool = require("../db/pool"); // Get all households a user belongs to exports.getUserHouseholds = async (userId) => { const result = await pool.query( `SELECT h.id, h.name, h.invite_code, h.created_at, hm.role, hm.joined_at, (SELECT COUNT(*) FROM household_members WHERE household_id = h.id) as member_count FROM households h JOIN household_members hm ON h.id = hm.household_id WHERE hm.user_id = $1 ORDER BY hm.joined_at DESC`, [userId] ); return result.rows; }; // Get household by ID (with member check) exports.getHouseholdById = async (householdId, userId) => { const result = await pool.query( `SELECT h.id, h.name, h.invite_code, h.created_at, h.created_by, hm.role as user_role, (SELECT COUNT(*) FROM household_members WHERE household_id = h.id) as member_count FROM households h LEFT JOIN household_members hm ON h.id = hm.household_id AND hm.user_id = $2 WHERE h.id = $1`, [householdId, userId] ); return result.rows[0]; }; // Create new household exports.createHousehold = async (name, createdBy) => { // Generate random 6-digit invite code const inviteCode = 'H' + Math.random().toString(36).substring(2, 8).toUpperCase(); const result = await pool.query( `INSERT INTO households (name, created_by, invite_code) VALUES ($1, $2, $3) RETURNING id, name, invite_code, created_at`, [name, createdBy, inviteCode] ); // Add creator as admin await pool.query( `INSERT INTO household_members (household_id, user_id, role) VALUES ($1, $2, 'admin')`, [result.rows[0].id, createdBy] ); return result.rows[0]; }; // Update household exports.updateHousehold = async (householdId, updates) => { const { name } = updates; const result = await pool.query( `UPDATE households SET name = COALESCE($1, name) WHERE id = $2 RETURNING id, name, invite_code, created_at`, [name, householdId] ); return result.rows[0]; }; // Delete household exports.deleteHousehold = async (householdId) => { await pool.query('DELETE FROM households WHERE id = $1', [householdId]); }; // Refresh invite code exports.refreshInviteCode = async (householdId) => { const inviteCode = 'H' + Math.random().toString(36).substring(2, 8).toUpperCase(); const result = await pool.query( `UPDATE households SET invite_code = $1, code_expires_at = NULL WHERE id = $2 RETURNING id, name, invite_code`, [inviteCode, householdId] ); return result.rows[0]; }; // Join household via invite code exports.joinHousehold = async (inviteCode, userId) => { const householdResult = await pool.query( `SELECT id, name FROM households WHERE invite_code = $1 AND (code_expires_at IS NULL OR code_expires_at > NOW())`, [inviteCode] ); if (householdResult.rows.length === 0) return null; const household = householdResult.rows[0]; const existingMember = await pool.query( `SELECT id FROM household_members WHERE household_id = $1 AND user_id = $2`, [household.id, userId] ); if (existingMember.rows.length > 0) return { ...household, alreadyMember: true }; // Add as user role await pool.query( `INSERT INTO household_members (household_id, user_id, role) VALUES ($1, $2, 'user')`, [household.id, userId] ); return { ...household, alreadyMember: false }; }; // Get household members exports.getHouseholdMembers = async (householdId) => { const result = await pool.query( `SELECT u.id, u.username, u.name, u.display_name, hm.role, hm.joined_at FROM household_members hm JOIN users u ON hm.user_id = u.id WHERE hm.household_id = $1 ORDER BY CASE hm.role WHEN 'admin' THEN 1 WHEN 'user' THEN 2 END, hm.joined_at ASC`, [householdId] ); return result.rows; }; // Update member role exports.updateMemberRole = async (householdId, userId, newRole) => { const result = await pool.query( `UPDATE household_members SET role = $1 WHERE household_id = $2 AND user_id = $3 RETURNING user_id, role`, [newRole, householdId, userId] ); return result.rows[0]; }; // Remove member from household exports.removeMember = async (householdId, userId) => { await pool.query( `DELETE FROM household_members WHERE household_id = $1 AND user_id = $2`, [householdId, userId] ); }; // Get user's role in household exports.getUserRole = async (householdId, userId) => { const result = await pool.query( `SELECT role FROM household_members WHERE household_id = $1 AND user_id = $2`, [householdId, userId] ); return result.rows[0]?.role || null; }; // Check if user is household member exports.isHouseholdMember = async (householdId, userId) => { const result = await pool.query( `SELECT 1 FROM household_members WHERE household_id = $1 AND user_id = $2`, [householdId, userId] ); return result.rows.length > 0; };