WFDASH-WEBAPP/scripts/migrations/2026-09-30-create-giellie-chats.ts
Dave b35159d859 feat(giellie): chat store and giellie_chats migration
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-30 23:44:55 +02:00

79 lines
2.7 KiB
TypeScript

/**
* One-shot migration: create the `giellie_chats` collection (Giellie agent
* chat history — ONE collection; transcript lives in the `messages` json).
*
* Run with:
*
* npm run pb:migrate:giellie-chats
*
* Reads/writes go through the server's admin client; the API rules below
* only matter for direct PB access: a user can list/view their own chats,
* nobody can create/update/delete via the public API.
*
* Idempotent — exits early if the collection exists.
* Rollback: delete the `giellie_chats` collection in the PB admin UI.
*/
import "./_env-loader";
import PocketBase from "pocketbase";
const PB_URL = process.env.NEXT_PUBLIC_POCKETBASE_URL || "http://127.0.0.1:8090";
const ADMIN_EMAIL = process.env.PB_ADMIN_EMAIL;
const ADMIN_PASSWORD = process.env.PB_ADMIN_PASSWORD;
async function main() {
if (!ADMIN_EMAIL || !ADMIN_PASSWORD) {
throw new Error("Set PB_ADMIN_EMAIL and PB_ADMIN_PASSWORD (e.g. from .env.local).");
}
const pb = new PocketBase(PB_URL);
await pb.collection("_superusers").authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD);
console.log(`[giellie-chats] Authenticated against ${PB_URL}`);
const all = await pb.collections.getFullList();
if (all.find((c) => c.name === "giellie_chats")) {
console.log("[giellie-chats] giellie_chats already exists — skipping.");
return;
}
const users = all.find((c) => c.name === "users");
if (!users) throw new Error("users collection not found");
await pb.collections.create({
name: "giellie_chats",
type: "base",
listRule: "user = @request.auth.id",
viewRule: "user = @request.auth.id",
createRule: null,
updateRule: null,
deleteRule: null,
fields: [
{
name: "user",
type: "relation",
required: true,
collectionId: users.id,
maxSelect: 1,
cascadeDelete: true,
},
// Explicit max: PB treats max 0 as a 5000-char cap, not unlimited.
{ name: "title", type: "text", required: false, max: 200 },
{ name: "messages", type: "json", required: false, maxSize: 5000000 },
{ name: "pending_action", type: "json", required: false, maxSize: 1000000 },
{
name: "attachments",
type: "file",
required: false,
maxSelect: 50,
maxSize: 10485760,
mimeTypes: [],
},
{ name: "created", type: "autodate", onCreate: true, onUpdate: false },
{ name: "updated", type: "autodate", onCreate: true, onUpdate: true },
],
indexes: ["CREATE INDEX idx_giellie_chats_user ON giellie_chats (user, updated)"],
});
console.log("[giellie-chats] Created giellie_chats collection.");
}
main().catch((e) => {
console.error(e);
process.exit(1);
});