Files
cmdb-insight/docs/DATABASE-NORMALIZATION-PROPOSAL.md
Bert Hausmans cdee0e8819 UI styling improvements: dashboard headers and navigation
- Restore blue PageHeader on Dashboard (/app-components)
- Update homepage (/) with subtle header design without blue bar
- Add uniform PageHeader styling to application edit page
- Fix Rapporten link on homepage to point to /reports overview
- Improve header descriptions spacing for better readability
2026-01-21 03:24:56 +01:00

6.7 KiB

Database Normalisatie Voorstel

Huidige Probleem

De huidige database structuur heeft duplicatie en is niet goed genormaliseerd:

  1. object_types tabel bevat:

    • jira_type_id, type_name, display_name, description, sync_priority, object_count
  2. configured_object_types tabel bevat:

    • schema_id, schema_name, object_type_id, object_type_name, display_name, description, object_count, enabled

Problemen:

  • Duplicatie van display_name, description, object_count
  • Geen expliciete relatie tussen schemas en object types
  • schema_name wordt opgeslagen in elke object type row (niet genormaliseerd)
  • Verwarring tussen object_type_name en type_name
  • Twee tabellen die dezelfde informatie bevatten

Voorgestelde Genormaliseerde Structuur

1. schemas Tabel

CREATE TABLE IF NOT EXISTS schemas (
  id SERIAL PRIMARY KEY,                    -- Auto-increment PK
  jira_schema_id TEXT NOT NULL UNIQUE,      -- Jira schema ID (bijv. "6", "8")
  name TEXT NOT NULL,                        -- Schema naam (bijv. "Application Management")
  description TEXT,                          -- Optionele beschrijving
  discovered_at TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

Doel: Centrale opslag van alle Jira Assets schemas.

2. object_types Tabel (Aangepast)

CREATE TABLE IF NOT EXISTS object_types (
  id SERIAL PRIMARY KEY,                     -- Auto-increment PK
  schema_id INTEGER NOT NULL REFERENCES schemas(id) ON DELETE CASCADE,
  jira_type_id INTEGER NOT NULL,            -- Jira object type ID
  type_name TEXT NOT NULL UNIQUE,           -- PascalCase type name (bijv. "ApplicationComponent")
  display_name TEXT NOT NULL,                -- Original Jira name (bijv. "Application Component")
  description TEXT,                          -- Optionele beschrijving
  sync_priority INTEGER DEFAULT 0,          -- Sync prioriteit
  object_count INTEGER DEFAULT 0,            -- Aantal objecten in Jira
  enabled BOOLEAN NOT NULL DEFAULT FALSE,   -- KEY CHANGE: enabled flag hier!
  discovered_at TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
  UNIQUE(schema_id, jira_type_id)           -- Een object type kan maar 1x per schema voorkomen
);

Doel: Alle object types met hun schema relatie en enabled status.

3. attributes Tabel (Ongewijzigd)

CREATE TABLE IF NOT EXISTS attributes (
  id SERIAL PRIMARY KEY,
  jira_attr_id INTEGER NOT NULL,
  object_type_name TEXT NOT NULL REFERENCES object_types(type_name) ON DELETE CASCADE,
  -- ... rest blijft hetzelfde
);

Voordelen van Genormaliseerde Structuur

  1. Geen Duplicatie:

    • Schema informatie staat maar 1x in schemas tabel
    • Object type informatie staat maar 1x in object_types tabel
    • enabled flag staat direct bij object type
  2. Duidelijke Relaties:

    • Foreign key schema_id maakt relatie expliciet
    • Database constraints zorgen voor data integriteit
  3. Eenvoudigere Queries:

    -- Alle enabled object types met hun schema
    SELECT ot.*, s.name as schema_name
    FROM object_types ot
    JOIN schemas s ON ot.schema_id = s.id
    WHERE ot.enabled = TRUE;
    
  4. Minder Verwarring:

    • Geen object_type_name vs type_name meer
    • Geen configured_object_types vs object_types meer
    • Eén bron van waarheid
  5. Eenvoudigere Migratie:

    • configured_object_types kan worden verwijderd
    • Data kan worden gemigreerd naar nieuwe structuur

Migratie Plan

  1. Nieuwe Tabellen Aanmaken:

    • schemas tabel
    • object_types tabel aanpassen (toevoegen schema_id, enabled)
  2. Data Migreren:

    • Unieke schemas uit configured_object_types naar schemas
    • Object types uit configured_object_types naar object_types met juiste schema_id FK
    • enabled flag overnemen
  3. Foreign Keys Aanpassen:

    • attributes.object_type_name blijft verwijzen naar object_types.type_name
    • objects.object_type_name blijft verwijzen naar object_types.type_name
  4. Code Aanpassen:

    • schemaConfigurationService aanpassen voor nieuwe structuur
    • schemaDiscoveryService aanpassen voor nieuwe structuur
    • schemaCacheService aanpassen voor JOIN met schemas
  5. Oude Tabel Verwijderen:

    • configured_object_types tabel verwijderen na migratie

Impact op Bestaande Code

Services die aangepast moeten worden:

  1. schemaConfigurationService.ts:

    • discoverAndStoreSchemasAndObjectTypes() - eerst schemas opslaan, dan object types
    • getConfiguredObjectTypes() - JOIN met schemas
    • setObjectTypeEnabled() - direct op object_types.enabled
    • getEnabledObjectTypes() - WHERE enabled = TRUE
  2. schemaDiscoveryService.ts:

    • Moet ook schemas en object types in nieuwe structuur opslaan
    • Moet enabled flag respecteren
  3. schemaCacheService.ts:

    • fetchFromDatabase() - JOIN met schemas voor schema naam
    • Filter op object_types.enabled = TRUE
  4. syncEngine.ts:

    • Gebruikt al getEnabledObjectTypes() - blijft werken na aanpassing service

SQL Migratie Script

-- Stap 1: Maak schemas tabel
CREATE TABLE IF NOT EXISTS schemas (
  id SERIAL PRIMARY KEY,
  jira_schema_id TEXT NOT NULL UNIQUE,
  name TEXT NOT NULL,
  description TEXT,
  discovered_at TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- Stap 2: Voeg schema_id en enabled toe aan object_types
ALTER TABLE object_types 
  ADD COLUMN IF NOT EXISTS schema_id INTEGER REFERENCES schemas(id) ON DELETE CASCADE,
  ADD COLUMN IF NOT EXISTS enabled BOOLEAN NOT NULL DEFAULT FALSE;

-- Stap 3: Migreer data
-- Eerst: unieke schemas
INSERT INTO schemas (jira_schema_id, name, description, discovered_at, updated_at)
SELECT DISTINCT 
  schema_id as jira_schema_id,
  schema_name as name,
  NULL as description,
  MIN(discovered_at) as discovered_at,
  MAX(updated_at) as updated_at
FROM configured_object_types
GROUP BY schema_id, schema_name
ON CONFLICT(jira_schema_id) DO NOTHING;

-- Dan: object types met schema_id FK
UPDATE object_types ot
SET 
  schema_id = s.id,
  enabled = COALESCE(
    (SELECT enabled FROM configured_object_types cot 
     WHERE cot.object_type_id = ot.jira_type_id 
     AND cot.schema_id = s.jira_schema_id 
     LIMIT 1),
    FALSE
  )
FROM schemas s
WHERE EXISTS (
  SELECT 1 FROM configured_object_types cot
  WHERE cot.object_type_id = ot.jira_type_id
  AND cot.schema_id = s.jira_schema_id
);

-- Stap 4: Verwijder oude tabel (na verificatie)
-- DROP TABLE IF EXISTS configured_object_types;

Conclusie

De genormaliseerde structuur is veel cleaner, elimineert duplicatie, en maakt queries eenvoudiger. De enabled flag staat nu direct bij het object type, wat logischer is.