Files
openmaic/OpenMAIC/lib/makelore-course/immutability.ts

35 lines
1.5 KiB
TypeScript

import type { CourseRecord } from '@/lib/course-framework/types';
import { readCourseRecord } from '@/lib/course-framework/store';
import { readFrozenLearningPackageRecord } from '@/lib/makelore-course/package';
type CoursePublicationState = Pick<CourseRecord, 'publication' | 'externalPublication'>;
/** A frozen course id is a one-shot immutable product identity. */
export class FrozenLearningCourseMutationError extends Error {
constructor(public readonly courseId: string) {
super(`课程 ${courseId} 已冻结,不能继续生成或重新生成;如需修改,请新建课程`);
this.name = 'FrozenLearningCourseMutationError';
}
}
/**
* Enforce the single immutable-course rule at every source mutation boundary.
*
* The frozen record is authoritative: Works can successfully finalize an
* archive and then fail before writing the later external-publication receipt.
* Legacy publication receipts remain additional evidence for courses created
* before aggregate finalization was introduced.
*/
export async function assertLearningCourseMutable(
courseId: string,
knownRecord?: CoursePublicationState | null,
): Promise<void> {
const [frozen, record] = await Promise.all([
readFrozenLearningPackageRecord(courseId),
knownRecord === undefined ? readCourseRecord(courseId) : Promise.resolve(knownRecord),
]);
if (frozen || record?.publication || record?.externalPublication) {
throw new FrozenLearningCourseMutationError(courseId);
}
}