feat: initial project structure (Model Project) - Backend + Multi-Frontend + Docker

This commit is contained in:
VPS 4 Builder
2026-05-15 10:39:35 +02:00
commit 3beac0e0f2
288 changed files with 78761 additions and 0 deletions
+89
View File
@@ -0,0 +1,89 @@
'use strict'
const { query } = require('../database/postgres')
function tFilter(tenantId, alias = 't') {
if (!tenantId) return ''
const id = parseInt(tenantId, 10)
if (!Number.isInteger(id) || id <= 0) throw new Error('tenantId inválido')
return `AND ${alias}.tenant_id = ${id}`
}
class Analytics {
static async getRevenueStats(raffle_id = null, tenantId = null) {
const raffleFilter = raffle_id ? `AND r.id = $1` : ''
const tenantFilter = tenantId ? `AND t.tenant_id = ${parseInt(tenantId)}` : ''
const params = raffle_id ? [raffle_id] : []
const sql = `
SELECT
COALESCE(SUM(t.price_paid), 0) AS total_revenue,
COALESCE(AVG(t.price_paid), 0) AS avg_price,
COUNT(t.id) AS total_tickets_sold
FROM tickets t
JOIN raffles r ON r.id = t.raffle_id
WHERE t.status = 'sold' ${raffleFilter} ${tenantFilter}
`
const res = await query(sql, params)
const row = res[0] || { total_revenue: 0, avg_price: 0, total_tickets_sold: 0 }
const tWhere = tenantId ? `WHERE tenant_id = ${parseInt(tenantId, 10)}` : ''
const [usersRow] = await query(`SELECT COUNT(*) AS cnt FROM users ${tWhere}`)
const [activeRow] = await query(
tenantId
? `SELECT COUNT(t.id) AS cnt FROM tickets t JOIN raffles r ON r.id = t.raffle_id WHERE r.tenant_id = ${parseInt(tenantId, 10)} AND t.status = 'sold'`
: `SELECT COUNT(*) AS cnt FROM tickets WHERE status = 'sold'`
)
row.total_users = usersRow?.cnt ?? 0
row.active_tickets = activeRow?.cnt ?? 0
return row
}
static getSalesByDay(tenantId = null) {
const f = tFilter(tenantId)
return query(`
SELECT
DATE(t.data_compra) AS date,
COUNT(t.id) AS tickets_sold,
SUM(t.price_paid) AS revenue
FROM tickets t
WHERE t.data_compra >= NOW() - INTERVAL '30 days' AND t.status = 'sold' ${f}
GROUP BY date
ORDER BY date ASC
`)
}
static getSalesByHour(tenantId = null) {
const f = tFilter(tenantId)
return query(`
SELECT
EXTRACT(HOUR FROM t.data_compra) AS hour_of_day,
COUNT(t.id) AS tickets_sold,
COALESCE(SUM(t.price_paid), 0) AS revenue
FROM tickets t
WHERE t.data_compra >= NOW() - INTERVAL '7 days' AND t.status = 'sold' ${f}
GROUP BY hour_of_day
ORDER BY hour_of_day ASC
`)
}
static getSalesByRaffle(tenantId = null) {
const f = tenantId ? `AND r.tenant_id = ${parseInt(tenantId)}` : ''
return query(`
SELECT
r.id AS raffle_id,
r.titulo AS raffle_name,
COUNT(t.id) AS tickets_sold,
r.total_numeros,
COALESCE(SUM(t.price_paid), 0) AS revenue
FROM raffles r
LEFT JOIN tickets t ON t.raffle_id = r.id AND t.status = 'sold'
WHERE r.ativo = 1 ${f}
GROUP BY r.id, r.titulo, r.total_numeros
ORDER BY tickets_sold DESC
`)
}
}
module.exports = Analytics