188 lines
6.3 KiB
TypeScript
188 lines
6.3 KiB
TypeScript
import type { Kysely } from 'kysely';
|
|
|
|
import {
|
|
FACTS_TABLE,
|
|
FACT_EMBEDDINGS_TABLE,
|
|
FACT_TOPICS_TABLE,
|
|
SPACES_TABLE,
|
|
TOPIC_ALIASES_TABLE,
|
|
TOPIC_RELATIONS_TABLE,
|
|
TOPICS_TABLE,
|
|
} from './schema';
|
|
import type { IdentityDatabaseSchema } from '../types/database';
|
|
|
|
export async function initializeSchema(
|
|
db: Kysely<IdentityDatabaseSchema>,
|
|
): Promise<void> {
|
|
await db.schema
|
|
.createTable(SPACES_TABLE)
|
|
.ifNotExists()
|
|
.addColumn('id', 'text', (column) => column.primaryKey())
|
|
.addColumn('name', 'text', (column) => column.notNull())
|
|
.addColumn('normalized_name', 'text', (column) => column.notNull().unique())
|
|
.addColumn('description', 'text')
|
|
.addColumn('metadata', 'text')
|
|
.addColumn('created_at', 'text', (column) => column.notNull())
|
|
.addColumn('updated_at', 'text', (column) => column.notNull())
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createTable(TOPICS_TABLE)
|
|
.ifNotExists()
|
|
.addColumn('id', 'text', (column) => column.primaryKey())
|
|
.addColumn('space_id', 'text', (column) =>
|
|
column.notNull().references(`${SPACES_TABLE}.id`).onDelete('cascade'),
|
|
)
|
|
.addColumn('name', 'text', (column) => column.notNull())
|
|
.addColumn('normalized_name', 'text', (column) => column.notNull())
|
|
.addColumn('category', 'text', (column) => column.notNull())
|
|
.addColumn('granularity', 'text', (column) => column.notNull())
|
|
.addColumn('description', 'text')
|
|
.addColumn('metadata', 'text')
|
|
.addColumn('created_at', 'text', (column) => column.notNull())
|
|
.addColumn('updated_at', 'text', (column) => column.notNull())
|
|
.addUniqueConstraint('topics_space_normalized_name_key', ['space_id', 'normalized_name'])
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createTable(FACTS_TABLE)
|
|
.ifNotExists()
|
|
.addColumn('id', 'text', (column) => column.primaryKey())
|
|
.addColumn('space_id', 'text', (column) =>
|
|
column.notNull().references(`${SPACES_TABLE}.id`).onDelete('cascade'),
|
|
)
|
|
.addColumn('statement', 'text', (column) => column.notNull())
|
|
.addColumn('summary', 'text')
|
|
.addColumn('source', 'text')
|
|
.addColumn('confidence', 'real')
|
|
.addColumn('metadata', 'text')
|
|
.addColumn('created_at', 'text', (column) => column.notNull())
|
|
.addColumn('updated_at', 'text', (column) => column.notNull())
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createTable(FACT_EMBEDDINGS_TABLE)
|
|
.ifNotExists()
|
|
.addColumn('fact_id', 'text', (column) =>
|
|
column.notNull().references(`${FACTS_TABLE}.id`).onDelete('cascade'),
|
|
)
|
|
.addColumn('model', 'text', (column) => column.notNull())
|
|
.addColumn('dimensions', 'integer', (column) => column.notNull())
|
|
.addColumn('embedding', 'text', (column) => column.notNull())
|
|
.addColumn('content_hash', 'text', (column) => column.notNull())
|
|
.addColumn('created_at', 'text', (column) => column.notNull())
|
|
.addColumn('updated_at', 'text', (column) => column.notNull())
|
|
.addPrimaryKeyConstraint('fact_embeddings_pk', ['fact_id', 'model'])
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createTable(FACT_TOPICS_TABLE)
|
|
.ifNotExists()
|
|
.addColumn('fact_id', 'text', (column) =>
|
|
column.notNull().references(`${FACTS_TABLE}.id`).onDelete('cascade'),
|
|
)
|
|
.addColumn('topic_id', 'text', (column) =>
|
|
column.notNull().references(`${TOPICS_TABLE}.id`).onDelete('cascade'),
|
|
)
|
|
.addColumn('role', 'text')
|
|
.addColumn('position', 'integer', (column) => column.notNull())
|
|
.addColumn('created_at', 'text', (column) => column.notNull())
|
|
.addPrimaryKeyConstraint('fact_topics_pk', ['fact_id', 'topic_id', 'position'])
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createTable(TOPIC_RELATIONS_TABLE)
|
|
.ifNotExists()
|
|
.addColumn('parent_topic_id', 'text', (column) =>
|
|
column.notNull().references(`${TOPICS_TABLE}.id`).onDelete('cascade'),
|
|
)
|
|
.addColumn('child_topic_id', 'text', (column) =>
|
|
column.notNull().references(`${TOPICS_TABLE}.id`).onDelete('cascade'),
|
|
)
|
|
.addColumn('relation', 'text', (column) => column.notNull())
|
|
.addColumn('created_at', 'text', (column) => column.notNull())
|
|
.addPrimaryKeyConstraint('topic_relations_pk', ['parent_topic_id', 'child_topic_id', 'relation'])
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createTable(TOPIC_ALIASES_TABLE)
|
|
.ifNotExists()
|
|
.addColumn('id', 'text', (column) => column.primaryKey())
|
|
.addColumn('space_id', 'text', (column) =>
|
|
column.notNull().references(`${SPACES_TABLE}.id`).onDelete('cascade'),
|
|
)
|
|
.addColumn('topic_id', 'text', (column) =>
|
|
column.notNull().references(`${TOPICS_TABLE}.id`).onDelete('cascade'),
|
|
)
|
|
.addColumn('alias', 'text', (column) => column.notNull())
|
|
.addColumn('normalized_alias', 'text', (column) => column.notNull())
|
|
.addColumn('is_primary', 'integer', (column) => column.notNull())
|
|
.addColumn('created_at', 'text', (column) => column.notNull())
|
|
.addColumn('updated_at', 'text', (column) => column.notNull())
|
|
.addUniqueConstraint('topic_aliases_space_normalized_alias_key', ['space_id', 'normalized_alias'])
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createIndex('topics_space_id_idx')
|
|
.ifNotExists()
|
|
.on(TOPICS_TABLE)
|
|
.column('space_id')
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createIndex('facts_space_id_idx')
|
|
.ifNotExists()
|
|
.on(FACTS_TABLE)
|
|
.column('space_id')
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createIndex('fact_topics_topic_id_idx')
|
|
.ifNotExists()
|
|
.on(FACT_TOPICS_TABLE)
|
|
.column('topic_id')
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createIndex('fact_topics_fact_id_idx')
|
|
.ifNotExists()
|
|
.on(FACT_TOPICS_TABLE)
|
|
.column('fact_id')
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createIndex('fact_embeddings_model_idx')
|
|
.ifNotExists()
|
|
.on(FACT_EMBEDDINGS_TABLE)
|
|
.column('model')
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createIndex('topic_relations_parent_topic_id_idx')
|
|
.ifNotExists()
|
|
.on(TOPIC_RELATIONS_TABLE)
|
|
.column('parent_topic_id')
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createIndex('topic_relations_child_topic_id_idx')
|
|
.ifNotExists()
|
|
.on(TOPIC_RELATIONS_TABLE)
|
|
.column('child_topic_id')
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createIndex('topic_aliases_space_id_idx')
|
|
.ifNotExists()
|
|
.on(TOPIC_ALIASES_TABLE)
|
|
.column('space_id')
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createIndex('topic_aliases_topic_id_idx')
|
|
.ifNotExists()
|
|
.on(TOPIC_ALIASES_TABLE)
|
|
.column('topic_id')
|
|
.execute();
|
|
}
|