94 lines
3.9 KiB
JavaScript
94 lines
3.9 KiB
JavaScript
/**
|
|
* @param { import("knex").Knex } knex
|
|
* @returns { Promise<void> }
|
|
*/
|
|
exports.up = async function (knex) {
|
|
await knex.schema.createTable('comments', (table) => {
|
|
table.uuid('id').primary().defaultTo(knex.raw('(UUID())'));
|
|
table.string('parent_object_api_name').notNullable();
|
|
table.uuid('parent_record_id').notNullable();
|
|
table.uuid('author_user_id').notNullable();
|
|
table.text('content').notNullable();
|
|
table.timestamps(true, true);
|
|
|
|
table.foreign('author_user_id').references('id').inTable('users').onDelete('CASCADE');
|
|
table.index(['parent_object_api_name', 'parent_record_id'], 'comments_parent_idx');
|
|
table.index(['author_user_id'], 'comments_author_idx');
|
|
});
|
|
|
|
await knex.schema.createTable('semantic_documents', (table) => {
|
|
table.uuid('id').primary().defaultTo(knex.raw('(UUID())'));
|
|
table.string('entity_type').notNullable();
|
|
table.uuid('entity_id').notNullable();
|
|
table.string('title').nullable();
|
|
table.text('narrative').nullable();
|
|
table.json('metadata').nullable();
|
|
table.json('source_summary').nullable();
|
|
table.timestamps(true, true);
|
|
|
|
table.unique(['entity_type', 'entity_id'], {
|
|
indexName: 'semantic_documents_entity_unique',
|
|
});
|
|
table.index(['entity_type'], 'semantic_documents_type_idx');
|
|
});
|
|
|
|
await knex.schema.createTable('semantic_chunks', (table) => {
|
|
table.uuid('id').primary().defaultTo(knex.raw('(UUID())'));
|
|
table.uuid('semantic_document_id').notNullable();
|
|
table.integer('chunk_index').notNullable();
|
|
table.string('source_kind').notNullable().defaultTo('base_record');
|
|
table.uuid('source_ref_id').nullable();
|
|
table.text('text').notNullable();
|
|
table.json('metadata').nullable();
|
|
table.timestamps(true, true);
|
|
|
|
table.foreign('semantic_document_id').references('id').inTable('semantic_documents').onDelete('CASCADE');
|
|
table.unique(['semantic_document_id', 'chunk_index'], {
|
|
indexName: 'semantic_chunks_doc_index_unique',
|
|
});
|
|
table.index(['semantic_document_id'], 'semantic_chunks_document_idx');
|
|
table.index(['source_kind'], 'semantic_chunks_source_kind_idx');
|
|
});
|
|
|
|
await knex.schema.createTable('semantic_links', (table) => {
|
|
table.uuid('id').primary().defaultTo(knex.raw('(UUID())'));
|
|
table.string('source_entity_type', 100).notNullable();
|
|
table.uuid('source_entity_id').notNullable();
|
|
table.string('target_entity_type', 100).notNullable();
|
|
table.uuid('target_entity_id').notNullable();
|
|
table.string('link_type', 100).notNullable().defaultTo('related_to');
|
|
table.string('status').notNullable().defaultTo('suggested');
|
|
table.string('origin').notNullable().defaultTo('semantic');
|
|
table.decimal('confidence', 5, 4).notNullable().defaultTo(0);
|
|
table.text('reason').nullable();
|
|
table.json('evidence').nullable();
|
|
table.uuid('suggested_by_user_id').nullable();
|
|
table.uuid('reviewed_by_user_id').nullable();
|
|
table.timestamp('reviewed_at').nullable();
|
|
table.timestamps(true, true);
|
|
|
|
table.foreign('suggested_by_user_id').references('id').inTable('users').onDelete('SET NULL');
|
|
table.foreign('reviewed_by_user_id').references('id').inTable('users').onDelete('SET NULL');
|
|
|
|
table.unique(
|
|
['source_entity_type', 'source_entity_id', 'target_entity_type', 'target_entity_id', 'link_type'],
|
|
{ indexName: 'semantic_links_unique_pair_type' },
|
|
);
|
|
|
|
table.index(['source_entity_type', 'source_entity_id'], 'semantic_links_source_idx');
|
|
table.index(['target_entity_type', 'target_entity_id'], 'semantic_links_target_idx');
|
|
table.index(['status'], 'semantic_links_status_idx');
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @param { import("knex").Knex } knex
|
|
* @returns { Promise<void> }
|
|
*/
|
|
exports.down = async function (knex) {
|
|
await knex.schema.dropTableIfExists('semantic_links');
|
|
await knex.schema.dropTableIfExists('semantic_chunks');
|
|
await knex.schema.dropTableIfExists('semantic_documents');
|
|
await knex.schema.dropTableIfExists('comments');
|
|
};
|