feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
/**
|
|
|
|
|
|
* Shinkan Jinkendo API Client
|
|
|
|
|
|
*
|
|
|
|
|
|
* Zentrale API-Kommunikation mit automatischer Token-Injektion
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2026-05-22 11:12:50 +02:00
|
|
|
|
import { request, ACTIVE_CLUB_STORAGE_KEY, requestText } from '../api/client.js'
|
2026-05-14 21:49:56 +02:00
|
|
|
|
import * as exercises from '../api/exercises.js'
|
2026-05-14 21:39:45 +02:00
|
|
|
|
import * as planning from '../api/planning.js'
|
2026-05-20 16:42:25 +02:00
|
|
|
|
import * as skillProfiles from '../api/skillProfiles.js'
|
2026-04-27 14:48:46 +02:00
|
|
|
|
|
2026-05-14 21:31:04 +02:00
|
|
|
|
export { ACTIVE_CLUB_STORAGE_KEY }
|
2026-05-14 21:49:56 +02:00
|
|
|
|
export * from '../api/exercises.js'
|
2026-05-14 21:39:45 +02:00
|
|
|
|
export * from '../api/planning.js'
|
2026-05-20 16:42:25 +02:00
|
|
|
|
export * from '../api/skillProfiles.js'
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// Auth
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
export async function login(email, password) {
|
|
|
|
|
|
return request('/api/auth/login', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify({ email, password })
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 16:40:49 +02:00
|
|
|
|
export async function register(email, password, name, extra = {}) {
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
return request('/api/auth/register', {
|
|
|
|
|
|
method: 'POST',
|
2026-05-05 16:40:49 +02:00
|
|
|
|
body: JSON.stringify({ email, password, name, ...extra }),
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function logout() {
|
|
|
|
|
|
return request('/api/auth/logout', { method: 'POST' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function getCurrentProfile() {
|
|
|
|
|
|
return request('/api/profiles/me')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 16:12:17 +02:00
|
|
|
|
/** Liste aller Profile – nur für Plattform-Admins (Vereinsanlage). */
|
|
|
|
|
|
export async function listProfiles() {
|
|
|
|
|
|
return request('/api/profiles')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 21:05:52 +02:00
|
|
|
|
/** Alle Nutzer inkl. Vereinsmitgliedschaften — nur Portal-Admin (UI: Admin → Nutzer). */
|
|
|
|
|
|
export async function listAdminUsers() {
|
|
|
|
|
|
return request('/api/admin/users')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-07 12:36:46 +02:00
|
|
|
|
/** Medien-Speicher (MEDIA_ROOT + relativer Unterordner) — GET: admin/superadmin, PUT: nur superadmin. */
|
|
|
|
|
|
export async function getPlatformMediaStorage() {
|
|
|
|
|
|
return request('/api/admin/platform-media-storage')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function putPlatformMediaStorage(payload) {
|
|
|
|
|
|
return request('/api/admin/platform-media-storage', {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(payload),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-29 11:19:05 +02:00
|
|
|
|
export async function updateProfile(profileId, data) {
|
|
|
|
|
|
return request(`/api/profiles/${profileId}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-09 10:32:33 +02:00
|
|
|
|
/**
|
|
|
|
|
|
* Passwort anderer Konten: Standard leerer Body → E-Mail mit Reset-Link (wie Passwort vergessen).
|
|
|
|
|
|
* Nur Super-Admins dürfen `newPassword` setzen (direktes Überschreiben des Passwort-Hashes).
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function managementPasswordReset(profileId, newPassword = null) {
|
|
|
|
|
|
const body = {}
|
|
|
|
|
|
if (newPassword != null && String(newPassword).trim() !== '') {
|
|
|
|
|
|
body.new_password = newPassword
|
|
|
|
|
|
}
|
2026-05-09 10:15:16 +02:00
|
|
|
|
return request(`/api/profiles/${profileId}/management-password-reset`, {
|
|
|
|
|
|
method: 'POST',
|
2026-05-09 10:32:33 +02:00
|
|
|
|
body: JSON.stringify(body),
|
2026-05-09 10:15:16 +02:00
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-29 11:19:05 +02:00
|
|
|
|
export async function changePassword(newPassword) {
|
|
|
|
|
|
return request('/api/auth/pin', {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify({ pin: newPassword }),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-29 11:37:54 +02:00
|
|
|
|
/** GET /api/auth/verify/{token} — keine Auth nötig; Token gehört zur URL des Bestätigungslinks */
|
|
|
|
|
|
export async function verifyEmail(token) {
|
|
|
|
|
|
const t = encodeURIComponent(token)
|
|
|
|
|
|
return request(`/api/auth/verify/${t}`, {
|
|
|
|
|
|
method: 'GET',
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function resendVerification(email) {
|
|
|
|
|
|
return request('/api/auth/resend-verification', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify({ email }),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// Clubs & Groups
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
export async function listClubs() {
|
|
|
|
|
|
return request('/api/clubs')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Clubs & Organization Management complete
Backend:
- Created routers/clubs.py with full CRUD
- Clubs: list, get, create, update, delete (admin only)
- Divisions: list, create, update, delete (admin only)
- Training Groups: list, get, create, update, delete (admin/trainer)
- Registered clubs router in main.py
- Permission checks: admin for clubs/divisions, trainer for groups
Frontend:
- Complete ClubsPage with 3 tabs (Vereine, Sparten, Gruppen)
- Role-based UI (admin sees all actions, trainer can manage groups)
- Full CRUD forms with modals
- Mobile-responsive card layouts
- Updated api.js with all club/division/group functions
Migration already exists: 002_organization.sql (clubs, divisions, training_groups)
Next: Skills & Methods display (read-only)
2026-04-22 16:48:02 +02:00
|
|
|
|
export async function getClub(id) {
|
|
|
|
|
|
return request(`/api/clubs/${id}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
export async function createClub(data) {
|
|
|
|
|
|
return request('/api/clubs', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Clubs & Organization Management complete
Backend:
- Created routers/clubs.py with full CRUD
- Clubs: list, get, create, update, delete (admin only)
- Divisions: list, create, update, delete (admin only)
- Training Groups: list, get, create, update, delete (admin/trainer)
- Registered clubs router in main.py
- Permission checks: admin for clubs/divisions, trainer for groups
Frontend:
- Complete ClubsPage with 3 tabs (Vereine, Sparten, Gruppen)
- Role-based UI (admin sees all actions, trainer can manage groups)
- Full CRUD forms with modals
- Mobile-responsive card layouts
- Updated api.js with all club/division/group functions
Migration already exists: 002_organization.sql (clubs, divisions, training_groups)
Next: Skills & Methods display (read-only)
2026-04-22 16:48:02 +02:00
|
|
|
|
export async function updateClub(id, data) {
|
|
|
|
|
|
return request(`/api/clubs/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteClub(id) {
|
|
|
|
|
|
return request(`/api/clubs/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 16:29:11 +02:00
|
|
|
|
/** Vereinsmitglieder (API für Admin ohne eigene UI) */
|
|
|
|
|
|
export async function listClubMembers(clubId, { includeInactive = false } = {}) {
|
|
|
|
|
|
const q = includeInactive ? '?include_inactive=true' : ''
|
|
|
|
|
|
return request(`/api/clubs/${clubId}/members${q}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function getClubMember(clubId, profileId) {
|
|
|
|
|
|
return request(`/api/clubs/${clubId}/members/${profileId}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function addClubMember(clubId, payload) {
|
|
|
|
|
|
return request(`/api/clubs/${clubId}/members`, {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(payload),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateClubMember(clubId, profileId, payload) {
|
|
|
|
|
|
return request(`/api/clubs/${clubId}/members/${profileId}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(payload),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function removeClubMember(clubId, profileId) {
|
|
|
|
|
|
return request(`/api/clubs/${clubId}/members/${profileId}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-05 16:40:49 +02:00
|
|
|
|
/** Aktive Vereine (öffentlich, für Registrierungswahl). */
|
|
|
|
|
|
export async function listPublicClubsDirectory() {
|
|
|
|
|
|
return request('/api/clubs/public-directory')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Vereinsinternes Mitgliederverzeichnis (Trainer-/Co-Auswahl). */
|
|
|
|
|
|
export async function clubMembersDirectory(clubId) {
|
|
|
|
|
|
return request(`/api/clubs/${clubId}/members/directory`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Eigene Beitrittsanträge. */
|
|
|
|
|
|
export async function getMyClubJoinRequests() {
|
|
|
|
|
|
return request('/api/me/club-join-requests')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createClubJoinRequest(payload) {
|
|
|
|
|
|
return request('/api/me/club-join-requests', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(payload),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function withdrawClubJoinRequest(requestId) {
|
|
|
|
|
|
return request(`/api/me/club-join-requests/${requestId}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Offene Anträge (Vereins-/Plattform-Admin). */
|
|
|
|
|
|
export async function listClubJoinRequests(clubId) {
|
|
|
|
|
|
return request(`/api/clubs/${clubId}/join-requests`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function acceptClubJoinRequest(clubId, requestId, roles = ['trainer']) {
|
|
|
|
|
|
return request(`/api/clubs/${clubId}/join-requests/${requestId}/accept`, {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify({ roles }),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function rejectClubJoinRequest(clubId, requestId) {
|
|
|
|
|
|
return request(`/api/clubs/${clubId}/join-requests/${requestId}/reject`, {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify({}),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-09 09:13:38 +02:00
|
|
|
|
/** Aggregierter Posteingang: offene Beitrittsanträge für Vereins-/Plattform-Admins. */
|
|
|
|
|
|
export async function getInboxJoinRequests() {
|
|
|
|
|
|
return request('/api/me/inbox/join-requests')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Clubs & Organization Management complete
Backend:
- Created routers/clubs.py with full CRUD
- Clubs: list, get, create, update, delete (admin only)
- Divisions: list, create, update, delete (admin only)
- Training Groups: list, get, create, update, delete (admin/trainer)
- Registered clubs router in main.py
- Permission checks: admin for clubs/divisions, trainer for groups
Frontend:
- Complete ClubsPage with 3 tabs (Vereine, Sparten, Gruppen)
- Role-based UI (admin sees all actions, trainer can manage groups)
- Full CRUD forms with modals
- Mobile-responsive card layouts
- Updated api.js with all club/division/group functions
Migration already exists: 002_organization.sql (clubs, divisions, training_groups)
Next: Skills & Methods display (read-only)
2026-04-22 16:48:02 +02:00
|
|
|
|
export async function listDivisions(clubId) {
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
const query = clubId ? `?club_id=${clubId}` : ''
|
feat: Clubs & Organization Management complete
Backend:
- Created routers/clubs.py with full CRUD
- Clubs: list, get, create, update, delete (admin only)
- Divisions: list, create, update, delete (admin only)
- Training Groups: list, get, create, update, delete (admin/trainer)
- Registered clubs router in main.py
- Permission checks: admin for clubs/divisions, trainer for groups
Frontend:
- Complete ClubsPage with 3 tabs (Vereine, Sparten, Gruppen)
- Role-based UI (admin sees all actions, trainer can manage groups)
- Full CRUD forms with modals
- Mobile-responsive card layouts
- Updated api.js with all club/division/group functions
Migration already exists: 002_organization.sql (clubs, divisions, training_groups)
Next: Skills & Methods display (read-only)
2026-04-22 16:48:02 +02:00
|
|
|
|
return request(`/api/divisions${query}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createDivision(data) {
|
|
|
|
|
|
return request('/api/divisions', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateDivision(id, data) {
|
|
|
|
|
|
return request(`/api/divisions/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteDivision(id) {
|
|
|
|
|
|
return request(`/api/divisions/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function listTrainingGroups(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/groups${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function getTrainingGroup(id) {
|
|
|
|
|
|
return request(`/api/groups/${id}`)
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createTrainingGroup(data) {
|
|
|
|
|
|
return request('/api/groups', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Clubs & Organization Management complete
Backend:
- Created routers/clubs.py with full CRUD
- Clubs: list, get, create, update, delete (admin only)
- Divisions: list, create, update, delete (admin only)
- Training Groups: list, get, create, update, delete (admin/trainer)
- Registered clubs router in main.py
- Permission checks: admin for clubs/divisions, trainer for groups
Frontend:
- Complete ClubsPage with 3 tabs (Vereine, Sparten, Gruppen)
- Role-based UI (admin sees all actions, trainer can manage groups)
- Full CRUD forms with modals
- Mobile-responsive card layouts
- Updated api.js with all club/division/group functions
Migration already exists: 002_organization.sql (clubs, divisions, training_groups)
Next: Skills & Methods display (read-only)
2026-04-22 16:48:02 +02:00
|
|
|
|
export async function updateTrainingGroup(id, data) {
|
|
|
|
|
|
return request(`/api/groups/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteTrainingGroup(id) {
|
|
|
|
|
|
return request(`/api/groups/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// Skills & Methods
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
feat: Skills & Methods catalog complete
Backend:
- Created routers/skills.py with full CRUD
- Skills: list (with category filter), get, create, update, delete
- Methods: list (with category filter), get, create, update, delete
- Default: only show active items
- Read access: all authenticated users
- Write access: admin only
- Registered skills router in main.py
Frontend:
- Complete SkillsPage with 2 tabs (Fähigkeiten, Trainingsmethoden)
- Browse by category with cards layout
- Admin CRUD forms (importance rating for skills, duration/group size for methods)
- Mobile-responsive grid layout
- Updated api.js with all skill/method functions
- Added /skills route to App.jsx
Migration already exists: 003_catalogs.sql (skills, training_methods + seed data)
Next: Training Planning (core feature)
2026-04-22 16:50:31 +02:00
|
|
|
|
export async function listSkills(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/skills${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-27 11:53:25 +02:00
|
|
|
|
/** Admin: Fähigkeiten hierarchisch sortiert (Hauptkategorie → Kategorie → Sortierung) */
|
|
|
|
|
|
export async function listSkillsCatalog(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/skills/catalog${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Skills & Methods catalog complete
Backend:
- Created routers/skills.py with full CRUD
- Skills: list (with category filter), get, create, update, delete
- Methods: list (with category filter), get, create, update, delete
- Default: only show active items
- Read access: all authenticated users
- Write access: admin only
- Registered skills router in main.py
Frontend:
- Complete SkillsPage with 2 tabs (Fähigkeiten, Trainingsmethoden)
- Browse by category with cards layout
- Admin CRUD forms (importance rating for skills, duration/group size for methods)
- Mobile-responsive grid layout
- Updated api.js with all skill/method functions
- Added /skills route to App.jsx
Migration already exists: 003_catalogs.sql (skills, training_methods + seed data)
Next: Training Planning (core feature)
2026-04-22 16:50:31 +02:00
|
|
|
|
export async function getSkill(id) {
|
|
|
|
|
|
return request(`/api/skills/${id}`)
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createSkill(data) {
|
|
|
|
|
|
return request('/api/skills', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Skills & Methods catalog complete
Backend:
- Created routers/skills.py with full CRUD
- Skills: list (with category filter), get, create, update, delete
- Methods: list (with category filter), get, create, update, delete
- Default: only show active items
- Read access: all authenticated users
- Write access: admin only
- Registered skills router in main.py
Frontend:
- Complete SkillsPage with 2 tabs (Fähigkeiten, Trainingsmethoden)
- Browse by category with cards layout
- Admin CRUD forms (importance rating for skills, duration/group size for methods)
- Mobile-responsive grid layout
- Updated api.js with all skill/method functions
- Added /skills route to App.jsx
Migration already exists: 003_catalogs.sql (skills, training_methods + seed data)
Next: Training Planning (core feature)
2026-04-22 16:50:31 +02:00
|
|
|
|
export async function updateSkill(id, data) {
|
|
|
|
|
|
return request(`/api/skills/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteSkill(id) {
|
|
|
|
|
|
return request(`/api/skills/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function listMethods(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/methods${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function getMethod(id) {
|
|
|
|
|
|
return request(`/api/methods/${id}`)
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createMethod(data) {
|
|
|
|
|
|
return request('/api/methods', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Skills & Methods catalog complete
Backend:
- Created routers/skills.py with full CRUD
- Skills: list (with category filter), get, create, update, delete
- Methods: list (with category filter), get, create, update, delete
- Default: only show active items
- Read access: all authenticated users
- Write access: admin only
- Registered skills router in main.py
Frontend:
- Complete SkillsPage with 2 tabs (Fähigkeiten, Trainingsmethoden)
- Browse by category with cards layout
- Admin CRUD forms (importance rating for skills, duration/group size for methods)
- Mobile-responsive grid layout
- Updated api.js with all skill/method functions
- Added /skills route to App.jsx
Migration already exists: 003_catalogs.sql (skills, training_methods + seed data)
Next: Training Planning (core feature)
2026-04-22 16:50:31 +02:00
|
|
|
|
export async function updateMethod(id, data) {
|
|
|
|
|
|
return request(`/api/methods/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteMethod(id) {
|
|
|
|
|
|
return request(`/api/methods/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 07:52:03 +02:00
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// Catalogs (Admin-verwaltbare Stammdaten)
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
// Focus Areas
|
|
|
|
|
|
export async function listFocusAreas(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/focus-areas${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createFocusArea(data) {
|
|
|
|
|
|
return request('/api/focus-areas', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateFocusArea(id, data) {
|
|
|
|
|
|
return request(`/api/focus-areas/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteFocusArea(id) {
|
|
|
|
|
|
return request(`/api/focus-areas/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-24 07:51:40 +02:00
|
|
|
|
// Admin Hierarchy (Tree View)
|
|
|
|
|
|
export async function getAdminHierarchy() {
|
|
|
|
|
|
return request('/api/admin/hierarchy')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-22 09:57:39 +02:00
|
|
|
|
// Superadmin: KI Skill-Retrieval-Profile (Migration 068, exercise_ai)
|
|
|
|
|
|
export async function listAiSkillRetrievalProfiles() {
|
|
|
|
|
|
return request('/api/admin/ai-skill-retrieval-profiles')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function getAiSkillRetrievalProfile(profileId) {
|
|
|
|
|
|
return request(`/api/admin/ai-skill-retrieval-profiles/${profileId}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createAiSkillRetrievalProfile(data) {
|
|
|
|
|
|
return request('/api/admin/ai-skill-retrieval-profiles', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateAiSkillRetrievalProfile(profileId, data) {
|
|
|
|
|
|
return request(`/api/admin/ai-skill-retrieval-profiles/${profileId}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteAiSkillRetrievalProfile(profileId) {
|
|
|
|
|
|
return request(`/api/admin/ai-skill-retrieval-profiles/${profileId}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-22 11:02:02 +02:00
|
|
|
|
/** Superadmin: KI Prompt-Templates (ai_prompts) */
|
|
|
|
|
|
export async function listAdminAiPrompts() {
|
|
|
|
|
|
return request('/api/admin/ai-prompts')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function getAdminAiPrompt(promptId) {
|
|
|
|
|
|
return request(`/api/admin/ai-prompts/${promptId}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateAdminAiPrompt(promptId, data) {
|
|
|
|
|
|
return request(`/api/admin/ai-prompts/${promptId}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function previewAdminAiPrompt(promptId, data) {
|
|
|
|
|
|
return request(`/api/admin/ai-prompts/${promptId}/preview`, {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data || {}),
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function resetAdminAiPromptTemplate(promptId) {
|
|
|
|
|
|
return request(`/api/admin/ai-prompts/${promptId}/reset-template`, { method: 'POST' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function getAdminAiPromptPlaceholdersCatalog() {
|
|
|
|
|
|
return request('/api/admin/ai-prompts/catalog/placeholders')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-27 11:32:30 +02:00
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// Reifegradmodelle / Fähigkeitsmatrix
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
export async function listMaturityModels(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(
|
|
|
|
|
|
Object.entries(filters).filter(([, v]) => v !== undefined && v !== null && v !== '')
|
|
|
|
|
|
).toString()
|
|
|
|
|
|
return request(`/api/maturity-models${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function resolveMaturityModel(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(
|
|
|
|
|
|
Object.entries(filters).filter(([, v]) => v !== undefined && v !== null && v !== '')
|
|
|
|
|
|
).toString()
|
|
|
|
|
|
return request(`/api/maturity-models/resolve${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function getMaturityModel(id) {
|
|
|
|
|
|
return request(`/api/maturity-models/${id}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createMaturityModel(data) {
|
|
|
|
|
|
return request('/api/maturity-models', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateMaturityModel(id, data) {
|
|
|
|
|
|
return request(`/api/maturity-models/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteMaturityModel(id) {
|
|
|
|
|
|
return request(`/api/maturity-models/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function addMaturityModelSkill(modelId, data) {
|
|
|
|
|
|
return request(`/api/maturity-models/${modelId}/skills`, {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function removeMaturityModelSkill(modelId, skillId) {
|
|
|
|
|
|
return request(`/api/maturity-models/${modelId}/skills/${skillId}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function upsertMaturityModelSkillLevels(modelId, data) {
|
|
|
|
|
|
return request(`/api/maturity-models/${modelId}/skill-levels`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-27 12:35:48 +02:00
|
|
|
|
/** Hierarchische Zuordnung Modell → Fokus / Stilrichtung / Trainingsstil (training_types) */
|
|
|
|
|
|
export async function listMaturityModelContextBindings() {
|
|
|
|
|
|
return request('/api/maturity-model-context-bindings')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function upsertMaturityModelContextBinding(data) {
|
|
|
|
|
|
return request('/api/maturity-model-context-bindings', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteMaturityModelContextBinding(id) {
|
|
|
|
|
|
return request(`/api/maturity-model-context-bindings/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-27 12:48:22 +02:00
|
|
|
|
export async function importMaturityModelBundle(payload) {
|
|
|
|
|
|
return request('/api/maturity-models/import', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(payload)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function exportMaturityModelBundle(modelId) {
|
|
|
|
|
|
return request(`/api/maturity-models/${modelId}/export`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function exportResolvedMaturityBundle(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(
|
|
|
|
|
|
Object.entries(filters).filter(([, v]) => v !== undefined && v !== null && v !== '')
|
|
|
|
|
|
).toString()
|
|
|
|
|
|
return request(`/api/maturity-models/export-resolved${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-27 13:13:36 +02:00
|
|
|
|
/** Komplett: Fähigkeitskatalog + Reifegradmodelle + Kontext-Bindings (slug-/namensbasiert auf Ziel-DB) */
|
|
|
|
|
|
export async function exportMatrixStackBundle() {
|
|
|
|
|
|
return request('/api/admin/matrix-stack/export')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function importMatrixStackBundle(payload) {
|
|
|
|
|
|
return request('/api/admin/matrix-stack/import', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(payload)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-22 11:12:50 +02:00
|
|
|
|
/** Superadmin: flacher Export für zentrale Pflege (Beschreibungen, Gewichtungen) */
|
|
|
|
|
|
export async function exportMatrixEditorBundle() {
|
|
|
|
|
|
return request('/api/admin/matrix-editor/export')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function exportMatrixEditorCsv(part) {
|
|
|
|
|
|
const format = part === 'skills' ? 'csv_skills' : 'csv_matrix'
|
|
|
|
|
|
return requestText(`/api/admin/matrix-editor/export?format=${format}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function importMatrixEditorBundle(payload) {
|
|
|
|
|
|
return request('/api/admin/matrix-editor/import', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(payload)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 12:27:09 +02:00
|
|
|
|
// Style Directions (formerly Training Styles)
|
|
|
|
|
|
export async function listStyleDirections(filters = {}) {
|
2026-04-23 07:52:03 +02:00
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/training-styles${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-24 15:20:39 +02:00
|
|
|
|
// Backward-compatibility alias
|
|
|
|
|
|
export const listTrainingStyles = listStyleDirections
|
|
|
|
|
|
|
2026-04-23 12:27:09 +02:00
|
|
|
|
export async function createStyleDirection(data) {
|
2026-04-23 07:52:03 +02:00
|
|
|
|
return request('/api/training-styles', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 12:27:09 +02:00
|
|
|
|
export async function updateStyleDirection(id, data) {
|
2026-04-23 07:52:03 +02:00
|
|
|
|
return request(`/api/training-styles/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 12:27:09 +02:00
|
|
|
|
export async function deleteStyleDirection(id) {
|
2026-04-23 07:52:03 +02:00
|
|
|
|
return request(`/api/training-styles/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Training Characters
|
|
|
|
|
|
export async function listTrainingCharacters(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/training-characters${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createTrainingCharacter(data) {
|
|
|
|
|
|
return request('/api/training-characters', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateTrainingCharacter(id, data) {
|
|
|
|
|
|
return request(`/api/training-characters/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteTrainingCharacter(id) {
|
|
|
|
|
|
return request(`/api/training-characters/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 12:12:48 +02:00
|
|
|
|
// Training Types (Breitensport, Leistungssport, etc.)
|
|
|
|
|
|
export async function listTrainingTypes(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/training-types${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createTrainingType(data) {
|
|
|
|
|
|
return request('/api/training-types', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateTrainingType(id, data) {
|
|
|
|
|
|
return request(`/api/training-types/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteTrainingType(id) {
|
|
|
|
|
|
return request(`/api/training-types/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-27 11:53:25 +02:00
|
|
|
|
// Skill main categories (Hauptgruppen im Fähigkeitskatalog)
|
|
|
|
|
|
export async function listSkillMainCategories() {
|
|
|
|
|
|
return request('/api/skill-main-categories')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createSkillMainCategory(data) {
|
|
|
|
|
|
return request('/api/skill-main-categories', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateSkillMainCategory(id, data) {
|
|
|
|
|
|
return request(`/api/skill-main-categories/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteSkillMainCategory(id) {
|
|
|
|
|
|
return request(`/api/skill-main-categories/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 07:52:03 +02:00
|
|
|
|
// Skill Categories
|
|
|
|
|
|
export async function listSkillCategories(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/skill-categories${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createSkillCategory(data) {
|
|
|
|
|
|
return request('/api/skill-categories', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateSkillCategory(id, data) {
|
|
|
|
|
|
return request(`/api/skill-categories/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteSkillCategory(id) {
|
|
|
|
|
|
return request(`/api/skill-categories/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Trainer Focus Areas
|
|
|
|
|
|
export async function listTrainerFocusAreas(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/trainer-focus-areas${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function assignTrainerFocusArea(data) {
|
|
|
|
|
|
return request('/api/trainer-focus-areas', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteTrainerFocusArea(id) {
|
|
|
|
|
|
return request(`/api/trainer-focus-areas/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 08:55:54 +02:00
|
|
|
|
// Target Groups (Zielgruppen)
|
|
|
|
|
|
export async function listTargetGroups(filters = {}) {
|
|
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/target-groups${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createTargetGroup(data) {
|
|
|
|
|
|
return request('/api/target-groups', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateTargetGroup(id, data) {
|
|
|
|
|
|
return request(`/api/target-groups/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteTargetGroup(id) {
|
|
|
|
|
|
return request(`/api/target-groups/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 12:27:09 +02:00
|
|
|
|
// Style Direction → Target Groups (M:N Assignments)
|
|
|
|
|
|
export async function listStyleDirectionTargetGroups(filters = {}) {
|
2026-04-23 10:45:14 +02:00
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/training-style-target-groups${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 12:27:09 +02:00
|
|
|
|
export async function createStyleDirectionTargetGroup(data) {
|
2026-04-23 10:45:14 +02:00
|
|
|
|
return request('/api/training-style-target-groups', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 12:27:09 +02:00
|
|
|
|
export async function updateStyleDirectionTargetGroup(id, data) {
|
2026-04-23 10:45:14 +02:00
|
|
|
|
return request(`/api/training-style-target-groups/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 12:27:09 +02:00
|
|
|
|
export async function deleteStyleDirectionTargetGroup(id) {
|
2026-04-23 10:45:14 +02:00
|
|
|
|
return request(`/api/training-style-target-groups/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 12:27:09 +02:00
|
|
|
|
export async function getStyleDirectionsHierarchy(filters = {}) {
|
2026-04-23 10:45:14 +02:00
|
|
|
|
const query = new URLSearchParams(filters).toString()
|
|
|
|
|
|
return request(`/api/training-styles/hierarchy${query ? '?' + query : ''}`)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-23 14:22:17 +02:00
|
|
|
|
// Trainer Contexts (Fokussierte Ansichten)
|
|
|
|
|
|
export async function listTrainerContexts() {
|
|
|
|
|
|
return request('/api/trainer-contexts')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function createTrainerContext(data) {
|
|
|
|
|
|
return request('/api/trainer-contexts', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function updateTrainerContext(id, data) {
|
|
|
|
|
|
return request(`/api/trainer-contexts/${id}`, {
|
|
|
|
|
|
method: 'PUT',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function deleteTrainerContext(id) {
|
|
|
|
|
|
return request(`/api/trainer-contexts/${id}`, { method: 'DELETE' })
|
|
|
|
|
|
}
|
|
|
|
|
|
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// Version & Health
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
export async function getVersion() {
|
|
|
|
|
|
return request('/api/version')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export async function healthCheck() {
|
|
|
|
|
|
return request('/health')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export const api = {
|
|
|
|
|
|
// Auth
|
|
|
|
|
|
login,
|
|
|
|
|
|
register,
|
|
|
|
|
|
logout,
|
|
|
|
|
|
getCurrentProfile,
|
2026-05-05 16:12:17 +02:00
|
|
|
|
listProfiles,
|
2026-05-05 21:05:52 +02:00
|
|
|
|
listAdminUsers,
|
2026-04-29 11:19:05 +02:00
|
|
|
|
updateProfile,
|
2026-05-09 10:15:16 +02:00
|
|
|
|
managementPasswordReset,
|
2026-04-29 11:19:05 +02:00
|
|
|
|
changePassword,
|
2026-04-29 11:37:54 +02:00
|
|
|
|
verifyEmail,
|
|
|
|
|
|
resendVerification,
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
|
|
|
|
|
|
// Clubs & Groups
|
|
|
|
|
|
listClubs,
|
feat: Clubs & Organization Management complete
Backend:
- Created routers/clubs.py with full CRUD
- Clubs: list, get, create, update, delete (admin only)
- Divisions: list, create, update, delete (admin only)
- Training Groups: list, get, create, update, delete (admin/trainer)
- Registered clubs router in main.py
- Permission checks: admin for clubs/divisions, trainer for groups
Frontend:
- Complete ClubsPage with 3 tabs (Vereine, Sparten, Gruppen)
- Role-based UI (admin sees all actions, trainer can manage groups)
- Full CRUD forms with modals
- Mobile-responsive card layouts
- Updated api.js with all club/division/group functions
Migration already exists: 002_organization.sql (clubs, divisions, training_groups)
Next: Skills & Methods display (read-only)
2026-04-22 16:48:02 +02:00
|
|
|
|
getClub,
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
createClub,
|
feat: Clubs & Organization Management complete
Backend:
- Created routers/clubs.py with full CRUD
- Clubs: list, get, create, update, delete (admin only)
- Divisions: list, create, update, delete (admin only)
- Training Groups: list, get, create, update, delete (admin/trainer)
- Registered clubs router in main.py
- Permission checks: admin for clubs/divisions, trainer for groups
Frontend:
- Complete ClubsPage with 3 tabs (Vereine, Sparten, Gruppen)
- Role-based UI (admin sees all actions, trainer can manage groups)
- Full CRUD forms with modals
- Mobile-responsive card layouts
- Updated api.js with all club/division/group functions
Migration already exists: 002_organization.sql (clubs, divisions, training_groups)
Next: Skills & Methods display (read-only)
2026-04-22 16:48:02 +02:00
|
|
|
|
updateClub,
|
|
|
|
|
|
deleteClub,
|
2026-05-05 16:29:11 +02:00
|
|
|
|
listClubMembers,
|
|
|
|
|
|
getClubMember,
|
|
|
|
|
|
addClubMember,
|
|
|
|
|
|
updateClubMember,
|
|
|
|
|
|
removeClubMember,
|
2026-05-05 16:40:49 +02:00
|
|
|
|
listPublicClubsDirectory,
|
|
|
|
|
|
clubMembersDirectory,
|
|
|
|
|
|
getMyClubJoinRequests,
|
|
|
|
|
|
createClubJoinRequest,
|
|
|
|
|
|
withdrawClubJoinRequest,
|
|
|
|
|
|
listClubJoinRequests,
|
|
|
|
|
|
acceptClubJoinRequest,
|
|
|
|
|
|
rejectClubJoinRequest,
|
2026-05-09 09:13:38 +02:00
|
|
|
|
getInboxJoinRequests,
|
feat: Clubs & Organization Management complete
Backend:
- Created routers/clubs.py with full CRUD
- Clubs: list, get, create, update, delete (admin only)
- Divisions: list, create, update, delete (admin only)
- Training Groups: list, get, create, update, delete (admin/trainer)
- Registered clubs router in main.py
- Permission checks: admin for clubs/divisions, trainer for groups
Frontend:
- Complete ClubsPage with 3 tabs (Vereine, Sparten, Gruppen)
- Role-based UI (admin sees all actions, trainer can manage groups)
- Full CRUD forms with modals
- Mobile-responsive card layouts
- Updated api.js with all club/division/group functions
Migration already exists: 002_organization.sql (clubs, divisions, training_groups)
Next: Skills & Methods display (read-only)
2026-04-22 16:48:02 +02:00
|
|
|
|
listDivisions,
|
|
|
|
|
|
createDivision,
|
|
|
|
|
|
updateDivision,
|
|
|
|
|
|
deleteDivision,
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
listTrainingGroups,
|
feat: Clubs & Organization Management complete
Backend:
- Created routers/clubs.py with full CRUD
- Clubs: list, get, create, update, delete (admin only)
- Divisions: list, create, update, delete (admin only)
- Training Groups: list, get, create, update, delete (admin/trainer)
- Registered clubs router in main.py
- Permission checks: admin for clubs/divisions, trainer for groups
Frontend:
- Complete ClubsPage with 3 tabs (Vereine, Sparten, Gruppen)
- Role-based UI (admin sees all actions, trainer can manage groups)
- Full CRUD forms with modals
- Mobile-responsive card layouts
- Updated api.js with all club/division/group functions
Migration already exists: 002_organization.sql (clubs, divisions, training_groups)
Next: Skills & Methods display (read-only)
2026-04-22 16:48:02 +02:00
|
|
|
|
getTrainingGroup,
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
createTrainingGroup,
|
feat: Clubs & Organization Management complete
Backend:
- Created routers/clubs.py with full CRUD
- Clubs: list, get, create, update, delete (admin only)
- Divisions: list, create, update, delete (admin only)
- Training Groups: list, get, create, update, delete (admin/trainer)
- Registered clubs router in main.py
- Permission checks: admin for clubs/divisions, trainer for groups
Frontend:
- Complete ClubsPage with 3 tabs (Vereine, Sparten, Gruppen)
- Role-based UI (admin sees all actions, trainer can manage groups)
- Full CRUD forms with modals
- Mobile-responsive card layouts
- Updated api.js with all club/division/group functions
Migration already exists: 002_organization.sql (clubs, divisions, training_groups)
Next: Skills & Methods display (read-only)
2026-04-22 16:48:02 +02:00
|
|
|
|
updateTrainingGroup,
|
|
|
|
|
|
deleteTrainingGroup,
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
|
|
|
|
|
|
// Skills & Methods
|
|
|
|
|
|
listSkills,
|
2026-04-27 11:53:25 +02:00
|
|
|
|
listSkillsCatalog,
|
feat: Skills & Methods catalog complete
Backend:
- Created routers/skills.py with full CRUD
- Skills: list (with category filter), get, create, update, delete
- Methods: list (with category filter), get, create, update, delete
- Default: only show active items
- Read access: all authenticated users
- Write access: admin only
- Registered skills router in main.py
Frontend:
- Complete SkillsPage with 2 tabs (Fähigkeiten, Trainingsmethoden)
- Browse by category with cards layout
- Admin CRUD forms (importance rating for skills, duration/group size for methods)
- Mobile-responsive grid layout
- Updated api.js with all skill/method functions
- Added /skills route to App.jsx
Migration already exists: 003_catalogs.sql (skills, training_methods + seed data)
Next: Training Planning (core feature)
2026-04-22 16:50:31 +02:00
|
|
|
|
getSkill,
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
createSkill,
|
feat: Skills & Methods catalog complete
Backend:
- Created routers/skills.py with full CRUD
- Skills: list (with category filter), get, create, update, delete
- Methods: list (with category filter), get, create, update, delete
- Default: only show active items
- Read access: all authenticated users
- Write access: admin only
- Registered skills router in main.py
Frontend:
- Complete SkillsPage with 2 tabs (Fähigkeiten, Trainingsmethoden)
- Browse by category with cards layout
- Admin CRUD forms (importance rating for skills, duration/group size for methods)
- Mobile-responsive grid layout
- Updated api.js with all skill/method functions
- Added /skills route to App.jsx
Migration already exists: 003_catalogs.sql (skills, training_methods + seed data)
Next: Training Planning (core feature)
2026-04-22 16:50:31 +02:00
|
|
|
|
updateSkill,
|
|
|
|
|
|
deleteSkill,
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
listMethods,
|
feat: Skills & Methods catalog complete
Backend:
- Created routers/skills.py with full CRUD
- Skills: list (with category filter), get, create, update, delete
- Methods: list (with category filter), get, create, update, delete
- Default: only show active items
- Read access: all authenticated users
- Write access: admin only
- Registered skills router in main.py
Frontend:
- Complete SkillsPage with 2 tabs (Fähigkeiten, Trainingsmethoden)
- Browse by category with cards layout
- Admin CRUD forms (importance rating for skills, duration/group size for methods)
- Mobile-responsive grid layout
- Updated api.js with all skill/method functions
- Added /skills route to App.jsx
Migration already exists: 003_catalogs.sql (skills, training_methods + seed data)
Next: Training Planning (core feature)
2026-04-22 16:50:31 +02:00
|
|
|
|
getMethod,
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
createMethod,
|
feat: Skills & Methods catalog complete
Backend:
- Created routers/skills.py with full CRUD
- Skills: list (with category filter), get, create, update, delete
- Methods: list (with category filter), get, create, update, delete
- Default: only show active items
- Read access: all authenticated users
- Write access: admin only
- Registered skills router in main.py
Frontend:
- Complete SkillsPage with 2 tabs (Fähigkeiten, Trainingsmethoden)
- Browse by category with cards layout
- Admin CRUD forms (importance rating for skills, duration/group size for methods)
- Mobile-responsive grid layout
- Updated api.js with all skill/method functions
- Added /skills route to App.jsx
Migration already exists: 003_catalogs.sql (skills, training_methods + seed data)
Next: Training Planning (core feature)
2026-04-22 16:50:31 +02:00
|
|
|
|
updateMethod,
|
|
|
|
|
|
deleteMethod,
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
|
2026-05-14 21:49:56 +02:00
|
|
|
|
// Exercises + Medien/Archiv (Progression, KI) → frontend/src/api/exercises.js
|
|
|
|
|
|
...exercises,
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
|
2026-05-14 21:39:45 +02:00
|
|
|
|
// Training Planning → frontend/src/api/planning.js
|
|
|
|
|
|
...planning,
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
|
2026-05-21 08:11:46 +02:00
|
|
|
|
// Fähigkeiten-Profile & Vorschläge (Phase 3) → frontend/src/api/skillProfiles.js
|
|
|
|
|
|
...skillProfiles,
|
|
|
|
|
|
|
2026-04-23 07:52:03 +02:00
|
|
|
|
// Catalogs
|
|
|
|
|
|
listFocusAreas,
|
|
|
|
|
|
createFocusArea,
|
|
|
|
|
|
updateFocusArea,
|
|
|
|
|
|
deleteFocusArea,
|
2026-04-24 08:25:03 +02:00
|
|
|
|
getAdminHierarchy,
|
2026-05-22 09:57:39 +02:00
|
|
|
|
listAiSkillRetrievalProfiles,
|
|
|
|
|
|
getAiSkillRetrievalProfile,
|
|
|
|
|
|
createAiSkillRetrievalProfile,
|
|
|
|
|
|
updateAiSkillRetrievalProfile,
|
|
|
|
|
|
deleteAiSkillRetrievalProfile,
|
2026-05-22 11:02:02 +02:00
|
|
|
|
listAdminAiPrompts,
|
|
|
|
|
|
getAdminAiPrompt,
|
|
|
|
|
|
updateAdminAiPrompt,
|
|
|
|
|
|
previewAdminAiPrompt,
|
|
|
|
|
|
resetAdminAiPromptTemplate,
|
|
|
|
|
|
getAdminAiPromptPlaceholdersCatalog,
|
2026-04-23 12:27:09 +02:00
|
|
|
|
listStyleDirections,
|
2026-04-27 15:03:48 +02:00
|
|
|
|
listTrainingStyles,
|
2026-04-23 12:27:09 +02:00
|
|
|
|
createStyleDirection,
|
|
|
|
|
|
updateStyleDirection,
|
|
|
|
|
|
deleteStyleDirection,
|
2026-04-23 07:52:03 +02:00
|
|
|
|
listTrainingCharacters,
|
|
|
|
|
|
createTrainingCharacter,
|
|
|
|
|
|
updateTrainingCharacter,
|
|
|
|
|
|
deleteTrainingCharacter,
|
2026-04-23 12:12:48 +02:00
|
|
|
|
listTrainingTypes,
|
|
|
|
|
|
createTrainingType,
|
|
|
|
|
|
updateTrainingType,
|
|
|
|
|
|
deleteTrainingType,
|
2026-04-27 11:53:25 +02:00
|
|
|
|
listSkillMainCategories,
|
|
|
|
|
|
createSkillMainCategory,
|
|
|
|
|
|
updateSkillMainCategory,
|
|
|
|
|
|
deleteSkillMainCategory,
|
2026-04-23 07:52:03 +02:00
|
|
|
|
listSkillCategories,
|
|
|
|
|
|
createSkillCategory,
|
|
|
|
|
|
updateSkillCategory,
|
|
|
|
|
|
deleteSkillCategory,
|
|
|
|
|
|
listTrainerFocusAreas,
|
|
|
|
|
|
assignTrainerFocusArea,
|
|
|
|
|
|
deleteTrainerFocusArea,
|
2026-04-23 08:55:54 +02:00
|
|
|
|
listTargetGroups,
|
|
|
|
|
|
createTargetGroup,
|
|
|
|
|
|
updateTargetGroup,
|
|
|
|
|
|
deleteTargetGroup,
|
2026-04-23 12:27:09 +02:00
|
|
|
|
listStyleDirectionTargetGroups,
|
|
|
|
|
|
createStyleDirectionTargetGroup,
|
|
|
|
|
|
updateStyleDirectionTargetGroup,
|
|
|
|
|
|
deleteStyleDirectionTargetGroup,
|
2026-04-27 11:32:30 +02:00
|
|
|
|
listMaturityModels,
|
2026-04-27 12:35:48 +02:00
|
|
|
|
listMaturityModelContextBindings,
|
|
|
|
|
|
upsertMaturityModelContextBinding,
|
|
|
|
|
|
deleteMaturityModelContextBinding,
|
2026-04-27 12:48:22 +02:00
|
|
|
|
importMaturityModelBundle,
|
|
|
|
|
|
exportMaturityModelBundle,
|
|
|
|
|
|
exportResolvedMaturityBundle,
|
2026-04-27 13:13:36 +02:00
|
|
|
|
exportMatrixStackBundle,
|
|
|
|
|
|
importMatrixStackBundle,
|
2026-05-22 11:12:50 +02:00
|
|
|
|
exportMatrixEditorBundle,
|
|
|
|
|
|
exportMatrixEditorCsv,
|
|
|
|
|
|
importMatrixEditorBundle,
|
2026-04-27 11:32:30 +02:00
|
|
|
|
resolveMaturityModel,
|
|
|
|
|
|
getMaturityModel,
|
|
|
|
|
|
createMaturityModel,
|
|
|
|
|
|
updateMaturityModel,
|
|
|
|
|
|
deleteMaturityModel,
|
|
|
|
|
|
addMaturityModelSkill,
|
|
|
|
|
|
removeMaturityModelSkill,
|
|
|
|
|
|
upsertMaturityModelSkillLevels,
|
2026-04-23 12:27:09 +02:00
|
|
|
|
getStyleDirectionsHierarchy,
|
2026-04-23 14:22:17 +02:00
|
|
|
|
listTrainerContexts,
|
|
|
|
|
|
createTrainerContext,
|
|
|
|
|
|
updateTrainerContext,
|
|
|
|
|
|
deleteTrainerContext,
|
2026-04-23 07:52:03 +02:00
|
|
|
|
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
// System
|
|
|
|
|
|
getVersion,
|
2026-04-24 16:06:49 +02:00
|
|
|
|
healthCheck,
|
|
|
|
|
|
|
|
|
|
|
|
// MediaWiki Import
|
|
|
|
|
|
previewMediaWikiImport: (category, importType = 'exercise', limit = 10) =>
|
|
|
|
|
|
request(`/api/import/mediawiki/preview?category=${encodeURIComponent(category)}&import_type=${importType}&limit=${limit}`),
|
|
|
|
|
|
|
|
|
|
|
|
executeMediaWikiImport: (data) =>
|
|
|
|
|
|
request('/api/import/mediawiki/execute', {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify(data)
|
|
|
|
|
|
}),
|
|
|
|
|
|
|
|
|
|
|
|
getMediaWikiImportStatus: (logId) =>
|
|
|
|
|
|
request(`/api/import/mediawiki/status/${logId}`),
|
|
|
|
|
|
|
|
|
|
|
|
listMediaWikiImportLogs: () =>
|
|
|
|
|
|
request('/api/import/mediawiki/logs'),
|
|
|
|
|
|
|
|
|
|
|
|
deleteMediaWikiImportReference: (refId) =>
|
2026-05-10 11:53:07 +02:00
|
|
|
|
request(`/api/import/mediawiki/references/${refId}`, { method: 'DELETE' }),
|
|
|
|
|
|
|
|
|
|
|
|
// Legal Documents (public)
|
|
|
|
|
|
getPublishedLegalDocument: (documentType) =>
|
|
|
|
|
|
request(`/api/legal-documents/${documentType}/published`),
|
|
|
|
|
|
|
|
|
|
|
|
// Legal Documents (superadmin)
|
|
|
|
|
|
listLegalDocuments: (documentType) =>
|
|
|
|
|
|
request(`/api/admin/legal-documents${documentType ? `?document_type=${documentType}` : ''}`),
|
|
|
|
|
|
createLegalDocument: (data) =>
|
|
|
|
|
|
request('/api/admin/legal-documents', { method: 'POST', body: JSON.stringify(data) }),
|
|
|
|
|
|
getLegalDocument: (id) =>
|
|
|
|
|
|
request(`/api/admin/legal-documents/${id}`),
|
|
|
|
|
|
updateLegalDocument: (id, data) =>
|
|
|
|
|
|
request(`/api/admin/legal-documents/${id}`, { method: 'PUT', body: JSON.stringify(data) }),
|
|
|
|
|
|
publishLegalDocument: (id, changeNote) =>
|
|
|
|
|
|
request(`/api/admin/legal-documents/${id}/publish`, {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
body: JSON.stringify({ change_note: changeNote }),
|
|
|
|
|
|
}),
|
|
|
|
|
|
archiveLegalDocument: (id) =>
|
|
|
|
|
|
request(`/api/admin/legal-documents/${id}/archive`, { method: 'POST' }),
|
2026-05-10 12:25:04 +02:00
|
|
|
|
copyLegalDocumentAsDraft: (id) =>
|
|
|
|
|
|
request(`/api/admin/legal-documents/${id}/copy-as-draft`, { method: 'POST' }),
|
2026-05-10 11:53:07 +02:00
|
|
|
|
getLegalDocumentAudit: (id) =>
|
|
|
|
|
|
request(`/api/admin/legal-documents/${id}/audit`),
|
2026-05-11 17:54:53 +02:00
|
|
|
|
|
|
|
|
|
|
// P-13: Content-Melde-Backend
|
|
|
|
|
|
submitContentReport: (body) =>
|
|
|
|
|
|
request('/api/content-reports', { method: 'POST', body: JSON.stringify(body) }),
|
|
|
|
|
|
getInboxContentReports: () =>
|
|
|
|
|
|
request('/api/me/inbox/content-reports'),
|
|
|
|
|
|
getContentReport: (id) =>
|
|
|
|
|
|
request(`/api/content-reports/${id}`),
|
|
|
|
|
|
patchContentReport: (id, body) =>
|
|
|
|
|
|
request(`/api/content-reports/${id}`, { method: 'PATCH', body: JSON.stringify(body) }),
|
|
|
|
|
|
setLegalHoldFromReport: (id, body) =>
|
|
|
|
|
|
request(`/api/content-reports/${id}/legal-hold`, { method: 'POST', body: JSON.stringify(body) }),
|
feat: Complete MVP setup - Docker, Frontend, Migrations, CI/CD
Docker & Deployment:
- docker-compose.yml (Prod: Port 3003/8003)
- docker-compose.dev-env.yml (Dev: Port 3098/8098)
- Backend Dockerfile (Python 3.12-slim)
- Frontend Dockerfile (Node 20 + Nginx)
- Gitea Actions (deploy-dev.yml, deploy-prod.yml)
Frontend:
- React 18 + Vite setup
- package.json, vite.config.js, index.html
- App.jsx (minimal with version display)
- api.js (complete API client)
- app.css + AuthContext from Mitai
- main.jsx entry point
Backend Migrations:
- 001_auth_membership.sql (Auth + Features + Tier Limits)
- 002_organization.sql (Clubs, Divisions, Training Groups)
- 003_catalogs.sql (Skills + Methods with sample data)
Documentation:
- .claude/rules/ (ARCHITECTURE, CODING_RULES, etc.)
- SHINKAN_PROJECT_SETUP.md (technical setup guide)
Server:
- Directories created on Pi: /home/lars/docker/shinkan[-dev]
- Gitea Runner configured and running
Ready for first deployment to dev.shinkan.jinkendo.de
version: 0.1.0
date: 2026-04-21
2026-04-21 14:36:52 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default api
|