Initial commit: Telegram Management System
Some checks failed
Deploy / deploy (push) Has been cancelled

Full-stack web application for Telegram management
- Frontend: Vue 3 + Vben Admin
- Backend: NestJS
- Features: User management, group broadcast, statistics

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
你的用户名
2025-11-04 15:37:50 +08:00
commit 237c7802e5
3674 changed files with 525172 additions and 0 deletions

View File

@@ -0,0 +1,660 @@
import Joi from '@hapi/joi';
import { EventCollector } from '../services/EventCollector.js';
import { MetricsProcessor } from '../services/MetricsProcessor.js';
import { RealtimeAnalytics } from '../services/RealtimeAnalytics.js';
import { ReportGenerator } from '../services/ReportGenerator.js';
import { AlertManager } from '../services/AlertManager.js';
import { logger } from '../utils/logger.js';
import dashboardRoutes from './dashboard.js';
const eventCollector = EventCollector.getInstance();
const metricsProcessor = MetricsProcessor.getInstance();
const realtimeAnalytics = RealtimeAnalytics.getInstance();
const reportGenerator = ReportGenerator.getInstance();
const alertManager = AlertManager.getInstance();
export default [
...dashboardRoutes,
// Event Collection Routes
{
method: 'POST',
path: '/api/v1/events',
options: {
validate: {
payload: Joi.object({
type: Joi.string().required(),
accountId: Joi.string().required(),
userId: Joi.string().optional(),
sessionId: Joi.string().optional(),
action: Joi.string().required(),
target: Joi.string().optional(),
value: Joi.number().optional(),
metadata: Joi.object().optional(),
properties: Joi.object().optional()
})
},
handler: async (request, h) => {
try {
const result = await eventCollector.collectEvent(request.payload);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Event collection error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'POST',
path: '/api/v1/events/bulk',
options: {
validate: {
payload: Joi.object({
events: Joi.array().items(
Joi.object({
type: Joi.string().required(),
accountId: Joi.string().required(),
userId: Joi.string().optional(),
sessionId: Joi.string().optional(),
action: Joi.string().required(),
target: Joi.string().optional(),
value: Joi.number().optional(),
metadata: Joi.object().optional(),
properties: Joi.object().optional()
})
).required()
})
},
handler: async (request, h) => {
try {
const { events } = request.payload;
const result = await eventCollector.collectBulkEvents(events);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Bulk event collection error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'GET',
path: '/api/v1/events',
options: {
validate: {
query: Joi.object({
type: Joi.string().optional(),
accountId: Joi.string().optional(),
userId: Joi.string().optional(),
startTime: Joi.date().iso().optional(),
endTime: Joi.date().iso().optional(),
limit: Joi.number().min(1).max(1000).default(100),
offset: Joi.number().min(0).default(0),
aggregation: Joi.string().valid('hourly', 'daily', 'by_type').optional()
})
},
handler: async (request, h) => {
try {
const result = await eventCollector.queryEvents(request.query);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Event query error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
// Metrics Routes
{
method: 'GET',
path: '/api/v1/metrics/{metricId}',
options: {
validate: {
params: Joi.object({
metricId: Joi.string().required()
}),
query: Joi.object({
startTime: Joi.date().iso().optional(),
endTime: Joi.date().iso().optional(),
dimensions: Joi.object().optional(),
limit: Joi.number().min(1).max(10000).default(1000)
})
},
handler: async (request, h) => {
try {
const { metricId } = request.params;
const result = await metricsProcessor.getMetric(metricId, request.query);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Metric query error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'GET',
path: '/api/v1/metrics/{metricId}/summary',
options: {
validate: {
params: Joi.object({
metricId: Joi.string().required()
})
},
handler: async (request, h) => {
try {
const { metricId } = request.params;
const result = await metricsProcessor.getMetricSummary(metricId);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Metric summary error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'PUT',
path: '/api/v1/metrics/{metricId}',
options: {
validate: {
params: Joi.object({
metricId: Joi.string().required()
}),
payload: Joi.object({
name: Joi.string(),
description: Joi.string(),
formula: Joi.string(),
dimensions: Joi.array().items(Joi.string()),
aggregations: Joi.array().items(Joi.string()),
refreshInterval: Joi.number(),
retentionDays: Joi.number(),
active: Joi.boolean()
})
},
handler: async (request, h) => {
try {
const { metricId } = request.params;
const result = await metricsProcessor.updateMetricDefinition(metricId, request.payload);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Metric update error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
// Real-time Analytics Routes
{
method: 'GET',
path: '/api/v1/realtime/dashboard/{accountId}',
options: {
validate: {
params: Joi.object({
accountId: Joi.string().required()
})
},
handler: async (request, h) => {
try {
const { accountId } = request.params;
const result = await realtimeAnalytics.getDashboard(accountId);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Dashboard error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'POST',
path: '/api/v1/realtime/subscribe',
options: {
validate: {
payload: Joi.object({
accountId: Joi.string().required(),
metrics: Joi.array().items(Joi.string()).required(),
filters: Joi.object().optional()
})
},
handler: async (request, h) => {
try {
const { accountId, metrics, filters } = request.payload;
const subscriptionId = await realtimeAnalytics.subscribe(accountId, metrics, filters);
return h.response({
success: true,
data: { subscriptionId }
});
} catch (error) {
logger.error('Subscription error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'DELETE',
path: '/api/v1/realtime/subscribe/{subscriptionId}',
options: {
validate: {
params: Joi.object({
subscriptionId: Joi.string().required()
})
},
handler: async (request, h) => {
try {
const { subscriptionId } = request.params;
const result = realtimeAnalytics.unsubscribe(subscriptionId);
return h.response({
success: true,
data: { unsubscribed: result }
});
} catch (error) {
logger.error('Unsubscribe error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
// Report Generation Routes
{
method: 'POST',
path: '/api/v1/reports/generate',
options: {
validate: {
payload: Joi.object({
accountId: Joi.string().required(),
type: Joi.string().valid(
'campaign_performance',
'user_analytics',
'ab_test'
).required(),
period: Joi.string().valid(
'today', 'yesterday', 'this_week', 'last_week',
'this_month', 'last_month', 'last_30_days', 'last_90_days'
).optional(),
startDate: Joi.date().iso().optional(),
endDate: Joi.date().iso().optional(),
filters: Joi.object().optional(),
format: Joi.string().valid('json', 'pdf', 'excel', 'csv').default('json')
})
},
handler: async (request, h) => {
try {
const result = await reportGenerator.generateReport(request.payload);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Report generation error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'POST',
path: '/api/v1/reports/schedule',
options: {
validate: {
payload: Joi.object({
accountId: Joi.string().required(),
type: Joi.string().required(),
schedule: Joi.string().required(), // cron expression
recipients: Joi.array().items(Joi.string()).required(),
format: Joi.string().valid('pdf', 'excel', 'csv').default('pdf')
})
},
handler: async (request, h) => {
try {
const result = await reportGenerator.scheduleReport(request.payload);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Report scheduling error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'GET',
path: '/api/v1/reports/history',
options: {
validate: {
query: Joi.object({
accountId: Joi.string().required(),
limit: Joi.number().min(1).max(100).default(20)
})
},
handler: async (request, h) => {
try {
const { accountId, limit } = request.query;
const result = await reportGenerator.getReportHistory(accountId, limit);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Report history error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
// Alert Management Routes
{
method: 'POST',
path: '/api/v1/alerts/rules',
options: {
validate: {
payload: Joi.object({
ruleId: Joi.string().required(),
name: Joi.string().required(),
description: Joi.string().optional(),
metric: Joi.string().required(),
condition: Joi.object({
operator: Joi.string().valid('>', '>=', '<', '<=', '=', '==', '!=').required(),
threshold: Joi.number().required(),
duration: Joi.number().min(0).default(300)
}).required(),
severity: Joi.string().valid('low', 'medium', 'high', 'critical').required(),
channels: Joi.array().items(Joi.string()).required(),
cooldown: Joi.number().min(0).default(1800),
accountId: Joi.string().optional(),
active: Joi.boolean().default(true)
})
},
handler: async (request, h) => {
try {
const result = await alertManager.createAlertRule(request.payload);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Alert rule creation error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'PUT',
path: '/api/v1/alerts/rules/{ruleId}',
options: {
validate: {
params: Joi.object({
ruleId: Joi.string().required()
}),
payload: Joi.object({
name: Joi.string(),
description: Joi.string(),
condition: Joi.object(),
severity: Joi.string().valid('low', 'medium', 'high', 'critical'),
channels: Joi.array().items(Joi.string()),
cooldown: Joi.number(),
active: Joi.boolean()
})
},
handler: async (request, h) => {
try {
const { ruleId } = request.params;
const result = await alertManager.updateAlertRule(ruleId, request.payload);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Alert rule update error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'DELETE',
path: '/api/v1/alerts/rules/{ruleId}',
options: {
validate: {
params: Joi.object({
ruleId: Joi.string().required()
})
},
handler: async (request, h) => {
try {
const { ruleId } = request.params;
const result = await alertManager.deleteAlertRule(ruleId);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Alert rule deletion error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'GET',
path: '/api/v1/alerts/history',
options: {
validate: {
query: Joi.object({
ruleId: Joi.string().optional(),
severity: Joi.string().optional(),
startTime: Joi.date().iso().optional(),
endTime: Joi.date().iso().optional(),
limit: Joi.number().min(1).max(1000).default(100)
})
},
handler: async (request, h) => {
try {
const result = await alertManager.getAlertHistory(request.query);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Alert history error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'POST',
path: '/api/v1/alerts/{alertId}/acknowledge',
options: {
validate: {
params: Joi.object({
alertId: Joi.string().required()
})
},
handler: async (request, h) => {
try {
const { alertId } = request.params;
const result = await alertManager.acknowledgeAlert(alertId);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Alert acknowledge error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'POST',
path: '/api/v1/alerts/{alertId}/resolve',
options: {
validate: {
params: Joi.object({
alertId: Joi.string().required()
}),
payload: Joi.object({
resolution: Joi.string().required()
})
},
handler: async (request, h) => {
try {
const { alertId } = request.params;
const { resolution } = request.payload;
const result = await alertManager.resolveAlert(alertId, resolution);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Alert resolve error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
},
{
method: 'GET',
path: '/api/v1/alerts/stats',
options: {
validate: {
query: Joi.object({
period: Joi.string().valid('1h', '24h', '7d').default('24h')
})
},
handler: async (request, h) => {
try {
const { period } = request.query;
const result = await alertManager.getAlertStats(period);
return h.response({
success: true,
data: result
});
} catch (error) {
logger.error('Alert stats error:', error);
return h.response({
success: false,
error: error.message
}).code(500);
}
}
}
}
];