Files
hristudio/scripts/archive/seed-story-red-rock.ts

275 lines
7.1 KiB
TypeScript

import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import * as schema from "../../src/server/db/schema";
import { sql } from "drizzle-orm";
import { v4 as uuidv4 } from "uuid";
// Database connection
const connectionString = process.env.DATABASE_URL!;
const connection = postgres(connectionString);
const db = drizzle(connection, { schema });
async function main() {
console.log("🌱 Seeding 'Story: Red Rock' experiment...");
try {
// 1. Find Admin User & Study
const user = await db.query.users.findFirst({
where: (users, { eq }) => eq(users.email, "sean@soconnor.dev"),
});
if (!user) throw new Error("Admin user 'sean@soconnor.dev' not found.");
const study = await db.query.studies.findFirst({
where: (studies, { eq }) => eq(studies.name, "Comparative WoZ Study"),
});
if (!study) throw new Error("Study 'Comparative WoZ Study' not found.");
const robot = await db.query.robots.findFirst({
where: (robots, { eq }) => eq(robots.name, "NAO6"),
});
if (!robot) throw new Error("Robot 'NAO6' not found.");
// 2. Create Experiment
const [experiment] = await db
.insert(schema.experiments)
.values({
studyId: study.id,
name: "Story: Red Rock",
description:
"A story about a red rock on Mars with comprehension check and branching.",
version: 1,
status: "draft",
robotId: robot.id,
createdBy: user.id,
})
.returning();
if (!experiment) throw new Error("Failed to create experiment");
console.log(`✅ Created Experiment: ${experiment.id}`);
// 3. Create Steps (in reverse for ID references if needed, but we'll use uuid placeholders)
const conclusionId = uuidv4();
const branchAId = uuidv4();
const branchBId = uuidv4();
const checkId = uuidv4();
// Step 1: The Hook
const [step1] = await db
.insert(schema.steps)
.values({
experimentId: experiment.id,
name: "The Hook",
type: "wizard",
orderIndex: 0,
})
.returning();
// Step 2: The Narrative
const [step2] = await db
.insert(schema.steps)
.values({
experimentId: experiment.id,
name: "The Narrative",
type: "wizard",
orderIndex: 1,
})
.returning();
// Step 3: Comprehension Check (Conditional)
const [step3] = await db
.insert(schema.steps)
.values({
id: checkId,
experimentId: experiment.id,
name: "Comprehension Check",
type: "conditional",
orderIndex: 2,
conditions: {
variable: "last_wizard_response",
options: [
{
label: "Answer: Red (Correct)",
value: "Red",
variant: "default",
nextStepId: branchAId,
},
{
label: "Answer: Other (Incorrect)",
value: "Incorrect",
variant: "destructive",
nextStepId: branchBId,
},
],
},
})
.returning();
// Step 4: Branch A (Correct)
const [step4] = await db
.insert(schema.steps)
.values({
id: branchAId,
experimentId: experiment.id,
name: "Branch A: Correct Response",
type: "wizard",
orderIndex: 3,
conditions: { nextStepId: conclusionId }, // SKIP BRANCH B
})
.returning();
// Step 5: Branch B (Incorrect)
const [step5] = await db
.insert(schema.steps)
.values({
id: branchBId,
experimentId: experiment.id,
name: "Branch B: Incorrect Response",
type: "wizard",
orderIndex: 4,
conditions: { nextStepId: conclusionId },
})
.returning();
// Step 6: Conclusion
const [step6] = await db
.insert(schema.steps)
.values({
id: conclusionId,
experimentId: experiment.id,
name: "Conclusion",
type: "wizard",
orderIndex: 5,
})
.returning();
// 4. Create Actions
// The Hook
await db.insert(schema.actions).values([
{
stepId: step1!.id,
name: "Say Hello",
type: "nao6-ros2.say_text",
orderIndex: 0,
parameters: { text: "Hello! Are you ready for a story?" },
},
{
stepId: step1!.id,
name: "Wave",
type: "nao6-ros2.move_arm",
orderIndex: 1,
parameters: { arm: "right", shoulder_pitch: 0.5 },
},
]);
// The Narrative
await db.insert(schema.actions).values([
{
stepId: step2!.id,
name: "The Story",
type: "nao6-ros2.say_text",
orderIndex: 0,
parameters: {
text: "Once, a traveler went to Mars. He found a bright red rock that glowed.",
},
},
{
stepId: step2!.id,
name: "Look Left",
type: "nao6-ros2.turn_head",
orderIndex: 1,
parameters: { yaw: 0.5, speed: 0.3 },
},
{
stepId: step2!.id,
name: "Look Right",
type: "nao6-ros2.turn_head",
orderIndex: 2,
parameters: { yaw: -0.5, speed: 0.3 },
},
]);
// Comprehension Check
await db.insert(schema.actions).values([
{
stepId: step3!.id,
name: "Ask Color",
type: "nao6-ros2.say_text",
orderIndex: 0,
parameters: { text: "What color was the rock I found on Mars?" },
},
{
stepId: step3!.id,
name: "Wait for Color",
type: "wizard_wait_for_response",
orderIndex: 1,
parameters: {
options: ["Red", "Blue", "Green", "Incorrect"],
prompt_text: "What color did the participant say?",
},
},
]);
// Branch A (Using say_with_emotion)
await db
.insert(schema.actions)
.values([
{
stepId: step4!.id,
name: "Happy Response",
type: "nao6-ros2.say_with_emotion",
orderIndex: 0,
parameters: {
text: "Exacty! It was a glowing red rock.",
emotion: "happy",
},
},
]);
// Branch B
await db.insert(schema.actions).values([
{
stepId: step5!.id,
name: "Correct them",
type: "nao6-ros2.say_text",
orderIndex: 0,
parameters: { text: "Actually, it was red." },
},
{
stepId: step5!.id,
name: "Shake Head",
type: "nao6-ros2.turn_head",
orderIndex: 1,
parameters: { yaw: 0.3, speed: 0.5 },
},
]);
// Conclusion
await db.insert(schema.actions).values([
{
stepId: step6!.id,
name: "Final Goodbye",
type: "nao6-ros2.say_text",
orderIndex: 0,
parameters: { text: "That is all for today. Goodbye!" },
},
{
stepId: step6!.id,
name: "Rest",
type: "nao6-ros2.move_arm",
orderIndex: 1,
parameters: { shoulder_pitch: 1.5 },
},
]);
console.log("✅ Seed completed successfully!");
} catch (err) {
console.error("❌ Seed failed:", err);
process.exit(1);
} finally {
await connection.end();
}
}
main();