Production Release: RestDays Widget + Trainingstyp Fix #16

Merged
Lars merged 10 commits from develop into main 2026-03-23 09:24:17 +01:00
Owner

Changes in this release:

Features

  • Dashboard RestDays Widget with today highlighting
  • RestDaysPage visual improvements (HEUTE badge)

Bugfixes

  • #13: Fixed training type creation (JSONB Json() wrapper)
  • Improved error handling in api.js

Commits

  • 7a0b209: feat: dashboard rest days widget + today highlighting
  • 2977050: fix: wrap abilities dict with Json() for JSONB insert (#13)

Testing

  • ? dev.mitai.jinkendo.de tested
  • ? Training type creation works
  • ? RestDays widget displays correctly

Deployment

Gitea Runner will automatically deploy to mitai.jinkendo.de

Issue closed: #13

## Changes in this release: ### Features - Dashboard RestDays Widget with today highlighting - RestDaysPage visual improvements (HEUTE badge) ### Bugfixes - #13: Fixed training type creation (JSONB Json() wrapper) - Improved error handling in api.js ### Commits - 7a0b209: feat: dashboard rest days widget + today highlighting - 2977050: fix: wrap abilities dict with Json() for JSONB insert (#13) ## Testing - ? dev.mitai.jinkendo.de tested - ? Training type creation works - ? RestDays widget displays correctly ## Deployment Gitea Runner will automatically deploy to mitai.jinkendo.de **Issue closed:** #13
Lars added 10 commits 2026-03-23 09:24:04 +01:00
fix: photo upload with empty date string
All checks were successful
Deploy Development / deploy (push) Successful in 54s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
ef27660fc8
Problem:
- Photo upload with empty date parameter (date='')
- PostgreSQL rejects empty string for DATE field
- Error: "invalid input syntax for type date: ''"
- Occurred when saving circumference entry with only photo

Fix:
- Convert empty string to NULL before INSERT
- Check: date if date and date.strip() else None
- NULL is valid for optional date field

Test case:
- Circumference entry with only photo → should work now
- Photo without date → stored with date=NULL ✓

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix: photo upload date parameter parsing
All checks were successful
Deploy Development / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
0278a8e4a6
Problem: Photos were always getting NULL date instead of form date,
causing frontend to fallback to created timestamp (today).

Root cause: FastAPI requires Form() wrapper for form fields when
mixing with File() parameters. Without it, the date parameter was
treated as query parameter and always received empty string.

Solution:
- Import Form from fastapi
- Change date parameter from str="" to str=Form("")
- Return photo_date instead of date in response (consistency)

Now photos correctly use the date from the upload form and can be
backdated when uploading later.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: flexible rest days system with JSONB config (v9d Phase 2a)
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
b63d15fd02
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>
feat: RestDaysPage UI with Quick Mode presets (v9d Phase 2a)
All checks were successful
Deploy Development / deploy (push) Successful in 45s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
c265ab1245
Quick Mode with 4 presets:
- 💪 Kraft-Ruhetag (strength/hiit pause, cardio allowed, max 60%)
- 🏃 Cardio-Ruhetag (cardio pause, strength/mobility allowed, max 70%)
- 🧘 Entspannungstag (all pause, only meditation/walk, max 40%)
- 📉 Deload (all allowed, max 70% intensity)

Features:
- Preset selection with visual cards
- Date picker
- Optional note field
- List view with inline editing
- Delete with confirmation
- Toast notifications
- Detail view (shows rest_from, allows, intensity_max)

Integration:
- Route: /rest-days
- CaptureHub entry: 🛌 Ruhetage

Next Phase:
- Custom Mode (full control)
- Activity conflict warnings
- Weekly planning integration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix: wrap rest_config dict with Json() for psycopg2 JSONB insert
All checks were successful
Deploy Development / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
7d627cf128
Error: psycopg2.ProgrammingError: can't adapt type 'dict'
Solution: Import psycopg2.extras.Json and wrap config_dict

Changes:
- Import Json from psycopg2.extras
- Wrap config_dict with Json() in INSERT
- Wrap config_dict with Json() in UPDATE

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: multi-dimensional rest days + development routes architecture (v9d → v9e)
All checks were successful
Deploy Development / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
6916e5b808
## Changes:

**Frontend:**
- Fix double icon in rest day list (removed icons from FOCUS_LABELS)
- Icon now shows once with proper styling

**Migration 011:**
- Remove UNIQUE constraint (profile_id, date) from rest_days
- Allow multiple rest day types per date
- Use case: Muscle recovery + Mental rest same day

**Architecture: Development Routes**
New document: `.claude/docs/functional/DEVELOPMENT_ROUTES.md`

6 Independent Development Routes:
- 💪 Kraft (Strength): Muscle, power, HIIT
- 🏃 Kondition (Conditioning): Cardio, endurance, VO2max
- 🧘 Mental: Stress, focus, competition readiness
- 🤸 Koordination (Coordination): Balance, agility, technique
- 🧘‍♂️ Mobilität (Mobility): Flexibility, ROM, fascia
- 🎯 Technik (Technique): Sport-specific skills

Each route has:
- Independent rest requirements
- Independent training plans
- Independent progress tracking
- Independent goals & habits

**Future (v9e):**
- Route-based weekly planning
- Multi-route conflict validation
- Auto-rest on poor recovery
- Route balance analysis (KI)

**Future (v9g):**
- Habits per route (route_habits table)
- Streak tracking per route
- Dashboard route-habits widget

**Backlog Updated:**
- v9d: Rest days  (in testing)
- v9e: Development Routes & Weekly Planning (new)
- v9g: Habits per Route (extended)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fix: remove ON CONFLICT clause after constraint removal
All checks were successful
Deploy Development / deploy (push) Successful in 43s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
f2e2aff17f
Migration 011 removed UNIQUE constraint (profile_id, date) to allow
multiple rest days per date, but INSERT still used ON CONFLICT.

Error: psycopg2.errors.InvalidColumnReference: there is no unique or
exclusion constraint matching the ON CONFLICT specification

Solution: Remove ON CONFLICT clause, use plain INSERT.
Multiple entries per date now allowed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: prevent duplicate rest day types per date (Migration 012)
All checks were successful
Deploy Development / deploy (push) Successful in 47s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
f87b93ce2f
Problem: User can create multiple rest days of same type per date
(e.g., 2x Mental Rest on 2026-03-23) - makes no sense.

Solution: UNIQUE constraint on (profile_id, date, focus)

## Migration 012:
- Add focus column (extracted from rest_config JSONB)
- Populate from existing data
- Add NOT NULL constraint
- Add CHECK constraint (valid focus values)
- Add UNIQUE constraint (profile_id, date, focus)
- Add index for performance

## Backend:
- Insert focus column alongside rest_config
- Handle UniqueViolation gracefully
- User-friendly error: "Du hast bereits einen Ruhetag 'Muskelregeneration' für 23.03."

## Benefits:
- DB-level enforcement (clean)
- Fast queries (no JSONB scan)
- Clear error messages
- Prevents: 2x muscle_recovery same day
- Allows: muscle_recovery + mental_rest same day ✓

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: dashboard rest days widget + today highlighting
All checks were successful
Deploy Development / deploy (push) Successful in 50s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 14s
7a0b2097ae
- Add RestDaysWidget component showing today's rest days with icons & colors
- Integrate widget into Dashboard (above training distribution)
- Highlight current day in RestDaysPage (accent border + HEUTE badge)
- Fix: Improve error handling in api.js (parse JSON detail field)

Part of v9d Phase 2 (Vitals & Recovery)
fix: wrap abilities dict with Json() for JSONB insert (#13)
All checks were successful
Deploy Development / deploy (push) Successful in 49s
Build Test / lint-backend (push) Successful in 0s
Build Test / build-frontend (push) Successful in 13s
29770503bf
Problem: Creating new training types via Admin UI resulted in
'Internal Server Error' because abilities dict was passed directly
to PostgreSQL JSONB column without Json() wrapper.

Solution:
- Import Json from psycopg2.extras
- Wrap abilities_json with Json() in INSERT
- Wrap data.abilities with Json() in UPDATE

Same issue as rest_days JSONB fix (commit 7d627cf).

Closes #13
Lars merged commit 03f4b871a9 into main 2026-03-23 09:24:17 +01:00
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: Lars/mitai-jinkendo#16
No description provided.