45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
import { MeiliSearch } from 'meilisearch';
|
|
|
|
export { MeiliSearch } from 'meilisearch';
|
|
|
|
export interface MeiliDocument {
|
|
id: string; // DB Message.id
|
|
tenantId: string; // tenant owner — required for multi-tenant filter
|
|
content: string;
|
|
senderName: string; // empty string when null
|
|
sourceGroupId: string;
|
|
sourceGroupName: string;
|
|
tags: string[];
|
|
platform: string;
|
|
approvedAt: number; // Unix ms — Meilisearch sorts numbers, not ISO strings
|
|
}
|
|
|
|
export const MESSAGES_INDEX = 'tower-messages';
|
|
|
|
export function createMeiliClient(url: string, masterKey: string): MeiliSearch {
|
|
return new MeiliSearch({ host: url, apiKey: masterKey });
|
|
}
|
|
|
|
export async function configureIndex(client: MeiliSearch): Promise<void> {
|
|
// Ensure the index exists with the correct primary key
|
|
// (Meilisearch v1.11 can't infer it when multiple fields end with `id`)
|
|
try {
|
|
await client.getIndex(MESSAGES_INDEX);
|
|
} catch {
|
|
await client.createIndex(MESSAGES_INDEX, { primaryKey: 'id' });
|
|
}
|
|
await client.index(MESSAGES_INDEX).updateSettings({
|
|
searchableAttributes: ['content', 'senderName', 'sourceGroupName'],
|
|
filterableAttributes: ['tenantId', 'sourceGroupId', 'tags', 'platform'],
|
|
sortableAttributes: ['approvedAt'],
|
|
});
|
|
}
|
|
|
|
export async function indexMessage(client: MeiliSearch, doc: MeiliDocument): Promise<void> {
|
|
await client.index(MESSAGES_INDEX).addDocuments([doc], { primaryKey: 'id' });
|
|
}
|
|
|
|
export async function deleteMessage(client: MeiliSearch, id: string): Promise<void> {
|
|
await client.index(MESSAGES_INDEX).deleteDocument(id);
|
|
}
|