chore(ops): restore all source files in newwhats.clube67.com
continuous-integration/webhook Falha no deploy de clube67_newwhats.local (VPS 4)
continuous-integration/webhook Falha no deploy de clube67_newwhats.local (VPS 4)
This commit is contained in:
+117
@@ -0,0 +1,117 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createFinanceRoutes = createFinanceRoutes;
|
||||
const express_1 = require("express");
|
||||
function createFinanceRoutes(ctx) {
|
||||
const router = (0, express_1.Router)();
|
||||
const { db, hooks } = ctx;
|
||||
// GET /plans — List subscription plans
|
||||
router.get('/plans', async (_req, res) => {
|
||||
try {
|
||||
const plans = await db('subscription_plans').orderBy('monthly_price', 'asc');
|
||||
res.json({ plans });
|
||||
}
|
||||
catch (err) {
|
||||
res.status(500).json({ error: 'Erro ao listar planos' });
|
||||
}
|
||||
});
|
||||
// GET /invoices — List invoices (optional partner filter)
|
||||
router.get('/invoices', async (req, res) => {
|
||||
try {
|
||||
const partnerId = req.query.partner_id;
|
||||
const status = req.query.status;
|
||||
let query = db('invoices')
|
||||
.join('partners', 'invoices.partner_id', 'partners.id')
|
||||
.select('invoices.*', 'partners.company_name');
|
||||
if (partnerId)
|
||||
query = query.where({ 'invoices.partner_id': partnerId });
|
||||
if (status)
|
||||
query = query.where({ 'invoices.status': status });
|
||||
const invoices = await query.orderBy('invoices.due_date', 'desc');
|
||||
res.json({ invoices });
|
||||
}
|
||||
catch (err) {
|
||||
res.status(500).json({ error: 'Erro ao listar faturas' });
|
||||
}
|
||||
});
|
||||
// POST /invoices — Create invoice
|
||||
router.post('/invoices', async (req, res) => {
|
||||
try {
|
||||
const { partner_id, plan_id, amount, due_date } = req.body;
|
||||
const [id] = await db('invoices').insert({
|
||||
partner_id, plan_id, amount,
|
||||
issue_date: db.fn.now(),
|
||||
due_date,
|
||||
status: 'Pendente',
|
||||
});
|
||||
await hooks.emit('invoice:created', { invoiceId: id, partnerId: partner_id });
|
||||
const invoice = await db('invoices').where({ id }).first();
|
||||
res.status(201).json(invoice);
|
||||
}
|
||||
catch (err) {
|
||||
res.status(500).json({ error: 'Erro ao criar fatura' });
|
||||
}
|
||||
});
|
||||
// PUT /invoices/:id/pay — Mark invoice as paid
|
||||
router.put('/invoices/:id/pay', async (req, res) => {
|
||||
try {
|
||||
await db('invoices').where({ id: req.params.id }).update({
|
||||
status: 'Paga',
|
||||
paid_at: db.fn.now(),
|
||||
});
|
||||
await hooks.emit('invoice:paid', { invoiceId: req.params.id });
|
||||
res.json({ message: 'Fatura paga com sucesso' });
|
||||
}
|
||||
catch (err) {
|
||||
res.status(500).json({ error: 'Erro ao pagar fatura' });
|
||||
}
|
||||
});
|
||||
// GET /dashboard — Financial overview
|
||||
router.get('/dashboard', async (_req, res) => {
|
||||
try {
|
||||
const [totalRevenue] = await db('invoices')
|
||||
.where({ status: 'Paga' })
|
||||
.sum('amount as total');
|
||||
const [pendingRevenue] = await db('invoices')
|
||||
.where({ status: 'Pendente' })
|
||||
.sum('amount as total');
|
||||
const [overdueRevenue] = await db('invoices')
|
||||
.where({ status: 'Atrasada' })
|
||||
.sum('amount as total');
|
||||
const [activeSubscriptions] = await db('partners')
|
||||
.where({ status: 'active' })
|
||||
.count('id as count');
|
||||
const planDistribution = await db('partners')
|
||||
.select('subscription_plan_id as plan')
|
||||
.count('id as count')
|
||||
.where({ status: 'active' })
|
||||
.groupBy('subscription_plan_id');
|
||||
res.json({
|
||||
totalRevenue: Number(totalRevenue.total || 0),
|
||||
pendingRevenue: Number(pendingRevenue.total || 0),
|
||||
overdueRevenue: Number(overdueRevenue.total || 0),
|
||||
activeSubscriptions: Number(activeSubscriptions.count),
|
||||
planDistribution,
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
res.status(500).json({ error: 'Erro ao buscar dashboard financeiro' });
|
||||
}
|
||||
});
|
||||
// GET /commissions — List commissions
|
||||
router.get('/commissions', async (req, res) => {
|
||||
try {
|
||||
const partnerId = req.query.partner_id;
|
||||
let query = db('commissions');
|
||||
if (partnerId)
|
||||
query = query.where({ partner_id: partnerId });
|
||||
const commissions = await query.orderBy('transaction_date', 'desc');
|
||||
res.json({ commissions });
|
||||
}
|
||||
catch (err) {
|
||||
res.status(500).json({ error: 'Erro ao listar comissões' });
|
||||
}
|
||||
});
|
||||
return router;
|
||||
}
|
||||
//# sourceMappingURL=routes.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../../../plugins/financeiro/backend/routes.ts"],"names":[],"mappings":"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"}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
import { Router, Request, Response } from 'express';
|
||||
import { PluginContext } from '../../../backend/src/core/types';
|
||||
|
||||
export function createFinanceRoutes(ctx: PluginContext): Router {
|
||||
const router = Router();
|
||||
const { db, hooks } = ctx;
|
||||
|
||||
// GET /plans — List subscription plans
|
||||
router.get('/plans', async (_req: Request, res: Response) => {
|
||||
try {
|
||||
const plans = await db('subscription_plans').orderBy('monthly_price', 'asc');
|
||||
res.json({ plans });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: 'Erro ao listar planos' });
|
||||
}
|
||||
});
|
||||
|
||||
// GET /invoices — List invoices (optional partner filter)
|
||||
router.get('/invoices', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const partnerId = req.query.partner_id as string;
|
||||
const status = req.query.status as string;
|
||||
|
||||
let query = db('invoices')
|
||||
.join('partners', 'invoices.partner_id', 'partners.id')
|
||||
.select('invoices.*', 'partners.company_name');
|
||||
|
||||
if (partnerId) query = query.where({ 'invoices.partner_id': partnerId });
|
||||
if (status) query = query.where({ 'invoices.status': status });
|
||||
|
||||
const invoices = await query.orderBy('invoices.due_date', 'desc');
|
||||
res.json({ invoices });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: 'Erro ao listar faturas' });
|
||||
}
|
||||
});
|
||||
|
||||
// POST /invoices — Create invoice
|
||||
router.post('/invoices', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { partner_id, plan_id, amount, due_date } = req.body;
|
||||
|
||||
const [id] = await db('invoices').insert({
|
||||
partner_id, plan_id, amount,
|
||||
issue_date: db.fn.now(),
|
||||
due_date,
|
||||
status: 'Pendente',
|
||||
});
|
||||
|
||||
await hooks.emit('invoice:created', { invoiceId: id, partnerId: partner_id });
|
||||
const invoice = await db('invoices').where({ id }).first();
|
||||
res.status(201).json(invoice);
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: 'Erro ao criar fatura' });
|
||||
}
|
||||
});
|
||||
|
||||
// PUT /invoices/:id/pay — Mark invoice as paid
|
||||
router.put('/invoices/:id/pay', async (req: Request, res: Response) => {
|
||||
try {
|
||||
await db('invoices').where({ id: req.params.id }).update({
|
||||
status: 'Paga',
|
||||
paid_at: db.fn.now(),
|
||||
});
|
||||
await hooks.emit('invoice:paid', { invoiceId: req.params.id });
|
||||
res.json({ message: 'Fatura paga com sucesso' });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: 'Erro ao pagar fatura' });
|
||||
}
|
||||
});
|
||||
|
||||
// GET /dashboard — Financial overview
|
||||
router.get('/dashboard', async (_req: Request, res: Response) => {
|
||||
try {
|
||||
const [totalRevenue] = await db('invoices')
|
||||
.where({ status: 'Paga' })
|
||||
.sum('amount as total');
|
||||
|
||||
const [pendingRevenue] = await db('invoices')
|
||||
.where({ status: 'Pendente' })
|
||||
.sum('amount as total');
|
||||
|
||||
const [overdueRevenue] = await db('invoices')
|
||||
.where({ status: 'Atrasada' })
|
||||
.sum('amount as total');
|
||||
|
||||
const [activeSubscriptions] = await db('partners')
|
||||
.where({ status: 'active' })
|
||||
.count('id as count');
|
||||
|
||||
const planDistribution = await db('partners')
|
||||
.select('subscription_plan_id as plan')
|
||||
.count('id as count')
|
||||
.where({ status: 'active' })
|
||||
.groupBy('subscription_plan_id');
|
||||
|
||||
res.json({
|
||||
totalRevenue: Number(totalRevenue.total || 0),
|
||||
pendingRevenue: Number(pendingRevenue.total || 0),
|
||||
overdueRevenue: Number(overdueRevenue.total || 0),
|
||||
activeSubscriptions: Number(activeSubscriptions.count),
|
||||
planDistribution,
|
||||
});
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: 'Erro ao buscar dashboard financeiro' });
|
||||
}
|
||||
});
|
||||
|
||||
// GET /commissions — List commissions
|
||||
router.get('/commissions', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const partnerId = req.query.partner_id as string;
|
||||
let query = db('commissions');
|
||||
if (partnerId) query = query.where({ partner_id: partnerId });
|
||||
const commissions = await query.orderBy('transaction_date', 'desc');
|
||||
res.json({ commissions });
|
||||
} catch (err: any) {
|
||||
res.status(500).json({ error: 'Erro ao listar comissões' });
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const routes_1 = require("./backend/routes");
|
||||
const manifest_json_1 = __importDefault(require("./manifest.json"));
|
||||
const plugin = {
|
||||
manifest: manifest_json_1.default,
|
||||
async activate(ctx) {
|
||||
const router = (0, routes_1.createFinanceRoutes)(ctx);
|
||||
ctx.app.use('/api/finance', router);
|
||||
// Listen for new partners to create initial invoice
|
||||
ctx.hooks.register('partner:created', async (data) => {
|
||||
ctx.logger.info(`Creating initial invoice for partner ${data.partnerId}`);
|
||||
});
|
||||
ctx.logger.info('Finance routes registered at /api/finance');
|
||||
},
|
||||
async deactivate(ctx) {
|
||||
ctx.logger.info('Financeiro plugin deactivated');
|
||||
},
|
||||
};
|
||||
exports.default = plugin;
|
||||
//# sourceMappingURL=index.js.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../plugins/financeiro/index.ts"],"names":[],"mappings":";;;;;AACA,6CAAuD;AACvD,oEAAuC;AAEvC,MAAM,MAAM,GAAmB;IAC3B,QAAQ,EAAE,uBAAe;IAEzB,KAAK,CAAC,QAAQ,CAAC,GAAkB;QAC7B,MAAM,MAAM,GAAG,IAAA,4BAAmB,EAAC,GAAG,CAAC,CAAC;QACxC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QAEpC,oDAAoD;QACpD,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,iBAAiB,EAAE,KAAK,EAAE,IAA2B,EAAE,EAAE;YACxE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,wCAAwC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAkB;QAC/B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IACrD,CAAC;CACJ,CAAC;AAEF,kBAAe,MAAM,CAAC"}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { PluginInstance, PluginContext } from '../../backend/src/core/types';
|
||||
import { createFinanceRoutes } from './backend/routes';
|
||||
import manifest from './manifest.json';
|
||||
|
||||
const plugin: PluginInstance = {
|
||||
manifest: manifest as any,
|
||||
|
||||
async activate(ctx: PluginContext): Promise<void> {
|
||||
const router = createFinanceRoutes(ctx);
|
||||
ctx.app.use('/api/finance', router);
|
||||
|
||||
// Listen for new partners to create initial invoice
|
||||
ctx.hooks.register('partner:created', async (data: { partnerId: string }) => {
|
||||
ctx.logger.info(`Creating initial invoice for partner ${data.partnerId}`);
|
||||
});
|
||||
|
||||
ctx.logger.info('Finance routes registered at /api/finance');
|
||||
},
|
||||
|
||||
async deactivate(ctx: PluginContext): Promise<void> {
|
||||
ctx.logger.info('Financeiro plugin deactivated');
|
||||
},
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "financeiro",
|
||||
"displayName": "Financeiro",
|
||||
"version": "1.0.0",
|
||||
"description": "Planos de assinatura, faturas, comissões e controle financeiro de parceiros.",
|
||||
"author": "Clube67",
|
||||
"category": "business",
|
||||
"enabled": true,
|
||||
"canDisable": true,
|
||||
"dependencies": [
|
||||
"core-auth",
|
||||
"partners"
|
||||
],
|
||||
"backend": {
|
||||
"routePrefix": "/api/finance",
|
||||
"hasMigrations": true
|
||||
},
|
||||
"frontend": {
|
||||
"menuItems": [
|
||||
{
|
||||
"id": "finance-dashboard",
|
||||
"label": "Financeiro",
|
||||
"icon": "DollarSign",
|
||||
"href": "/admin/finance",
|
||||
"roles": [
|
||||
"super_admin",
|
||||
"finance"
|
||||
],
|
||||
"order": 50
|
||||
},
|
||||
{
|
||||
"id": "finance-invoices",
|
||||
"label": "Faturas",
|
||||
"icon": "FileText",
|
||||
"href": "/partner/invoices",
|
||||
"roles": [
|
||||
"partner_admin"
|
||||
],
|
||||
"order": 55
|
||||
}
|
||||
],
|
||||
"widgets": [
|
||||
{
|
||||
"id": "finance-mrr",
|
||||
"component": "MRRWidget",
|
||||
"span": 2,
|
||||
"roles": [
|
||||
"super_admin",
|
||||
"finance"
|
||||
],
|
||||
"order": 30
|
||||
}
|
||||
]
|
||||
},
|
||||
"hooks": {
|
||||
"subscribes": [
|
||||
"partner:created",
|
||||
"partner:deactivated"
|
||||
],
|
||||
"emits": [
|
||||
"invoice:created",
|
||||
"invoice:paid",
|
||||
"invoice:overdue"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user