feat: implement Story 3.1 — chat panel UI with streaming AI responses

Add AI copilot chat panel to the diagram editor with streaming responses,
chat history persistence, and markdown rendering. Includes copilot API route,
diagram-aware system prompt, and schema with 15 passing tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-02-28 10:03:43 +00:00
parent 9d13d0f562
commit 26215d9060
20 changed files with 3223 additions and 37 deletions

View File

@@ -0,0 +1,2 @@
ALTER TABLE "chat"."chat" ADD COLUMN "diagram_id" text;--> statement-breakpoint
CREATE INDEX "chat_diagram_id_idx" ON "chat"."chat" USING btree ("diagram_id");

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,13 @@
"when": 1771885601062,
"tag": "0001_fuzzy_gorilla_man",
"breakpoints": true
},
{
"idx": 2,
"version": "7",
"when": 1772245471347,
"tag": "0002_numerous_siren",
"breakpoints": true
}
]
}

View File

@@ -1,5 +1,12 @@
import { relations } from "drizzle-orm";
import { integer, jsonb, pgSchema, timestamp, text } from "drizzle-orm/pg-core";
import {
index,
integer,
jsonb,
pgSchema,
timestamp,
text,
} from "drizzle-orm/pg-core";
import { generateId } from "@turbostarter/shared/utils";
@@ -15,17 +22,22 @@ export const messageRoleEnum = schema.enum("role", [
"user",
]);
export const chat = schema.table("chat", {
id: text().primaryKey().notNull().$defaultFn(generateId),
name: text(),
userId: text()
.references(() => user.id, {
onDelete: "cascade",
onUpdate: "cascade",
})
.notNull(),
createdAt: timestamp().defaultNow(),
});
export const chat = schema.table(
"chat",
{
id: text().primaryKey().notNull().$defaultFn(generateId),
name: text(),
diagramId: text(),
userId: text()
.references(() => user.id, {
onDelete: "cascade",
onUpdate: "cascade",
})
.notNull(),
createdAt: timestamp().defaultNow(),
},
(t) => [index("chat_diagram_id_idx").on(t.diagramId)],
);
export const message = schema.table("message", {
id: text().primaryKey().notNull().$defaultFn(generateId),