mitai-jinkendo/backend/migrations/012_rest_days_unique_focus.sql
Lars f87b93ce2f
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
feat: prevent duplicate rest day types per date (Migration 012)
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>
2026-03-22 17:36:49 +01:00

35 lines
1.1 KiB
SQL

-- Migration 012: Unique constraint on (profile_id, date, focus)
-- v9d Phase 2a: Prevent duplicate rest day types per date
-- Date: 2026-03-22
-- Add focus column (extracted from rest_config for performance + constraints)
ALTER TABLE rest_days
ADD COLUMN IF NOT EXISTS focus VARCHAR(20);
-- Populate from existing JSONB data
UPDATE rest_days
SET focus = rest_config->>'focus'
WHERE focus IS NULL;
-- Make NOT NULL (safe because we just populated all rows)
ALTER TABLE rest_days
ALTER COLUMN focus SET NOT NULL;
-- Add CHECK constraint for valid focus values
ALTER TABLE rest_days
ADD CONSTRAINT valid_focus CHECK (
focus IN ('muscle_recovery', 'cardio_recovery', 'mental_rest', 'deload', 'injury')
);
-- Add UNIQUE constraint: Same profile + date + focus = duplicate
ALTER TABLE rest_days
ADD CONSTRAINT unique_rest_day_per_focus
UNIQUE (profile_id, date, focus);
-- Add index for efficient queries by focus
CREATE INDEX IF NOT EXISTS idx_rest_days_focus
ON rest_days(focus);
-- Comment for documentation
COMMENT ON COLUMN rest_days.focus IS 'Extracted from rest_config.focus for performance and constraints. Prevents duplicate rest day types per date.';