feat: enable hybrid local and remote module execution
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
ALTER TABLE "student_saved_maps"
|
||||
ADD COLUMN "runtime_kind" TEXT NOT NULL DEFAULT 'SIMULATION';
|
||||
|
||||
UPDATE "student_saved_maps"
|
||||
SET "runtime_kind" = CASE
|
||||
WHEN "database_path" IS NOT NULL THEN 'PLATFORM_3D'
|
||||
WHEN "source_map_key" = 'nav2-platform-slam' THEN 'PLATFORM_2D'
|
||||
ELSE 'SIMULATION'
|
||||
END;
|
||||
|
||||
CREATE INDEX "student_saved_maps_user_id_course_id_week_runtime_kind_idx"
|
||||
ON "student_saved_maps"("user_id", "course_id", "week", "runtime_kind");
|
||||
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE "student_saved_maps"
|
||||
ADD COLUMN "yaml_url" TEXT,
|
||||
ADD COLUMN "pgm_url" TEXT,
|
||||
ADD COLUMN "database_url" TEXT;
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
ALTER TABLE "student_custom_modules"
|
||||
ADD COLUMN "runtime_target" TEXT NOT NULL DEFAULT 'LOCAL';
|
||||
|
||||
DROP INDEX "student_custom_modules_user_id_course_id_week_folder_name_key";
|
||||
|
||||
CREATE UNIQUE INDEX "student_custom_modules_user_id_course_id_week_folder_name_runtime_target_key"
|
||||
ON "student_custom_modules"("user_id", "course_id", "week", "folder_name", "runtime_target");
|
||||
|
||||
CREATE INDEX "student_custom_modules_user_id_course_id_week_runtime_target_sort_order_idx"
|
||||
ON "student_custom_modules"("user_id", "course_id", "week", "runtime_target", "sort_order");
|
||||
@@ -0,0 +1,64 @@
|
||||
ALTER TABLE "instructor_curriculum_week_overrides"
|
||||
ADD COLUMN "is_team_project" BOOLEAN DEFAULT false;
|
||||
|
||||
CREATE TABLE "team_studio_repositories" (
|
||||
"id" UUID NOT NULL,
|
||||
"group_id" UUID NOT NULL,
|
||||
"week_id" UUID NOT NULL,
|
||||
"module_id" UUID NOT NULL,
|
||||
"repo_owner" TEXT NOT NULL,
|
||||
"repo_name" TEXT NOT NULL,
|
||||
"repository_url" TEXT NOT NULL,
|
||||
"template_repository_url" TEXT NOT NULL,
|
||||
"created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMPTZ(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "team_studio_repositories_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "team_studio_repositories_group_id_module_id_key"
|
||||
ON "team_studio_repositories"("group_id", "module_id");
|
||||
CREATE INDEX "team_studio_repositories_week_id_idx"
|
||||
ON "team_studio_repositories"("week_id");
|
||||
CREATE INDEX "team_studio_repositories_repo_owner_repo_name_idx"
|
||||
ON "team_studio_repositories"("repo_owner", "repo_name");
|
||||
|
||||
ALTER TABLE "team_studio_repositories"
|
||||
ADD CONSTRAINT "team_studio_repositories_group_id_fkey"
|
||||
FOREIGN KEY ("group_id") REFERENCES "student_groups"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "team_studio_repositories"
|
||||
ADD CONSTRAINT "team_studio_repositories_module_id_fkey"
|
||||
FOREIGN KEY ("module_id") REFERENCES "course_week_modules"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
CREATE TABLE "team_custom_modules" (
|
||||
"id" UUID NOT NULL,
|
||||
"group_id" UUID NOT NULL,
|
||||
"creator_id" UUID NOT NULL,
|
||||
"course_id" UUID NOT NULL,
|
||||
"week" INTEGER NOT NULL,
|
||||
"sort_order" INTEGER NOT NULL,
|
||||
"category" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"folder_name" TEXT NOT NULL,
|
||||
"docker_image" TEXT,
|
||||
"package_name" TEXT NOT NULL,
|
||||
"launch_file" TEXT NOT NULL,
|
||||
"created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMPTZ(3) NOT NULL,
|
||||
CONSTRAINT "team_custom_modules_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "team_custom_modules_group_id_course_id_week_folder_name_key"
|
||||
ON "team_custom_modules"("group_id", "course_id", "week", "folder_name");
|
||||
CREATE INDEX "team_custom_modules_group_id_course_id_week_sort_order_idx"
|
||||
ON "team_custom_modules"("group_id", "course_id", "week", "sort_order");
|
||||
|
||||
ALTER TABLE "team_custom_modules"
|
||||
ADD CONSTRAINT "team_custom_modules_group_id_fkey"
|
||||
FOREIGN KEY ("group_id") REFERENCES "student_groups"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "team_custom_modules"
|
||||
ADD CONSTRAINT "team_custom_modules_creator_id_fkey"
|
||||
FOREIGN KEY ("creator_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "team_custom_modules"
|
||||
ADD CONSTRAINT "team_custom_modules_course_id_fkey"
|
||||
FOREIGN KEY ("course_id") REFERENCES "courses"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,45 @@
|
||||
CREATE TABLE "student_custom_module_repositories" (
|
||||
"id" UUID NOT NULL,
|
||||
"user_id" UUID NOT NULL,
|
||||
"custom_module_id" UUID NOT NULL,
|
||||
"repo_owner" TEXT NOT NULL,
|
||||
"repo_name" TEXT NOT NULL,
|
||||
"repository_url" TEXT NOT NULL,
|
||||
"created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMPTZ(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "student_custom_module_repositories_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "team_custom_module_repositories" (
|
||||
"id" UUID NOT NULL,
|
||||
"group_id" UUID NOT NULL,
|
||||
"custom_module_id" UUID NOT NULL,
|
||||
"repo_owner" TEXT NOT NULL,
|
||||
"repo_name" TEXT NOT NULL,
|
||||
"repository_url" TEXT NOT NULL,
|
||||
"created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" TIMESTAMPTZ(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "team_custom_module_repositories_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "student_custom_module_repositories_custom_module_id_key" ON "student_custom_module_repositories"("custom_module_id");
|
||||
CREATE INDEX "student_custom_module_repositories_user_id_idx" ON "student_custom_module_repositories"("user_id");
|
||||
CREATE INDEX "student_custom_module_repositories_repo_owner_repo_name_idx" ON "student_custom_module_repositories"("repo_owner", "repo_name");
|
||||
CREATE UNIQUE INDEX "team_custom_module_repositories_custom_module_id_key" ON "team_custom_module_repositories"("custom_module_id");
|
||||
CREATE INDEX "team_custom_module_repositories_group_id_idx" ON "team_custom_module_repositories"("group_id");
|
||||
CREATE INDEX "team_custom_module_repositories_repo_owner_repo_name_idx" ON "team_custom_module_repositories"("repo_owner", "repo_name");
|
||||
|
||||
ALTER TABLE "student_custom_module_repositories"
|
||||
ADD CONSTRAINT "student_custom_module_repositories_user_id_fkey"
|
||||
FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "student_custom_module_repositories"
|
||||
ADD CONSTRAINT "student_custom_module_repositories_custom_module_id_fkey"
|
||||
FOREIGN KEY ("custom_module_id") REFERENCES "student_custom_modules"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "team_custom_module_repositories"
|
||||
ADD CONSTRAINT "team_custom_module_repositories_group_id_fkey"
|
||||
FOREIGN KEY ("group_id") REFERENCES "student_groups"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "team_custom_module_repositories"
|
||||
ADD CONSTRAINT "team_custom_module_repositories_custom_module_id_fkey"
|
||||
FOREIGN KEY ("custom_module_id") REFERENCES "team_custom_modules"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,33 @@
|
||||
-- Align the LMS platform record with the checked-in NAV2-MKMini profile.
|
||||
-- The speed is the real YHS CAN safety limit, not the higher simulation-only cap.
|
||||
UPDATE "platforms"
|
||||
SET
|
||||
"vehicle_type" = 'MK-mini',
|
||||
"wheelbase_meters" = 0.600,
|
||||
"max_speed_meters_per_second" = 0.300,
|
||||
"max_steering_angle_degrees" = 28.6479
|
||||
WHERE "platform_key" ILIKE '%mkmini%';
|
||||
|
||||
UPDATE "instructor_platforms" AS instance
|
||||
SET
|
||||
"vehicle_type" = 'MK-mini',
|
||||
"wheelbase_meters" = 0.600,
|
||||
"max_speed_meters_per_second" = 0.300,
|
||||
"max_steering_angle_degrees" = 28.6479
|
||||
FROM "platforms" AS platform
|
||||
WHERE instance."platform_id" = platform."id"
|
||||
AND platform."platform_key" ILIKE '%mkmini%';
|
||||
|
||||
UPDATE "course_week_modules"
|
||||
SET "prebuilt_artifacts" = jsonb_build_array(
|
||||
jsonb_build_object(
|
||||
'type', 'build-install',
|
||||
'fileName', 'lms-nav2-mkmini-build-install-amd64.tar.zst',
|
||||
'url', 'https://pub-ca0a1bc004d8409da3329dbb9ac32bcf.r2.dev/studio-artifacts/modules/lms-nav2-mkmini/1.0.0/prebuilt/amd64/lms-nav2-mkmini-build-install-amd64.tar.zst',
|
||||
'checksumSha256', '8b36d3fda6a81a49da140529d9874e99b734d05e01e12a49e719e2b26f8803d9',
|
||||
'architecture', 'amd64',
|
||||
'required', false,
|
||||
'extractPath', '.'
|
||||
)
|
||||
)
|
||||
WHERE "folder_name" = '[lms-nav2-mkmini]nav2-mkmini_v1.0.0_ws';
|
||||
+96
-1
@@ -31,8 +31,10 @@ model User {
|
||||
platformControlSessions PlatformControlSession[]
|
||||
platformControlQueueEntries PlatformControlQueueEntry[]
|
||||
studioRepositories StudioRepository[]
|
||||
customModuleRepositories StudentCustomModuleRepository[]
|
||||
savedMaps StudentSavedMap[]
|
||||
customModules StudentCustomModule[]
|
||||
teamCustomModules TeamCustomModule[] @relation("TeamCustomModuleCreator")
|
||||
submissionScores SubmissionScore[]
|
||||
submissionTotalScores SubmissionTotalScore[]
|
||||
|
||||
@@ -77,6 +79,9 @@ model StudentGroup {
|
||||
platformControlSessions PlatformControlSession[]
|
||||
platformControlQueueEntries PlatformControlQueueEntry[]
|
||||
curriculumSettings InstructorCurriculumSetting[]
|
||||
teamStudioRepositories TeamStudioRepository[]
|
||||
teamCustomModuleRepositories TeamCustomModuleRepository[]
|
||||
teamCustomModules TeamCustomModule[]
|
||||
|
||||
@@unique([organizationName, name])
|
||||
@@index([organizationId])
|
||||
@@ -162,6 +167,7 @@ model Course {
|
||||
weekMaps CourseWeekMap[]
|
||||
savedMaps StudentSavedMap[]
|
||||
customModules StudentCustomModule[]
|
||||
teamCustomModules TeamCustomModule[]
|
||||
submissionScores SubmissionScore[]
|
||||
submissionTotalScores SubmissionTotalScore[]
|
||||
|
||||
@@ -267,8 +273,12 @@ model StudentSavedMap {
|
||||
viewerModel String @map("viewer_model")
|
||||
yamlPath String @map("yaml_path")
|
||||
pgmPath String @map("pgm_path")
|
||||
yamlUrl String? @map("yaml_url")
|
||||
pgmUrl String? @map("pgm_url")
|
||||
previewPgm String? @map("preview_pgm")
|
||||
databasePath String? @map("database_path")
|
||||
databaseUrl String? @map("database_url")
|
||||
runtimeKind String @default("SIMULATION") @map("runtime_kind")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
@@ -276,6 +286,7 @@ model StudentSavedMap {
|
||||
|
||||
@@unique([userId, courseId, week, yamlPath])
|
||||
@@index([userId, courseId, week, createdAt])
|
||||
@@index([userId, courseId, week, runtimeKind])
|
||||
@@map("student_saved_maps")
|
||||
}
|
||||
|
||||
@@ -291,16 +302,78 @@ model StudentCustomModule {
|
||||
dockerImage String? @map("docker_image")
|
||||
packageName String @map("package_name")
|
||||
launchFile String @map("launch_file")
|
||||
runtimeTarget String @default("LOCAL") @map("runtime_target")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
||||
repository StudentCustomModuleRepository?
|
||||
|
||||
@@unique([userId, courseId, week, folderName])
|
||||
@@unique([userId, courseId, week, folderName, runtimeTarget])
|
||||
@@index([userId, courseId, week, sortOrder])
|
||||
@@index([userId, courseId, week, runtimeTarget, sortOrder])
|
||||
@@map("student_custom_modules")
|
||||
}
|
||||
|
||||
model TeamCustomModule {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
groupId String @map("group_id") @db.Uuid
|
||||
creatorId String @map("creator_id") @db.Uuid
|
||||
courseId String @map("course_id") @db.Uuid
|
||||
week Int
|
||||
sortOrder Int @map("sort_order")
|
||||
category String
|
||||
name String
|
||||
folderName String @map("folder_name")
|
||||
dockerImage String? @map("docker_image")
|
||||
packageName String @map("package_name")
|
||||
launchFile String @map("launch_file")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
group StudentGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
||||
creator User @relation("TeamCustomModuleCreator", fields: [creatorId], references: [id], onDelete: Cascade)
|
||||
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
||||
repository TeamCustomModuleRepository?
|
||||
|
||||
@@unique([groupId, courseId, week, folderName])
|
||||
@@index([groupId, courseId, week, sortOrder])
|
||||
@@map("team_custom_modules")
|
||||
}
|
||||
|
||||
model StudentCustomModuleRepository {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
userId String @map("user_id") @db.Uuid
|
||||
customModuleId String @unique @map("custom_module_id") @db.Uuid
|
||||
repoOwner String @map("repo_owner")
|
||||
repoName String @map("repo_name")
|
||||
repositoryUrl String @map("repository_url")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
customModule StudentCustomModule @relation(fields: [customModuleId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([userId])
|
||||
@@index([repoOwner, repoName])
|
||||
@@map("student_custom_module_repositories")
|
||||
}
|
||||
|
||||
model TeamCustomModuleRepository {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
groupId String @map("group_id") @db.Uuid
|
||||
customModuleId String @unique @map("custom_module_id") @db.Uuid
|
||||
repoOwner String @map("repo_owner")
|
||||
repoName String @map("repo_name")
|
||||
repositoryUrl String @map("repository_url")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
group StudentGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
||||
customModule TeamCustomModule @relation(fields: [customModuleId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([groupId])
|
||||
@@index([repoOwner, repoName])
|
||||
@@map("team_custom_module_repositories")
|
||||
}
|
||||
|
||||
model InstructorCurriculumSetting {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
organizationId String? @map("organization_id") @db.Uuid
|
||||
@@ -333,6 +406,7 @@ model InstructorCurriculumWeekOverride {
|
||||
overview String?
|
||||
deliverable String?
|
||||
requiresSourceSubmission Boolean? @default(true) @map("requires_source_submission")
|
||||
isTeamProject Boolean? @default(false) @map("is_team_project")
|
||||
learningSteps Json? @map("learning_steps")
|
||||
topics Json?
|
||||
topicDetails Json? @map("topic_details")
|
||||
@@ -540,6 +614,7 @@ model CourseWeekModule {
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
week CourseWeek @relation(fields: [weekId], references: [id], onDelete: Cascade)
|
||||
studioRepositories StudioRepository[]
|
||||
teamStudioRepositories TeamStudioRepository[]
|
||||
submissionScores SubmissionScore[]
|
||||
|
||||
@@unique([weekId, folderName])
|
||||
@@ -568,6 +643,26 @@ model StudioRepository {
|
||||
@@map("studio_repositories")
|
||||
}
|
||||
|
||||
model TeamStudioRepository {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
groupId String @map("group_id") @db.Uuid
|
||||
weekId String @map("week_id") @db.Uuid
|
||||
moduleId String @map("module_id") @db.Uuid
|
||||
repoOwner String @map("repo_owner")
|
||||
repoName String @map("repo_name")
|
||||
repositoryUrl String @map("repository_url")
|
||||
templateRepositoryUrl String @map("template_repository_url")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
group StudentGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
||||
module CourseWeekModule @relation(fields: [moduleId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([groupId, moduleId])
|
||||
@@index([weekId])
|
||||
@@index([repoOwner, repoName])
|
||||
@@map("team_studio_repositories")
|
||||
}
|
||||
|
||||
model SubmissionScore {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
courseId String @map("course_id") @db.Uuid
|
||||
|
||||
Reference in New Issue
Block a user