feat(cohorts): rename Programs to Cohorts with data migration (#694)

* feat(cohorts): rename Programs to Cohorts with data migration

- Add cohort database tables and Drizzle migration alongside legacy program tables
- Introduce migrate-programs-to-cohorts script to copy existing program data safely
- Rename API routes (/cohort), services, queries, validation, and error codes
- Rename dashboard feature module, routes (/cohorts), navigation, and translations
- Update docs, emails, and internal compliance cron endpoints for cohort terminology
- Keep legacy program tables in place for rollback until explicitly removed

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

* fix(db): restore migrate:answer-data script alongside cohort migration

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

* fix(db): cast program enums when migrating data to cohort tables

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

* fix(db): truncate cohort tables before program-to-cohort copy

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

* fix(db): report accurate row counts in programs-to-cohorts migration

Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Rotimi Best <rotimi-best@users.noreply.github.com>
This commit is contained in:
Rotimi Best
2026-07-02 12:10:31 +01:00
committed by GitHub
co-authored by Rotimi Best Cursor Agent
parent fe9f8c441f
commit ec61bfe7d9
115 changed files with 19703 additions and 6046 deletions
+16 -16
View File
@@ -157,22 +157,22 @@ export const ErrorCodes = {
// Token auth admin errors
TOKEN_AUTH_ALREADY_EXISTS: 'TOKEN_AUTH_ALREADY_EXISTS',
// Program errors
PROGRAM_NOT_FOUND: 'PROGRAM_NOT_FOUND',
PROGRAM_FORBIDDEN: 'PROGRAM_FORBIDDEN',
PROGRAM_CREATE_FAILED: 'PROGRAM_CREATE_FAILED',
PROGRAM_UPDATE_FAILED: 'PROGRAM_UPDATE_FAILED',
PROGRAM_DELETE_FAILED: 'PROGRAM_DELETE_FAILED',
COURSE_ALREADY_IN_PROGRAM: 'COURSE_ALREADY_IN_PROGRAM',
MEMBER_ALREADY_IN_PROGRAM: 'MEMBER_ALREADY_IN_PROGRAM',
PROGRAM_MEMBER_NOT_FOUND: 'PROGRAM_MEMBER_NOT_FOUND',
PROGRAM_NEWSFEED_NOT_FOUND: 'PROGRAM_NEWSFEED_NOT_FOUND',
PROGRAM_NEWSFEED_COMMENT_NOT_FOUND: 'PROGRAM_NEWSFEED_COMMENT_NOT_FOUND',
PROGRAM_MEMBER_CHECK_FAILED: 'PROGRAM_MEMBER_CHECK_FAILED',
PROGRAM_GOAL_NOT_FOUND: 'PROGRAM_GOAL_NOT_FOUND',
PROGRAM_GOAL_CREATE_FAILED: 'PROGRAM_GOAL_CREATE_FAILED',
PROGRAM_GOAL_UPDATE_FAILED: 'PROGRAM_GOAL_UPDATE_FAILED',
PROGRAM_GOAL_DELETE_FAILED: 'PROGRAM_GOAL_DELETE_FAILED',
// Cohort errors
COHORT_NOT_FOUND: 'COHORT_NOT_FOUND',
COHORT_FORBIDDEN: 'COHORT_FORBIDDEN',
COHORT_CREATE_FAILED: 'COHORT_CREATE_FAILED',
COHORT_UPDATE_FAILED: 'COHORT_UPDATE_FAILED',
COHORT_DELETE_FAILED: 'COHORT_DELETE_FAILED',
COURSE_ALREADY_IN_COHORT: 'COURSE_ALREADY_IN_COHORT',
MEMBER_ALREADY_IN_COHORT: 'MEMBER_ALREADY_IN_COHORT',
COHORT_MEMBER_NOT_FOUND: 'COHORT_MEMBER_NOT_FOUND',
COHORT_NEWSFEED_NOT_FOUND: 'COHORT_NEWSFEED_NOT_FOUND',
COHORT_NEWSFEED_COMMENT_NOT_FOUND: 'COHORT_NEWSFEED_COMMENT_NOT_FOUND',
COHORT_MEMBER_CHECK_FAILED: 'COHORT_MEMBER_CHECK_FAILED',
COHORT_GOAL_NOT_FOUND: 'COHORT_GOAL_NOT_FOUND',
COHORT_GOAL_CREATE_FAILED: 'COHORT_GOAL_CREATE_FAILED',
COHORT_GOAL_UPDATE_FAILED: 'COHORT_GOAL_UPDATE_FAILED',
COHORT_GOAL_DELETE_FAILED: 'COHORT_GOAL_DELETE_FAILED',
// AI assistant chat
NO_MESSAGES_TO_COMPACT: 'NO_MESSAGES_TO_COMPACT',