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:
Ник (Claude)
2026-06-11 18:26:38 +03:00
parent eede50bee7
commit 2e60a6e316
4 changed files with 331 additions and 3 deletions
+9
View File
@@ -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() });