mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-25 11:34:39 +02:00
feat(matrix): add Stats Bot and Project Doc Bot services
Complete GDPR-compliant bot suite for Matrix: matrix-stats-bot (port 3312): - Analytics reports from Umami - Commands: !stats, !today, !week, !realtime, !users - Scheduled daily/weekly reports to Matrix room matrix-project-doc-bot (port 3313): - Project documentation with photos, voice, text - Voice transcription via OpenAI Whisper - Blog generation with 5 styles (casual, technical, tutorial, social, story) - Commands: !new, !projects, !switch, !status, !generate, !export - Uses PostgreSQL + S3 (MinIO) for storage Changes: - docker-compose.macmini.yml: Added both Matrix bots - health-check.sh: Added health checks for both bots Environment variables required: - MATRIX_STATS_BOT_TOKEN, MATRIX_PROJECT_DOC_BOT_TOKEN - OPENAI_API_KEY (for Project Doc Bot) https://claude.ai/code/session_01E3r5aFW3YLAhEJfsL2ryhv
This commit is contained in:
parent
aabe328b51
commit
7c5e9e3c49
46 changed files with 2215 additions and 0 deletions
8
services/matrix-stats-bot/src/users/users.module.ts
Normal file
8
services/matrix-stats-bot/src/users/users.module.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { UsersService } from './users.service';
|
||||
|
||||
@Module({
|
||||
providers: [UsersService],
|
||||
exports: [UsersService],
|
||||
})
|
||||
export class UsersModule {}
|
||||
55
services/matrix-stats-bot/src/users/users.service.ts
Normal file
55
services/matrix-stats-bot/src/users/users.service.ts
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import postgres from 'postgres';
|
||||
|
||||
interface UserStats {
|
||||
total: number;
|
||||
verified: number;
|
||||
lastWeek: number;
|
||||
lastMonth: number;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class UsersService implements OnModuleInit {
|
||||
private readonly logger = new Logger(UsersService.name);
|
||||
private sql: postgres.Sql | null = null;
|
||||
|
||||
constructor(private configService: ConfigService) {}
|
||||
|
||||
async onModuleInit() {
|
||||
const databaseUrl = this.configService.get<string>('database.url');
|
||||
if (databaseUrl) {
|
||||
try {
|
||||
this.sql = postgres(databaseUrl);
|
||||
this.logger.log('Database connected for user stats');
|
||||
} catch (error) {
|
||||
this.logger.warn('Failed to connect to database:', error);
|
||||
}
|
||||
} else {
|
||||
this.logger.warn('DATABASE_URL not configured - user stats disabled');
|
||||
}
|
||||
}
|
||||
|
||||
async getUserStats(): Promise<UserStats | null> {
|
||||
if (!this.sql) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const [totalResult] = await this.sql`SELECT COUNT(*) as count FROM "user"`;
|
||||
const [verifiedResult] = await this.sql`SELECT COUNT(*) as count FROM "user" WHERE "emailVerified" = true`;
|
||||
const [weekResult] = await this.sql`SELECT COUNT(*) as count FROM "user" WHERE "createdAt" > NOW() - INTERVAL '7 days'`;
|
||||
const [monthResult] = await this.sql`SELECT COUNT(*) as count FROM "user" WHERE "createdAt" > NOW() - INTERVAL '30 days'`;
|
||||
|
||||
return {
|
||||
total: parseInt(totalResult.count, 10),
|
||||
verified: parseInt(verifiedResult.count, 10),
|
||||
lastWeek: parseInt(weekResult.count, 10),
|
||||
lastMonth: parseInt(monthResult.count, 10),
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error('Failed to get user stats:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue