Add specifications for gamification, generation, and R42 chat services

- Introduced gamification service spec detailing responsibilities, API surface, XP calculation, levels, streaks, badges, milestone cards, and heatmap data.
- Added generation service spec outlining the process for generating micro learning content, including API endpoints, AI call configuration, prompt strategies, and error handling.
- Created R42 chat service spec covering chatbot interactions, retrieval pipeline, prompt construction, response generation, and stateless design principles.
This commit is contained in:
RaymondVerhoef
2026-05-23 18:13:08 +02:00
parent dda20612e9
commit 472685f0d7
62 changed files with 11552 additions and 21 deletions

View File

@@ -0,0 +1,25 @@
import { getPocketBase } from '../lib/pocketbase.js';
export async function applyVersion(newVersionId: string): Promise<void> {
const pb = await getPocketBase();
// Get all employees
const employees = await pb.collection('employee_curriculum_state').getFullList();
for (const emp of employees) {
await pb.collection('employee_curriculum_state').update(emp.id, {
active_version: newVersionId,
});
}
// Supersede old active version
const activeVersions = await pb.collection('curriculum_versions').getFullList({
filter: 'status = "active"',
});
for (const v of activeVersions) {
await pb.collection('curriculum_versions').update(v.id, { status: 'superseded' });
}
// Activate new version
await pb.collection('curriculum_versions').update(newVersionId, { status: 'active' });
}

View File

@@ -0,0 +1,25 @@
import { getPocketBase } from '../lib/pocketbase.js';
/**
* Returns the set of week numbers that are "frozen" for an employee —
* weeks they have already started or completed, derived from their current_week.
* Weeks < current_week are rendered from session_completions and must not be
* replaced by a new curriculum version.
*/
export async function getFrozenWeeks(userId: string): Promise<Set<number>> {
const pb = await getPocketBase();
const records = await pb.collection('employee_curriculum_state').getFullList({
filter: `user = "${userId}"`,
});
const state = records[0];
if (!state) return new Set();
const currentWeek = state['current_week'] as number;
const frozen = new Set<number>();
for (let w = 1; w < currentWeek; w++) {
frozen.add(w);
}
return frozen;
}