feat: implement real tenant creation functionality
All checks were successful
Build and Deploy / build-and-push (push) Successful in 2m6s
All checks were successful
Build and Deploy / build-and-push (push) Successful in 2m6s
This commit is contained in:
@@ -123,13 +123,55 @@ app.get('/api/attendances/:id', async (req, res) => {
|
|||||||
// --- Rotas de Tenants (Super Admin) ---
|
// --- Rotas de Tenants (Super Admin) ---
|
||||||
app.get('/api/tenants', async (req, res) => {
|
app.get('/api/tenants', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const [rows] = await pool.query('SELECT * FROM tenants');
|
const query = `
|
||||||
|
SELECT t.*,
|
||||||
|
(SELECT COUNT(*) FROM users u WHERE u.tenant_id = t.id) as user_count,
|
||||||
|
(SELECT COUNT(*) FROM attendances a WHERE a.tenant_id = t.id) as attendance_count
|
||||||
|
FROM tenants t
|
||||||
|
`;
|
||||||
|
const [rows] = await pool.query(query);
|
||||||
res.json(rows);
|
res.json(rows);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json({ error: error.message });
|
res.status(500).json({ error: error.message });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Criar Tenant
|
||||||
|
app.post('/api/tenants', async (req, res) => {
|
||||||
|
const { name, slug, admin_email, status } = req.body;
|
||||||
|
const crypto = require('crypto');
|
||||||
|
|
||||||
|
const connection = await pool.getConnection();
|
||||||
|
try {
|
||||||
|
await connection.beginTransaction();
|
||||||
|
|
||||||
|
const tenantId = `tenant_${crypto.randomUUID().split('-')[0]}`;
|
||||||
|
|
||||||
|
// 1. Criar Tenant
|
||||||
|
await connection.query(
|
||||||
|
'INSERT INTO tenants (id, name, slug, admin_email, status) VALUES (?, ?, ?, ?, ?)',
|
||||||
|
[tenantId, name, slug, admin_email, status || 'active']
|
||||||
|
);
|
||||||
|
|
||||||
|
// 2. Criar Usuário Admin Default
|
||||||
|
const userId = `u_${crypto.randomUUID().split('-')[0]}`;
|
||||||
|
await connection.query(
|
||||||
|
'INSERT INTO users (id, tenant_id, name, email, role, status) VALUES (?, ?, ?, ?, ?, ?)',
|
||||||
|
[userId, tenantId, 'Admin', admin_email, 'admin', 'active']
|
||||||
|
);
|
||||||
|
|
||||||
|
await connection.commit();
|
||||||
|
res.status(201).json({ message: 'Tenant created successfully', id: tenantId });
|
||||||
|
} catch (error) {
|
||||||
|
await connection.rollback();
|
||||||
|
console.error('Erro ao criar tenant:', error);
|
||||||
|
res.status(500).json({ error: error.message });
|
||||||
|
} finally {
|
||||||
|
connection.release();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Serve index.html for any unknown routes (for client-side routing)
|
// Serve index.html for any unknown routes (for client-side routing)
|
||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
app.get('*', (req, res) => {
|
app.get('*', (req, res) => {
|
||||||
|
|||||||
@@ -67,3 +67,28 @@ export const getAttendanceById = async (id: string): Promise<Attendance | undefi
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getTenants = async (): Promise<any[]> => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${API_URL}/tenants`);
|
||||||
|
if (!response.ok) throw new Error('Falha ao buscar tenants');
|
||||||
|
return await response.json();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("API Error (getTenants):", error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const createTenant = async (tenantData: any): Promise<boolean> => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${API_URL}/tenants`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(tenantData)
|
||||||
|
});
|
||||||
|
return response.ok;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("API Error (createTenant):", error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user