managarten/services/matrix-project-doc-bot/src/database/schema.ts
Claude 7c5e9e3c49
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
2026-01-28 00:44:28 +00:00

33 lines
1.3 KiB
TypeScript

import { pgTable, text, timestamp, uuid, integer } from 'drizzle-orm/pg-core';
export const projects = pgTable('projects', {
id: uuid('id').primaryKey().defaultRandom(),
matrixUserId: text('matrix_user_id').notNull(),
name: text('name').notNull(),
status: text('status').notNull().default('active'), // active, archived
createdAt: timestamp('created_at').notNull().defaultNow(),
updatedAt: timestamp('updated_at').notNull().defaultNow(),
});
export const projectItems = pgTable('project_items', {
id: uuid('id').primaryKey().defaultRandom(),
projectId: uuid('project_id')
.notNull()
.references(() => projects.id, { onDelete: 'cascade' }),
type: text('type').notNull(), // photo, voice, text
content: text('content'), // text content or transcription
mediaUrl: text('media_url'), // S3 URL for media
mediaMxcUrl: text('media_mxc_url'), // Matrix MXC URL
duration: integer('duration'), // Voice duration in seconds
createdAt: timestamp('created_at').notNull().defaultNow(),
});
export const generations = pgTable('generations', {
id: uuid('id').primaryKey().defaultRandom(),
projectId: uuid('project_id')
.notNull()
.references(() => projects.id, { onDelete: 'cascade' }),
style: text('style').notNull(),
content: text('content').notNull(),
createdAt: timestamp('created_at').notNull().defaultNow(),
});