AkurAI Build
Menu

popagent

public

Latest change 87f51a535b92b11ccaf217f96b05a14c907d8eac - Store project documentation in PostgreSQL by Ólafur Búi Ólafsson

import { documentationIndex } from "./documentation-index";
import { storage } from "./storage";

type ImportedNote = {
  workspaceId: string;
  folder: string;
  path: string;
  title: string;
  content: string;
  sourceNoteId: number;
  sourceNotebookId: number;
  updatedAt: number;
};

const source = process.argv[2];
if (!source) throw new Error("Usage: bun src/migrate-akurai-notes.ts <export.json>");
const notes = await Bun.file(source).json() as ImportedNote[];
await documentationIndex.init();

for (const note of notes) {
  const revision = new Bun.CryptoHasher("sha256").update(note.content).digest("hex");
  await storage.db.tx(async (db) => {
    await db.none(`
      INSERT INTO popagent_document_folders (workspace_id, path, name)
      VALUES ($1, split_part($2, '/', 1), $3)
      ON CONFLICT (workspace_id, path) DO UPDATE SET name = EXCLUDED.name
    `, [note.workspaceId, note.path, note.folder]);
    await db.none(`
      INSERT INTO popagent_document_pages
        (workspace_id, path, title, content, revision, source_note_id, source_notebook_id, created_at, updated_at)
      VALUES ($1, $2, $3, $4, $5, $6, $7, to_timestamp($8), to_timestamp($8))
      ON CONFLICT (source_note_id) DO UPDATE SET
        workspace_id = EXCLUDED.workspace_id, path = EXCLUDED.path, title = EXCLUDED.title,
        content = EXCLUDED.content, revision = EXCLUDED.revision,
        source_notebook_id = EXCLUDED.source_notebook_id, updated_at = EXCLUDED.updated_at
    `, [note.workspaceId, note.path, note.title, note.content, revision, note.sourceNoteId, note.sourceNotebookId, note.updatedAt]);
  });
}

for (const workspaceId of new Set(notes.map((note) => note.workspaceId))) {
  await documentationIndex.indexWorkspace(workspaceId);
}

console.log(`Migrated and indexed ${notes.length} AkurAI Notes documents`);