mirror of
https://github.com/soconnor0919/hristudio.git
synced 2026-03-23 19:27:51 -04:00
feat: Implement digital signatures for participant consent and introduce study forms management.
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
import * as schema from "../../src/server/db/schema";
|
||||
@@ -9,38 +8,39 @@ const connection = postgres(connectionString);
|
||||
const db = drizzle(connection, { schema });
|
||||
|
||||
async function main() {
|
||||
console.log("🔍 Checking seeded actions...");
|
||||
console.log("🔍 Checking seeded actions...");
|
||||
|
||||
const actions = await db.query.actions.findMany({
|
||||
where: (actions, { or, eq, like }) => or(
|
||||
eq(actions.type, "sequence"),
|
||||
eq(actions.type, "parallel"),
|
||||
eq(actions.type, "loop"),
|
||||
eq(actions.type, "branch"),
|
||||
like(actions.type, "hristudio-core%")
|
||||
),
|
||||
limit: 10
|
||||
});
|
||||
const actions = await db.query.actions.findMany({
|
||||
where: (actions, { or, eq, like }) =>
|
||||
or(
|
||||
eq(actions.type, "sequence"),
|
||||
eq(actions.type, "parallel"),
|
||||
eq(actions.type, "loop"),
|
||||
eq(actions.type, "branch"),
|
||||
like(actions.type, "hristudio-core%"),
|
||||
),
|
||||
limit: 10,
|
||||
});
|
||||
|
||||
console.log(`Found ${actions.length} control actions.`);
|
||||
console.log(`Found ${actions.length} control actions.`);
|
||||
|
||||
for (const action of actions) {
|
||||
console.log(`\nAction: ${action.name} (${action.type})`);
|
||||
console.log(`ID: ${action.id}`);
|
||||
// Explicitly log parameters to check structure
|
||||
console.log("Parameters:", JSON.stringify(action.parameters, null, 2));
|
||||
for (const action of actions) {
|
||||
console.log(`\nAction: ${action.name} (${action.type})`);
|
||||
console.log(`ID: ${action.id}`);
|
||||
// Explicitly log parameters to check structure
|
||||
console.log("Parameters:", JSON.stringify(action.parameters, null, 2));
|
||||
|
||||
const params = action.parameters as any;
|
||||
if (params.children) {
|
||||
console.log(`✅ Has ${params.children.length} children in parameters.`);
|
||||
} else if (params.trueBranch || params.falseBranch) {
|
||||
console.log(`✅ Has branches in parameters.`);
|
||||
} else {
|
||||
console.log(`❌ No children/branches found in parameters.`);
|
||||
}
|
||||
const params = action.parameters as any;
|
||||
if (params.children) {
|
||||
console.log(`✅ Has ${params.children.length} children in parameters.`);
|
||||
} else if (params.trueBranch || params.falseBranch) {
|
||||
console.log(`✅ Has branches in parameters.`);
|
||||
} else {
|
||||
console.log(`❌ No children/branches found in parameters.`);
|
||||
}
|
||||
}
|
||||
|
||||
await connection.end();
|
||||
await connection.end();
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
import * as schema from "../../src/server/db/schema";
|
||||
@@ -9,57 +8,59 @@ const connection = postgres(connectionString);
|
||||
const db = drizzle(connection, { schema });
|
||||
|
||||
async function main() {
|
||||
console.log("🔍 Checking Database State...");
|
||||
console.log("🔍 Checking Database State...");
|
||||
|
||||
// 1. Check Plugin
|
||||
const plugins = await db.query.plugins.findMany();
|
||||
console.log(`\nFound ${plugins.length} plugins.`);
|
||||
// 1. Check Plugin
|
||||
const plugins = await db.query.plugins.findMany();
|
||||
console.log(`\nFound ${plugins.length} plugins.`);
|
||||
|
||||
const expectedKeys = new Set<string>();
|
||||
const expectedKeys = new Set<string>();
|
||||
|
||||
for (const p of plugins) {
|
||||
const meta = p.metadata as any;
|
||||
const defs = p.actionDefinitions as any[];
|
||||
for (const p of plugins) {
|
||||
const meta = p.metadata as any;
|
||||
const defs = p.actionDefinitions as any[];
|
||||
|
||||
console.log(`Plugin [${p.name}] (ID: ${p.id}):`);
|
||||
console.log(` - Robot ID (Column): ${p.robotId}`);
|
||||
console.log(` - Metadata.robotId: ${meta?.robotId}`);
|
||||
console.log(` - Action Definitions: ${defs?.length ?? 0} found.`);
|
||||
console.log(`Plugin [${p.name}] (ID: ${p.id}):`);
|
||||
console.log(` - Robot ID (Column): ${p.robotId}`);
|
||||
console.log(` - Metadata.robotId: ${meta?.robotId}`);
|
||||
console.log(` - Action Definitions: ${defs?.length ?? 0} found.`);
|
||||
|
||||
if (defs && meta?.robotId) {
|
||||
defs.forEach(d => {
|
||||
const key = `${meta.robotId}.${d.id}`;
|
||||
expectedKeys.add(key);
|
||||
// console.log(` -> Registers: ${key}`);
|
||||
});
|
||||
}
|
||||
if (defs && meta?.robotId) {
|
||||
defs.forEach((d) => {
|
||||
const key = `${meta.robotId}.${d.id}`;
|
||||
expectedKeys.add(key);
|
||||
// console.log(` -> Registers: ${key}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Check Actions
|
||||
const actions = await db.query.actions.findMany();
|
||||
console.log(`\nFound ${actions.length} actions.`);
|
||||
let errorCount = 0;
|
||||
for (const a of actions) {
|
||||
// Only check plugin actions
|
||||
if (a.sourceKind === 'plugin' || a.type.includes(".")) {
|
||||
const isRegistered = expectedKeys.has(a.type);
|
||||
const pluginIdMatch = a.pluginId === 'nao6-ros2';
|
||||
// 2. Check Actions
|
||||
const actions = await db.query.actions.findMany();
|
||||
console.log(`\nFound ${actions.length} actions.`);
|
||||
let errorCount = 0;
|
||||
for (const a of actions) {
|
||||
// Only check plugin actions
|
||||
if (a.sourceKind === "plugin" || a.type.includes(".")) {
|
||||
const isRegistered = expectedKeys.has(a.type);
|
||||
const pluginIdMatch = a.pluginId === "nao6-ros2";
|
||||
|
||||
console.log(`Action [${a.name}] (Type: ${a.type}):`);
|
||||
console.log(` - PluginId: ${a.pluginId} ${pluginIdMatch ? '✅' : '❌'}`);
|
||||
console.log(` - In Registry: ${isRegistered ? '✅' : '❌'}`);
|
||||
console.log(`Action [${a.name}] (Type: ${a.type}):`);
|
||||
console.log(` - PluginId: ${a.pluginId} ${pluginIdMatch ? "✅" : "❌"}`);
|
||||
console.log(` - In Registry: ${isRegistered ? "✅" : "❌"}`);
|
||||
|
||||
if (!isRegistered || !pluginIdMatch) errorCount++;
|
||||
}
|
||||
if (!isRegistered || !pluginIdMatch) errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (errorCount > 0) {
|
||||
console.log(`\n❌ Found ${errorCount} actions with issues.`);
|
||||
} else {
|
||||
console.log("\n✅ All plugin actions validated successfully against registry definitions.");
|
||||
}
|
||||
if (errorCount > 0) {
|
||||
console.log(`\n❌ Found ${errorCount} actions with issues.`);
|
||||
} else {
|
||||
console.log(
|
||||
"\n✅ All plugin actions validated successfully against registry definitions.",
|
||||
);
|
||||
}
|
||||
|
||||
await connection.end();
|
||||
await connection.end();
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
|
||||
@@ -1,58 +1,60 @@
|
||||
|
||||
import { db } from "~/server/db";
|
||||
import { steps, experiments, actions } from "~/server/db/schema";
|
||||
import { eq, asc } from "drizzle-orm";
|
||||
|
||||
async function debugExperimentStructure() {
|
||||
console.log("Debugging Experiment Structure for Interactive Storyteller...");
|
||||
console.log("Debugging Experiment Structure for Interactive Storyteller...");
|
||||
|
||||
// Find the experiment
|
||||
const experiment = await db.query.experiments.findFirst({
|
||||
where: eq(experiments.name, "The Interactive Storyteller"),
|
||||
// Find the experiment
|
||||
const experiment = await db.query.experiments.findFirst({
|
||||
where: eq(experiments.name, "The Interactive Storyteller"),
|
||||
with: {
|
||||
steps: {
|
||||
orderBy: [asc(steps.orderIndex)],
|
||||
with: {
|
||||
steps: {
|
||||
orderBy: [asc(steps.orderIndex)],
|
||||
with: {
|
||||
actions: {
|
||||
orderBy: [asc(actions.orderIndex)],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
actions: {
|
||||
orderBy: [asc(actions.orderIndex)],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!experiment) {
|
||||
console.error("Experiment not found!");
|
||||
return;
|
||||
if (!experiment) {
|
||||
console.error("Experiment not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Experiment: ${experiment.name} (${experiment.id})`);
|
||||
console.log(`Plugin Dependencies:`, experiment.pluginDependencies);
|
||||
console.log("---------------------------------------------------");
|
||||
|
||||
experiment.steps.forEach((step, index) => {
|
||||
console.log(`Step ${index + 1}: ${step.name}`);
|
||||
console.log(` ID: ${step.id}`);
|
||||
console.log(` Type: ${step.type}`);
|
||||
console.log(` Order: ${step.orderIndex}`);
|
||||
console.log(` Conditions:`, JSON.stringify(step.conditions, null, 2));
|
||||
|
||||
if (step.actions && step.actions.length > 0) {
|
||||
console.log(` Actions (${step.actions.length}):`);
|
||||
step.actions.forEach((action, actionIndex) => {
|
||||
console.log(` ${actionIndex + 1}. [${action.type}] ${action.name}`);
|
||||
if (action.type === "wizard_wait_for_response") {
|
||||
console.log(
|
||||
` Options:`,
|
||||
JSON.stringify((action.parameters as any)?.options, null, 2),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`Experiment: ${experiment.name} (${experiment.id})`);
|
||||
console.log(`Plugin Dependencies:`, experiment.pluginDependencies);
|
||||
console.log("---------------------------------------------------");
|
||||
|
||||
experiment.steps.forEach((step, index) => {
|
||||
console.log(`Step ${index + 1}: ${step.name}`);
|
||||
console.log(` ID: ${step.id}`);
|
||||
console.log(` Type: ${step.type}`);
|
||||
console.log(` Order: ${step.orderIndex}`);
|
||||
console.log(` Conditions:`, JSON.stringify(step.conditions, null, 2));
|
||||
|
||||
if (step.actions && step.actions.length > 0) {
|
||||
console.log(` Actions (${step.actions.length}):`);
|
||||
step.actions.forEach((action, actionIndex) => {
|
||||
console.log(` ${actionIndex + 1}. [${action.type}] ${action.name}`);
|
||||
if (action.type === 'wizard_wait_for_response') {
|
||||
console.log(` Options:`, JSON.stringify((action.parameters as any)?.options, null, 2));
|
||||
}
|
||||
});
|
||||
}
|
||||
console.log("---------------------------------------------------");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
debugExperimentStructure()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,42 +1,41 @@
|
||||
|
||||
import { db } from "../../src/server/db";
|
||||
import { experiments, steps } from "../../src/server/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
async function inspectAllSteps() {
|
||||
const result = await db.query.experiments.findMany({
|
||||
with: {
|
||||
steps: {
|
||||
orderBy: (steps, { asc }) => [asc(steps.orderIndex)],
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
type: true,
|
||||
orderIndex: true,
|
||||
conditions: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const result = await db.query.experiments.findMany({
|
||||
with: {
|
||||
steps: {
|
||||
orderBy: (steps, { asc }) => [asc(steps.orderIndex)],
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
type: true,
|
||||
orderIndex: true,
|
||||
conditions: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`Found ${result.length} experiments.`);
|
||||
console.log(`Found ${result.length} experiments.`);
|
||||
|
||||
for (const exp of result) {
|
||||
console.log(`Experiment: ${exp.name} (${exp.id})`);
|
||||
for (const step of exp.steps) {
|
||||
// Only print conditional steps or the first step
|
||||
if (step.type === 'conditional' || step.orderIndex === 0) {
|
||||
console.log(` [${step.orderIndex}] ${step.name} (${step.type})`);
|
||||
console.log(` Conditions: ${JSON.stringify(step.conditions)}`);
|
||||
}
|
||||
}
|
||||
console.log('---');
|
||||
for (const exp of result) {
|
||||
console.log(`Experiment: ${exp.name} (${exp.id})`);
|
||||
for (const step of exp.steps) {
|
||||
// Only print conditional steps or the first step
|
||||
if (step.type === "conditional" || step.orderIndex === 0) {
|
||||
console.log(` [${step.orderIndex}] ${step.name} (${step.type})`);
|
||||
console.log(` Conditions: ${JSON.stringify(step.conditions)}`);
|
||||
}
|
||||
}
|
||||
console.log("---");
|
||||
}
|
||||
}
|
||||
|
||||
inspectAllSteps()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,47 +1,46 @@
|
||||
|
||||
import { db } from "~/server/db";
|
||||
import { actions, steps } from "~/server/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
async function inspectAction() {
|
||||
console.log("Inspecting Action 10851aef-e720-45fc-ba5e-05e1e3425dab...");
|
||||
console.log("Inspecting Action 10851aef-e720-45fc-ba5e-05e1e3425dab...");
|
||||
|
||||
const actionId = "10851aef-e720-45fc-ba5e-05e1e3425dab";
|
||||
const actionId = "10851aef-e720-45fc-ba5e-05e1e3425dab";
|
||||
|
||||
const action = await db.query.actions.findFirst({
|
||||
where: eq(actions.id, actionId),
|
||||
with: {
|
||||
step: {
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
type: true,
|
||||
conditions: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const action = await db.query.actions.findFirst({
|
||||
where: eq(actions.id, actionId),
|
||||
with: {
|
||||
step: {
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
type: true,
|
||||
conditions: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!action) {
|
||||
console.error("Action not found!");
|
||||
return;
|
||||
}
|
||||
if (!action) {
|
||||
console.error("Action not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Action Found:");
|
||||
console.log(" Name:", action.name);
|
||||
console.log(" Type:", action.type);
|
||||
console.log(" Parameters:", JSON.stringify(action.parameters, null, 2));
|
||||
console.log("Action Found:");
|
||||
console.log(" Name:", action.name);
|
||||
console.log(" Type:", action.type);
|
||||
console.log(" Parameters:", JSON.stringify(action.parameters, null, 2));
|
||||
|
||||
console.log("Parent Step:");
|
||||
console.log(" ID:", action.step.id);
|
||||
console.log(" Name:", action.step.name);
|
||||
console.log(" Type:", action.step.type);
|
||||
console.log(" Conditions:", JSON.stringify(action.step.conditions, null, 2));
|
||||
console.log("Parent Step:");
|
||||
console.log(" ID:", action.step.id);
|
||||
console.log(" Name:", action.step.name);
|
||||
console.log(" Type:", action.step.type);
|
||||
console.log(" Conditions:", JSON.stringify(action.step.conditions, null, 2));
|
||||
}
|
||||
|
||||
inspectAction()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,30 +1,29 @@
|
||||
|
||||
import { db } from "~/server/db";
|
||||
import { steps } from "~/server/db/schema";
|
||||
import { eq, inArray } from "drizzle-orm";
|
||||
|
||||
async function inspectBranchSteps() {
|
||||
console.log("Inspecting Steps 4 (Branch A) and 5 (Branch B)...");
|
||||
console.log("Inspecting Steps 4 (Branch A) and 5 (Branch B)...");
|
||||
|
||||
const step4Id = "3a2dc0b7-a43e-4236-9b9e-f957abafc1e5";
|
||||
const step5Id = "3ae2fe8a-fc5d-4a04-baa5-699a21f19e30";
|
||||
const step4Id = "3a2dc0b7-a43e-4236-9b9e-f957abafc1e5";
|
||||
const step5Id = "3ae2fe8a-fc5d-4a04-baa5-699a21f19e30";
|
||||
|
||||
const branchSteps = await db.query.steps.findMany({
|
||||
where: inArray(steps.id, [step4Id, step5Id])
|
||||
});
|
||||
const branchSteps = await db.query.steps.findMany({
|
||||
where: inArray(steps.id, [step4Id, step5Id]),
|
||||
});
|
||||
|
||||
branchSteps.forEach(step => {
|
||||
console.log(`Step: ${step.name} (${step.id})`);
|
||||
console.log(` Type: ${step.type}`);
|
||||
console.log(` Order: ${step.orderIndex}`);
|
||||
console.log(` Conditions:`, JSON.stringify(step.conditions, null, 2));
|
||||
console.log("---------------------------------------------------");
|
||||
});
|
||||
branchSteps.forEach((step) => {
|
||||
console.log(`Step: ${step.name} (${step.id})`);
|
||||
console.log(` Type: ${step.type}`);
|
||||
console.log(` Order: ${step.orderIndex}`);
|
||||
console.log(` Conditions:`, JSON.stringify(step.conditions, null, 2));
|
||||
console.log("---------------------------------------------------");
|
||||
});
|
||||
}
|
||||
|
||||
inspectBranchSteps()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
|
||||
import { db } from "../../src/server/db";
|
||||
import { steps } from "../../src/server/db/schema";
|
||||
import { eq, like } from "drizzle-orm";
|
||||
|
||||
async function checkSteps() {
|
||||
const allSteps = await db.select().from(steps).where(like(steps.name, "%Comprehension Check%"));
|
||||
const allSteps = await db
|
||||
.select()
|
||||
.from(steps)
|
||||
.where(like(steps.name, "%Comprehension Check%"));
|
||||
|
||||
console.log("Found steps:", allSteps.length);
|
||||
console.log("Found steps:", allSteps.length);
|
||||
|
||||
for (const step of allSteps) {
|
||||
console.log("Step Name:", step.name);
|
||||
console.log("Type:", step.type);
|
||||
console.log("Conditions (typeof):", typeof step.conditions);
|
||||
console.log("Conditions (value):", JSON.stringify(step.conditions, null, 2));
|
||||
}
|
||||
for (const step of allSteps) {
|
||||
console.log("Step Name:", step.name);
|
||||
console.log("Type:", step.type);
|
||||
console.log("Conditions (typeof):", typeof step.conditions);
|
||||
console.log(
|
||||
"Conditions (value):",
|
||||
JSON.stringify(step.conditions, null, 2),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
checkSteps()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,61 +1,62 @@
|
||||
|
||||
|
||||
import { db } from "~/server/db";
|
||||
import { steps, experiments } from "~/server/db/schema";
|
||||
import { eq, asc } from "drizzle-orm";
|
||||
|
||||
async function inspectExperimentSteps() {
|
||||
// Find experiment by ID
|
||||
const experiment = await db.query.experiments.findFirst({
|
||||
where: eq(experiments.id, "961d0cb1-256d-4951-8387-6d855a0ae603")
|
||||
});
|
||||
// Find experiment by ID
|
||||
const experiment = await db.query.experiments.findFirst({
|
||||
where: eq(experiments.id, "961d0cb1-256d-4951-8387-6d855a0ae603"),
|
||||
});
|
||||
|
||||
if (!experiment) {
|
||||
console.log("Experiment not found!");
|
||||
return;
|
||||
if (!experiment) {
|
||||
console.log("Experiment not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Inspecting Experiment: ${experiment.name} (${experiment.id})`);
|
||||
|
||||
const experimentSteps = await db.query.steps.findMany({
|
||||
where: eq(steps.experimentId, experiment.id),
|
||||
orderBy: [asc(steps.orderIndex)],
|
||||
with: {
|
||||
actions: {
|
||||
orderBy: (actions, { asc }) => [asc(actions.orderIndex)],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
console.log(`Found ${experimentSteps.length} steps.`);
|
||||
|
||||
for (const step of experimentSteps) {
|
||||
console.log("--------------------------------------------------");
|
||||
console.log(`Step [${step.orderIndex}] ID: ${step.id}`);
|
||||
console.log(`Name: ${step.name}`);
|
||||
console.log(`Type: ${step.type}`);
|
||||
|
||||
if (step.type === "conditional") {
|
||||
console.log("Conditions:", JSON.stringify(step.conditions, null, 2));
|
||||
}
|
||||
|
||||
console.log(`Inspecting Experiment: ${experiment.name} (${experiment.id})`);
|
||||
|
||||
const experimentSteps = await db.query.steps.findMany({
|
||||
where: eq(steps.experimentId, experiment.id),
|
||||
orderBy: [asc(steps.orderIndex)],
|
||||
with: {
|
||||
actions: {
|
||||
orderBy: (actions, { asc }) => [asc(actions.orderIndex)]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`Found ${experimentSteps.length} steps.`);
|
||||
|
||||
for (const step of experimentSteps) {
|
||||
console.log("--------------------------------------------------");
|
||||
console.log(`Step [${step.orderIndex}] ID: ${step.id}`);
|
||||
console.log(`Name: ${step.name}`);
|
||||
console.log(`Type: ${step.type}`);
|
||||
|
||||
|
||||
if (step.type === 'conditional') {
|
||||
console.log("Conditions:", JSON.stringify(step.conditions, null, 2));
|
||||
}
|
||||
|
||||
if (step.actions.length > 0) {
|
||||
console.log("Actions:");
|
||||
for (const action of step.actions) {
|
||||
console.log(` - [${action.orderIndex}] ${action.name} (${action.type})`);
|
||||
if (action.type === 'wizard_wait_for_response') {
|
||||
console.log(" Parameters:", JSON.stringify(action.parameters, null, 2));
|
||||
}
|
||||
}
|
||||
if (step.actions.length > 0) {
|
||||
console.log("Actions:");
|
||||
for (const action of step.actions) {
|
||||
console.log(
|
||||
` - [${action.orderIndex}] ${action.name} (${action.type})`,
|
||||
);
|
||||
if (action.type === "wizard_wait_for_response") {
|
||||
console.log(
|
||||
" Parameters:",
|
||||
JSON.stringify(action.parameters, null, 2),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inspectExperimentSteps()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,33 +1,32 @@
|
||||
|
||||
import { db } from "../../src/server/db";
|
||||
import { experiments } from "../../src/server/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
async function inspectVisualDesign() {
|
||||
const exps = await db.select().from(experiments);
|
||||
const exps = await db.select().from(experiments);
|
||||
|
||||
for (const exp of exps) {
|
||||
console.log(`Experiment: ${exp.name}`);
|
||||
if (exp.visualDesign) {
|
||||
const vd = exp.visualDesign as any;
|
||||
console.log("Visual Design Steps:");
|
||||
if (vd.steps && Array.isArray(vd.steps)) {
|
||||
vd.steps.forEach((s: any, i: number) => {
|
||||
console.log(` [${i}] ${s.name} (${s.type})`);
|
||||
console.log(` Trigger: ${JSON.stringify(s.trigger)}`);
|
||||
});
|
||||
} else {
|
||||
console.log(" No steps in visualDesign or invalid format.");
|
||||
}
|
||||
} else {
|
||||
console.log(" No visualDesign blob.");
|
||||
}
|
||||
for (const exp of exps) {
|
||||
console.log(`Experiment: ${exp.name}`);
|
||||
if (exp.visualDesign) {
|
||||
const vd = exp.visualDesign as any;
|
||||
console.log("Visual Design Steps:");
|
||||
if (vd.steps && Array.isArray(vd.steps)) {
|
||||
vd.steps.forEach((s: any, i: number) => {
|
||||
console.log(` [${i}] ${s.name} (${s.type})`);
|
||||
console.log(` Trigger: ${JSON.stringify(s.trigger)}`);
|
||||
});
|
||||
} else {
|
||||
console.log(" No steps in visualDesign or invalid format.");
|
||||
}
|
||||
} else {
|
||||
console.log(" No visualDesign blob.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inspectVisualDesign()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,69 +1,74 @@
|
||||
|
||||
import { db } from "~/server/db";
|
||||
import { actions, steps } from "~/server/db/schema";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
|
||||
async function patchActionParams() {
|
||||
console.log("Patching Action Parameters for Interactive Storyteller...");
|
||||
console.log("Patching Action Parameters for Interactive Storyteller...");
|
||||
|
||||
// Target Step IDs
|
||||
const step3CondId = "b9d43f8c-c40c-4f1c-9fdc-9076338d3c85"; // Step 3: Comprehension Check
|
||||
const actionId = "10851aef-e720-45fc-ba5e-05e1e3425dab"; // Action: Wait for Choice
|
||||
// Target Step IDs
|
||||
const step3CondId = "b9d43f8c-c40c-4f1c-9fdc-9076338d3c85"; // Step 3: Comprehension Check
|
||||
const actionId = "10851aef-e720-45fc-ba5e-05e1e3425dab"; // Action: Wait for Choice
|
||||
|
||||
// 1. Get the authoritative conditions from the Step
|
||||
const step = await db.query.steps.findFirst({
|
||||
where: eq(steps.id, step3CondId)
|
||||
});
|
||||
// 1. Get the authoritative conditions from the Step
|
||||
const step = await db.query.steps.findFirst({
|
||||
where: eq(steps.id, step3CondId),
|
||||
});
|
||||
|
||||
if (!step) {
|
||||
console.error("Step 3 not found!");
|
||||
return;
|
||||
}
|
||||
if (!step) {
|
||||
console.error("Step 3 not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
const conditions = step.conditions as any;
|
||||
const richOptions = conditions?.options;
|
||||
const conditions = step.conditions as any;
|
||||
const richOptions = conditions?.options;
|
||||
|
||||
if (!richOptions || !Array.isArray(richOptions)) {
|
||||
console.error("Step 3 conditions are missing valid options!");
|
||||
return;
|
||||
}
|
||||
if (!richOptions || !Array.isArray(richOptions)) {
|
||||
console.error("Step 3 conditions are missing valid options!");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Found rich options in Step:", JSON.stringify(richOptions, null, 2));
|
||||
console.log(
|
||||
"Found rich options in Step:",
|
||||
JSON.stringify(richOptions, null, 2),
|
||||
);
|
||||
|
||||
// 2. Get the Action
|
||||
const action = await db.query.actions.findFirst({
|
||||
where: eq(actions.id, actionId)
|
||||
});
|
||||
// 2. Get the Action
|
||||
const action = await db.query.actions.findFirst({
|
||||
where: eq(actions.id, actionId),
|
||||
});
|
||||
|
||||
if (!action) {
|
||||
console.error("Action not found!");
|
||||
return;
|
||||
}
|
||||
if (!action) {
|
||||
console.error("Action not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Current Action Parameters:", JSON.stringify(action.parameters, null, 2));
|
||||
console.log(
|
||||
"Current Action Parameters:",
|
||||
JSON.stringify(action.parameters, null, 2),
|
||||
);
|
||||
|
||||
// 3. Patch the Action Parameters
|
||||
// We replace the simple string options with the rich object options
|
||||
const currentParams = action.parameters as any;
|
||||
const newParams = {
|
||||
...currentParams,
|
||||
options: richOptions // Overwrite with rich options from step
|
||||
};
|
||||
// 3. Patch the Action Parameters
|
||||
// We replace the simple string options with the rich object options
|
||||
const currentParams = action.parameters as any;
|
||||
const newParams = {
|
||||
...currentParams,
|
||||
options: richOptions, // Overwrite with rich options from step
|
||||
};
|
||||
|
||||
console.log("New Action Parameters:", JSON.stringify(newParams, null, 2));
|
||||
console.log("New Action Parameters:", JSON.stringify(newParams, null, 2));
|
||||
|
||||
await db.execute(sql`
|
||||
await db.execute(sql`
|
||||
UPDATE hs_action
|
||||
SET parameters = ${JSON.stringify(newParams)}::jsonb
|
||||
WHERE id = ${actionId}
|
||||
`);
|
||||
|
||||
console.log("Action parameters successfully patched.");
|
||||
console.log("Action parameters successfully patched.");
|
||||
}
|
||||
|
||||
patchActionParams()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,92 +1,100 @@
|
||||
|
||||
import { db } from "~/server/db";
|
||||
import { steps } from "~/server/db/schema";
|
||||
import { eq, sql } from "drizzle-orm";
|
||||
|
||||
async function patchBranchSteps() {
|
||||
console.log("Patching branch steps for Interactive Storyteller...");
|
||||
console.log("Patching branch steps for Interactive Storyteller...");
|
||||
|
||||
// Target Step IDs (From debug output)
|
||||
const step3CondId = "b9d43f8c-c40c-4f1c-9fdc-9076338d3c85"; // Step 3: Comprehension Check
|
||||
const stepBranchAId = "3a2dc0b7-a43e-4236-9b9e-f957abafc1e5"; // Step 4: Branch A (Correct)
|
||||
const stepBranchBId = "3ae2fe8a-fc5d-4a04-baa5-699a21f19e30"; // Step 5: Branch B (Incorrect)
|
||||
const stepConclusionId = "cc3fbc7f-29e5-45e0-8d46-e80813c54292"; // Step 6: Conclusion
|
||||
// Target Step IDs (From debug output)
|
||||
const step3CondId = "b9d43f8c-c40c-4f1c-9fdc-9076338d3c85"; // Step 3: Comprehension Check
|
||||
const stepBranchAId = "3a2dc0b7-a43e-4236-9b9e-f957abafc1e5"; // Step 4: Branch A (Correct)
|
||||
const stepBranchBId = "3ae2fe8a-fc5d-4a04-baa5-699a21f19e30"; // Step 5: Branch B (Incorrect)
|
||||
const stepConclusionId = "cc3fbc7f-29e5-45e0-8d46-e80813c54292"; // Step 6: Conclusion
|
||||
|
||||
// Update Step 3 (The Conditional Step)
|
||||
console.log("Updating Step 3 (Conditional Step)...");
|
||||
const step3Conditional = await db.query.steps.findFirst({
|
||||
where: eq(steps.id, step3CondId)
|
||||
// Update Step 3 (The Conditional Step)
|
||||
console.log("Updating Step 3 (Conditional Step)...");
|
||||
const step3Conditional = await db.query.steps.findFirst({
|
||||
where: eq(steps.id, step3CondId),
|
||||
});
|
||||
|
||||
if (step3Conditional) {
|
||||
const currentConditions = (step3Conditional.conditions as any) || {};
|
||||
const options = currentConditions.options || [];
|
||||
|
||||
// Patch options to point to real step IDs
|
||||
const newOptions = options.map((opt: any) => {
|
||||
if (opt.value === "Correct") return { ...opt, nextStepId: stepBranchAId };
|
||||
if (opt.value === "Incorrect")
|
||||
return { ...opt, nextStepId: stepBranchBId };
|
||||
return opt;
|
||||
});
|
||||
|
||||
if (step3Conditional) {
|
||||
const currentConditions = (step3Conditional.conditions as any) || {};
|
||||
const options = currentConditions.options || [];
|
||||
const newConditions = { ...currentConditions, options: newOptions };
|
||||
|
||||
// Patch options to point to real step IDs
|
||||
const newOptions = options.map((opt: any) => {
|
||||
if (opt.value === "Correct") return { ...opt, nextStepId: stepBranchAId };
|
||||
if (opt.value === "Incorrect") return { ...opt, nextStepId: stepBranchBId };
|
||||
return opt;
|
||||
});
|
||||
|
||||
const newConditions = { ...currentConditions, options: newOptions };
|
||||
|
||||
await db.execute(sql`
|
||||
await db.execute(sql`
|
||||
UPDATE hs_step
|
||||
SET conditions = ${JSON.stringify(newConditions)}::jsonb
|
||||
WHERE id = ${step3CondId}
|
||||
`);
|
||||
console.log("Step 3 (Conditional) updated links.");
|
||||
} else {
|
||||
console.log("Step 3 (Conditional) not found.");
|
||||
}
|
||||
console.log("Step 3 (Conditional) updated links.");
|
||||
} else {
|
||||
console.log("Step 3 (Conditional) not found.");
|
||||
}
|
||||
|
||||
// Update Step 4 (Branch A)
|
||||
console.log("Updating Step 4 (Branch A)...");
|
||||
/*
|
||||
// Update Step 4 (Branch A)
|
||||
console.log("Updating Step 4 (Branch A)...");
|
||||
/*
|
||||
Note: We already patched Step 4 in previous run but under wrong assumption?
|
||||
Let's re-patch to be safe.
|
||||
Debug output showed ID: 3a2dc0b7-a43e-4236-9b9e-f957abafc1e5
|
||||
It should jump to Conclusion (cc3fbc7f...)
|
||||
*/
|
||||
const stepBranchA = await db.query.steps.findFirst({
|
||||
where: eq(steps.id, stepBranchAId)
|
||||
});
|
||||
const stepBranchA = await db.query.steps.findFirst({
|
||||
where: eq(steps.id, stepBranchAId),
|
||||
});
|
||||
|
||||
if (stepBranchA) {
|
||||
const currentConditions = (stepBranchA.conditions as Record<string, unknown>) || {};
|
||||
const newConditions = { ...currentConditions, nextStepId: stepConclusionId };
|
||||
if (stepBranchA) {
|
||||
const currentConditions =
|
||||
(stepBranchA.conditions as Record<string, unknown>) || {};
|
||||
const newConditions = {
|
||||
...currentConditions,
|
||||
nextStepId: stepConclusionId,
|
||||
};
|
||||
|
||||
await db.execute(sql`
|
||||
await db.execute(sql`
|
||||
UPDATE hs_step
|
||||
SET conditions = ${JSON.stringify(newConditions)}::jsonb
|
||||
WHERE id = ${stepBranchAId}
|
||||
`);
|
||||
console.log("Step 4 (Branch A) updated jump target.");
|
||||
}
|
||||
console.log("Step 4 (Branch A) updated jump target.");
|
||||
}
|
||||
|
||||
// Update Step 5 (Branch B)
|
||||
console.log("Updating Step 5 (Branch B)...");
|
||||
const stepBranchB = await db.query.steps.findFirst({
|
||||
where: eq(steps.id, stepBranchBId)
|
||||
});
|
||||
// Update Step 5 (Branch B)
|
||||
console.log("Updating Step 5 (Branch B)...");
|
||||
const stepBranchB = await db.query.steps.findFirst({
|
||||
where: eq(steps.id, stepBranchBId),
|
||||
});
|
||||
|
||||
if (stepBranchB) {
|
||||
const currentConditions = (stepBranchB.conditions as Record<string, unknown>) || {};
|
||||
const newConditions = { ...currentConditions, nextStepId: stepConclusionId };
|
||||
if (stepBranchB) {
|
||||
const currentConditions =
|
||||
(stepBranchB.conditions as Record<string, unknown>) || {};
|
||||
const newConditions = {
|
||||
...currentConditions,
|
||||
nextStepId: stepConclusionId,
|
||||
};
|
||||
|
||||
await db.execute(sql`
|
||||
await db.execute(sql`
|
||||
UPDATE hs_step
|
||||
SET conditions = ${JSON.stringify(newConditions)}::jsonb
|
||||
WHERE id = ${stepBranchBId}
|
||||
`);
|
||||
console.log("Step 5 (Branch B) updated jump target.");
|
||||
}
|
||||
console.log("Step 5 (Branch B) updated jump target.");
|
||||
}
|
||||
}
|
||||
|
||||
patchBranchSteps()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,43 +1,52 @@
|
||||
|
||||
import { convertDatabaseToSteps } from "../../src/lib/experiment-designer/block-converter";
|
||||
import { type ExperimentStep } from "../../src/lib/experiment-designer/types";
|
||||
|
||||
// Mock DB Steps (simulating what experimentsRouter returns before conversion)
|
||||
const mockDbSteps = [
|
||||
{
|
||||
id: "step-1",
|
||||
name: "Step 1",
|
||||
type: "wizard",
|
||||
orderIndex: 0,
|
||||
actions: [
|
||||
{
|
||||
id: "step-1",
|
||||
name: "Step 1",
|
||||
type: "wizard",
|
||||
orderIndex: 0,
|
||||
actions: [
|
||||
{
|
||||
id: "seq-1",
|
||||
name: "Test Sequence",
|
||||
type: "sequence",
|
||||
parameters: {
|
||||
children: [
|
||||
{
|
||||
id: "seq-1",
|
||||
name: "Test Sequence",
|
||||
type: "sequence",
|
||||
parameters: {
|
||||
children: [
|
||||
{ id: "child-1", name: "Child 1", type: "wait", parameters: { duration: 1 } },
|
||||
{ id: "child-2", name: "Child 2", type: "wait", parameters: { duration: 2 } }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
id: "child-1",
|
||||
name: "Child 1",
|
||||
type: "wait",
|
||||
parameters: { duration: 1 },
|
||||
},
|
||||
{
|
||||
id: "child-2",
|
||||
name: "Child 2",
|
||||
type: "wait",
|
||||
parameters: { duration: 2 },
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// Mock Store Logic (simulating store.ts)
|
||||
function cloneActions(actions: any[]): any[] {
|
||||
return actions.map((a) => ({
|
||||
...a,
|
||||
children: a.children ? cloneActions(a.children) : undefined,
|
||||
}));
|
||||
return actions.map((a) => ({
|
||||
...a,
|
||||
children: a.children ? cloneActions(a.children) : undefined,
|
||||
}));
|
||||
}
|
||||
|
||||
function cloneSteps(steps: any[]): any[] {
|
||||
return steps.map((s) => ({
|
||||
...s,
|
||||
actions: cloneActions(s.actions),
|
||||
}));
|
||||
return steps.map((s) => ({
|
||||
...s,
|
||||
actions: cloneActions(s.actions),
|
||||
}));
|
||||
}
|
||||
|
||||
console.log("🔹 Testing Hydration & Cloning...");
|
||||
@@ -47,15 +56,15 @@ const runtimeSteps = convertDatabaseToSteps(mockDbSteps);
|
||||
const seq = runtimeSteps[0]?.actions[0];
|
||||
|
||||
if (!seq) {
|
||||
console.error("❌ Conversion Failed: Sequence action not found.");
|
||||
process.exit(1);
|
||||
console.error("❌ Conversion Failed: Sequence action not found.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Runtime Children Count: ${seq.children?.length ?? "undefined"}`);
|
||||
|
||||
if (!seq.children || seq.children.length === 0) {
|
||||
console.error("❌ Conversion Failed: Children not hydrated from parameters.");
|
||||
process.exit(1);
|
||||
console.error("❌ Conversion Failed: Children not hydrated from parameters.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 2. Store Cloning
|
||||
@@ -63,14 +72,16 @@ const clonedSteps = cloneSteps(runtimeSteps);
|
||||
const clonedSeq = clonedSteps[0]?.actions[0];
|
||||
|
||||
if (!clonedSeq) {
|
||||
console.error("❌ Cloning Failed: Sequence action lost.");
|
||||
process.exit(1);
|
||||
console.error("❌ Cloning Failed: Sequence action lost.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(`Cloned Children Count: ${clonedSeq.children?.length ?? "undefined"}`);
|
||||
console.log(
|
||||
`Cloned Children Count: ${clonedSeq.children?.length ?? "undefined"}`,
|
||||
);
|
||||
|
||||
if (clonedSeq.children?.length === 2) {
|
||||
console.log("✅ SUCCESS: Data hydrated and cloned correctly.");
|
||||
console.log("✅ SUCCESS: Data hydrated and cloned correctly.");
|
||||
} else {
|
||||
console.error("❌ CLONING FAILED: Children lost during clone.");
|
||||
console.error("❌ CLONING FAILED: Children lost during clone.");
|
||||
}
|
||||
|
||||
@@ -9,113 +9,128 @@ const connection = postgres(connectionString);
|
||||
const db = drizzle(connection, { schema });
|
||||
|
||||
async function main() {
|
||||
console.log("🌱 Seeding 'Control Flow Demo' experiment...");
|
||||
console.log("🌱 Seeding 'Control Flow Demo' 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. Run seed-dev.ts first.");
|
||||
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. Run seed-dev.ts first.",
|
||||
);
|
||||
|
||||
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. Run seed-dev.ts first.");
|
||||
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. Run seed-dev.ts first.",
|
||||
);
|
||||
|
||||
// Find Robot
|
||||
const robot = await db.query.robots.findFirst({
|
||||
where: (robots, { eq }) => eq(robots.name, "NAO6")
|
||||
});
|
||||
if (!robot) throw new Error("Robot 'NAO6' not found. Run seed-dev.ts first.");
|
||||
// Find Robot
|
||||
const robot = await db.query.robots.findFirst({
|
||||
where: (robots, { eq }) => eq(robots.name, "NAO6"),
|
||||
});
|
||||
if (!robot)
|
||||
throw new Error("Robot 'NAO6' not found. Run seed-dev.ts first.");
|
||||
|
||||
// 2. Create Experiment
|
||||
const [experiment] = await db
|
||||
.insert(schema.experiments)
|
||||
.values({
|
||||
studyId: study.id,
|
||||
name: "Control Flow Demo",
|
||||
description:
|
||||
"Demonstration of enhanced control flow actions: Sequence, Parallel, Wait, Loop, Branch.",
|
||||
version: 1,
|
||||
status: "draft",
|
||||
robotId: robot.id,
|
||||
createdBy: user.id,
|
||||
})
|
||||
.returning();
|
||||
|
||||
// 2. Create Experiment
|
||||
const [experiment] = await db.insert(schema.experiments).values({
|
||||
studyId: study.id,
|
||||
name: "Control Flow Demo",
|
||||
description: "Demonstration of enhanced control flow actions: Sequence, Parallel, Wait, Loop, Branch.",
|
||||
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}`);
|
||||
|
||||
if (!experiment) throw new Error("Failed to create experiment");
|
||||
console.log(`✅ Created Experiment: ${experiment.id}`);
|
||||
// 3. Create Steps
|
||||
|
||||
// 3. Create Steps
|
||||
// Step 1: Sequence & Parallel
|
||||
const [step1] = await db
|
||||
.insert(schema.steps)
|
||||
.values({
|
||||
experimentId: experiment.id,
|
||||
name: "Complex Action Structures",
|
||||
description: "Demonstrating Sequence and Parallel groups",
|
||||
type: "robot",
|
||||
orderIndex: 0,
|
||||
required: true,
|
||||
durationEstimate: 30,
|
||||
})
|
||||
.returning();
|
||||
|
||||
// Step 1: Sequence & Parallel
|
||||
const [step1] = await db.insert(schema.steps).values({
|
||||
experimentId: experiment.id,
|
||||
name: "Complex Action Structures",
|
||||
description: "Demonstrating Sequence and Parallel groups",
|
||||
type: "robot",
|
||||
orderIndex: 0,
|
||||
required: true,
|
||||
durationEstimate: 30
|
||||
}).returning();
|
||||
// Step 2: Loops & Waits
|
||||
const [step2] = await db
|
||||
.insert(schema.steps)
|
||||
.values({
|
||||
experimentId: experiment.id,
|
||||
name: "Repetition & Delays",
|
||||
description: "Demonstrating Loop and Wait actions",
|
||||
type: "robot",
|
||||
orderIndex: 1,
|
||||
required: true,
|
||||
durationEstimate: 45,
|
||||
})
|
||||
.returning();
|
||||
|
||||
// Step 2: Loops & Waits
|
||||
const [step2] = await db.insert(schema.steps).values({
|
||||
experimentId: experiment.id,
|
||||
name: "Repetition & Delays",
|
||||
description: "Demonstrating Loop and Wait actions",
|
||||
type: "robot",
|
||||
orderIndex: 1,
|
||||
required: true,
|
||||
durationEstimate: 45
|
||||
}).returning();
|
||||
// 4. Create Actions
|
||||
|
||||
// 4. Create Actions
|
||||
// --- Step 1 Actions ---
|
||||
|
||||
// --- Step 1 Actions ---
|
||||
// Top-level Sequence
|
||||
const seqId = `seq-${Date.now()}`;
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step1!.id,
|
||||
name: "Introduction Sequence",
|
||||
type: "sequence", // New type
|
||||
orderIndex: 0,
|
||||
parameters: {},
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
// No explicit children column in schema?
|
||||
// Wait, schema.actions has "children" as jsonb or it's a recursive relationship?
|
||||
// Let's check schema/types.
|
||||
// Looking at ActionChip, it expects `action.children`.
|
||||
// In DB, it's likely stored in `children` jsonb column if it exists, OR we need to perform recursive inserts if schema supports parentId.
|
||||
// Checking `types.ts` or schema...
|
||||
// Assuming flat list references for now or JSONB.
|
||||
// Wait, `ExperimentAction` in types has `children?: ExperimentAction[]`.
|
||||
// If the DB schema `actions` table handles nesting via `parameters` or specific column, I need to know.
|
||||
// Defaulting to "children" property in JSON parameter if DB doesn't have parentId.
|
||||
// Checking `schema.ts`: "children" is likely NOT a column if I haven't seen it in seed-dev.
|
||||
// However, `ActionChip` uses `action.children`. Steps map to `actions`.
|
||||
// If `actions` table has `parentId` or `children` JSONB.
|
||||
// I will assume `children` is part of the `parameters` or a simplified representation for now,
|
||||
// BUT `FlowWorkspace` treats `action.children` as real actions.
|
||||
// Let's check `schema.ts` quickly.
|
||||
});
|
||||
|
||||
// Top-level Sequence
|
||||
const seqId = `seq-${Date.now()}`;
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step1!.id,
|
||||
name: "Introduction Sequence",
|
||||
type: "sequence", // New type
|
||||
orderIndex: 0,
|
||||
parameters: {},
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
// No explicit children column in schema?
|
||||
// Wait, schema.actions has "children" as jsonb or it's a recursive relationship?
|
||||
// Let's check schema/types.
|
||||
// Looking at ActionChip, it expects `action.children`.
|
||||
// In DB, it's likely stored in `children` jsonb column if it exists, OR we need to perform recursive inserts if schema supports parentId.
|
||||
// Checking `types.ts` or schema...
|
||||
// Assuming flat list references for now or JSONB.
|
||||
// Wait, `ExperimentAction` in types has `children?: ExperimentAction[]`.
|
||||
// If the DB schema `actions` table handles nesting via `parameters` or specific column, I need to know.
|
||||
// Defaulting to "children" property in JSON parameter if DB doesn't have parentId.
|
||||
// Checking `schema.ts`: "children" is likely NOT a column if I haven't seen it in seed-dev.
|
||||
// However, `ActionChip` uses `action.children`. Steps map to `actions`.
|
||||
// If `actions` table has `parentId` or `children` JSONB.
|
||||
// I will assume `children` is part of the `parameters` or a simplified representation for now,
|
||||
// BUT `FlowWorkspace` treats `action.children` as real actions.
|
||||
// Let's check `schema.ts` quickly.
|
||||
});
|
||||
// I need to check schema.actions definition effectively.
|
||||
// For this pass, I will insert them as flat actions since I can't confirm nesting storage without checking schema.
|
||||
// But the user WANTS to see the nesting (Sequence, Parallel).
|
||||
// The `SortableActionChip` renders `action.children`.
|
||||
// The `TrialExecutionEngine` executes `action.children`.
|
||||
// So the data MUST include children.
|
||||
// Most likely `actions` table has a `children` JSONB column.
|
||||
|
||||
// I need to check schema.actions definition effectively.
|
||||
// For this pass, I will insert them as flat actions since I can't confirm nesting storage without checking schema.
|
||||
// But the user WANTS to see the nesting (Sequence, Parallel).
|
||||
// The `SortableActionChip` renders `action.children`.
|
||||
// The `TrialExecutionEngine` executes `action.children`.
|
||||
// So the data MUST include children.
|
||||
// Most likely `actions` table has a `children` JSONB column.
|
||||
|
||||
// I will insert a Parallel action with embedded children in the `children` column (if it exists) or `parameters`.
|
||||
// Re-reading `scripts/seed-dev.ts`: It doesn't show any nested actions.
|
||||
// I will read `src/server/db/schema.ts` to be sure.
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
// I will insert a Parallel action with embedded children in the `children` column (if it exists) or `parameters`.
|
||||
// Re-reading `scripts/seed-dev.ts`: It doesn't show any nested actions.
|
||||
// I will read `src/server/db/schema.ts` to be sure.
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// I'll write the file AFTER checking schema to ensure I structure the nested actions correctly.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
import * as schema from "../../src/server/db/schema";
|
||||
@@ -11,231 +10,245 @@ const connection = postgres(connectionString);
|
||||
const db = drizzle(connection, { schema });
|
||||
|
||||
async function main() {
|
||||
console.log("🌱 Seeding 'Control Flow Demo' experiment...");
|
||||
console.log("🌱 Seeding 'Control Flow Demo' 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. Run seed-dev.ts first.");
|
||||
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. Run seed-dev.ts first.",
|
||||
);
|
||||
|
||||
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. Run seed-dev.ts first.");
|
||||
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. Run seed-dev.ts first.",
|
||||
);
|
||||
|
||||
// Find Robot
|
||||
const robot = await db.query.robots.findFirst({
|
||||
where: (robots, { eq }) => eq(robots.name, "NAO6")
|
||||
});
|
||||
if (!robot) throw new Error("Robot 'NAO6' not found. Run seed-dev.ts first.");
|
||||
// Find Robot
|
||||
const robot = await db.query.robots.findFirst({
|
||||
where: (robots, { eq }) => eq(robots.name, "NAO6"),
|
||||
});
|
||||
if (!robot)
|
||||
throw new Error("Robot 'NAO6' not found. Run seed-dev.ts first.");
|
||||
|
||||
// 2. Create Experiment
|
||||
const [experiment] = await db
|
||||
.insert(schema.experiments)
|
||||
.values({
|
||||
studyId: study.id,
|
||||
name: "Control Flow Demo",
|
||||
description:
|
||||
"Demonstration of enhanced control flow actions: Sequence, Parallel, Wait, Loop, Branch.",
|
||||
version: 1,
|
||||
status: "draft",
|
||||
robotId: robot.id,
|
||||
createdBy: user.id,
|
||||
})
|
||||
.returning();
|
||||
|
||||
// 2. Create Experiment
|
||||
const [experiment] = await db.insert(schema.experiments).values({
|
||||
studyId: study.id,
|
||||
name: "Control Flow Demo",
|
||||
description: "Demonstration of enhanced control flow actions: Sequence, Parallel, Wait, Loop, Branch.",
|
||||
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}`);
|
||||
|
||||
if (!experiment) throw new Error("Failed to create experiment");
|
||||
console.log(`✅ Created Experiment: ${experiment.id}`);
|
||||
// 3. Create Steps
|
||||
|
||||
// 3. Create Steps
|
||||
// Step 1: Sequence & Parallel
|
||||
const [step1] = await db
|
||||
.insert(schema.steps)
|
||||
.values({
|
||||
experimentId: experiment.id,
|
||||
name: "Complex Action Structures",
|
||||
description: "Demonstrating Sequence and Parallel groups",
|
||||
type: "robot",
|
||||
orderIndex: 0,
|
||||
required: true,
|
||||
durationEstimate: 30,
|
||||
})
|
||||
.returning();
|
||||
if (!step1) throw new Error("Failed to create step1");
|
||||
|
||||
// Step 1: Sequence & Parallel
|
||||
const [step1] = await db.insert(schema.steps).values({
|
||||
experimentId: experiment.id,
|
||||
name: "Complex Action Structures",
|
||||
description: "Demonstrating Sequence and Parallel groups",
|
||||
type: "robot",
|
||||
orderIndex: 0,
|
||||
required: true,
|
||||
durationEstimate: 30
|
||||
}).returning();
|
||||
if (!step1) throw new Error("Failed to create step1");
|
||||
// Step 2: Loops & Waits
|
||||
const [step2] = await db
|
||||
.insert(schema.steps)
|
||||
.values({
|
||||
experimentId: experiment.id,
|
||||
name: "Repetition & Delays",
|
||||
description: "Demonstrating Loop and Wait actions",
|
||||
type: "robot",
|
||||
orderIndex: 1,
|
||||
required: true,
|
||||
durationEstimate: 45,
|
||||
})
|
||||
.returning();
|
||||
if (!step2) throw new Error("Failed to create step2");
|
||||
|
||||
// Step 2: Loops & Waits
|
||||
const [step2] = await db.insert(schema.steps).values({
|
||||
experimentId: experiment.id,
|
||||
name: "Repetition & Delays",
|
||||
description: "Demonstrating Loop and Wait actions",
|
||||
type: "robot",
|
||||
orderIndex: 1,
|
||||
required: true,
|
||||
durationEstimate: 45
|
||||
}).returning();
|
||||
if (!step2) throw new Error("Failed to create step2");
|
||||
// 4. Create Actions
|
||||
|
||||
// 4. Create Actions
|
||||
// --- Step 1 Actions ---
|
||||
|
||||
// --- Step 1 Actions ---
|
||||
// Action 1: Sequence
|
||||
// Note: Nested children are stored in 'children' property of the action object in frontend,
|
||||
// but in DB 'parameters' is the JSONB field.
|
||||
// However, looking at ActionChip, it expects `action.children`.
|
||||
// The `ExperimentAction` type usually has `children` at top level.
|
||||
// If the DB doesn't have it, the API must be hydrating it.
|
||||
// BUT, for the purpose of this seed which writes to DB directly, I will put it in `parameters.children`
|
||||
// and assume the frontend/API handles it or I'm missing a column.
|
||||
// Actually, looking at schema again, `actions` table DOES NOT have children.
|
||||
// So it MUST be in `parameters` or it's not persisted in this table structure yet (which would be a bug, but I'm seeding what exists).
|
||||
// Wait, if I put it in parameters, does the UI read it?
|
||||
// `ActionChip` reads `action.children`.
|
||||
// I will try to put it in `parameters` and distinct `children` property in the JSON passed to `parameters`?
|
||||
// No, `parameters` is jsonb.
|
||||
// I will assume for now that the system expects it in parameters if it's not a column, OR it's not fully supported in DB yet.
|
||||
// I will stick to what the UI likely consumes. `parameters: { children: [...] }`
|
||||
|
||||
// Action 1: Sequence
|
||||
// Note: Nested children are stored in 'children' property of the action object in frontend,
|
||||
// but in DB 'parameters' is the JSONB field.
|
||||
// However, looking at ActionChip, it expects `action.children`.
|
||||
// The `ExperimentAction` type usually has `children` at top level.
|
||||
// If the DB doesn't have it, the API must be hydrating it.
|
||||
// BUT, for the purpose of this seed which writes to DB directly, I will put it in `parameters.children`
|
||||
// and assume the frontend/API handles it or I'm missing a column.
|
||||
// Actually, looking at schema again, `actions` table DOES NOT have children.
|
||||
// So it MUST be in `parameters` or it's not persisted in this table structure yet (which would be a bug, but I'm seeding what exists).
|
||||
// Wait, if I put it in parameters, does the UI read it?
|
||||
// `ActionChip` reads `action.children`.
|
||||
// I will try to put it in `parameters` and distinct `children` property in the JSON passed to `parameters`?
|
||||
// No, `parameters` is jsonb.
|
||||
// I will assume for now that the system expects it in parameters if it's not a column, OR it's not fully supported in DB yet.
|
||||
// I will stick to what the UI likely consumes. `parameters: { children: [...] }`
|
||||
// Sequence
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step1.id,
|
||||
name: "Introduction Sequence",
|
||||
type: "sequence",
|
||||
orderIndex: 0,
|
||||
// Embedding children here to demonstrate.
|
||||
// Real implementation might vary if keys are strictly checked.
|
||||
parameters: {
|
||||
children: [
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Say Hello",
|
||||
type: "nao6-ros2.say_text",
|
||||
parameters: { text: "Hello there!" },
|
||||
category: "interaction",
|
||||
},
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Wave Hand",
|
||||
type: "nao6-ros2.move_arm",
|
||||
parameters: { arm: "right", action: "wave" },
|
||||
category: "movement",
|
||||
},
|
||||
],
|
||||
},
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
sourceKind: "core",
|
||||
});
|
||||
|
||||
// Sequence
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step1.id,
|
||||
name: "Introduction Sequence",
|
||||
type: "sequence",
|
||||
orderIndex: 0,
|
||||
// Embedding children here to demonstrate.
|
||||
// Real implementation might vary if keys are strictly checked.
|
||||
parameters: {
|
||||
children: [
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Say Hello",
|
||||
type: "nao6-ros2.say_text",
|
||||
parameters: { text: "Hello there!" },
|
||||
category: "interaction"
|
||||
},
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Wave Hand",
|
||||
type: "nao6-ros2.move_arm",
|
||||
parameters: { arm: "right", action: "wave" },
|
||||
category: "movement"
|
||||
}
|
||||
]
|
||||
// Parallel
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step1.id,
|
||||
name: "Parallel Actions",
|
||||
type: "parallel",
|
||||
orderIndex: 1,
|
||||
parameters: {
|
||||
children: [
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Say 'Moving'",
|
||||
type: "nao6-ros2.say_text",
|
||||
parameters: { text: "I am moving and talking." },
|
||||
category: "interaction",
|
||||
},
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Walk Forward",
|
||||
type: "nao6-ros2.move_to",
|
||||
parameters: { x: 0.5, y: 0 },
|
||||
category: "movement",
|
||||
},
|
||||
],
|
||||
},
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
sourceKind: "core",
|
||||
});
|
||||
|
||||
// --- Step 2 Actions ---
|
||||
|
||||
// Loop
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step2.id,
|
||||
name: "Repeat Message",
|
||||
type: "loop",
|
||||
orderIndex: 0,
|
||||
parameters: {
|
||||
iterations: 3,
|
||||
children: [
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Say 'Echo'",
|
||||
type: "nao6-ros2.say_text",
|
||||
parameters: { text: "Echo" },
|
||||
category: "interaction",
|
||||
},
|
||||
],
|
||||
},
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
sourceKind: "core",
|
||||
});
|
||||
|
||||
// Wait
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step2.id,
|
||||
name: "Wait 5 Seconds",
|
||||
type: "wait",
|
||||
orderIndex: 1,
|
||||
parameters: { duration: 5 },
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
sourceKind: "core",
|
||||
});
|
||||
|
||||
// Branch (Controls step routing, not nested actions)
|
||||
// Note: Branch configuration is stored in step.trigger.conditions, not action.parameters
|
||||
// The branch action itself is just a marker that this step has conditional routing
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step2.id,
|
||||
name: "Conditional Routing",
|
||||
type: "branch",
|
||||
orderIndex: 2,
|
||||
parameters: {
|
||||
// Branch actions don't have nested children
|
||||
// Routing is configured at the step level via trigger.conditions
|
||||
},
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
sourceKind: "core",
|
||||
});
|
||||
|
||||
// Update step2 to have conditional routing
|
||||
await db
|
||||
.update(schema.steps)
|
||||
.set({
|
||||
type: "conditional",
|
||||
conditions: {
|
||||
options: [
|
||||
{
|
||||
label: "High Score Path",
|
||||
nextStepIndex: 2, // Would go to a hypothetical step 3
|
||||
variant: "default",
|
||||
},
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
sourceKind: "core"
|
||||
});
|
||||
|
||||
// Parallel
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step1.id,
|
||||
name: "Parallel Actions",
|
||||
type: "parallel",
|
||||
orderIndex: 1,
|
||||
parameters: {
|
||||
children: [
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Say 'Moving'",
|
||||
type: "nao6-ros2.say_text",
|
||||
parameters: { text: "I am moving and talking." },
|
||||
category: "interaction"
|
||||
},
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Walk Forward",
|
||||
type: "nao6-ros2.move_to",
|
||||
parameters: { x: 0.5, y: 0 },
|
||||
category: "movement"
|
||||
}
|
||||
]
|
||||
{
|
||||
label: "Low Score Path",
|
||||
nextStepIndex: 0, // Loop back to step 1
|
||||
variant: "outline",
|
||||
},
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
sourceKind: "core"
|
||||
});
|
||||
|
||||
|
||||
// --- Step 2 Actions ---
|
||||
|
||||
// Loop
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step2.id,
|
||||
name: "Repeat Message",
|
||||
type: "loop",
|
||||
orderIndex: 0,
|
||||
parameters: {
|
||||
iterations: 3,
|
||||
children: [
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Say 'Echo'",
|
||||
type: "nao6-ros2.say_text",
|
||||
parameters: { text: "Echo" },
|
||||
category: "interaction"
|
||||
}
|
||||
]
|
||||
},
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
sourceKind: "core"
|
||||
});
|
||||
|
||||
// Wait
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step2.id,
|
||||
name: "Wait 5 Seconds",
|
||||
type: "wait",
|
||||
orderIndex: 1,
|
||||
parameters: { duration: 5 },
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
sourceKind: "core"
|
||||
});
|
||||
|
||||
// Branch (Controls step routing, not nested actions)
|
||||
// Note: Branch configuration is stored in step.trigger.conditions, not action.parameters
|
||||
// The branch action itself is just a marker that this step has conditional routing
|
||||
await db.insert(schema.actions).values({
|
||||
stepId: step2.id,
|
||||
name: "Conditional Routing",
|
||||
type: "branch",
|
||||
orderIndex: 2,
|
||||
parameters: {
|
||||
// Branch actions don't have nested children
|
||||
// Routing is configured at the step level via trigger.conditions
|
||||
},
|
||||
pluginId: "hristudio-core",
|
||||
category: "control",
|
||||
sourceKind: "core"
|
||||
});
|
||||
|
||||
// Update step2 to have conditional routing
|
||||
await db.update(schema.steps)
|
||||
.set({
|
||||
type: "conditional",
|
||||
conditions: {
|
||||
options: [
|
||||
{
|
||||
label: "High Score Path",
|
||||
nextStepIndex: 2, // Would go to a hypothetical step 3
|
||||
variant: "default"
|
||||
},
|
||||
{
|
||||
label: "Low Score Path",
|
||||
nextStepIndex: 0, // Loop back to step 1
|
||||
variant: "outline"
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
.where(sql`id = ${step2.id}`);
|
||||
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
await connection.end();
|
||||
}
|
||||
],
|
||||
},
|
||||
})
|
||||
.where(sql`id = ${step2.id}`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
await connection.end();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
@@ -1,69 +1,77 @@
|
||||
|
||||
// Mock of the logic in WizardInterface.tsx handleNextStep
|
||||
const steps = [
|
||||
{
|
||||
id: "b9d43f8c-c40c-4f1c-9fdc-9076338d3c85",
|
||||
name: "Step 3 (Conditional)",
|
||||
order: 2
|
||||
{
|
||||
id: "b9d43f8c-c40c-4f1c-9fdc-9076338d3c85",
|
||||
name: "Step 3 (Conditional)",
|
||||
order: 2,
|
||||
},
|
||||
{
|
||||
id: "3a2dc0b7-a43e-4236-9b9e-f957abafc1e5",
|
||||
name: "Step 4 (Branch A)",
|
||||
order: 3,
|
||||
conditions: {
|
||||
nextStepId: "cc3fbc7f-29e5-45e0-8d46-e80813c54292",
|
||||
},
|
||||
{
|
||||
id: "3a2dc0b7-a43e-4236-9b9e-f957abafc1e5",
|
||||
name: "Step 4 (Branch A)",
|
||||
order: 3,
|
||||
conditions: {
|
||||
"nextStepId": "cc3fbc7f-29e5-45e0-8d46-e80813c54292"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "3ae2fe8a-fc5d-4a04-baa5-699a21f19e30",
|
||||
name: "Step 5 (Branch B)",
|
||||
order: 4,
|
||||
conditions: {
|
||||
nextStepId: "cc3fbc7f-29e5-45e0-8d46-e80813c54292",
|
||||
},
|
||||
{
|
||||
id: "3ae2fe8a-fc5d-4a04-baa5-699a21f19e30",
|
||||
name: "Step 5 (Branch B)",
|
||||
order: 4,
|
||||
conditions: {
|
||||
"nextStepId": "cc3fbc7f-29e5-45e0-8d46-e80813c54292"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "cc3fbc7f-29e5-45e0-8d46-e80813c54292",
|
||||
name: "Step 6 (Conclusion)",
|
||||
order: 5
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "cc3fbc7f-29e5-45e0-8d46-e80813c54292",
|
||||
name: "Step 6 (Conclusion)",
|
||||
order: 5,
|
||||
},
|
||||
];
|
||||
|
||||
function simulateNextStep(currentStepIndex: number) {
|
||||
const currentStep = steps[currentStepIndex];
|
||||
const currentStep = steps[currentStepIndex];
|
||||
|
||||
if (!currentStep) {
|
||||
console.log("No step found at index:", currentStepIndex);
|
||||
return;
|
||||
}
|
||||
if (!currentStep) {
|
||||
console.log("No step found at index:", currentStepIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`\n--- Simulating Next Step from: ${currentStep.name} ---`);
|
||||
console.log("Current Step Data:", JSON.stringify(currentStep, null, 2));
|
||||
console.log(`\n--- Simulating Next Step from: ${currentStep.name} ---`);
|
||||
console.log("Current Step Data:", JSON.stringify(currentStep, null, 2));
|
||||
|
||||
// Logic from WizardInterface.tsx
|
||||
console.log("[WizardInterface] Checking for nextStepId condition:", currentStep?.conditions);
|
||||
// Logic from WizardInterface.tsx
|
||||
console.log(
|
||||
"[WizardInterface] Checking for nextStepId condition:",
|
||||
currentStep?.conditions,
|
||||
);
|
||||
|
||||
if (currentStep?.conditions?.nextStepId) {
|
||||
const nextId = String(currentStep.conditions.nextStepId);
|
||||
const targetIndex = steps.findIndex(s => s.id === nextId);
|
||||
if (currentStep?.conditions?.nextStepId) {
|
||||
const nextId = String(currentStep.conditions.nextStepId);
|
||||
const targetIndex = steps.findIndex((s) => s.id === nextId);
|
||||
|
||||
console.log(`Target ID: ${nextId}`);
|
||||
console.log(`Target Index Found: ${targetIndex}`);
|
||||
console.log(`Target ID: ${nextId}`);
|
||||
console.log(`Target Index Found: ${targetIndex}`);
|
||||
|
||||
if (targetIndex !== -1) {
|
||||
console.log(`[WizardInterface] Condition-based jump to step ${targetIndex} (${nextId})`);
|
||||
return targetIndex;
|
||||
} else {
|
||||
console.warn(`[WizardInterface] Targeted nextStepId ${nextId} not found in steps list.`);
|
||||
}
|
||||
if (targetIndex !== -1) {
|
||||
console.log(
|
||||
`[WizardInterface] Condition-based jump to step ${targetIndex} (${nextId})`,
|
||||
);
|
||||
return targetIndex;
|
||||
} else {
|
||||
console.log("[WizardInterface] No nextStepId found in conditions, proceeding linearly.");
|
||||
console.warn(
|
||||
`[WizardInterface] Targeted nextStepId ${nextId} not found in steps list.`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.log(
|
||||
"[WizardInterface] No nextStepId found in conditions, proceeding linearly.",
|
||||
);
|
||||
}
|
||||
|
||||
// Default: Linear progression
|
||||
const nextIndex = currentStepIndex + 1;
|
||||
console.log(`Proceeding linearly to index ${nextIndex}`);
|
||||
return nextIndex;
|
||||
// Default: Linear progression
|
||||
const nextIndex = currentStepIndex + 1;
|
||||
console.log(`Proceeding linearly to index ${nextIndex}`);
|
||||
return nextIndex;
|
||||
}
|
||||
|
||||
// Simulate Branch A (Index 1 in this array, but 3 in real experiment?)
|
||||
|
||||
@@ -1,60 +1,59 @@
|
||||
|
||||
import { convertDatabaseToAction } from "../../src/lib/experiment-designer/block-converter";
|
||||
|
||||
const mockDbAction = {
|
||||
id: "eaf8f85b-75cf-4973-b436-092516b4e0e4",
|
||||
name: "Introduction Sequence",
|
||||
description: null,
|
||||
type: "sequence",
|
||||
orderIndex: 0,
|
||||
parameters: {
|
||||
"children": [
|
||||
{
|
||||
"id": "75018b01-a964-41fb-8612-940a29020d4a",
|
||||
"name": "Say Hello",
|
||||
"type": "nao6-ros2.say_text",
|
||||
"category": "interaction",
|
||||
"parameters": {
|
||||
"text": "Hello there!"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "d7020530-6477-41f3-84a4-5141778c93da",
|
||||
"name": "Wave Hand",
|
||||
"type": "nao6-ros2.move_arm",
|
||||
"category": "movement",
|
||||
"parameters": {
|
||||
"arm": "right",
|
||||
"action": "wave"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
timeout: null,
|
||||
retryCount: 0,
|
||||
sourceKind: "core",
|
||||
pluginId: "hristudio-core",
|
||||
pluginVersion: null,
|
||||
robotId: null,
|
||||
baseActionId: null,
|
||||
category: "control",
|
||||
transport: null,
|
||||
ros2: null,
|
||||
rest: null,
|
||||
retryable: null,
|
||||
parameterSchemaRaw: null
|
||||
id: "eaf8f85b-75cf-4973-b436-092516b4e0e4",
|
||||
name: "Introduction Sequence",
|
||||
description: null,
|
||||
type: "sequence",
|
||||
orderIndex: 0,
|
||||
parameters: {
|
||||
children: [
|
||||
{
|
||||
id: "75018b01-a964-41fb-8612-940a29020d4a",
|
||||
name: "Say Hello",
|
||||
type: "nao6-ros2.say_text",
|
||||
category: "interaction",
|
||||
parameters: {
|
||||
text: "Hello there!",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "d7020530-6477-41f3-84a4-5141778c93da",
|
||||
name: "Wave Hand",
|
||||
type: "nao6-ros2.move_arm",
|
||||
category: "movement",
|
||||
parameters: {
|
||||
arm: "right",
|
||||
action: "wave",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
timeout: null,
|
||||
retryCount: 0,
|
||||
sourceKind: "core",
|
||||
pluginId: "hristudio-core",
|
||||
pluginVersion: null,
|
||||
robotId: null,
|
||||
baseActionId: null,
|
||||
category: "control",
|
||||
transport: null,
|
||||
ros2: null,
|
||||
rest: null,
|
||||
retryable: null,
|
||||
parameterSchemaRaw: null,
|
||||
};
|
||||
|
||||
console.log("Testing convertDatabaseToAction...");
|
||||
try {
|
||||
const result = convertDatabaseToAction(mockDbAction);
|
||||
console.log("Result:", JSON.stringify(result, null, 2));
|
||||
const result = convertDatabaseToAction(mockDbAction);
|
||||
console.log("Result:", JSON.stringify(result, null, 2));
|
||||
|
||||
if (result.children && result.children.length > 0) {
|
||||
console.log("✅ Children hydrated successfully.");
|
||||
} else {
|
||||
console.error("❌ Children NOT hydrated.");
|
||||
}
|
||||
if (result.children && result.children.length > 0) {
|
||||
console.log("✅ Children hydrated successfully.");
|
||||
} else {
|
||||
console.error("❌ Children NOT hydrated.");
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("❌ Error during conversion:", e);
|
||||
console.error("❌ Error during conversion:", e);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { appRouter } from "../../src/server/api/root";
|
||||
import { createCallerFactory } from "../../src/server/api/trpc";
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
@@ -13,59 +12,63 @@ const db = drizzle(connection, { schema });
|
||||
|
||||
// 2. Mock Session
|
||||
const mockSession = {
|
||||
user: {
|
||||
id: "0e830889-ab46-4b48-a8ba-1d4bd3e665ed", // Admin user ID from seed
|
||||
name: "Sean O'Connor",
|
||||
email: "sean@soconnor.dev"
|
||||
},
|
||||
expires: new Date().toISOString()
|
||||
user: {
|
||||
id: "0e830889-ab46-4b48-a8ba-1d4bd3e665ed", // Admin user ID from seed
|
||||
name: "Sean O'Connor",
|
||||
email: "sean@soconnor.dev",
|
||||
},
|
||||
expires: new Date().toISOString(),
|
||||
};
|
||||
|
||||
// 3. Create Caller
|
||||
const createCaller = createCallerFactory(appRouter);
|
||||
const caller = createCaller({
|
||||
db,
|
||||
session: mockSession as any,
|
||||
headers: new Headers()
|
||||
db,
|
||||
session: mockSession as any,
|
||||
headers: new Headers(),
|
||||
});
|
||||
|
||||
async function main() {
|
||||
console.log("🔍 Fetching experiment via TRPC caller...");
|
||||
console.log("🔍 Fetching experiment via TRPC caller...");
|
||||
|
||||
// Get ID first
|
||||
const exp = await db.query.experiments.findFirst({
|
||||
where: eq(schema.experiments.name, "Control Flow Demo"),
|
||||
columns: { id: true }
|
||||
// Get ID first
|
||||
const exp = await db.query.experiments.findFirst({
|
||||
where: eq(schema.experiments.name, "Control Flow Demo"),
|
||||
columns: { id: true },
|
||||
});
|
||||
|
||||
if (!exp) {
|
||||
console.error("❌ Experiment not found");
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await caller.experiments.get({ id: exp.id });
|
||||
|
||||
console.log(`✅ Fetched experiment: ${result.name} (${result.id})`);
|
||||
|
||||
if (result.steps && result.steps.length > 0) {
|
||||
console.log(`Checking ${result.steps.length} steps...`);
|
||||
const actions = result.steps[0]!.actions; // Step 1 actions
|
||||
console.log(`Step 1 has ${actions.length} actions.`);
|
||||
|
||||
actions.forEach((a) => {
|
||||
if (["sequence", "parallel", "loop", "branch"].includes(a.type)) {
|
||||
console.log(`\nAction: ${a.name} (${a.type})`);
|
||||
console.log(
|
||||
`Children Count: ${a.children ? a.children.length : "UNDEFINED"}`,
|
||||
);
|
||||
if (a.children && a.children.length > 0) {
|
||||
console.log(
|
||||
`First Child: ${a.children[0]!.name} (${a.children[0]!.type})`,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error("❌ No steps found in result.");
|
||||
}
|
||||
|
||||
if (!exp) {
|
||||
console.error("❌ Experiment not found");
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await caller.experiments.get({ id: exp.id });
|
||||
|
||||
console.log(`✅ Fetched experiment: ${result.name} (${result.id})`);
|
||||
|
||||
if (result.steps && result.steps.length > 0) {
|
||||
console.log(`Checking ${result.steps.length} steps...`);
|
||||
const actions = result.steps[0]!.actions; // Step 1 actions
|
||||
console.log(`Step 1 has ${actions.length} actions.`);
|
||||
|
||||
actions.forEach(a => {
|
||||
if (["sequence", "parallel", "loop", "branch"].includes(a.type)) {
|
||||
console.log(`\nAction: ${a.name} (${a.type})`);
|
||||
console.log(`Children Count: ${a.children ? a.children.length : 'UNDEFINED'}`);
|
||||
if (a.children && a.children.length > 0) {
|
||||
console.log(`First Child: ${a.children[0]!.name} (${a.children[0]!.type})`);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error("❌ No steps found in result.");
|
||||
}
|
||||
|
||||
await connection.end();
|
||||
await connection.end();
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
@@ -1,44 +1,46 @@
|
||||
|
||||
import { db } from "../../src/server/db";
|
||||
import { experiments } from "../../src/server/db/schema";
|
||||
import { eq, asc } from "drizzle-orm";
|
||||
import { convertDatabaseToSteps } from "../../src/lib/experiment-designer/block-converter";
|
||||
|
||||
async function verifyConversion() {
|
||||
const experiment = await db.query.experiments.findFirst({
|
||||
const experiment = await db.query.experiments.findFirst({
|
||||
with: {
|
||||
steps: {
|
||||
orderBy: (steps, { asc }) => [asc(steps.orderIndex)],
|
||||
with: {
|
||||
steps: {
|
||||
orderBy: (steps, { asc }) => [asc(steps.orderIndex)],
|
||||
with: {
|
||||
actions: {
|
||||
orderBy: (actions, { asc }) => [asc(actions.orderIndex)],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
actions: {
|
||||
orderBy: (actions, { asc }) => [asc(actions.orderIndex)],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!experiment) {
|
||||
console.log("No experiment found");
|
||||
return;
|
||||
if (!experiment) {
|
||||
console.log("No experiment found");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("Raw DB Steps Count:", experiment.steps.length);
|
||||
const converted = convertDatabaseToSteps(experiment.steps);
|
||||
|
||||
console.log("Converted Steps:");
|
||||
converted.forEach((s, idx) => {
|
||||
console.log(`[${idx}] ${s.name} (${s.type})`);
|
||||
console.log(` Trigger:`, JSON.stringify(s.trigger));
|
||||
if (s.type === "conditional") {
|
||||
console.log(
|
||||
` Conditions populated?`,
|
||||
Object.keys(s.trigger.conditions).length > 0,
|
||||
);
|
||||
}
|
||||
|
||||
console.log("Raw DB Steps Count:", experiment.steps.length);
|
||||
const converted = convertDatabaseToSteps(experiment.steps);
|
||||
|
||||
console.log("Converted Steps:");
|
||||
converted.forEach((s, idx) => {
|
||||
console.log(`[${idx}] ${s.name} (${s.type})`);
|
||||
console.log(` Trigger:`, JSON.stringify(s.trigger));
|
||||
if (s.type === 'conditional') {
|
||||
console.log(` Conditions populated?`, Object.keys(s.trigger.conditions).length > 0);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
verifyConversion()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -8,83 +8,100 @@ const client = postgres(connectionString);
|
||||
const db = drizzle(client, { schema });
|
||||
|
||||
async function verify() {
|
||||
console.log("🔍 Verifying Study Readiness...");
|
||||
console.log("🔍 Verifying Study Readiness...");
|
||||
|
||||
// 1. Check Study
|
||||
const study = await db.query.studies.findFirst({
|
||||
where: eq(schema.studies.name, "Comparative WoZ Study")
|
||||
});
|
||||
// 1. Check Study
|
||||
const study = await db.query.studies.findFirst({
|
||||
where: eq(schema.studies.name, "Comparative WoZ Study"),
|
||||
});
|
||||
|
||||
if (!study) {
|
||||
console.error("❌ Study 'Comparative WoZ Study' not found.");
|
||||
process.exit(1);
|
||||
if (!study) {
|
||||
console.error("❌ Study 'Comparative WoZ Study' not found.");
|
||||
process.exit(1);
|
||||
}
|
||||
console.log("✅ Study found:", study.name);
|
||||
|
||||
// 2. Check Experiment
|
||||
const experiment = await db.query.experiments.findFirst({
|
||||
where: eq(schema.experiments.name, "The Interactive Storyteller"),
|
||||
});
|
||||
|
||||
if (!experiment) {
|
||||
console.error("❌ Experiment 'The Interactive Storyteller' not found.");
|
||||
process.exit(1);
|
||||
}
|
||||
console.log("✅ Experiment found:", experiment.name);
|
||||
|
||||
// 3. Check Steps
|
||||
const steps = await db.query.steps.findMany({
|
||||
where: eq(schema.steps.experimentId, experiment.id),
|
||||
orderBy: schema.steps.orderIndex,
|
||||
});
|
||||
|
||||
console.log(`ℹ️ Found ${steps.length} steps.`);
|
||||
if (steps.length < 5) {
|
||||
console.error("❌ Expected at least 5 steps, found " + steps.length);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Verify Step Names
|
||||
const expectedSteps = [
|
||||
"The Hook",
|
||||
"The Narrative - Part 1",
|
||||
"Comprehension Check",
|
||||
"Positive Feedback",
|
||||
"Conclusion",
|
||||
];
|
||||
for (let i = 0; i < expectedSteps.length; i++) {
|
||||
const step = steps[i];
|
||||
if (!step) continue;
|
||||
|
||||
if (step.name !== expectedSteps[i]) {
|
||||
console.error(
|
||||
`❌ Step mismatch at index ${i}. Expected '${expectedSteps[i]}', got '${step.name}'`,
|
||||
);
|
||||
} else {
|
||||
console.log(`✅ Step ${i + 1}: ${step.name}`);
|
||||
}
|
||||
console.log("✅ Study found:", study.name);
|
||||
}
|
||||
|
||||
// 2. Check Experiment
|
||||
const experiment = await db.query.experiments.findFirst({
|
||||
where: eq(schema.experiments.name, "The Interactive Storyteller")
|
||||
});
|
||||
// 4. Check Plugin Actions
|
||||
// Find the NAO6 plugin
|
||||
const plugin = await db.query.plugins.findFirst({
|
||||
where: (plugins, { eq, and }) =>
|
||||
and(
|
||||
eq(plugins.name, "NAO6 Robot (Enhanced ROS2 Integration)"),
|
||||
eq(plugins.status, "active"),
|
||||
),
|
||||
});
|
||||
|
||||
if (!experiment) {
|
||||
console.error("❌ Experiment 'The Interactive Storyteller' not found.");
|
||||
process.exit(1);
|
||||
if (!plugin) {
|
||||
console.error("❌ NAO6 Plugin not found.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const actions = plugin.actionDefinitions as any[];
|
||||
const requiredActions = [
|
||||
"nao_nod",
|
||||
"nao_shake_head",
|
||||
"nao_bow",
|
||||
"nao_open_hand",
|
||||
];
|
||||
|
||||
for (const actionId of requiredActions) {
|
||||
const found = actions.find((a) => a.id === actionId);
|
||||
if (!found) {
|
||||
console.error(`❌ Plugin missing action: ${actionId}`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log("✅ Experiment found:", experiment.name);
|
||||
console.log(`✅ Plugin has action: ${actionId}`);
|
||||
}
|
||||
|
||||
// 3. Check Steps
|
||||
const steps = await db.query.steps.findMany({
|
||||
where: eq(schema.steps.experimentId, experiment.id),
|
||||
orderBy: schema.steps.orderIndex
|
||||
});
|
||||
|
||||
console.log(`ℹ️ Found ${steps.length} steps.`);
|
||||
if (steps.length < 5) {
|
||||
console.error("❌ Expected at least 5 steps, found " + steps.length);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Verify Step Names
|
||||
const expectedSteps = ["The Hook", "The Narrative - Part 1", "Comprehension Check", "Positive Feedback", "Conclusion"];
|
||||
for (let i = 0; i < expectedSteps.length; i++) {
|
||||
const step = steps[i];
|
||||
if (!step) continue;
|
||||
|
||||
if (step.name !== expectedSteps[i]) {
|
||||
console.error(`❌ Step mismatch at index ${i}. Expected '${expectedSteps[i]}', got '${step.name}'`);
|
||||
} else {
|
||||
console.log(`✅ Step ${i + 1}: ${step.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Check Plugin Actions
|
||||
// Find the NAO6 plugin
|
||||
const plugin = await db.query.plugins.findFirst({
|
||||
where: (plugins, { eq, and }) => and(eq(plugins.name, "NAO6 Robot (Enhanced ROS2 Integration)"), eq(plugins.status, "active"))
|
||||
});
|
||||
|
||||
if (!plugin) {
|
||||
console.error("❌ NAO6 Plugin not found.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const actions = plugin.actionDefinitions as any[];
|
||||
const requiredActions = ["nao_nod", "nao_shake_head", "nao_bow", "nao_open_hand"];
|
||||
|
||||
for (const actionId of requiredActions) {
|
||||
const found = actions.find(a => a.id === actionId);
|
||||
if (!found) {
|
||||
console.error(`❌ Plugin missing action: ${actionId}`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(`✅ Plugin has action: ${actionId}`);
|
||||
}
|
||||
|
||||
console.log("🎉 Verification Complete: Platform is ready for the study!");
|
||||
process.exit(0);
|
||||
console.log("🎉 Verification Complete: Platform is ready for the study!");
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
verify().catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,84 +1,86 @@
|
||||
|
||||
import { db } from "~/server/db";
|
||||
import { experiments, steps, actions } from "~/server/db/schema";
|
||||
import { eq, asc, desc } from "drizzle-orm";
|
||||
import { convertDatabaseToSteps } from "~/lib/experiment-designer/block-converter";
|
||||
|
||||
async function verifyTrpcLogic() {
|
||||
console.log("Verifying TRPC Logic for Interactive Storyteller...");
|
||||
console.log("Verifying TRPC Logic for Interactive Storyteller...");
|
||||
|
||||
// 1. Simulate the DB Query from experiments.ts
|
||||
const experiment = await db.query.experiments.findFirst({
|
||||
where: eq(experiments.name, "The Interactive Storyteller"),
|
||||
with: {
|
||||
study: {
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
createdBy: {
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
robot: true,
|
||||
steps: {
|
||||
with: {
|
||||
actions: {
|
||||
orderBy: [asc(actions.orderIndex)],
|
||||
},
|
||||
},
|
||||
orderBy: [asc(steps.orderIndex)],
|
||||
},
|
||||
// 1. Simulate the DB Query from experiments.ts
|
||||
const experiment = await db.query.experiments.findFirst({
|
||||
where: eq(experiments.name, "The Interactive Storyteller"),
|
||||
with: {
|
||||
study: {
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
});
|
||||
},
|
||||
createdBy: {
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
email: true,
|
||||
},
|
||||
},
|
||||
robot: true,
|
||||
steps: {
|
||||
with: {
|
||||
actions: {
|
||||
orderBy: [asc(actions.orderIndex)],
|
||||
},
|
||||
},
|
||||
orderBy: [asc(steps.orderIndex)],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!experiment) {
|
||||
console.error("Experiment not found!");
|
||||
return;
|
||||
}
|
||||
if (!experiment) {
|
||||
console.error("Experiment not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Simulate the Transformation
|
||||
console.log("Transforming DB steps to Designer steps...");
|
||||
const transformedSteps = convertDatabaseToSteps(experiment.steps);
|
||||
// 2. Simulate the Transformation
|
||||
console.log("Transforming DB steps to Designer steps...");
|
||||
const transformedSteps = convertDatabaseToSteps(experiment.steps);
|
||||
|
||||
// 3. Inspect Step 4 (Branch A)
|
||||
// Step index 3 (0-based) is Branch A
|
||||
const branchAStep = transformedSteps[3];
|
||||
// 3. Inspect Step 4 (Branch A)
|
||||
// Step index 3 (0-based) is Branch A
|
||||
const branchAStep = transformedSteps[3];
|
||||
|
||||
if (branchAStep) {
|
||||
console.log("Step 4 (Branch A):", branchAStep.name);
|
||||
console.log(" Type:", branchAStep.type);
|
||||
console.log(" Trigger:", JSON.stringify(branchAStep.trigger, null, 2));
|
||||
} else {
|
||||
console.error("Step 4 (Branch A) not found in transformed steps!");
|
||||
process.exit(1);
|
||||
}
|
||||
if (branchAStep) {
|
||||
console.log("Step 4 (Branch A):", branchAStep.name);
|
||||
console.log(" Type:", branchAStep.type);
|
||||
console.log(" Trigger:", JSON.stringify(branchAStep.trigger, null, 2));
|
||||
} else {
|
||||
console.error("Step 4 (Branch A) not found in transformed steps!");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Check conditions specifically
|
||||
const conditions = branchAStep.trigger?.conditions as any;
|
||||
if (conditions?.nextStepId) {
|
||||
console.log("SUCCESS: nextStepId found in conditions:", conditions.nextStepId);
|
||||
} else {
|
||||
console.error("FAILURE: nextStepId MISSING in conditions!");
|
||||
}
|
||||
// Check conditions specifically
|
||||
const conditions = branchAStep.trigger?.conditions as any;
|
||||
if (conditions?.nextStepId) {
|
||||
console.log(
|
||||
"SUCCESS: nextStepId found in conditions:",
|
||||
conditions.nextStepId,
|
||||
);
|
||||
} else {
|
||||
console.error("FAILURE: nextStepId MISSING in conditions!");
|
||||
}
|
||||
|
||||
// Inspect Step 5 (Branch B) for completeness
|
||||
const branchBStep = transformedSteps[4];
|
||||
if (branchBStep) {
|
||||
console.log("Step 5 (Branch B):", branchBStep.name);
|
||||
console.log(" Trigger:", JSON.stringify(branchBStep.trigger, null, 2));
|
||||
} else {
|
||||
console.warn("Step 5 (Branch B) not found in transformed steps.");
|
||||
}
|
||||
// Inspect Step 5 (Branch B) for completeness
|
||||
const branchBStep = transformedSteps[4];
|
||||
if (branchBStep) {
|
||||
console.log("Step 5 (Branch B):", branchBStep.name);
|
||||
console.log(" Trigger:", JSON.stringify(branchBStep.trigger, null, 2));
|
||||
} else {
|
||||
console.warn("Step 5 (Branch B) not found in transformed steps.");
|
||||
}
|
||||
}
|
||||
|
||||
verifyTrpcLogic()
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
import * as schema from "../src/server/db/schema";
|
||||
@@ -9,18 +8,18 @@ const connection = postgres(connectionString);
|
||||
const db = drizzle(connection, { schema });
|
||||
|
||||
async function main() {
|
||||
const exp = await db.query.experiments.findFirst({
|
||||
where: eq(schema.experiments.name, "Control Flow Demo"),
|
||||
columns: { id: true }
|
||||
});
|
||||
const exp = await db.query.experiments.findFirst({
|
||||
where: eq(schema.experiments.name, "Control Flow Demo"),
|
||||
columns: { id: true },
|
||||
});
|
||||
|
||||
if (exp) {
|
||||
console.log(`Experiment ID: ${exp.id}`);
|
||||
} else {
|
||||
console.error("Experiment not found");
|
||||
}
|
||||
if (exp) {
|
||||
console.log(`Experiment ID: ${exp.id}`);
|
||||
} else {
|
||||
console.error("Experiment not found");
|
||||
}
|
||||
|
||||
await connection.end();
|
||||
await connection.end();
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
import { drizzle } from "drizzle-orm/postgres-js";
|
||||
import postgres from "postgres";
|
||||
import * as schema from "../src/server/db/schema";
|
||||
@@ -9,18 +8,18 @@ const connection = postgres(connectionString);
|
||||
const db = drizzle(connection, { schema });
|
||||
|
||||
async function main() {
|
||||
const user = await db.query.users.findFirst({
|
||||
where: eq(schema.users.email, "sean@soconnor.dev"),
|
||||
columns: { id: true }
|
||||
});
|
||||
const user = await db.query.users.findFirst({
|
||||
where: eq(schema.users.email, "sean@soconnor.dev"),
|
||||
columns: { id: true },
|
||||
});
|
||||
|
||||
if (user) {
|
||||
console.log(`User ID: ${user.id}`);
|
||||
} else {
|
||||
console.error("User not found");
|
||||
}
|
||||
if (user) {
|
||||
console.log(`User ID: ${user.id}`);
|
||||
} else {
|
||||
console.error("User not found");
|
||||
}
|
||||
|
||||
await connection.end();
|
||||
await connection.end();
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user