shinkan-jinkendo/backend/migrations/025_maturity_model_context_mn.sql

161 lines
6.7 KiB
MySQL
Raw Permalink Normal View History

-- Migration 025: Reifegradmodell-Kontext als M:N (Fokusbereich, Stilrichtung, Zielgruppe)
-- + Bootstrap: ein Modell aus allen importierten Skills (Wiki / Migration 023)
-- Datum: 2026-04-27
-- ============================================================================
-- JUNCTION TABLES
-- ============================================================================
CREATE TABLE IF NOT EXISTS maturity_model_focus_areas (
id SERIAL PRIMARY KEY,
maturity_model_id INT NOT NULL REFERENCES maturity_models(id) ON DELETE CASCADE,
focus_area_id INT NOT NULL REFERENCES focus_areas(id) ON DELETE CASCADE,
is_primary BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE (maturity_model_id, focus_area_id)
);
CREATE INDEX IF NOT EXISTS idx_mmfa_model ON maturity_model_focus_areas(maturity_model_id);
CREATE INDEX IF NOT EXISTS idx_mmfa_focus ON maturity_model_focus_areas(focus_area_id);
CREATE TABLE IF NOT EXISTS maturity_model_style_directions (
id SERIAL PRIMARY KEY,
maturity_model_id INT NOT NULL REFERENCES maturity_models(id) ON DELETE CASCADE,
style_direction_id INT NOT NULL REFERENCES style_directions(id) ON DELETE CASCADE,
is_primary BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE (maturity_model_id, style_direction_id)
);
CREATE INDEX IF NOT EXISTS idx_mmsd_model ON maturity_model_style_directions(maturity_model_id);
CREATE INDEX IF NOT EXISTS idx_mmsd_style ON maturity_model_style_directions(style_direction_id);
CREATE TABLE IF NOT EXISTS maturity_model_target_groups (
id SERIAL PRIMARY KEY,
maturity_model_id INT NOT NULL REFERENCES maturity_models(id) ON DELETE CASCADE,
target_group_id INT NOT NULL REFERENCES target_groups(id) ON DELETE CASCADE,
is_primary BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE (maturity_model_id, target_group_id)
);
CREATE INDEX IF NOT EXISTS idx_mmtg_model ON maturity_model_target_groups(maturity_model_id);
CREATE INDEX IF NOT EXISTS idx_mmtg_tg ON maturity_model_target_groups(target_group_id);
-- ============================================================================
-- Daten aus 1:1-FKs übernehmen (falls Spalten noch existieren), dann FK-Spalten entfernen
-- ============================================================================
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'maturity_models' AND column_name = 'focus_area_id'
) THEN
INSERT INTO maturity_model_focus_areas (maturity_model_id, focus_area_id, is_primary)
SELECT id, focus_area_id, true
FROM maturity_models
WHERE focus_area_id IS NOT NULL
ON CONFLICT (maturity_model_id, focus_area_id) DO NOTHING;
END IF;
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'maturity_models' AND column_name = 'style_direction_id'
) THEN
INSERT INTO maturity_model_style_directions (maturity_model_id, style_direction_id, is_primary)
SELECT id, style_direction_id, true
FROM maturity_models
WHERE style_direction_id IS NOT NULL
ON CONFLICT (maturity_model_id, style_direction_id) DO NOTHING;
END IF;
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'maturity_models' AND column_name = 'target_group_id'
) THEN
INSERT INTO maturity_model_target_groups (maturity_model_id, target_group_id, is_primary)
SELECT id, target_group_id, true
FROM maturity_models
WHERE target_group_id IS NOT NULL
ON CONFLICT (maturity_model_id, target_group_id) DO NOTHING;
END IF;
END $$;
ALTER TABLE maturity_models DROP CONSTRAINT IF EXISTS maturity_models_context_name_unique;
ALTER TABLE maturity_models DROP COLUMN IF EXISTS focus_area_id;
ALTER TABLE maturity_models DROP COLUMN IF EXISTS style_direction_id;
ALTER TABLE maturity_models DROP COLUMN IF EXISTS target_group_id;
CREATE UNIQUE INDEX IF NOT EXISTS idx_maturity_models_wiki_import
ON maturity_models(import_source, import_id)
WHERE import_id IS NOT NULL;
-- ============================================================================
-- Bootstrap: Standard-Modell für alle Skills aus der Wiki-Matrix (Migration 023)
-- ============================================================================
DO $$
DECLARE
mid INT;
n_skills INT;
BEGIN
SELECT COUNT(*) INTO n_skills FROM skills;
IF n_skills = 0 THEN
RAISE NOTICE 'Bootstrap: keine Skills – übersprungen';
RETURN;
END IF;
SELECT id INTO mid FROM maturity_models WHERE import_id = 'faehigkeitsmatrix_karatetrainer' LIMIT 1;
IF mid IS NOT NULL THEN
RAISE NOTICE 'Bootstrap: Modell bereits vorhanden (id=%)', mid;
RETURN;
END IF;
INSERT INTO maturity_models (name, description, level_count, status, import_source, import_id, version)
VALUES (
'Fähigkeitsmatrix (Wiki Import)',
'Alle Fähigkeiten aus der Wiki-Matrix (Karatetrainer). Haupt- und Untergruppen kommen aus skill_main_categories / skill_categories.',
5,
'active',
'wiki_matrix',
'faehigkeitsmatrix_karatetrainer',
'1.0'
)
RETURNING id INTO mid;
INSERT INTO maturity_model_focus_areas (maturity_model_id, focus_area_id, is_primary)
SELECT mid, fa.id, (fa.name = 'Karate')
FROM focus_areas fa
WHERE fa.name IN ('Karate', 'Selbstverteidigung', 'Gewaltschutz')
ON CONFLICT (maturity_model_id, focus_area_id) DO NOTHING;
INSERT INTO model_levels (maturity_model_id, level_number, name, description, sort_order)
VALUES
(mid, 1, 'Einsteiger', NULL, 1),
(mid, 2, 'Grundlagen', NULL, 2),
(mid, 3, 'Aufbau', NULL, 3),
(mid, 4, 'Fortgeschritten', NULL, 4),
(mid, 5, 'Experte', NULL, 5);
INSERT INTO model_skills (maturity_model_id, skill_id, sort_order, relevance)
SELECT
mid,
s.id,
ROW_NUMBER() OVER (
ORDER BY mc.sort_order NULLS LAST, sc.sort_order NULLS LAST, s.name
),
NULL
FROM skills s
LEFT JOIN skill_categories sc ON s.category_id = sc.id
LEFT JOIN skill_main_categories mc ON s.main_category_id = mc.id;
INSERT INTO model_skill_levels (maturity_model_id, skill_id, level_number, description, observable_criteria)
SELECT mid, sld.skill_id, sld.level, sld.description, NULL
FROM skill_level_definitions sld
ON CONFLICT (maturity_model_id, skill_id, level_number) DO NOTHING;
RAISE NOTICE 'Bootstrap: Reifegradmodell id=% angelegt (% Skills)', mid, n_skills;
END $$;