mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 21:21:10 +02:00
Mirrors the frontend unification (single IndexedDB) on the backend. All services now use pgSchema() for isolation within one shared database, enabling cross-schema JOINs, simplified ops, and zero DB setup for new apps. - Migrate 7 services from pgTable() to pgSchema(): mana-user (usr), mana-media (media), todo, traces, presi, uload, cards - Update all DATABASE_URLs in .env.development, docker-compose, configs - Rewrite init-db scripts for 2 databases + 12 schemas - Rewrite setup-databases.sh for consolidated architecture - Update shared-drizzle-config default to mana_platform - Update CLAUDE.md with new database architecture docs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
import { uuid, text, varchar, timestamp, jsonb, index, pgEnum } from 'drizzle-orm/pg-core';
|
|
import { relations } from 'drizzle-orm';
|
|
import { cardsSchema } from './schema';
|
|
import { decks } from './decks';
|
|
|
|
// AI generation status enum
|
|
export const aiGenerationStatusEnum = pgEnum('ai_generation_status', [
|
|
'pending',
|
|
'processing',
|
|
'completed',
|
|
'failed',
|
|
]);
|
|
|
|
// AI generation metadata structure
|
|
export interface AIGenerationMetadata {
|
|
inputTokens?: number;
|
|
outputTokens?: number;
|
|
totalTokens?: number;
|
|
duration?: number;
|
|
error?: string;
|
|
cardCount?: number;
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
export const aiGenerations = cardsSchema.table(
|
|
'ai_generations',
|
|
{
|
|
id: uuid('id').primaryKey().defaultRandom(),
|
|
userId: text('user_id').notNull(),
|
|
deckId: uuid('deck_id').references(() => decks.id, { onDelete: 'set null' }),
|
|
functionName: varchar('function_name', { length: 100 }).notNull(),
|
|
prompt: text('prompt').notNull(),
|
|
model: varchar('model', { length: 100 }),
|
|
status: aiGenerationStatusEnum('status').default('pending').notNull(),
|
|
metadata: jsonb('metadata').default({}).$type<AIGenerationMetadata>(),
|
|
completedAt: timestamp('completed_at', { withTimezone: true }),
|
|
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
|
},
|
|
(table) => [
|
|
index('idx_ai_generations_user_id').on(table.userId),
|
|
index('idx_ai_generations_deck_id').on(table.deckId),
|
|
index('idx_ai_generations_status').on(table.status),
|
|
index('idx_ai_generations_created_at').on(table.createdAt),
|
|
]
|
|
);
|
|
|
|
export const aiGenerationsRelations = relations(aiGenerations, ({ one }) => ({
|
|
deck: one(decks, {
|
|
fields: [aiGenerations.deckId],
|
|
references: [decks.id],
|
|
}),
|
|
}));
|
|
|
|
export type AIGeneration = typeof aiGenerations.$inferSelect;
|
|
export type NewAIGeneration = typeof aiGenerations.$inferInsert;
|