2026-03-19 11:15:35 +01:00
|
|
|
"""
|
|
|
|
|
Mitai Jinkendo API - Main Application
|
|
|
|
|
|
|
|
|
|
FastAPI backend with modular router structure.
|
|
|
|
|
"""
|
|
|
|
|
import os
|
2026-03-16 13:35:11 +01:00
|
|
|
from pathlib import Path
|
|
|
|
|
|
2026-03-19 11:15:35 +01:00
|
|
|
from fastapi import FastAPI
|
2026-03-16 13:35:11 +01:00
|
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
|
from slowapi import Limiter, _rate_limit_exceeded_handler
|
|
|
|
|
from slowapi.util import get_remote_address
|
|
|
|
|
from slowapi.errors import RateLimitExceeded
|
|
|
|
|
|
2026-03-19 11:15:35 +01:00
|
|
|
from db import init_db
|
2026-03-18 08:27:33 +01:00
|
|
|
|
2026-04-11 19:04:27 +02:00
|
|
|
# Placeholder registry: load all register_placeholder() side-effects before any request
|
|
|
|
|
# so get_placeholder_catalog() and exports see consistent metadata (see Phase A plan).
|
|
|
|
|
import placeholder_registrations # noqa: F401
|
|
|
|
|
|
2026-03-19 11:15:35 +01:00
|
|
|
# Import routers
|
|
|
|
|
from routers import auth, profiles, weight, circumference, caliper
|
|
|
|
|
from routers import activity, nutrition, photos, insights, prompts
|
2026-03-19 13:09:33 +01:00
|
|
|
from routers import admin, stats, exportdata, importdata
|
|
|
|
|
from routers import subscription, coupons, features, tiers_mgmt, tier_limits
|
feat: admin CRUD for training types + distribution chart in ActivityPage
Backend (v9d Phase 1b):
- Migration 006: Add abilities JSONB column + descriptions
- admin_training_types.py: Full CRUD endpoints for training types
- List, Get, Create, Update, Delete
- Abilities taxonomy endpoint (5 dimensions: koordinativ, konditionell, kognitiv, psychisch, taktisch)
- Validation: Cannot delete types in use
- Register admin_training_types router in main.py
Frontend:
- AdminTrainingTypesPage: Full CRUD UI
- Create/edit form with all fields (category, subcategory, names, icon, descriptions, sort_order)
- List grouped by category with color coding
- Delete with usage check
- Note about abilities mapping coming in v9f
- Add TrainingTypeDistribution to ActivityPage stats tab
- Add admin link in AdminPanel (v9d section)
- Update api.js with admin training types methods
Notes:
- Abilities mapping UI deferred to v9f (flexible prompt system)
- Placeholders (abilities column) in place for future AI analysis
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 15:32:32 +01:00
|
|
|
from routers import user_restrictions, access_grants, training_types, admin_training_types
|
refactor: vitals architecture - separate baseline vs blood pressure
BREAKING CHANGE: vitals_log split into vitals_baseline + blood_pressure_log
**Architektur-Änderung:**
- Baseline-Vitals (langsam veränderlich, 1x täglich morgens)
→ vitals_baseline (RHR, HRV, VO2 Max, SpO2, Atemfrequenz)
- Kontext-abhängige Vitals (mehrfach täglich, situativ)
→ blood_pressure_log (Blutdruck + Kontext-Tagging)
**Migration 015:**
- CREATE TABLE vitals_baseline (once daily, morning measurements)
- CREATE TABLE blood_pressure_log (multiple daily, context-aware)
- Migrate data from vitals_log → new tables
- Rename vitals_log → vitals_log_backup_pre_015 (safety)
- Prepared for future: glucose_log, temperature_log (commented)
**Backend:**
- NEW: routers/vitals_baseline.py (CRUD + Apple Health import)
- NEW: routers/blood_pressure.py (CRUD + Omron import + context)
- UPDATED: main.py (register new routers, remove old vitals)
- UPDATED: insights.py (query new tables, split template vars)
**Frontend:**
- UPDATED: api.js (new endpoints für baseline + BP)
- UPDATED: Analysis.jsx (add {{bp_summary}} variable)
**Nächster Schritt:**
- Frontend: VitalsPage.jsx refactoren (3 Tabs: Morgenmessung, Blutdruck, Import)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:02:40 +01:00
|
|
|
from routers import admin_activity_mappings, sleep, rest_days
|
|
|
|
|
from routers import vitals_baseline, blood_pressure # v9d Phase 2d Refactored
|
feat: Training Type Profiles - Phase 1.1 Foundation (#15)
## Implemented
### DB-Schema (Migrations)
- Migration 013: training_parameters table (16 standard parameters)
- Migration 014: training_types.profile + activity_log.evaluation columns
- Performance metric calculations (avg_hr_percent, kcal_per_km)
### Backend - Rule Engine
- RuleEvaluator: Generic rule evaluation with 9 operators
- gte, lte, gt, lt, eq, neq, between, in, not_in
- Weighted scoring system
- Pass strategies: all_must_pass, weighted_score, at_least_n
- IntensityZoneEvaluator: HR zone analysis
- TrainingEffectsEvaluator: Abilities development
### Backend - Master Evaluator
- TrainingProfileEvaluator: 7-dimensional evaluation
1. Minimum Requirements (Quality Gates)
2. Intensity Zones (HR zones)
3. Training Effects (Abilities)
4. Periodization (Frequency & Recovery)
5. Performance Indicators (KPIs)
6. Safety (Warnings)
7. AI Context (simplified for MVP)
- evaluation_helper.py: Utilities for loading + saving
- routers/evaluation.py: API endpoints
- POST /api/evaluation/activity/{id}
- POST /api/evaluation/batch
- GET /api/evaluation/parameters
### Integration
- main.py: Router registration
## TODO (Phase 1.2)
- Auto-evaluation on activity INSERT/UPDATE
- Admin-UI for profile editing
- User-UI for results display
## Testing
- ✅ Syntax checks passed
- 🔲 Runtime testing pending (after auto-evaluation)
Part of Issue #15 - Training Type Profiles System
2026-03-23 10:49:26 +01:00
|
|
|
from routers import evaluation # v9d/v9e Training Type Profiles (#15)
|
2026-03-27 19:48:05 +01:00
|
|
|
from routers import goals, focus_areas # v9e/v9g Goal System v2.0 (Dynamic Focus Areas)
|
2026-03-28 06:31:31 +01:00
|
|
|
from routers import goal_types, goal_progress, training_phases, fitness_tests # v9h Goal System (Split routers)
|
2026-03-28 18:26:22 +01:00
|
|
|
from routers import charts # Phase 0c Multi-Layer Architecture
|
2026-04-03 18:02:25 +02:00
|
|
|
from routers import workflow_questions # Phase 1 Workflow Engine - Question Catalog
|
feat: Phase 2 - Normalisierung + Workflow Executor
Backend:
- normalization_engine.py (200 Zeilen): Synonym-Mapping, 5 Statuswerte
* normalize_decision_signal(): Kaskade (exact → case → synonym → invalid)
* apply_synonym_mapping(): DB-basierte Synonyme (case-insensitive)
* normalize_all_signals(): Batch-Processing gegen Katalog
* load_question_catalog(): Lädt normalization_rules aus DB
- workflow_executor.py (440 Zeilen): Sequenzielle Workflow-Ausführung
* execute_workflow(): Traversiert DAG in topologischer Reihenfolge
* execute_node(): Führt analysis nodes aus (start/end = no-op)
* aggregate_results(): Kombiniert analysis_core + normalized_signals
* save_execution_state(): Persistiert in workflow_executions
- workflow_models.py: Erweitert um Phase 2 Models
* SignalStatus Enum (valid, normalized, unclear, invalid, not_decidable)
* NormalizedSignal (question_type, raw_value, normalized_value, status)
* NodeExecutionState (node_id, status, analysis_core, normalized_signals)
* ExecutionResult (execution_id, workflow_id, status, node_states, aggregated_result)
- workflow_engine.py: Neue Funktion get_execution_order()
* Flattened topological sort für sequenzielle Execution
* Phase 7: Wird zu levels (parallele Execution)
- prompt_executor.py: execute_workflow_prompt() Implementierung
* Ruft workflow_executor.execute_workflow() auf
* Konvertiert ExecutionResult zu API-Response
- routers/workflows.py (230 Zeilen): Workflow Execution API
* POST /api/workflows/{id}/execute (mit enable_debug)
* GET /api/workflows/executions/{id} (lädt gespeicherten State)
* GET /api/workflows (listet alle aktiven Workflows)
* GET /api/workflows/{id} (lädt einzelnen Workflow mit Graph)
- main.py: Router-Registrierung (workflows.router)
Tests:
- test_phase2_normalization.py (17 Tests): Alle Normalisierungs-Szenarien
* Exact match, case-insensitive, synonym mapping, invalid, whitespace
* Batch-Normalisierung, not_in_catalog, mixed validity
- test_phase2_workflow_executor.py (10 Tests): Executor + Aggregation
* aggregate_results mit verschiedenen Konstellationen
* execute_node für start/end/analysis/unknown
* Integration mit question_augmenter + result_container_parser
Alle 27 Unit-Tests bestanden.
version: 0.9k (backend)
module: workflow 0.3.0
Konzept: .claude/task/Workflow_engine_prompting_engine/anforderungsanalyse_umsetzungsplan.md (Phase 2)
2026-04-03 21:20:23 +02:00
|
|
|
from routers import workflows # Phase 2 Workflow Engine - Execution
|
2026-04-06 19:45:06 +02:00
|
|
|
from routers import reference_values # Persönliche Referenzwerte (Profil)
|
2026-04-06 19:51:23 +02:00
|
|
|
from routers import admin_reference_value_types # Admin: Referenzwert-Typen
|
2026-04-23 16:18:10 +02:00
|
|
|
from routers import app_dashboard # Geschützter App-Bereich: Dashboard-Layout + Widget-Katalog
|
2026-04-29 11:28:04 +02:00
|
|
|
from routers import reports # Strukturierter PDF-Bericht (Profil v1)
|
2026-04-09 21:37:19 +02:00
|
|
|
from routers import csv_import, admin_csv_templates # Issue #21 Universal CSV Parser
|
2026-04-14 11:49:14 +02:00
|
|
|
from routers import admin_training_parameters, admin_activity_attribute_profiles # EAV session metrics
|
2026-09-12 14:35:57 +02:00
|
|
|
from routers import bls, admin_bls, admin_food_mappings # BLS catalog + FDDB mapping
|
2026-09-13 10:36:08 +02:00
|
|
|
from routers import tandoor # per-user Tandoor connection
|
2026-03-19 11:15:35 +01:00
|
|
|
|
|
|
|
|
# ── App Configuration ─────────────────────────────────────────────────────────
|
2026-03-16 13:35:11 +01:00
|
|
|
DATA_DIR = Path(os.getenv("DATA_DIR", "./data"))
|
|
|
|
|
PHOTOS_DIR = Path(os.getenv("PHOTOS_DIR", "./photos"))
|
|
|
|
|
DATA_DIR.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
PHOTOS_DIR.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
|
|
|
|
app = FastAPI(title="Mitai Jinkendo API", version="3.0.0")
|
2026-03-19 11:15:35 +01:00
|
|
|
|
|
|
|
|
# Rate limiting
|
2026-03-16 13:35:11 +01:00
|
|
|
limiter = Limiter(key_func=get_remote_address)
|
|
|
|
|
app.state.limiter = limiter
|
|
|
|
|
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
|
2026-03-19 11:15:35 +01:00
|
|
|
|
|
|
|
|
# CORS
|
2026-03-16 13:35:11 +01:00
|
|
|
app.add_middleware(
|
|
|
|
|
CORSMiddleware,
|
|
|
|
|
allow_origins=os.getenv("ALLOWED_ORIGINS", "*").split(","),
|
|
|
|
|
allow_credentials=True,
|
|
|
|
|
allow_methods=["GET","POST","PUT","DELETE","OPTIONS"],
|
|
|
|
|
allow_headers=["*"],
|
|
|
|
|
)
|
|
|
|
|
|
2026-03-19 11:15:35 +01:00
|
|
|
# ── Startup Event ─────────────────────────────────────────────────────────────
|
2026-03-19 07:56:36 +01:00
|
|
|
@app.on_event("startup")
|
|
|
|
|
async def startup_event():
|
2026-03-19 11:15:35 +01:00
|
|
|
"""Run database initialization on startup."""
|
2026-03-19 08:26:09 +01:00
|
|
|
try:
|
|
|
|
|
init_db()
|
|
|
|
|
except Exception as e:
|
2026-04-15 08:12:58 +02:00
|
|
|
print(f"[WARN] init_db() failed (non-fatal): {e}")
|
2026-03-19 11:15:35 +01:00
|
|
|
# Don't crash on startup - can be created manually
|
|
|
|
|
|
feat: add v9c subscription system database schema
Phase 1: Database Migration Complete
Created migration infrastructure:
- backend/migrations/v9c_subscription_system.sql (11 new tables)
- backend/apply_v9c_migration.py (auto-migration runner)
- Updated main.py startup event to apply migration
New tables (Feature-Registry Pattern):
1. app_settings - Global configuration
2. tiers - Subscription tiers (free/basic/premium/selfhosted)
3. features - Feature registry (11 limitable features)
4. tier_limits - Tier x Feature matrix (44 initial limits)
5. user_feature_restrictions - Individual user overrides
6. user_feature_usage - Usage tracking with reset periods
7. coupons - Coupon management (single-use, period, Wellpass)
8. coupon_redemptions - Redemption history
9. access_grants - Time-limited access with pause/resume logic
10. user_activity_log - Activity tracking (JSONB details)
11. user_stats - Aggregated statistics
Extended profiles table:
- tier, trial_ends_at, email_verified, email_verify_token
- invited_by, invitation_token
Initial data inserted:
- 4 tiers (free/basic/premium/selfhosted)
- 11 features (weight, circumference, caliper, nutrition, activity, photos, ai_calls, ai_pipeline, export_*)
- 44 tier_limits (complete Tier x Feature matrix)
- App settings (trial duration, self-registration config)
Migration auto-runs on container startup (similar to SQLite→PostgreSQL).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 12:42:43 +01:00
|
|
|
# Apply v9c migration if needed
|
|
|
|
|
try:
|
|
|
|
|
from apply_v9c_migration import apply_migration
|
|
|
|
|
apply_migration()
|
|
|
|
|
except Exception as e:
|
2026-04-15 08:12:58 +02:00
|
|
|
print(f"[WARN] v9c migration failed (non-fatal): {e}")
|
feat: add v9c subscription system database schema
Phase 1: Database Migration Complete
Created migration infrastructure:
- backend/migrations/v9c_subscription_system.sql (11 new tables)
- backend/apply_v9c_migration.py (auto-migration runner)
- Updated main.py startup event to apply migration
New tables (Feature-Registry Pattern):
1. app_settings - Global configuration
2. tiers - Subscription tiers (free/basic/premium/selfhosted)
3. features - Feature registry (11 limitable features)
4. tier_limits - Tier x Feature matrix (44 initial limits)
5. user_feature_restrictions - Individual user overrides
6. user_feature_usage - Usage tracking with reset periods
7. coupons - Coupon management (single-use, period, Wellpass)
8. coupon_redemptions - Redemption history
9. access_grants - Time-limited access with pause/resume logic
10. user_activity_log - Activity tracking (JSONB details)
11. user_stats - Aggregated statistics
Extended profiles table:
- tier, trial_ends_at, email_verified, email_verify_token
- invited_by, invitation_token
Initial data inserted:
- 4 tiers (free/basic/premium/selfhosted)
- 11 features (weight, circumference, caliper, nutrition, activity, photos, ai_calls, ai_pipeline, export_*)
- 44 tier_limits (complete Tier x Feature matrix)
- App settings (trial duration, self-registration config)
Migration auto-runs on container startup (similar to SQLite→PostgreSQL).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 12:42:43 +01:00
|
|
|
|
2026-03-19 11:15:35 +01:00
|
|
|
# ── Register Routers ──────────────────────────────────────────────────────────
|
|
|
|
|
app.include_router(auth.router) # /api/auth/*
|
|
|
|
|
app.include_router(profiles.router) # /api/profiles/*, /api/profile
|
|
|
|
|
app.include_router(weight.router) # /api/weight/*
|
|
|
|
|
app.include_router(circumference.router) # /api/circumferences/*
|
|
|
|
|
app.include_router(caliper.router) # /api/caliper/*
|
|
|
|
|
app.include_router(activity.router) # /api/activity/*
|
|
|
|
|
app.include_router(nutrition.router) # /api/nutrition/*
|
|
|
|
|
app.include_router(photos.router) # /api/photos/*
|
|
|
|
|
app.include_router(insights.router) # /api/insights/*, /api/ai/*
|
|
|
|
|
app.include_router(prompts.router) # /api/prompts/*
|
|
|
|
|
app.include_router(admin.router) # /api/admin/*
|
|
|
|
|
app.include_router(stats.router) # /api/stats
|
|
|
|
|
app.include_router(exportdata.router) # /api/export/*
|
|
|
|
|
app.include_router(importdata.router) # /api/import/*
|
2026-03-19 13:09:33 +01:00
|
|
|
|
|
|
|
|
# v9c Subscription System
|
2026-03-19 13:05:55 +01:00
|
|
|
app.include_router(subscription.router) # /api/subscription/*
|
2026-03-19 13:07:09 +01:00
|
|
|
app.include_router(coupons.router) # /api/coupons/*
|
2026-03-19 13:09:33 +01:00
|
|
|
app.include_router(features.router) # /api/features (admin)
|
|
|
|
|
app.include_router(tiers_mgmt.router) # /api/tiers (admin)
|
|
|
|
|
app.include_router(tier_limits.router) # /api/tier-limits (admin)
|
|
|
|
|
app.include_router(user_restrictions.router) # /api/user-restrictions (admin)
|
|
|
|
|
app.include_router(access_grants.router) # /api/access-grants (admin)
|
2026-03-19 11:15:35 +01:00
|
|
|
|
2026-03-23 14:52:09 +01:00
|
|
|
# v9d Training Types & Sleep Module & Rest Days & Vitals
|
feat: admin CRUD for training types + distribution chart in ActivityPage
Backend (v9d Phase 1b):
- Migration 006: Add abilities JSONB column + descriptions
- admin_training_types.py: Full CRUD endpoints for training types
- List, Get, Create, Update, Delete
- Abilities taxonomy endpoint (5 dimensions: koordinativ, konditionell, kognitiv, psychisch, taktisch)
- Validation: Cannot delete types in use
- Register admin_training_types router in main.py
Frontend:
- AdminTrainingTypesPage: Full CRUD UI
- Create/edit form with all fields (category, subcategory, names, icon, descriptions, sort_order)
- List grouped by category with color coding
- Delete with usage check
- Note about abilities mapping coming in v9f
- Add TrainingTypeDistribution to ActivityPage stats tab
- Add admin link in AdminPanel (v9d section)
- Update api.js with admin training types methods
Notes:
- Abilities mapping UI deferred to v9f (flexible prompt system)
- Placeholders (abilities column) in place for future AI analysis
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 15:32:32 +01:00
|
|
|
app.include_router(training_types.router) # /api/training-types/*
|
|
|
|
|
app.include_router(admin_training_types.router) # /api/admin/training-types/*
|
2026-03-21 19:31:58 +01:00
|
|
|
app.include_router(admin_activity_mappings.router) # /api/admin/activity-mappings/*
|
2026-03-22 08:17:11 +01:00
|
|
|
app.include_router(sleep.router) # /api/sleep/* (v9d Phase 2b)
|
feat: flexible rest days system with JSONB config (v9d Phase 2a)
PROBLEM: Simple full_rest/active_recovery model doesn't support
context-specific rest days (e.g., strength rest but cardio allowed).
SOLUTION: JSONB-based flexible rest day configuration.
## Changes:
**Migration 010:**
- Refactor rest_days.type → rest_config JSONB
- Schema: {focus, rest_from[], allows[], intensity_max}
- Validation function with check constraint
- GIN index for performant JSONB queries
**Backend (routers/rest_days.py):**
- CRUD: list, create (upsert by date), get, update, delete
- Stats: count per week, focus distribution
- Validation: check activity conflicts with rest day config
**Frontend (api.js):**
- 7 new methods: listRestDays, createRestDay, updateRestDay,
deleteRestDay, getRestDaysStats, validateActivity
**Integration:**
- Router registered in main.py
- Ready for weekly planning validation rules
## Next Steps:
- Frontend UI (RestDaysPage with Quick/Custom mode)
- Activity conflict warnings
- Dashboard widget
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 16:20:52 +01:00
|
|
|
app.include_router(rest_days.router) # /api/rest-days/* (v9d Phase 2a)
|
refactor: vitals architecture - separate baseline vs blood pressure
BREAKING CHANGE: vitals_log split into vitals_baseline + blood_pressure_log
**Architektur-Änderung:**
- Baseline-Vitals (langsam veränderlich, 1x täglich morgens)
→ vitals_baseline (RHR, HRV, VO2 Max, SpO2, Atemfrequenz)
- Kontext-abhängige Vitals (mehrfach täglich, situativ)
→ blood_pressure_log (Blutdruck + Kontext-Tagging)
**Migration 015:**
- CREATE TABLE vitals_baseline (once daily, morning measurements)
- CREATE TABLE blood_pressure_log (multiple daily, context-aware)
- Migrate data from vitals_log → new tables
- Rename vitals_log → vitals_log_backup_pre_015 (safety)
- Prepared for future: glucose_log, temperature_log (commented)
**Backend:**
- NEW: routers/vitals_baseline.py (CRUD + Apple Health import)
- NEW: routers/blood_pressure.py (CRUD + Omron import + context)
- UPDATED: main.py (register new routers, remove old vitals)
- UPDATED: insights.py (query new tables, split template vars)
**Frontend:**
- UPDATED: api.js (new endpoints für baseline + BP)
- UPDATED: Analysis.jsx (add {{bp_summary}} variable)
**Nächster Schritt:**
- Frontend: VitalsPage.jsx refactoren (3 Tabs: Morgenmessung, Blutdruck, Import)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 16:02:40 +01:00
|
|
|
app.include_router(vitals_baseline.router) # /api/vitals/baseline/* (v9d Phase 2d Refactored)
|
|
|
|
|
app.include_router(blood_pressure.router) # /api/blood-pressure/* (v9d Phase 2d Refactored)
|
feat: Training Type Profiles - Phase 1.1 Foundation (#15)
## Implemented
### DB-Schema (Migrations)
- Migration 013: training_parameters table (16 standard parameters)
- Migration 014: training_types.profile + activity_log.evaluation columns
- Performance metric calculations (avg_hr_percent, kcal_per_km)
### Backend - Rule Engine
- RuleEvaluator: Generic rule evaluation with 9 operators
- gte, lte, gt, lt, eq, neq, between, in, not_in
- Weighted scoring system
- Pass strategies: all_must_pass, weighted_score, at_least_n
- IntensityZoneEvaluator: HR zone analysis
- TrainingEffectsEvaluator: Abilities development
### Backend - Master Evaluator
- TrainingProfileEvaluator: 7-dimensional evaluation
1. Minimum Requirements (Quality Gates)
2. Intensity Zones (HR zones)
3. Training Effects (Abilities)
4. Periodization (Frequency & Recovery)
5. Performance Indicators (KPIs)
6. Safety (Warnings)
7. AI Context (simplified for MVP)
- evaluation_helper.py: Utilities for loading + saving
- routers/evaluation.py: API endpoints
- POST /api/evaluation/activity/{id}
- POST /api/evaluation/batch
- GET /api/evaluation/parameters
### Integration
- main.py: Router registration
## TODO (Phase 1.2)
- Auto-evaluation on activity INSERT/UPDATE
- Admin-UI for profile editing
- User-UI for results display
## Testing
- ✅ Syntax checks passed
- 🔲 Runtime testing pending (after auto-evaluation)
Part of Issue #15 - Training Type Profiles System
2026-03-23 10:49:26 +01:00
|
|
|
app.include_router(evaluation.router) # /api/evaluation/* (v9d/v9e Training Profiles #15)
|
2026-03-28 06:31:31 +01:00
|
|
|
app.include_router(goals.router) # /api/goals/* (v9h Goal System Core CRUD + Focus Areas)
|
|
|
|
|
app.include_router(goal_types.router) # /api/goals/goal-types/* (v9h Goal Type Definitions)
|
|
|
|
|
app.include_router(goal_progress.router) # /api/goals/{goal_id}/progress/* (v9h Progress Tracking)
|
|
|
|
|
app.include_router(training_phases.router) # /api/goals/phases/* (v9h Training Phases)
|
|
|
|
|
app.include_router(fitness_tests.router) # /api/goals/tests/* (v9h Fitness Tests)
|
2026-03-27 19:48:05 +01:00
|
|
|
app.include_router(focus_areas.router) # /api/focus-areas/* (v9g Focus Area System v2.0 - Dynamic)
|
2026-03-21 13:05:33 +01:00
|
|
|
|
2026-03-28 18:26:22 +01:00
|
|
|
# Phase 0c Multi-Layer Architecture
|
|
|
|
|
app.include_router(charts.router) # /api/charts/* (Phase 0c Charts API)
|
|
|
|
|
|
feat: Phase 2 - Normalisierung + Workflow Executor
Backend:
- normalization_engine.py (200 Zeilen): Synonym-Mapping, 5 Statuswerte
* normalize_decision_signal(): Kaskade (exact → case → synonym → invalid)
* apply_synonym_mapping(): DB-basierte Synonyme (case-insensitive)
* normalize_all_signals(): Batch-Processing gegen Katalog
* load_question_catalog(): Lädt normalization_rules aus DB
- workflow_executor.py (440 Zeilen): Sequenzielle Workflow-Ausführung
* execute_workflow(): Traversiert DAG in topologischer Reihenfolge
* execute_node(): Führt analysis nodes aus (start/end = no-op)
* aggregate_results(): Kombiniert analysis_core + normalized_signals
* save_execution_state(): Persistiert in workflow_executions
- workflow_models.py: Erweitert um Phase 2 Models
* SignalStatus Enum (valid, normalized, unclear, invalid, not_decidable)
* NormalizedSignal (question_type, raw_value, normalized_value, status)
* NodeExecutionState (node_id, status, analysis_core, normalized_signals)
* ExecutionResult (execution_id, workflow_id, status, node_states, aggregated_result)
- workflow_engine.py: Neue Funktion get_execution_order()
* Flattened topological sort für sequenzielle Execution
* Phase 7: Wird zu levels (parallele Execution)
- prompt_executor.py: execute_workflow_prompt() Implementierung
* Ruft workflow_executor.execute_workflow() auf
* Konvertiert ExecutionResult zu API-Response
- routers/workflows.py (230 Zeilen): Workflow Execution API
* POST /api/workflows/{id}/execute (mit enable_debug)
* GET /api/workflows/executions/{id} (lädt gespeicherten State)
* GET /api/workflows (listet alle aktiven Workflows)
* GET /api/workflows/{id} (lädt einzelnen Workflow mit Graph)
- main.py: Router-Registrierung (workflows.router)
Tests:
- test_phase2_normalization.py (17 Tests): Alle Normalisierungs-Szenarien
* Exact match, case-insensitive, synonym mapping, invalid, whitespace
* Batch-Normalisierung, not_in_catalog, mixed validity
- test_phase2_workflow_executor.py (10 Tests): Executor + Aggregation
* aggregate_results mit verschiedenen Konstellationen
* execute_node für start/end/analysis/unknown
* Integration mit question_augmenter + result_container_parser
Alle 27 Unit-Tests bestanden.
version: 0.9k (backend)
module: workflow 0.3.0
Konzept: .claude/task/Workflow_engine_prompting_engine/anforderungsanalyse_umsetzungsplan.md (Phase 2)
2026-04-03 21:20:23 +02:00
|
|
|
# Phase 1-2 Workflow Engine
|
2026-04-03 18:02:25 +02:00
|
|
|
app.include_router(workflow_questions.router) # /api/workflow/questions/* (Phase 1 Question Catalog)
|
feat: Phase 2 - Normalisierung + Workflow Executor
Backend:
- normalization_engine.py (200 Zeilen): Synonym-Mapping, 5 Statuswerte
* normalize_decision_signal(): Kaskade (exact → case → synonym → invalid)
* apply_synonym_mapping(): DB-basierte Synonyme (case-insensitive)
* normalize_all_signals(): Batch-Processing gegen Katalog
* load_question_catalog(): Lädt normalization_rules aus DB
- workflow_executor.py (440 Zeilen): Sequenzielle Workflow-Ausführung
* execute_workflow(): Traversiert DAG in topologischer Reihenfolge
* execute_node(): Führt analysis nodes aus (start/end = no-op)
* aggregate_results(): Kombiniert analysis_core + normalized_signals
* save_execution_state(): Persistiert in workflow_executions
- workflow_models.py: Erweitert um Phase 2 Models
* SignalStatus Enum (valid, normalized, unclear, invalid, not_decidable)
* NormalizedSignal (question_type, raw_value, normalized_value, status)
* NodeExecutionState (node_id, status, analysis_core, normalized_signals)
* ExecutionResult (execution_id, workflow_id, status, node_states, aggregated_result)
- workflow_engine.py: Neue Funktion get_execution_order()
* Flattened topological sort für sequenzielle Execution
* Phase 7: Wird zu levels (parallele Execution)
- prompt_executor.py: execute_workflow_prompt() Implementierung
* Ruft workflow_executor.execute_workflow() auf
* Konvertiert ExecutionResult zu API-Response
- routers/workflows.py (230 Zeilen): Workflow Execution API
* POST /api/workflows/{id}/execute (mit enable_debug)
* GET /api/workflows/executions/{id} (lädt gespeicherten State)
* GET /api/workflows (listet alle aktiven Workflows)
* GET /api/workflows/{id} (lädt einzelnen Workflow mit Graph)
- main.py: Router-Registrierung (workflows.router)
Tests:
- test_phase2_normalization.py (17 Tests): Alle Normalisierungs-Szenarien
* Exact match, case-insensitive, synonym mapping, invalid, whitespace
* Batch-Normalisierung, not_in_catalog, mixed validity
- test_phase2_workflow_executor.py (10 Tests): Executor + Aggregation
* aggregate_results mit verschiedenen Konstellationen
* execute_node für start/end/analysis/unknown
* Integration mit question_augmenter + result_container_parser
Alle 27 Unit-Tests bestanden.
version: 0.9k (backend)
module: workflow 0.3.0
Konzept: .claude/task/Workflow_engine_prompting_engine/anforderungsanalyse_umsetzungsplan.md (Phase 2)
2026-04-03 21:20:23 +02:00
|
|
|
app.include_router(workflows.router) # /api/workflows/* (Phase 2 Execution)
|
2026-04-06 19:45:06 +02:00
|
|
|
app.include_router(reference_values.router) # /api/reference-value-types, /api/profile-reference-values
|
2026-04-06 19:51:23 +02:00
|
|
|
app.include_router(admin_reference_value_types.router) # /api/admin/reference-value-types
|
2026-04-07 11:38:35 +02:00
|
|
|
app.include_router(app_dashboard.router) # /api/app/dashboard-layout
|
2026-04-29 11:28:04 +02:00
|
|
|
app.include_router(reports.router) # /api/reports/* (Berichtsprofil + PDF)
|
2026-04-09 21:37:19 +02:00
|
|
|
app.include_router(csv_import.router) # /api/csv/* (Issue #21)
|
|
|
|
|
app.include_router(admin_csv_templates.router) # /api/admin/csv-templates/* (Issue #21)
|
2026-04-14 11:49:14 +02:00
|
|
|
app.include_router(admin_training_parameters.router) # /api/admin/training-parameters
|
|
|
|
|
app.include_router(admin_activity_attribute_profiles.router) # /api/admin/training-*-parameters
|
2026-09-12 14:35:57 +02:00
|
|
|
app.include_router(bls.router) # /api/bls/*
|
|
|
|
|
app.include_router(admin_bls.router) # /api/admin/bls/*
|
|
|
|
|
app.include_router(admin_food_mappings.router) # /api/admin/food-mappings
|
2026-09-13 10:36:08 +02:00
|
|
|
app.include_router(tandoor.router) # /api/tandoor/*
|
2026-04-03 18:02:25 +02:00
|
|
|
|
2026-03-19 11:15:35 +01:00
|
|
|
# ── Health Check ──────────────────────────────────────────────────────────────
|
|
|
|
|
@app.get("/")
|
|
|
|
|
def root():
|
|
|
|
|
"""API health check."""
|
feat: add v9c subscription system database schema
Phase 1: Database Migration Complete
Created migration infrastructure:
- backend/migrations/v9c_subscription_system.sql (11 new tables)
- backend/apply_v9c_migration.py (auto-migration runner)
- Updated main.py startup event to apply migration
New tables (Feature-Registry Pattern):
1. app_settings - Global configuration
2. tiers - Subscription tiers (free/basic/premium/selfhosted)
3. features - Feature registry (11 limitable features)
4. tier_limits - Tier x Feature matrix (44 initial limits)
5. user_feature_restrictions - Individual user overrides
6. user_feature_usage - Usage tracking with reset periods
7. coupons - Coupon management (single-use, period, Wellpass)
8. coupon_redemptions - Redemption history
9. access_grants - Time-limited access with pause/resume logic
10. user_activity_log - Activity tracking (JSONB details)
11. user_stats - Aggregated statistics
Extended profiles table:
- tier, trial_ends_at, email_verified, email_verify_token
- invited_by, invitation_token
Initial data inserted:
- 4 tiers (free/basic/premium/selfhosted)
- 11 features (weight, circumference, caliper, nutrition, activity, photos, ai_calls, ai_pipeline, export_*)
- 44 tier_limits (complete Tier x Feature matrix)
- App settings (trial duration, self-registration config)
Migration auto-runs on container startup (similar to SQLite→PostgreSQL).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 12:42:43 +01:00
|
|
|
return {"status": "ok", "service": "mitai-jinkendo", "version": "v9c-dev"}
|