All checks were successful
Deploy Development / deploy (push) Successful in 44s
Test Suite / pytest-backend (push) Successful in 40s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 12s
Test Suite / k6 /health Baseline (push) Successful in 33s
Test Suite / playwright-tests (push) Successful in 1m13s
- Incremented version to 0.8.185, reflecting the implementation of Phase C3 features. - Introduced the `POST /api/planning/progression-path-suggest` endpoint for generating exercise progression paths. - Enhanced the ExerciseProgressionGraphPanel with a new ExerciseProgressionPathBuilder for reviewing and saving paths. - Updated changelog to document the new capabilities in planning AI functionality.
196 lines
6.3 KiB
JavaScript
196 lines
6.3 KiB
JavaScript
/**
|
|
* Trainingsplanung: Einheiten, Vorlagen, Module, Rahmenprogramme, Dashboard-KPIs.
|
|
* Facade: weiterhin `utils/api.js` (default + Named Exports).
|
|
*/
|
|
import { request } from './client.js'
|
|
|
|
/** Query-Parameter wie GET /api/training-units. */
|
|
export async function listTrainingUnits(filters = {}) {
|
|
const q = new URLSearchParams()
|
|
if (filters.group_id != null && filters.group_id !== '') {
|
|
q.set('group_id', String(filters.group_id))
|
|
}
|
|
if (filters.club_id != null && filters.club_id !== '') {
|
|
q.set('club_id', String(filters.club_id))
|
|
}
|
|
if (filters.start_date) q.set('start_date', filters.start_date)
|
|
if (filters.end_date) q.set('end_date', filters.end_date)
|
|
if (filters.status) q.set('status', filters.status)
|
|
if (filters.debrief_pending === true) q.set('debrief_pending', 'true')
|
|
if (filters.assigned_to_me === true) q.set('assigned_to_me', 'true')
|
|
if (filters.sort) q.set('sort', String(filters.sort))
|
|
if (filters.limit != null && filters.limit !== '') q.set('limit', String(filters.limit))
|
|
if (filters.cursor_planned_date) q.set('cursor_planned_date', String(filters.cursor_planned_date))
|
|
if (filters.cursor_planned_time != null && filters.cursor_planned_time !== '') {
|
|
q.set('cursor_planned_time', String(filters.cursor_planned_time))
|
|
}
|
|
if (filters.cursor_id != null && filters.cursor_id !== '') q.set('cursor_id', String(filters.cursor_id))
|
|
const qs = q.toString()
|
|
return request(`/api/training-units${qs ? `?${qs}` : ''}`)
|
|
}
|
|
|
|
/** Dashboard Kurzüberblick: Entwürfe / meine Übungen / YTD abgeschlossene Einheiten (ein Roundtrip). */
|
|
export async function getDashboardKpis() {
|
|
return request('/api/dashboard/kpis')
|
|
}
|
|
|
|
/** Dashboard: Übungen in geplanten Einheiten, die für den Verein noch auf Sichtbarkeit „Verein“ gehören. */
|
|
export async function getTrainingExerciseClubVisibilityQueue(filters = {}) {
|
|
const q = new URLSearchParams()
|
|
if (filters.start_date) q.set('start_date', String(filters.start_date))
|
|
if (filters.end_date) q.set('end_date', String(filters.end_date))
|
|
if (filters.assigned_to_me === false) q.set('assigned_to_me', 'false')
|
|
if (filters.limit_units != null && filters.limit_units !== '') {
|
|
q.set('limit_units', String(filters.limit_units))
|
|
}
|
|
const qs = q.toString()
|
|
return request(`/api/training-units/exercises-club-visibility-queue${qs ? `?${qs}` : ''}`)
|
|
}
|
|
|
|
export async function getTrainingUnit(id) {
|
|
return request(`/api/training-units/${id}`)
|
|
}
|
|
|
|
export async function createTrainingUnit(data) {
|
|
return request('/api/training-units', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
export async function updateTrainingUnit(id, data) {
|
|
return request(`/api/training-units/${id}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
export async function deleteTrainingUnit(id) {
|
|
return request(`/api/training-units/${id}`, { method: 'DELETE' })
|
|
}
|
|
|
|
export async function quickCreateTrainingUnit(data) {
|
|
return request('/api/training-units/quick-create', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
/** Planungs-KI: kontextgebundene Übungssuche (Hybrid + Profil + optional LLM-Rerank). */
|
|
export async function suggestPlanningExercises(body = {}) {
|
|
return request('/api/planning/exercise-suggest', {
|
|
method: 'POST',
|
|
body: JSON.stringify(body),
|
|
})
|
|
}
|
|
|
|
/** Planungs-KI Phase C3: aufbauender Übungspfad für Progressionsgraphen. */
|
|
export async function suggestProgressionPath(body = {}) {
|
|
return request('/api/planning/progression-path-suggest', {
|
|
method: 'POST',
|
|
body: JSON.stringify(body),
|
|
})
|
|
}
|
|
|
|
/** Rahmen-Slot → geplante Einheit (tiefe Kopie, origin_framework_slot_id). */
|
|
export async function createTrainingUnitFromFrameworkSlot(data) {
|
|
return request('/api/training-units/from-framework-slot', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
export async function listTrainingPlanTemplates() {
|
|
return request('/api/training-plan-templates')
|
|
}
|
|
|
|
export async function getTrainingPlanTemplate(id) {
|
|
return request(`/api/training-plan-templates/${id}`)
|
|
}
|
|
|
|
export async function createTrainingPlanTemplate(data) {
|
|
return request('/api/training-plan-templates', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
export async function updateTrainingPlanTemplate(id, data) {
|
|
return request(`/api/training-plan-templates/${id}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
export async function deleteTrainingPlanTemplate(id) {
|
|
return request(`/api/training-plan-templates/${id}`, { method: 'DELETE' })
|
|
}
|
|
|
|
export async function listTrainingModules() {
|
|
return request('/api/training-modules')
|
|
}
|
|
|
|
export async function getTrainingModule(id) {
|
|
return request(`/api/training-modules/${id}`)
|
|
}
|
|
|
|
export async function createTrainingModule(data) {
|
|
return request('/api/training-modules', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
export async function updateTrainingModule(id, data) {
|
|
return request(`/api/training-modules/${id}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
export async function deleteTrainingModule(id) {
|
|
return request(`/api/training-modules/${id}`, { method: 'DELETE' })
|
|
}
|
|
|
|
/** Kopiert Modul-Inhalte ans Ende eines Abschnitts (section_order_index 0-basiert). */
|
|
export async function applyTrainingModuleToTrainingUnit(unitId, data) {
|
|
return request(`/api/training-units/${unitId}/apply-training-module`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
/** Geplanten Ablauf als Session-Blueprint in ein Rahmenprogramm schreiben (neu oder bestehend). */
|
|
export async function publishTrainingUnitToFramework(unitId, data) {
|
|
return request(`/api/training-units/${unitId}/publish-to-framework`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
export async function listTrainingFrameworkPrograms() {
|
|
return request('/api/training-framework-programs')
|
|
}
|
|
|
|
export async function getTrainingFrameworkProgram(id) {
|
|
return request(`/api/training-framework-programs/${id}`)
|
|
}
|
|
|
|
export async function createTrainingFrameworkProgram(data) {
|
|
return request('/api/training-framework-programs', {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
export async function updateTrainingFrameworkProgram(id, data) {
|
|
return request(`/api/training-framework-programs/${id}`, {
|
|
method: 'PUT',
|
|
body: JSON.stringify(data),
|
|
})
|
|
}
|
|
|
|
export async function deleteTrainingFrameworkProgram(id) {
|
|
return request(`/api/training-framework-programs/${id}`, { method: 'DELETE' })
|
|
}
|