feat: implement onboarding process and enrollment status tracking for users
This commit is contained in:
@@ -3,17 +3,36 @@ import { callLLM, cachedSystem } from './llm';
|
||||
import { EMIT_CURRICULUM_SCHEDULE_TOOL, EMIT_TOPIC_ENRICHMENT_TOOL } from './llmTools';
|
||||
|
||||
/**
|
||||
* Get the current curriculum week (1-26) based on an ISO week number.
|
||||
* Personal weeks since enrollment, starting at 1.
|
||||
* Cycle is purely relative: week 1 = first 7 days after start_date.
|
||||
* Returns 0 if the user has not yet enrolled.
|
||||
*/
|
||||
export function getCurriculumWeek(isoWeekNumber) {
|
||||
return ((isoWeekNumber - 1) % 26) + 1;
|
||||
export function getPersonalWeekNumber(startedAt, now = new Date()) {
|
||||
if (!startedAt) return 0;
|
||||
const start = startedAt instanceof Date ? startedAt : new Date(startedAt);
|
||||
if (Number.isNaN(start.getTime())) return 0;
|
||||
const elapsedMs = now.getTime() - start.getTime();
|
||||
if (elapsedMs < 0) return 0;
|
||||
const days = Math.floor(elapsedMs / 86_400_000);
|
||||
return Math.floor(days / 7) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current curriculum cycle (1, 2, 3...) based on an ISO week number.
|
||||
* Curriculum slot (1-26) for a given personal week number.
|
||||
* weekNumber is the absolute counter from getPersonalWeekNumber — it loops
|
||||
* through the 26-slot schedule indefinitely.
|
||||
*/
|
||||
export function getCurriculumCycle(isoWeekNumber) {
|
||||
return Math.floor((isoWeekNumber - 1) / 26) + 1;
|
||||
export function getCurriculumWeek(weekNumber) {
|
||||
if (!weekNumber || weekNumber < 1) return 0;
|
||||
return ((weekNumber - 1) % 26) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cycle (1, 2, 3...) for a given personal week number.
|
||||
*/
|
||||
export function getCurriculumCycle(weekNumber) {
|
||||
if (!weekNumber || weekNumber < 1) return 0;
|
||||
return Math.floor((weekNumber - 1) / 26) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -284,16 +303,17 @@ export async function getVersionHistory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the assigned topics and metadata for a given ISO week number.
|
||||
* Get the assigned topics and metadata for a given personal week number.
|
||||
*/
|
||||
export async function getCurrentWeekContent(isoWeekNumber) {
|
||||
export async function getCurrentWeekContent(personalWeekNumber) {
|
||||
const activeVersion = await db.getActiveCurriculumVersion();
|
||||
if (!activeVersion || !activeVersion.schedule) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const weekNumber = getCurriculumWeek(isoWeekNumber);
|
||||
const cycle = getCurriculumCycle(isoWeekNumber);
|
||||
|
||||
const weekNumber = getCurriculumWeek(personalWeekNumber);
|
||||
const cycle = getCurriculumCycle(personalWeekNumber);
|
||||
if (weekNumber < 1) return null;
|
||||
|
||||
const scheduleWeek = activeVersion.schedule.find(w => w.week_number === weekNumber);
|
||||
if (!scheduleWeek) return null;
|
||||
@@ -317,13 +337,14 @@ export async function getCurrentWeekContent(isoWeekNumber) {
|
||||
/**
|
||||
* Track progress for the current cycle based on completed weeks.
|
||||
*/
|
||||
export async function getYearProgress(userId, isoWeekNumber) {
|
||||
export async function getYearProgress(userId, personalWeekNumber) {
|
||||
const activeVersion = await db.getActiveCurriculumVersion();
|
||||
if (!activeVersion) {
|
||||
return { completed: 0, total: 26, percentage: 0 };
|
||||
}
|
||||
|
||||
const currentCycle = getCurriculumCycle(isoWeekNumber);
|
||||
|
||||
const currentCycle = getCurriculumCycle(personalWeekNumber);
|
||||
if (currentCycle < 1) return { completed: 0, total: 26, percentage: 0 };
|
||||
const cycleStartWeek = (currentCycle - 1) * 26 + 1;
|
||||
const cycleEndWeek = currentCycle * 26;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user