major major
This commit is contained in:
+108
-97
@@ -1,99 +1,99 @@
|
||||
{
|
||||
"teacherMap": {
|
||||
"1": "user_3AMTkSb5aZsaWlYnCd2x5iImprs",
|
||||
"2": "user_3AMTkUkKWrV9QWt9dvD2qOjoxiE",
|
||||
"3": "user_3AMTkRjafcujtrgbyS4SNoWFgjh",
|
||||
"4": "user_3AMTkfb5Y9O7a55cye9iQAHxLAB",
|
||||
"5": "user_3AMTkaTAmH3VOUCcxgeCfSTaaIX",
|
||||
"6": "user_3AMTkZQ1Jea1Mdc4gT9qqwhX9zb",
|
||||
"7": "user_3AMTkio1bTs7CEgKbXJQuJkcDYu",
|
||||
"8": "user_3AMTkkYnJUOui3Z73yZlx7KNg21",
|
||||
"9": "user_3AMTkmAn0DTuaxFdyR4ii1oPQr7",
|
||||
"10": "user_3AMTkvIYftbqLCpyuhSnCp0Xdcv",
|
||||
"11": "user_3AMTksKS8GKlkstBeBndBvDSMi8",
|
||||
"12": "user_3AMTkqRKtBPzjilxeONx344GQJS",
|
||||
"13": "user_3AMTkx8ZtB15yOcnEDgoAic3Z60",
|
||||
"14": "user_3AMTkz65CADkvCgyC5fh2qRxRQV",
|
||||
"15": "user_3AMTkzAvbz587Hc36Kvk4MXIBsL"
|
||||
"1": "user_3AcluevCik3awerLuiRklEiYlJK",
|
||||
"2": "user_3AclukmobwQyj1tnS2EpfGIEt6R",
|
||||
"3": "user_3Aclul7evfG5xOADBZnREFuhYJf",
|
||||
"4": "user_3Aclum88YIVFMJy42nhED1n0sYr",
|
||||
"5": "user_3AclusjcjWN31nZipvNmfMnxliI",
|
||||
"6": "user_3Acluy4wczfAKj0LgYUpqXx1Dwo",
|
||||
"7": "user_3AcluzotsLfMQe83PxIpQ5o1Ajq",
|
||||
"8": "user_3AcluuRXAW5Y0pfUI0bHKIl5PEp",
|
||||
"9": "user_3Aclv3yUI1stBwX8v1Y6BZw6xBB",
|
||||
"10": "user_3Aclv3EpmOTEXnSOCyXFuvkDGDP",
|
||||
"11": "user_3AclvFBzxeP3PqdRjT9Wcuy5Wvw",
|
||||
"12": "user_3AclvEh6mSOExxYPUjP5iqE06C8",
|
||||
"13": "user_3AclvCPsCtWmKKQplr2KfKAlAna",
|
||||
"14": "user_3AclvFUjLy3SwIL3egEjVmlUzDx",
|
||||
"15": "user_3AclvGYnbjRTd8unbv6bj0LJlIy"
|
||||
},
|
||||
"parentMap": {
|
||||
"1": "user_3AMTl8n08l1L5ierzRsTYWMdFZP",
|
||||
"2": "user_3AMTl8u9bFoUz7mFK14Zhh85K6X",
|
||||
"3": "user_3AMTlCd06BO0Y9WoBWXy2ictYYz",
|
||||
"4": "user_3AMTlCMBaMKRQv5BCQPX46Iv5xK",
|
||||
"5": "user_3AMTlGoIV7fNrrYhuOjoyTs1h1a",
|
||||
"6": "user_3AMTlGZpGBcdicxrK5pjYa901Hv",
|
||||
"7": "user_3AMTlQ4wTNdagORX0RmbdfDPdFT",
|
||||
"8": "user_3AMTlLQtI62V185SDKt3mge25gk",
|
||||
"9": "user_3AMTlMjordV5M4W13cg8XiQGMaP",
|
||||
"10": "user_3AMTlZKLWrUlRjeCFCiGBOmqI5l",
|
||||
"11": "user_3AMTlWlRgP2UBskbHenAXzqzNjn",
|
||||
"12": "user_3AMTlbgjdcsv8HKKnlpWoA42jiW",
|
||||
"13": "user_3AMTlauWbEOSp4xb9NzBTu7uNeI",
|
||||
"14": "user_3AMTlfzhy2jrbLrhCBaUSB6LwfW",
|
||||
"15": "user_3AMTll6wXmJI0KjTUvbXZZvSlGq",
|
||||
"16": "user_3AMTlosVB9G5Nr8ZSY4JkVtqGqT",
|
||||
"17": "user_3AMTlkMhTzRgPBEHDfu47qtwJ6i",
|
||||
"18": "user_3AMTlrbxKFS3HnwNQVKJaLNF3X7",
|
||||
"19": "user_3AMTlqQnvCBDhiH4qrUChkNxbE5",
|
||||
"20": "user_3AMTm3oZYPIAnNdzN63xfpV4QPI",
|
||||
"21": "user_3AMTm5OrIhMbQ325RYoCa0HAZlh",
|
||||
"22": "user_3AMTmB28qoyEFvcUlhXzaHVDJL9",
|
||||
"23": "user_3AMTmAPi7FmXoUirnikOnGfKIlO",
|
||||
"24": "user_3AMTmCaqV2OPnTRJk3Z902P9nos",
|
||||
"25": "user_3AMTmCnG8IyhdHGTskXDIWfVgKK"
|
||||
"1": "user_3AclvXcXbK4reTdS7oNXcwYOPLF",
|
||||
"2": "user_3AclvcMY65f4gujVmJwfTElOL4I",
|
||||
"3": "user_3AclvW0MF1AqFkRcapoJ7lFBTyi",
|
||||
"4": "user_3AclvgyTfukFFSnuZ7Ka3XQsBTB",
|
||||
"5": "user_3Aclvg9OfhvlTzwWluw2eSNNXRP",
|
||||
"6": "user_3AclvjgJNIhAzMelhWTzaIBU3q2",
|
||||
"7": "user_3AclvexY0qT0klmi2YEx9g0j2kn",
|
||||
"8": "user_3Aclvt7rWlBsErcFgMzY32PTtZk",
|
||||
"9": "user_3Aclvm2ako1pUz9zD0sxq0zcrtB",
|
||||
"10": "user_3AclvpzxKyOlI6yhS83zam9B3Ty",
|
||||
"11": "user_3AclvvlQgtOnlcymUW2FaM5Tk9I",
|
||||
"12": "user_3Aclvv0Jn0UrL7KVTswpJLojIVL",
|
||||
"13": "user_3AclvuAT2eVlEp8qFQg3dW7v5Nw",
|
||||
"14": "user_3Aclw79caQ2PJ7L6F0MzeyDKEqq",
|
||||
"15": "user_3Aclw72NNounCPLb27uNI1qJqY5",
|
||||
"16": "user_3Aclw7mjthXqbQsI2XKEsWJlUbp",
|
||||
"17": "user_3AclwDc08JgsMxWBIjFXFuVkKId",
|
||||
"18": "user_3AclwBWEplMgRAJ9eLzGqQVJSCI",
|
||||
"19": "user_3AclwBj5Qzo9d5yF1S4AT7OEwEN",
|
||||
"20": "user_3AclwKBjFVhqiC2KIvFGhqkdkFP",
|
||||
"21": "user_3AclwIhCpEdcksHaZCzlFJIFQgD",
|
||||
"22": "user_3AclwHyw3NQ3hwP77tgqBw5S0Nq",
|
||||
"23": "user_3AclwTy1XzFeeR0dz9ToErN5f3t",
|
||||
"24": "user_3AclwQsdiL8JzC4g3vbogU2XcN6",
|
||||
"25": "user_3AclwU8IiWYz0LKR2tO7jEHVdAF"
|
||||
},
|
||||
"studentMap": {
|
||||
"1": "user_3AMTmFbsTvd1bTYxbuaiJEWEib6",
|
||||
"2": "user_3AMTmLp1BkbpUdSDn9ynA4Y6JF2",
|
||||
"3": "user_3AMTmNTKwZ70qJn1VqqOgsMsn6B",
|
||||
"4": "user_3AMTmOWj8vhMDBh9wsO2rWFEfO3",
|
||||
"5": "user_3AMTmVJMwFUQ5xphwLHFFoCJ5hl",
|
||||
"6": "user_3AMTmVAfVEpQldG5aEZYNoObmqE",
|
||||
"7": "user_3AMTmXvXbUJ0hbMSGy2GxR4XBq3",
|
||||
"8": "user_3AMTmTZJJUaHpC6vPrRnlNQjzV1",
|
||||
"9": "user_3AMTmenWIejkaHVpU9ECpu2ym0b",
|
||||
"10": "user_3AMTmb2na93TGqMYW6dAO7bRhzZ",
|
||||
"11": "user_3AMTmmAhGdPyG73SqbZy65xo4zR",
|
||||
"12": "user_3AMTmiNz7s34137Vm7R40tldWFj",
|
||||
"13": "user_3AMTmhhd6xR4jQhqlytwF4JVc0N",
|
||||
"14": "user_3AMTmud3UuGWrvcCstxciqaRhJP",
|
||||
"15": "user_3AMTmwPzZcSKvVE1vCYagb4IrQO",
|
||||
"16": "user_3AMTmvzkaBKZs4f0qwc4Q2L0GNe",
|
||||
"17": "user_3AMTn3lCnHDzMShKlenMMPkDtoA",
|
||||
"18": "user_3AMTn3bE5un9OCnYr0iwftXrPPy",
|
||||
"19": "user_3AMTn4QZQqYQIps95xfehqdp4dt",
|
||||
"20": "user_3AMTn7sakhjRDyoKY7LmjcudCMn",
|
||||
"21": "user_3AMTnIgyMm8qJDxqYczGISUl4SU",
|
||||
"22": "user_3AMTnJj4Nd0oVkAZRssvRMAVbk7",
|
||||
"23": "user_3AMTnN15QzCO98nkpYo5eD34R5S",
|
||||
"24": "user_3AMTnM51Kdx7VxvbO7pIxIKCHcs",
|
||||
"25": "user_3AMTnPCxefgX1zECfff75vIMQEG",
|
||||
"26": "user_3AMTnXwI5GcroWoCvDREunhXuLA",
|
||||
"27": "user_3AMTnVoqmZanh2rqRKylP2KFPU2",
|
||||
"28": "user_3AMTnUCYRW9lfzGCj2X1agCKBR3",
|
||||
"29": "user_3AMTnV2uWRevLmHMpAgcLXpiM3k",
|
||||
"30": "user_3AMTnaDOgQgbZmJAcIJTX3exNeq",
|
||||
"31": "user_3AMTnaVlrBUic7iwIUBXZlrBNYp",
|
||||
"32": "user_3AMTng8nP5U5uzriwfkvmX1LbVo",
|
||||
"33": "user_3AMTnje4x1ektrJKGRUulxI2kJz",
|
||||
"34": "user_3AMTnnDJTdBhWYZZXl2mrlGHpgc",
|
||||
"35": "user_3AMTnoayLsbHr2ZmuUcuP40RImH",
|
||||
"36": "user_3AMTnupHywRyiHEgfOYls192hUs",
|
||||
"37": "user_3AMTnvI2VJoPiARcUuO7hP00C0m",
|
||||
"38": "user_3AMTnwh5t3ngn4U98Il3Ba9zn3b",
|
||||
"39": "user_3AMTnyC41WG5cG9ryBTXXazSXp2",
|
||||
"40": "user_3AMTo4h5975zlCH2h1GsSj4lmab",
|
||||
"41": "user_3AMTo3S5SZW96jfUZhZ1qr80BSe",
|
||||
"42": "user_3AMTo7ubYy6cgkvVbIClDnxR9UW",
|
||||
"43": "user_3AMToANk7wfWM411FkpwodGtz6J",
|
||||
"44": "user_3AMTo7Jb4xAnwiaUWdUqVPns950",
|
||||
"45": "user_3AMToDel0WihAMkoD28W7pgSoFf",
|
||||
"46": "user_3AMToGI2FXT9ZRi8WRoADjvu03i",
|
||||
"47": "user_3AMToDID2tATAjoVnaaxToKon3R",
|
||||
"48": "user_3AMToLwHwVZYvznCjPa58b29eQE",
|
||||
"49": "user_3AMToRmg19Bu1CwZ8rGz4ODkxjS",
|
||||
"50": "user_3AMToPjQulU7sRNtDe83TAnxnY1"
|
||||
"1": "user_3AclwbE0uJkJGKuHp1Zpn8gMsmQ",
|
||||
"2": "user_3AclwWTpwvqyBqUMWkDxtAY5c7J",
|
||||
"3": "user_3AclwYNQel4ZU9gIhTeStiF1Ze6",
|
||||
"4": "user_3AclwYrAL1BHDdL3WX8IhZktQN4",
|
||||
"5": "user_3Aclwk98pbn7UMCwJtUNJCvDluj",
|
||||
"6": "user_3AclwgmspnQjXqsqSgxbM5Bibqj",
|
||||
"7": "user_3AclwhuDRVreoGet0J0uuV1kC8E",
|
||||
"8": "user_3AclwnpM8BXNEJPeqnutsmVWMho",
|
||||
"9": "user_3Aclwp8KhfBigj2v1dBhnAcEZR6",
|
||||
"10": "user_3AclwnecWiKC7tTa5d2lbqQtBI4",
|
||||
"11": "user_3AclwvZ3xeaPpIee1GZSaF0ZcjZ",
|
||||
"12": "user_3Aclx07Hzs19WqTDY5XgkZOlA5Z",
|
||||
"13": "user_3Aclx0waQhbfrqHIuIbBI7xh4sQ",
|
||||
"14": "user_3Aclx1W0bqTDhFm5aXFaWhT3Zpj",
|
||||
"15": "user_3Aclx90O8i0uRp3QhFf4vdGRgJO",
|
||||
"16": "user_3Aclx3Wudlyg6UrLuYVPpisc9Kw",
|
||||
"17": "user_3Aclx1pknqQHygFrrfgBSbQM8P5",
|
||||
"18": "user_3AclxA2diOV37Z9RkTkFFxVRJCI",
|
||||
"19": "user_3AclxEYCVHlfshKyPTciQqBStYt",
|
||||
"20": "user_3AclxACCapDzlCapyET2IOl3TMi",
|
||||
"21": "user_3AclxOhxWRx6Wxq2FUoRECA2Irr",
|
||||
"22": "user_3AclxLC8W2o7R6MPkIbNVM4Qltw",
|
||||
"23": "user_3AclxORMxzSDn0gFyODb5hEZZOM",
|
||||
"24": "user_3AclxQSp6TOwDfRhMDfOGrYDnzc",
|
||||
"25": "user_3AclxUWnaRkJilrFTa8KSadPIOQ",
|
||||
"26": "user_3AclxVh9iksSofGVSlHhZuzzP8p",
|
||||
"27": "user_3AclxXf5JQwlyBFRQa3l1J2Z8H7",
|
||||
"28": "user_3AclxXRWh9OG3aOGZ75fxmoIrTy",
|
||||
"29": "user_3Aclxd1tcajIoLs0ss92G93plxc",
|
||||
"30": "user_3AclxlTKEK90s8UxTh2t1kZ8ckq",
|
||||
"31": "user_3AclxitgziRzcyQ6ZrCktA9F7SL",
|
||||
"32": "user_3Aclxl3jUH7ZkLDT60bygOcSXnp",
|
||||
"33": "user_3Aclxn9ZCLy55ov2bwc3OmR61nV",
|
||||
"34": "user_3Aclxqhy4nWJgAziVYw55XC9o3p",
|
||||
"35": "user_3Aclxs3SiQx0F6eAoeZkoieoIRb",
|
||||
"36": "user_3AclxvfvGobbMne72Yxhmu7Fffg",
|
||||
"37": "user_3Aclxu8hSwFVmjUgWVyXDuYDs6Z",
|
||||
"38": "user_3Aclxu20dFV0lzMyydeshUZOEV5",
|
||||
"39": "user_3Acly3gPFSpK7hQmMCJZSAuYeIF",
|
||||
"40": "user_3Acly45oxORkyRFuVfBLXIwNYGU",
|
||||
"41": "user_3Acly8AmTgp5Kwt7wVcJXU3GTYN",
|
||||
"42": "user_3AclyEuWVgcFXYDdX9od3suZOiT",
|
||||
"43": "user_3AclyBfcG4U2GQwIFGf4g2Hrsml",
|
||||
"44": "user_3AclyGTRbrzucyRS67zME9Z97x5",
|
||||
"45": "user_3AclyHWmt9JWT1n19gHmxb4E5pl",
|
||||
"46": "user_3AclyJah0uOBB8CB1QczkiMfq4L",
|
||||
"47": "user_3AclyO2ceOwUYl7f3u7e3kDJE2S",
|
||||
"48": "user_3AclyTZCkT3qO9afGXrYfap7Shu",
|
||||
"49": "user_3AclyRDenLpSPEbgA3naueu3egB",
|
||||
"50": "user_3AclyVSlp4TstXlvS1SMfp6Spl4"
|
||||
},
|
||||
"classes": [
|
||||
{
|
||||
@@ -101,42 +101,53 @@
|
||||
"name": "1A",
|
||||
"gradeId": 1,
|
||||
"capacity": 20,
|
||||
"supervisorId": "user_3AMTkSb5aZsaWlYnCd2x5iImprs"
|
||||
"supervisorId": "user_3AcluevCik3awerLuiRklEiYlJK",
|
||||
"schoolId": "default-school-1"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "2A",
|
||||
"gradeId": 2,
|
||||
"capacity": 20,
|
||||
"supervisorId": "user_3AMTkUkKWrV9QWt9dvD2qOjoxiE"
|
||||
"supervisorId": "user_3AclukmobwQyj1tnS2EpfGIEt6R",
|
||||
"schoolId": "default-school-1"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "3A",
|
||||
"gradeId": 3,
|
||||
"capacity": 20,
|
||||
"supervisorId": "user_3AMTkRjafcujtrgbyS4SNoWFgjh"
|
||||
"supervisorId": "user_3Aclul7evfG5xOADBZnREFuhYJf",
|
||||
"schoolId": "default-school-1"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "4A",
|
||||
"gradeId": 4,
|
||||
"capacity": 20,
|
||||
"supervisorId": "user_3AMTkfb5Y9O7a55cye9iQAHxLAB"
|
||||
"supervisorId": "user_3Aclum88YIVFMJy42nhED1n0sYr",
|
||||
"schoolId": "default-school-1"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "5A",
|
||||
"gradeId": 5,
|
||||
"capacity": 20,
|
||||
"supervisorId": "user_3AMTkaTAmH3VOUCcxgeCfSTaaIX"
|
||||
"supervisorId": "user_3AclusjcjWN31nZipvNmfMnxliI",
|
||||
"schoolId": "default-school-1"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"name": "6A",
|
||||
"gradeId": 6,
|
||||
"capacity": 20,
|
||||
"supervisorId": "user_3AMTkSb5aZsaWlYnCd2x5iImprs"
|
||||
"supervisorId": "user_3AcluevCik3awerLuiRklEiYlJK",
|
||||
"schoolId": "default-school-1"
|
||||
}
|
||||
]
|
||||
],
|
||||
"defaultSchoolId": "default-school-1",
|
||||
"independentTeacherId": "user_3AclvGojyeTkQjCvNa11lqR5Xd8",
|
||||
"independentSchoolId": "independent-school-1",
|
||||
"agencyTeacherId": "user_3AclvKuqUVtfwyWyuhN8cTo6CuY",
|
||||
"agencySchoolId": "agency-school-1"
|
||||
}
|
||||
+602
-28
@@ -31,22 +31,335 @@ async function cleanSupabase() {
|
||||
console.log("Cleaning up Supabase tables...");
|
||||
const tables = [
|
||||
"Result", "Assignment", "Exam", "Attendance", "Event", "Announcement",
|
||||
"Lesson", "TeacherSubject", "Student", "Teacher", "Parent", "Class", "Subject", "Grade"
|
||||
"Lesson", "TeacherSchool", "TeacherSubject", "StudentClass", "Student", "Teacher", "Parent", "Class", "Subject", "Grade", "School", "Admin"
|
||||
];
|
||||
for (const table of tables) {
|
||||
await supabase.from(table).delete().neq("id", "0" as any);
|
||||
}
|
||||
}
|
||||
|
||||
async function seedAdmin() {
|
||||
console.log("Syncing Admin...");
|
||||
type AdminSeedInfo = {
|
||||
adminId: string;
|
||||
defaultSchoolId: string;
|
||||
};
|
||||
|
||||
async function seedAdmin(): Promise<AdminSeedInfo | null> {
|
||||
console.log("Syncing Admin and Creating Default School...");
|
||||
const clerk = clerkClient();
|
||||
const users = await clerk.users.getUserList({ limit: 100 });
|
||||
const adminUser = users.data.find(u => u.username === "admin" || u.emailAddresses[0]?.emailAddress?.includes("admin"));
|
||||
|
||||
if (adminUser) {
|
||||
await supabase.from("Admin").upsert({ id: adminUser.id, username: adminUser.username || "admin" });
|
||||
console.log(`Synced Admin ID: ${adminUser.id}`);
|
||||
const defaultSchoolId = "default-school-1";
|
||||
await supabase.from("School").upsert({
|
||||
id: defaultSchoolId,
|
||||
name: "Lama Academy",
|
||||
type: "MANAGED",
|
||||
adminId: adminUser.id
|
||||
});
|
||||
|
||||
await supabase.from("Admin").upsert({
|
||||
id: adminUser.id,
|
||||
username: adminUser.username || "admin",
|
||||
schoolId: defaultSchoolId,
|
||||
});
|
||||
console.log(
|
||||
`Synced Admin ID: ${adminUser.id} and School ID: ${defaultSchoolId}`,
|
||||
);
|
||||
return { adminId: adminUser.id, defaultSchoolId };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Parse a CSV line respecting double-quoted fields (handles commas inside quotes). */
|
||||
function parseCsvLine(line: string): string[] {
|
||||
const trimmed = line.replace(/\r$/, "").trim();
|
||||
if (!trimmed) return [];
|
||||
const result: string[] = [];
|
||||
let current = "";
|
||||
let inQuotes = false;
|
||||
for (let i = 0; i < trimmed.length; i++) {
|
||||
const c = trimmed[i];
|
||||
if (c === '"') {
|
||||
if (inQuotes && trimmed[i + 1] === '"') {
|
||||
current += '"';
|
||||
i++;
|
||||
} else {
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
} else if (c === "," && !inQuotes) {
|
||||
result.push(current.trim());
|
||||
current = "";
|
||||
} else {
|
||||
current += c;
|
||||
}
|
||||
}
|
||||
result.push(current.trim());
|
||||
return result;
|
||||
}
|
||||
|
||||
async function seedSchoolDirectory(adminId: string) {
|
||||
try {
|
||||
console.log("Seeding School directory from school_data.csv...");
|
||||
const csvPath = path.join(process.cwd(), "school_data.csv");
|
||||
if (!fs.existsSync(csvPath)) {
|
||||
console.log("school_data.csv not found. Skipping school directory seed.");
|
||||
return;
|
||||
}
|
||||
|
||||
const raw = fs.readFileSync(csvPath, "utf-8");
|
||||
const lines = raw.split(/\r?\n/).filter((l) => l.trim().length > 0);
|
||||
if (lines.length <= 1) {
|
||||
console.log("school_data.csv has no data rows. Skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
const header = parseCsvLine(lines[0]);
|
||||
const idxUrn = header.indexOf("URN");
|
||||
const idxName = header.indexOf("EstablishmentName");
|
||||
const idxStatus = header.indexOf("EstablishmentStatus (name)");
|
||||
const idxTypeGroup = header.indexOf("EstablishmentTypeGroup (name)");
|
||||
|
||||
if (idxUrn === -1 || idxName === -1 || idxStatus === -1 || idxTypeGroup === -1) {
|
||||
console.log("Expected columns not found in school_data.csv header. Skipping.");
|
||||
return;
|
||||
}
|
||||
|
||||
const schools: { id: string; name: string; type: string; adminId: string }[] = [];
|
||||
|
||||
const MAX_ROWS = 500; // limit for local dev to avoid huge inserts
|
||||
const dataLines = lines.slice(1, 1 + MAX_ROWS);
|
||||
|
||||
for (const line of dataLines) {
|
||||
const cols = parseCsvLine(line);
|
||||
if (!cols.length) continue;
|
||||
|
||||
const status = cols[idxStatus];
|
||||
if (status !== "Open") continue;
|
||||
|
||||
const urn = cols[idxUrn];
|
||||
const name = cols[idxName];
|
||||
const typeGroup = cols[idxTypeGroup] || "";
|
||||
|
||||
if (!urn || !name) continue;
|
||||
|
||||
const schoolType =
|
||||
/independent/i.test(typeGroup) ? "INDEPENDENT" : "MANAGED";
|
||||
|
||||
schools.push({
|
||||
id: urn.toString(),
|
||||
name,
|
||||
type: schoolType,
|
||||
adminId,
|
||||
});
|
||||
}
|
||||
|
||||
if (schools.length === 0) {
|
||||
console.log("No open schools found to seed from CSV.");
|
||||
return;
|
||||
}
|
||||
|
||||
const { error } = await supabase.from("School").upsert(schools);
|
||||
if (error) {
|
||||
console.error("Error seeding School directory from CSV:", error);
|
||||
} else {
|
||||
console.log(`Seeded/updated ${schools.length} schools from directory.`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to seed School directory from CSV:", err);
|
||||
}
|
||||
}
|
||||
|
||||
async function seedTestTimetableForSchool(
|
||||
schoolId: string,
|
||||
teacherId: string,
|
||||
classId: number,
|
||||
subjectIds: number[],
|
||||
) {
|
||||
try {
|
||||
console.log(`Seeding basic timetable config for school ${schoolId}...`);
|
||||
|
||||
// 1. Ensure AcademicYear and SchoolTimetable exist for this school
|
||||
const { data: existingAy } = await supabase
|
||||
.from("AcademicYear")
|
||||
.select("id")
|
||||
.eq("schoolId", schoolId)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
let academicYearId: number;
|
||||
if (existingAy?.id) {
|
||||
academicYearId = existingAy.id;
|
||||
} else {
|
||||
const { data: newAy, error: ayError } = await supabase
|
||||
.from("AcademicYear")
|
||||
.insert({ schoolId, startYear: 2026, endYear: 2027, name: "2026-2027" })
|
||||
.select("id")
|
||||
.single();
|
||||
if (ayError || !newAy) {
|
||||
console.error("Error seeding AcademicYear for school", schoolId, ayError);
|
||||
return;
|
||||
}
|
||||
academicYearId = newAy.id;
|
||||
}
|
||||
|
||||
const { data: existingSt } = await supabase
|
||||
.from("SchoolTimetable")
|
||||
.select("id")
|
||||
.eq("academicYearId", academicYearId)
|
||||
.eq("schoolId", schoolId)
|
||||
.limit(1)
|
||||
.single();
|
||||
|
||||
let schoolTimetableId: number;
|
||||
if (existingSt?.id) {
|
||||
schoolTimetableId = existingSt.id;
|
||||
} else {
|
||||
const { data: newSt, error: stError } = await supabase
|
||||
.from("SchoolTimetable")
|
||||
.insert({ academicYearId, schoolId, name: "Standard Week" })
|
||||
.select("id")
|
||||
.single();
|
||||
if (stError || !newSt) {
|
||||
console.error("Error seeding SchoolTimetable for school", schoolId, stError);
|
||||
return;
|
||||
}
|
||||
schoolTimetableId = newSt.id;
|
||||
}
|
||||
|
||||
const termStart = new Date("2026-02-23T00:00:00.000Z");
|
||||
const termEnd = new Date("2026-03-27T00:00:00.000Z");
|
||||
|
||||
const { data: term, error: termError } = await supabase
|
||||
.from("Term")
|
||||
.insert({
|
||||
schoolId,
|
||||
academicYearId,
|
||||
name: "Spring Term 2026 (Seeded)",
|
||||
startDate: termStart.toISOString(),
|
||||
endDate: termEnd.toISOString(),
|
||||
})
|
||||
.select()
|
||||
.single();
|
||||
|
||||
if (termError) {
|
||||
console.error("Error seeding term for school", schoolId, termError);
|
||||
return;
|
||||
}
|
||||
|
||||
await supabase.from("Holiday").insert({
|
||||
schoolId,
|
||||
academicYearId,
|
||||
name: "Half Term Break",
|
||||
startDate: "2026-03-09T00:00:00.000Z",
|
||||
endDate: "2026-03-13T23:59:59.000Z",
|
||||
});
|
||||
|
||||
const { data: slots, error: slotError } = await supabase
|
||||
.from("SchoolTimetableSlot")
|
||||
.insert([
|
||||
{
|
||||
schoolId,
|
||||
schoolTimetableId,
|
||||
name: "Period 1",
|
||||
startTime: "09:00",
|
||||
endTime: "10:00",
|
||||
isTeachingSlot: true,
|
||||
position: 1,
|
||||
},
|
||||
{
|
||||
schoolId,
|
||||
schoolTimetableId,
|
||||
name: "Period 2",
|
||||
startTime: "10:15",
|
||||
endTime: "11:15",
|
||||
isTeachingSlot: true,
|
||||
position: 2,
|
||||
},
|
||||
{
|
||||
schoolId,
|
||||
schoolTimetableId,
|
||||
name: "Period 3",
|
||||
startTime: "11:30",
|
||||
endTime: "12:30",
|
||||
isTeachingSlot: true,
|
||||
position: 3,
|
||||
},
|
||||
])
|
||||
.select();
|
||||
|
||||
if (slotError || !slots || slots.length === 0) {
|
||||
console.error("Error seeding timetable slots for school", schoolId, slotError);
|
||||
return;
|
||||
}
|
||||
|
||||
const p1 = slots.find((s: any) => s.name === "Period 1");
|
||||
const p2 = slots.find((s: any) => s.name === "Period 2");
|
||||
const p3 = slots.find((s: any) => s.name === "Period 3");
|
||||
|
||||
if (!p1 || !p2 || !p3) {
|
||||
console.error("Missing seeded slots for school", schoolId);
|
||||
return;
|
||||
}
|
||||
|
||||
const { data: templates, error: templateError } = await supabase
|
||||
.from("TeacherTimetableTemplate")
|
||||
.insert({
|
||||
schoolId,
|
||||
schoolTimetableId,
|
||||
name: "Default Weekly Template (Seeded)",
|
||||
teacherId,
|
||||
})
|
||||
.select();
|
||||
|
||||
if (templateError || !templates || templates.length === 0) {
|
||||
console.error("Error seeding timetable template for school", schoolId, templateError);
|
||||
return;
|
||||
}
|
||||
|
||||
const templateId = templates[0].id as number;
|
||||
const [subjectA, subjectB] = subjectIds;
|
||||
|
||||
const entries = [
|
||||
{
|
||||
teacherTimetableTemplateId: templateId,
|
||||
schoolTimetableSlotId: p1.id,
|
||||
classId,
|
||||
subjectId: subjectA,
|
||||
dayOfWeek: 1,
|
||||
},
|
||||
{
|
||||
teacherTimetableTemplateId: templateId,
|
||||
schoolTimetableSlotId: p2.id,
|
||||
classId,
|
||||
subjectId: subjectB,
|
||||
dayOfWeek: 1,
|
||||
},
|
||||
{
|
||||
teacherTimetableTemplateId: templateId,
|
||||
schoolTimetableSlotId: p1.id,
|
||||
classId,
|
||||
subjectId: subjectB,
|
||||
dayOfWeek: 3,
|
||||
},
|
||||
{
|
||||
teacherTimetableTemplateId: templateId,
|
||||
schoolTimetableSlotId: p3.id,
|
||||
classId,
|
||||
subjectId: subjectA,
|
||||
dayOfWeek: 5,
|
||||
},
|
||||
];
|
||||
|
||||
const { error: entryError } = await supabase
|
||||
.from("TeacherTimetableEntry")
|
||||
.insert(entries);
|
||||
|
||||
if (entryError) {
|
||||
console.error("Error seeding timetable entries for school", schoolId, entryError);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to seed timetable config for school", schoolId, err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,27 +368,37 @@ async function main() {
|
||||
const clerk = clerkClient();
|
||||
await cleanClerk();
|
||||
await cleanSupabase();
|
||||
await seedAdmin();
|
||||
const adminInfo = await seedAdmin();
|
||||
|
||||
if (!adminInfo) {
|
||||
console.error("No Admin user found. Seed aborted.");
|
||||
return;
|
||||
}
|
||||
|
||||
const { adminId, defaultSchoolId } = adminInfo;
|
||||
|
||||
// Populate School directory from CSV (for My Schools / selection)
|
||||
await seedSchoolDirectory(adminId);
|
||||
|
||||
console.log("Seeding Grades and Subjects...");
|
||||
const grades = [1, 2, 3, 4, 5, 6].map((level) => ({ id: level, level }));
|
||||
await supabase.from("Grade").insert(grades);
|
||||
|
||||
const subjectsArray = [
|
||||
{ id: 1, name: "Mathematics" },
|
||||
{ id: 2, name: "Science" },
|
||||
{ id: 3, name: "English" },
|
||||
{ id: 4, name: "History" },
|
||||
{ id: 5, name: "Geography" },
|
||||
{ id: 6, name: "Physics" },
|
||||
{ id: 7, name: "Chemistry" },
|
||||
{ id: 8, name: "Biology" },
|
||||
{ id: 9, name: "Computer Science" },
|
||||
{ id: 10, name: "Art" },
|
||||
{ id: 1, name: "Mathematics", schoolId: defaultSchoolId },
|
||||
{ id: 2, name: "Science", schoolId: defaultSchoolId },
|
||||
{ id: 3, name: "English", schoolId: defaultSchoolId },
|
||||
{ id: 4, name: "History", schoolId: defaultSchoolId },
|
||||
{ id: 5, name: "Geography", schoolId: defaultSchoolId },
|
||||
{ id: 6, name: "Physics", schoolId: defaultSchoolId },
|
||||
{ id: 7, name: "Chemistry", schoolId: defaultSchoolId },
|
||||
{ id: 8, name: "Biology", schoolId: defaultSchoolId },
|
||||
{ id: 9, name: "Computer Science", schoolId: defaultSchoolId },
|
||||
{ id: 10, name: "Art", schoolId: defaultSchoolId },
|
||||
];
|
||||
await supabase.from("Subject").insert(subjectsArray);
|
||||
|
||||
console.log("Creating 15 Teachers...");
|
||||
console.log("Creating 15 Managed Teachers in Default School...");
|
||||
const teacherMap: Record<number, string> = {};
|
||||
for (let i = 1; i <= 15; i++) {
|
||||
const user = await clerk.users.createUser({
|
||||
@@ -100,23 +423,264 @@ async function main() {
|
||||
birthday: "1996-02-27T00:26:35.280Z"
|
||||
});
|
||||
|
||||
await supabase.from("TeacherSchool").insert({
|
||||
teacherId: user.id,
|
||||
schoolId: defaultSchoolId,
|
||||
isManaged: true
|
||||
});
|
||||
|
||||
await supabase.from("TeacherSubject").insert([
|
||||
{ subjectId: (i % 10) + 1, teacherId: user.id, isPrimary: true },
|
||||
{ subjectId: ((i + 1) % 10) + 1, teacherId: user.id }
|
||||
]);
|
||||
}
|
||||
|
||||
console.log("Creating 6 Classes...");
|
||||
console.log("Creating Independent Teacher & Test School...");
|
||||
const independentUser = await clerk.users.createUser({
|
||||
username: "independent1",
|
||||
password: PASSWORD,
|
||||
firstName: "Indy",
|
||||
lastName: "Teacher",
|
||||
publicMetadata: { role: "teacher", teacherType: "INDEPENDENT" },
|
||||
});
|
||||
|
||||
await supabase.from("Teacher").insert({
|
||||
id: independentUser.id,
|
||||
username: "independent1",
|
||||
name: "Indy",
|
||||
surname: "Teacher",
|
||||
email: "[email protected]",
|
||||
phone: "123-456-7890",
|
||||
address: "Independent Street 1",
|
||||
bloodType: "A+",
|
||||
sex: "FEMALE",
|
||||
birthday: "1990-01-01T00:00:00.000Z",
|
||||
});
|
||||
|
||||
const independentSchoolId = "independent-school-1";
|
||||
await supabase.from("School").upsert({
|
||||
id: independentSchoolId,
|
||||
name: "Independent School 1",
|
||||
type: "INDEPENDENT",
|
||||
adminId: independentUser.id,
|
||||
});
|
||||
|
||||
await supabase.from("TeacherSchool").insert({
|
||||
teacherId: independentUser.id,
|
||||
schoolId: independentSchoolId,
|
||||
isManaged: false,
|
||||
});
|
||||
|
||||
// Optional: basic schedule indicating this teacher works at their independent school on weekdays
|
||||
await supabase.from("TeacherSchoolSchedule").insert({
|
||||
teacherId: independentUser.id,
|
||||
schoolId: independentSchoolId,
|
||||
startDate: "2026-01-01T00:00:00.000Z",
|
||||
endDate: "2026-12-31T00:00:00.000Z",
|
||||
daysOfWeek: [1, 2, 3, 4, 5],
|
||||
});
|
||||
|
||||
const independentSubjects = [
|
||||
{ id: 1001, name: "Indy Mathematics", schoolId: independentSchoolId },
|
||||
{ id: 1002, name: "Indy English", schoolId: independentSchoolId },
|
||||
];
|
||||
await supabase.from("Subject").insert(independentSubjects);
|
||||
|
||||
await supabase.from("TeacherSubject").insert([
|
||||
{ subjectId: 1001, teacherId: independentUser.id, isPrimary: true },
|
||||
{ subjectId: 1002, teacherId: independentUser.id },
|
||||
]);
|
||||
|
||||
console.log("Creating Agency Teacher & Test Agency School...");
|
||||
const agencyUser = await clerk.users.createUser({
|
||||
username: "agency1",
|
||||
password: PASSWORD,
|
||||
firstName: "Agen",
|
||||
lastName: "Teacher",
|
||||
publicMetadata: { role: "teacher", teacherType: "AGENCY" },
|
||||
});
|
||||
|
||||
await supabase.from("Teacher").insert({
|
||||
id: agencyUser.id,
|
||||
username: "agency1",
|
||||
name: "Agen",
|
||||
surname: "Teacher",
|
||||
email: "[email protected]",
|
||||
phone: "987-654-3210",
|
||||
address: "Agency Road 1",
|
||||
bloodType: "B+",
|
||||
sex: "MALE",
|
||||
birthday: "1988-05-15T00:00:00.000Z",
|
||||
});
|
||||
|
||||
const agencySchoolId = "agency-school-1";
|
||||
await supabase.from("School").upsert({
|
||||
id: agencySchoolId,
|
||||
name: "Agency School 1",
|
||||
type: "AGENCY",
|
||||
adminId: agencyUser.id,
|
||||
});
|
||||
|
||||
await supabase.from("TeacherSchool").insert({
|
||||
teacherId: agencyUser.id,
|
||||
schoolId: agencySchoolId,
|
||||
isManaged: false,
|
||||
});
|
||||
|
||||
await supabase.from("TeacherSchoolSchedule").insert({
|
||||
teacherId: agencyUser.id,
|
||||
schoolId: agencySchoolId,
|
||||
startDate: "2026-01-01T00:00:00.000Z",
|
||||
endDate: "2026-12-31T00:00:00.000Z",
|
||||
daysOfWeek: [1, 3, 5], // Example: Mon, Wed, Fri
|
||||
});
|
||||
|
||||
const agencySubjects = [
|
||||
{ id: 1003, name: "Agency Mathematics", schoolId: agencySchoolId },
|
||||
{ id: 1004, name: "Agency English", schoolId: agencySchoolId },
|
||||
];
|
||||
await supabase.from("Subject").insert(agencySubjects);
|
||||
|
||||
await supabase.from("TeacherSubject").insert([
|
||||
{ subjectId: 1003, teacherId: agencyUser.id, isPrimary: true },
|
||||
{ subjectId: 1004, teacherId: agencyUser.id },
|
||||
]);
|
||||
|
||||
console.log("Creating additional Independent & Agency test teachers (blank setups)...");
|
||||
const independentUser2 = await clerk.users.createUser({
|
||||
username: "independent2",
|
||||
password: PASSWORD,
|
||||
firstName: "Indy",
|
||||
lastName: "Teacher2",
|
||||
publicMetadata: { role: "teacher", teacherType: "INDEPENDENT" },
|
||||
});
|
||||
|
||||
await supabase.from("Teacher").insert({
|
||||
id: independentUser2.id,
|
||||
username: "independent2",
|
||||
name: "Indy",
|
||||
surname: "Teacher2",
|
||||
email: "[email protected]",
|
||||
phone: "123-456-7891",
|
||||
address: "Independent Street 2",
|
||||
bloodType: "A+",
|
||||
sex: "MALE",
|
||||
birthday: "1992-01-01T00:00:00.000Z",
|
||||
});
|
||||
|
||||
const independentBlankSchoolId = "independent-school-2";
|
||||
await supabase.from("School").upsert({
|
||||
id: independentBlankSchoolId,
|
||||
name: "Independent School 2 (Blank)",
|
||||
type: "INDEPENDENT",
|
||||
adminId: independentUser2.id,
|
||||
});
|
||||
|
||||
await supabase.from("TeacherSchool").insert({
|
||||
teacherId: independentUser2.id,
|
||||
schoolId: independentBlankSchoolId,
|
||||
isManaged: false,
|
||||
});
|
||||
|
||||
await supabase.from("TeacherSchoolSchedule").insert({
|
||||
teacherId: independentUser2.id,
|
||||
schoolId: independentBlankSchoolId,
|
||||
startDate: "2026-01-01T00:00:00.000Z",
|
||||
endDate: "2026-12-31T00:00:00.000Z",
|
||||
daysOfWeek: [1, 2, 3, 4, 5],
|
||||
});
|
||||
|
||||
const agencyUser2 = await clerk.users.createUser({
|
||||
username: "agency2",
|
||||
password: PASSWORD,
|
||||
firstName: "Agen",
|
||||
lastName: "Teacher2",
|
||||
publicMetadata: { role: "teacher", teacherType: "AGENCY" },
|
||||
});
|
||||
|
||||
await supabase.from("Teacher").insert({
|
||||
id: agencyUser2.id,
|
||||
username: "agency2",
|
||||
name: "Agen",
|
||||
surname: "Teacher2",
|
||||
email: "[email protected]",
|
||||
phone: "987-654-3211",
|
||||
address: "Agency Road 2",
|
||||
bloodType: "B+",
|
||||
sex: "FEMALE",
|
||||
birthday: "1989-05-15T00:00:00.000Z",
|
||||
});
|
||||
|
||||
const agencyBlankSchoolId = "agency-school-2";
|
||||
await supabase.from("School").upsert({
|
||||
id: agencyBlankSchoolId,
|
||||
name: "Agency School 2 (Blank)",
|
||||
type: "AGENCY",
|
||||
adminId: agencyUser2.id,
|
||||
});
|
||||
|
||||
await supabase.from("TeacherSchool").insert({
|
||||
teacherId: agencyUser2.id,
|
||||
schoolId: agencyBlankSchoolId,
|
||||
isManaged: false,
|
||||
});
|
||||
|
||||
await supabase.from("TeacherSchoolSchedule").insert({
|
||||
teacherId: agencyUser2.id,
|
||||
schoolId: agencyBlankSchoolId,
|
||||
startDate: "2026-01-01T00:00:00.000Z",
|
||||
endDate: "2026-12-31T00:00:00.000Z",
|
||||
daysOfWeek: [2, 4], // Example: Tue, Thu
|
||||
});
|
||||
|
||||
console.log("Creating 6 Classes for default school...");
|
||||
const classesArray = [
|
||||
{ id: 1, name: "1A", gradeId: 1, capacity: 20, supervisorId: teacherMap[1] },
|
||||
{ id: 2, name: "2A", gradeId: 2, capacity: 20, supervisorId: teacherMap[2] },
|
||||
{ id: 3, name: "3A", gradeId: 3, capacity: 20, supervisorId: teacherMap[3] },
|
||||
{ id: 4, name: "4A", gradeId: 4, capacity: 20, supervisorId: teacherMap[4] },
|
||||
{ id: 5, name: "5A", gradeId: 5, capacity: 20, supervisorId: teacherMap[5] },
|
||||
{ id: 6, name: "6A", gradeId: 6, capacity: 20, supervisorId: teacherMap[1] },
|
||||
{ id: 1, name: "1A", gradeId: 1, capacity: 20, supervisorId: teacherMap[1], schoolId: defaultSchoolId },
|
||||
{ id: 2, name: "2A", gradeId: 2, capacity: 20, supervisorId: teacherMap[2], schoolId: defaultSchoolId },
|
||||
{ id: 3, name: "3A", gradeId: 3, capacity: 20, supervisorId: teacherMap[3], schoolId: defaultSchoolId },
|
||||
{ id: 4, name: "4A", gradeId: 4, capacity: 20, supervisorId: teacherMap[4], schoolId: defaultSchoolId },
|
||||
{ id: 5, name: "5A", gradeId: 5, capacity: 20, supervisorId: teacherMap[5], schoolId: defaultSchoolId },
|
||||
{ id: 6, name: "6A", gradeId: 6, capacity: 20, supervisorId: teacherMap[1], schoolId: defaultSchoolId },
|
||||
];
|
||||
await supabase.from("Class").insert(classesArray);
|
||||
|
||||
console.log("Creating test classes for Independent and Agency schools...");
|
||||
const independentClassId = 1001;
|
||||
const agencyClassId = 2001;
|
||||
|
||||
await supabase.from("Class").insert([
|
||||
{
|
||||
id: independentClassId,
|
||||
name: "Indy Class 1",
|
||||
gradeId: 1,
|
||||
capacity: 25,
|
||||
supervisorId: independentUser.id,
|
||||
schoolId: independentSchoolId,
|
||||
},
|
||||
{
|
||||
id: agencyClassId,
|
||||
name: "Agency Class 1",
|
||||
gradeId: 1,
|
||||
capacity: 25,
|
||||
supervisorId: agencyUser.id,
|
||||
schoolId: agencySchoolId,
|
||||
},
|
||||
]);
|
||||
|
||||
console.log("Seeding basic timetable config for Independent and Agency test schools...");
|
||||
await seedTestTimetableForSchool(
|
||||
independentSchoolId,
|
||||
independentUser.id,
|
||||
1001,
|
||||
[1001, 1002],
|
||||
);
|
||||
await seedTestTimetableForSchool(
|
||||
agencySchoolId,
|
||||
agencyUser.id,
|
||||
2001,
|
||||
[1003, 1004],
|
||||
);
|
||||
|
||||
console.log("Creating 25 Parents...");
|
||||
const parentMap: Record<number, string> = {};
|
||||
for (let i = 1; i <= 25; i++) {
|
||||
@@ -136,7 +700,8 @@ async function main() {
|
||||
surname: `PSurname${i}`,
|
||||
email: `parent${i}@example.com`,
|
||||
phone: `123-456-789${i}`,
|
||||
address: `Address${i}`
|
||||
address: `Address${i}`,
|
||||
schoolId: defaultSchoolId
|
||||
});
|
||||
}
|
||||
|
||||
@@ -165,8 +730,12 @@ async function main() {
|
||||
sex: i % 2 === 0 ? "MALE" : "FEMALE",
|
||||
parentId: parentMap[(i % 25) + 1],
|
||||
gradeId: classInfo.gradeId,
|
||||
classId: classInfo.id,
|
||||
birthday: "2016-02-27T00:26:35.281Z"
|
||||
birthday: "2016-02-27T00:26:35.281Z",
|
||||
schoolId: defaultSchoolId
|
||||
});
|
||||
await supabase.from("StudentClass").insert({
|
||||
studentId: user.id,
|
||||
classId: classInfo.id
|
||||
});
|
||||
}
|
||||
|
||||
@@ -176,7 +745,12 @@ async function main() {
|
||||
teacherMap,
|
||||
parentMap,
|
||||
studentMap,
|
||||
classes: classesArray
|
||||
classes: classesArray,
|
||||
defaultSchoolId,
|
||||
independentTeacherId: independentUser.id,
|
||||
independentSchoolId,
|
||||
agencyTeacherId: agencyUser.id,
|
||||
agencySchoolId,
|
||||
};
|
||||
fs.writeFileSync(seedDataPath, JSON.stringify(seedData, null, 2));
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ async function main() {
|
||||
throw new Error("seed-data.json not found! Please run `npm run seed:users` first.");
|
||||
}
|
||||
const data = JSON.parse(fs.readFileSync(seedDataPath, "utf-8"));
|
||||
const { teacherMap, studentMap, classes } = data;
|
||||
const { teacherMap, studentMap, classes, defaultSchoolId } = data;
|
||||
|
||||
console.log("Cleaning old Schedule & Attendance data...");
|
||||
const tablesToClean = ["LessonWhiteboard", "Attendance", "Result", "Assignment", "Exam", "Lesson"];
|
||||
@@ -142,12 +142,12 @@ async function main() {
|
||||
lessonsData.push({
|
||||
id: lessonIdCounter,
|
||||
name: `${classInfo.name} ${subjectKey} (${dayName})`,
|
||||
day: dayName,
|
||||
startTime: startTime.toISOString(),
|
||||
endTime: endTime.toISOString(),
|
||||
subjectId: subjectId,
|
||||
classId: classInfo.id,
|
||||
teacherId: teacherId
|
||||
teacherId: teacherId,
|
||||
schoolId: defaultSchoolId
|
||||
});
|
||||
|
||||
whiteboardsData.push({
|
||||
@@ -161,7 +161,8 @@ async function main() {
|
||||
title: `${subjectKey} Assessment`,
|
||||
startTime: startTime.toISOString(),
|
||||
endTime: endTime.toISOString(),
|
||||
lessonId: lessonIdCounter
|
||||
lessonId: lessonIdCounter,
|
||||
schoolId: defaultSchoolId
|
||||
});
|
||||
|
||||
// Only give results to a subset to prevent table explosions
|
||||
@@ -170,7 +171,8 @@ async function main() {
|
||||
id: resultIdCounter++,
|
||||
score: 60 + Math.floor(Math.random() * 41), // 60-100
|
||||
studentId: sId,
|
||||
examId: examIdCounter
|
||||
examId: examIdCounter,
|
||||
schoolId: defaultSchoolId
|
||||
});
|
||||
}
|
||||
examIdCounter++;
|
||||
@@ -183,7 +185,8 @@ async function main() {
|
||||
title: `${subjectKey} Practice`,
|
||||
startDate: startTime.toISOString(),
|
||||
dueDate: new Date(startTime.getTime() + 7 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
lessonId: lessonIdCounter
|
||||
lessonId: lessonIdCounter,
|
||||
schoolId: defaultSchoolId
|
||||
});
|
||||
}
|
||||
|
||||
@@ -195,7 +198,8 @@ async function main() {
|
||||
date: startTime.toISOString(),
|
||||
present: Math.random() < CONFIG.attendanceProbability,
|
||||
studentId: sId,
|
||||
lessonId: lessonIdCounter
|
||||
lessonId: lessonIdCounter,
|
||||
schoolId: defaultSchoolId
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -217,6 +221,12 @@ async function main() {
|
||||
await insertInChunks("Result", resultsData);
|
||||
await insertInChunks("Attendance", attendancesData);
|
||||
|
||||
// Keep Lesson id sequence in sync so "Generate lessons" from templates does not hit duplicate key
|
||||
const { error: syncErr } = await supabase.rpc("sync_lesson_id_sequence");
|
||||
if (syncErr) {
|
||||
console.warn("Lesson sequence sync skipped (run migrations if you use Generate lessons):", syncErr.message);
|
||||
}
|
||||
|
||||
console.log(`\n✅ Timeline successfully generated!`);
|
||||
console.log(`- Lessons: ${lessonsData.length}`);
|
||||
console.log(`- Whiteboards: ${whiteboardsData.length}`);
|
||||
|
||||
Reference in New Issue
Block a user