feat: billing system — credits, plans, transactions
DB: - plans: free/starter/pro/business с ценами и лимитами - user_subscriptions: подписка пользователя на план - user_balance: баланс кредитов + monthly reset - user_transactions: история всех движений кредитов - credit_costs: image=5, text_post=2, article=5, autopublish=0 Engine: - services/billing.js: getBalance, check, spend, credit, getTransactions, processMonthlyResets - routes/billing.js: GET /balance, /transactions, /plans, POST /admin/credit, GET /admin/users - routes/generate.js: списание кредитов перед генерацией (text_post, article, image) - index.js: GET /api/billing/plans публично (без auth)
This commit is contained in:
@@ -38,6 +38,14 @@ require('fs').mkdirSync(UPLOADS_DIR, { recursive: true });
|
||||
app.use('/uploads', express.static(UPLOADS_DIR, { maxAge: '7d', immutable: true }));
|
||||
|
||||
|
||||
// Публичные роуты (без auth)
|
||||
app.get('/api/billing/plans', async (req, res) => {
|
||||
const { query: q } = require('./src/config/db');
|
||||
const { rows: plans } = await q('SELECT * FROM plans WHERE is_active=true ORDER BY sort_order');
|
||||
const { rows: costs } = await q('SELECT * FROM credit_costs ORDER BY operation');
|
||||
res.json({ plans, costs });
|
||||
});
|
||||
|
||||
// Simple internal auth middleware
|
||||
app.use((req, res, next) => {
|
||||
const secret = req.headers['x-internal-secret'];
|
||||
@@ -82,6 +90,7 @@ app.use('/api/channel-stats', channelStatsRoutes);
|
||||
app.use('/api/calendar', calendarRoutes);
|
||||
app.use('/api/metrics', metricsRoutes);
|
||||
app.use('/api/usage', usageRoutes);
|
||||
app.use('/api/billing', require('./src/routes/billing'));
|
||||
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({ ok: true, service: 'zeropost-engine', time: new Date() });
|
||||
|
||||
Reference in New Issue
Block a user