fix: replace stale program references (#749)

This commit is contained in:
Rotimi Best
2026-07-13 02:09:57 +01:00
committed by GitHub
parent 484e4fb674
commit 5e8188fbd3
57 changed files with 524 additions and 533 deletions
+10 -10
View File
@@ -105,11 +105,11 @@ async function enrollCohortStudentsInGroups(
return groupMemberRows.length;
}
// ─── Program CRUD ────────────────────────────────────────────────────────────
// ─── Cohort CRUD ─────────────────────────────────────────────────────────────
export async function createCohort(organizationId: string, profileId: string, data: TCreateCohort) {
try {
const description = data.description?.trim() || `A program for ${data.name}`;
const description = data.description?.trim() || `A cohort for ${data.name}`;
return createCohortWithCreatorMembership(
{
@@ -195,7 +195,7 @@ export async function deleteCohort(cohortId: string) {
}
}
// ─── Program Members ─────────────────────────────────────────────────────────
// ─── Cohort Members ──────────────────────────────────────────────────────────
export async function listCohortMembers(cohortId: string) {
try {
@@ -323,7 +323,7 @@ export async function removeCohortMemberService(_cohortId: string, memberId: str
} catch (error) {
if (error instanceof AppError) throw error;
throw new AppError(
error instanceof Error ? error.message : 'Failed to remove program member',
error instanceof Error ? error.message : 'Failed to remove cohort member',
ErrorCodes.INTERNAL_ERROR,
500
);
@@ -360,7 +360,7 @@ export async function getEnrolledCohorts(profileId: string) {
}
}
// ─── Program Courses ─────────────────────────────────────────────────────────
// ─── Cohort Courses ──────────────────────────────────────────────────────────
export async function listCohortCourses(cohortId: string, profileId: string) {
try {
@@ -411,7 +411,7 @@ export async function addCourseToCohortService(cohortId: string, data: TAddCours
} catch (error) {
if (error instanceof AppError) throw error;
throw new AppError(
error instanceof Error ? error.message : 'Failed to add course to program',
error instanceof Error ? error.message : 'Failed to add course to cohort',
ErrorCodes.INTERNAL_ERROR,
500
);
@@ -422,20 +422,20 @@ export async function removeCourseFromCohortService(cohortId: string, courseId:
try {
const deleted = await removeCourseFromCohort(cohortId, courseId);
if (!deleted) {
throw new AppError('Course not found in program', ErrorCodes.NOT_FOUND, 404);
throw new AppError('Course not found in cohort', ErrorCodes.NOT_FOUND, 404);
}
return deleted;
} catch (error) {
if (error instanceof AppError) throw error;
throw new AppError(
error instanceof Error ? error.message : 'Failed to remove course from program',
error instanceof Error ? error.message : 'Failed to remove course from cohort',
ErrorCodes.INTERNAL_ERROR,
500
);
}
}
// ─── Program Newsfeed ────────────────────────────────────────────────────────
// ─── Cohort Newsfeed ─────────────────────────────────────────────────────────
export async function listCohortNewsfeed(cohortId: string, options: { cursor?: string; limit: number }) {
try {
@@ -524,7 +524,7 @@ export async function deleteCohortNewsfeedService(feedId: string) {
}
}
// ─── Program Newsfeed Comments ────────────────────────────────────────────────
// ─── Cohort Newsfeed Comments ────────────────────────────────────────────────
export async function listCohortNewsfeedComments(feedId: string) {
try {
+3 -3
View File
@@ -221,7 +221,7 @@ function decideStatus(args: {
*
* Pulls all student cohort-members, computes a per-learner status, and upserts
* `program_goal_assignment`. Designed to be safe to run repeatedly (idempotent)
* and cheap enough for daily cron over hundreds of programs.
* and cheap enough for daily cron over hundreds of cohorts.
*/
export async function evaluateGoal(goalId: string): Promise<{ evaluated: number }> {
const goal = await getCohortGoalById(goalId);
@@ -316,7 +316,7 @@ export async function evaluateGoal(goalId: string): Promise<{ evaluated: number
}
/**
* Re-evaluate every active goal in a cohort. Used after material program
* Re-evaluate every active goal in a cohort. Used after material cohort
* changes (member added, course added) or by cron sweeps.
*/
export async function evaluateCohortGoals(cohortId: string): Promise<{ evaluated: number }> {
@@ -450,7 +450,7 @@ export async function getMyGoals(profileId: string) {
/**
* Cross-cohort goal roll-up for the org owner. Lists every active goal in the
* org with its per-status counts so the dashboard can group by program.
* org with its per-status counts so the dashboard can group by cohort.
*/
export async function getOrgGoalsOverview(organizationId: string) {
const goals = await getCohortGoalsByOrg(organizationId);
+4 -4
View File
@@ -4,11 +4,11 @@ import type { TInviteStudentsToCohort, TAssignExistingStudentsToCohort } from '@
import { assignAudienceToCourses, importAudienceMembers } from '@api/services/organization/audience';
/**
* Invite students to a single program by email CSV.
* Invite students to a single cohort by email CSV.
*
* Thin wrapper that hardcodes `cohortIds = [cohortId]` and delegates to
* `importAudienceMembers`. Lets a Cohort ADMIN/TUTOR (or org admin) issue org
* invites scoped to *their own* program, without granting org-wide invite rights.
* invites scoped to *their own* cohort, without granting org-wide invite rights.
*/
export async function inviteStudentsToCohort(
cohortId: string,
@@ -35,8 +35,8 @@ export async function inviteStudentsToCohort(
/**
* Assign existing student profiles (already members of the org audience) to a
* single program. Same scoping logic as `inviteStudentsToCohort` — restricted
* to one program at a time so the caller's program-admin permission is enough.
* single cohort. Same scoping logic as `inviteStudentsToCohort` — restricted
* to one cohort at a time so the caller's cohort-admin permission is enough.
*/
export async function assignExistingStudentsToCohort(cohortId: string, data: TAssignExistingStudentsToCohort) {
const cohort = await getCohortById(cohortId);