feat: productionize learning engine and classroom

This commit is contained in:
inman committed 2026-08-16 21:44:52 +08:00
1 parent 2d04197f3f
commit ba35adfbfa
124 files changed
+9071 -796

No files matched your search

@@ -308,4 +308,57 @@ describe('job resume', () => {
false,
);
});
test('resume refuses a succeeded job without mutating its frozen source result', async () => {
const store = await importStore();
const runner = await importRunner();
await store.createClassroomGenerationJob('job-succeeded', INPUT);
await store.updateClassroomGenerationJob('job-succeeded', {
status: 'succeeded',
step: 'completed',
progress: 100,
message: 'Classroom generation completed',
result: {
classroomId: 'frozen-classroom',
url: 'http://localhost/classroom/frozen-classroom',
scenesCount: 2,
},
});
const before = await store.readClassroomGenerationJob('job-succeeded');
expect(
await runner.resumeClassroomGenerationJob('job-succeeded', 'http://localhost'),
).toBe(false);
expect(await store.readClassroomGenerationJob('job-succeeded')).toEqual(before);
expect(mocks.generateClassroom).not.toHaveBeenCalled();
});
test('resumes a failed job from its persisted input', async () => {
const store = await importStore();
const runner = await importRunner();
await store.createClassroomGenerationJob('job-failed-resume', INPUT);
await store.markClassroomGenerationJobFailed('job-failed-resume', 'provider failed');
mocks.generateClassroom.mockResolvedValueOnce({
id: 'recovered-classroom',
url: 'http://localhost/classroom/recovered-classroom',
scenesCount: 1,
});
expect(
await runner.resumeClassroomGenerationJob('job-failed-resume', 'http://localhost'),
).toBe(true);
expect(await store.readClassroomGenerationJob('job-failed-resume')).toMatchObject({
status: 'queued',
progress: 0,
message: 'Classroom generation job queued (resumed)',
});
await new Promise((resolve) => setTimeout(resolve, 50));
expect(await store.readClassroomGenerationJob('job-failed-resume')).toMatchObject({
status: 'succeeded',
result: { classroomId: 'recovered-classroom' },
});
});
});