diff --git a/docs/erd.svg b/docs/erd.svg
index 76d6985..fd4b3eb 100644
--- a/docs/erd.svg
+++ b/docs/erd.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/prisma/migrations/20260429171047_add_claude_worker/migration.sql b/prisma/migrations/20260429171047_add_claude_worker/migration.sql
new file mode 100644
index 0000000..f951db3
--- /dev/null
+++ b/prisma/migrations/20260429171047_add_claude_worker/migration.sql
@@ -0,0 +1,23 @@
+-- CreateTable
+CREATE TABLE "claude_workers" (
+ "id" TEXT NOT NULL,
+ "user_id" TEXT NOT NULL,
+ "token_id" TEXT NOT NULL,
+ "product_id" TEXT,
+ "started_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "last_seen_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "claude_workers_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateIndex
+CREATE INDEX "claude_workers_user_id_last_seen_at_idx" ON "claude_workers"("user_id", "last_seen_at");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "claude_workers_token_id_key" ON "claude_workers"("token_id");
+
+-- AddForeignKey
+ALTER TABLE "claude_workers" ADD CONSTRAINT "claude_workers_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "claude_workers" ADD CONSTRAINT "claude_workers_token_id_fkey" FOREIGN KEY ("token_id") REFERENCES "api_tokens"("id") ON DELETE CASCADE ON UPDATE CASCADE;
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 03d8eb0..6586980 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -84,6 +84,7 @@ model User {
asked_questions ClaudeQuestion[] @relation("ClaudeQuestionAsker")
answered_questions ClaudeQuestion[] @relation("ClaudeQuestionAnswerer")
claude_jobs ClaudeJob[]
+ claude_workers ClaudeWorker[]
@@index([active_product_id])
@@map("users")
@@ -100,14 +101,15 @@ model UserRole {
}
model ApiToken {
- id String @id @default(cuid())
- user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
- user_id String
- token_hash String @unique
- label String?
- created_at DateTime @default(now())
- revoked_at DateTime?
- claimed_jobs ClaudeJob[]
+ id String @id @default(cuid())
+ user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
+ user_id String
+ token_hash String @unique
+ label String?
+ created_at DateTime @default(now())
+ revoked_at DateTime?
+ claimed_jobs ClaudeJob[]
+ claude_worker ClaudeWorker?
@@index([token_hash])
@@map("api_tokens")
@@ -270,6 +272,21 @@ model ClaudeJob {
@@map("claude_jobs")
}
+model ClaudeWorker {
+ id String @id @default(cuid())
+ user User @relation(fields: [user_id], references: [id], onDelete: Cascade)
+ user_id String
+ token ApiToken @relation(fields: [token_id], references: [id], onDelete: Cascade)
+ token_id String
+ product_id String?
+ started_at DateTime @default(now())
+ last_seen_at DateTime @default(now())
+
+ @@unique([token_id])
+ @@index([user_id, last_seen_at])
+ @@map("claude_workers")
+}
+
model ProductMember {
id String @id @default(cuid())
product Product @relation(fields: [product_id], references: [id], onDelete: Cascade)