diff --git a/charts/my-recipes-chart/templates/db-migration-configmap.yaml b/charts/my-recipes-chart/templates/db-migration-configmap.yaml new file mode 100644 index 0000000..bb145c1 --- /dev/null +++ b/charts/my-recipes-chart/templates/db-migration-configmap.yaml @@ -0,0 +1,43 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-db-migration + namespace: {{ .Values.global.namespace }} +data: + migrate.sql: | + -- Add made_by column to recipes if it doesn't exist + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'recipes' AND column_name = 'made_by' + ) THEN + ALTER TABLE recipes ADD COLUMN made_by TEXT; + END IF; + END $$; + + -- Create index if it doesn't exist + CREATE INDEX IF NOT EXISTS idx_recipes_made_by ON recipes (made_by); + + -- Add is_admin column to users if it doesn't exist + DO $$ + BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'users' AND column_name = 'is_admin' + ) THEN + ALTER TABLE users ADD COLUMN is_admin BOOLEAN DEFAULT FALSE; + END IF; + END $$; + + -- Verify recipes schema + SELECT column_name, data_type + FROM information_schema.columns + WHERE table_name = 'recipes' + ORDER BY ordinal_position; + + -- Verify users schema + SELECT column_name, data_type + FROM information_schema.columns + WHERE table_name = 'users' + ORDER BY ordinal_position; diff --git a/charts/my-recipes-chart/templates/db-migration-job.yaml b/charts/my-recipes-chart/templates/db-migration-job.yaml index abb8a1b..f153342 100644 --- a/charts/my-recipes-chart/templates/db-migration-job.yaml +++ b/charts/my-recipes-chart/templates/db-migration-job.yaml @@ -1,110 +1,69 @@ -apiVersion: v1 -kind: ConfigMap +apiVersion: batch/v1 +kind: Job metadata: - name: {{ .Release.Name }}-db-migration + name: {{ .Release.Name }}-db-migration-{{ .Release.Revision }} namespace: {{ .Values.global.namespace }} -data: - migrate.sql: | - -- Create users table if it doesn't exist - CREATE TABLE IF NOT EXISTS users ( - id SERIAL PRIMARY KEY, - username TEXT UNIQUE NOT NULL, - email TEXT UNIQUE NOT NULL, - password_hash TEXT NOT NULL, - first_name TEXT, - last_name TEXT, - display_name TEXT NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP - ); + labels: + app: {{ .Release.Name }}-db-migration + component: migration + annotations: + "helm.sh/hook": post-upgrade,post-install + "helm.sh/hook-weight": "5" + "helm.sh/hook-delete-policy": before-hook-creation +spec: + ttlSecondsAfterFinished: 300 + template: + metadata: + labels: + app: {{ .Release.Name }}-db-migration + spec: + restartPolicy: Never + containers: + - name: migrate + image: postgres:16-alpine + command: + - /bin/sh + - -c + - | + echo "Waiting for database to be ready..." + until pg_isready -h $DB_HOST -U $DB_USER; do + echo "Database not ready, waiting..." + sleep 2 + done + echo "Database is ready, running migration..." + PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -U $DB_USER -d $DB_NAME -f /migration/migrate.sql + echo "Migration completed successfully" + env: + - name: DB_HOST + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-db-credentials + key: DB_HOST + - name: DB_PORT + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-db-credentials + key: DB_PORT + - name: DB_NAME + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-db-credentials + key: DB_NAME + - name: DB_USER + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-db-credentials + key: DB_USER + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Release.Name }}-db-credentials + key: DB_PASSWORD + volumeMounts: + - name: migration-script + mountPath: /migration + volumes: + - name: migration-script + configMap: + name: {{ .Release.Name }}-db-migration - -- Create recipes table if it doesn't exist (matching backend schema) - CREATE TABLE IF NOT EXISTS recipes ( - id SERIAL PRIMARY KEY, - name TEXT NOT NULL, - meal_type TEXT NOT NULL, - time_minutes INTEGER NOT NULL, - tags TEXT[] NOT NULL DEFAULT '{}', - ingredients TEXT[] NOT NULL DEFAULT '{}', - steps TEXT[] NOT NULL DEFAULT '{}', - image TEXT, - made_by TEXT, - user_id INTEGER REFERENCES users(id) ON DELETE SET NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP - ); - - -- Add new user columns if they don't exist - DO $$ - BEGIN - IF NOT EXISTS ( - SELECT 1 FROM information_schema.columns - WHERE table_name = 'users' AND column_name = 'first_name' - ) THEN - ALTER TABLE users ADD COLUMN first_name TEXT; - END IF; - END $$; - - DO $$ - BEGIN - IF NOT EXISTS ( - SELECT 1 FROM information_schema.columns - WHERE table_name = 'users' AND column_name = 'last_name' - ) THEN - ALTER TABLE users ADD COLUMN last_name TEXT; - END IF; - END $$; - - DO $$ - BEGIN - IF NOT EXISTS ( - SELECT 1 FROM information_schema.columns - WHERE table_name = 'users' AND column_name = 'display_name' - ) THEN - ALTER TABLE users ADD COLUMN display_name TEXT; - -- Set display_name to username for existing users - UPDATE users SET display_name = username WHERE display_name IS NULL; - ALTER TABLE users ALTER COLUMN display_name SET NOT NULL; - END IF; - END $$; - - -- Add user_id column if it doesn't exist (for existing recipes tables) - DO $$ - BEGIN - IF NOT EXISTS ( - SELECT 1 FROM information_schema.columns - WHERE table_name = 'recipes' AND column_name = 'user_id' - ) THEN - ALTER TABLE recipes ADD COLUMN user_id INTEGER REFERENCES users(id) ON DELETE SET NULL; - END IF; - END $$; - - -- Add created_at column to recipes if it doesn't exist - DO $$ - BEGIN - IF NOT EXISTS ( - SELECT 1 FROM information_schema.columns - WHERE table_name = 'recipes' AND column_name = 'created_at' - ) THEN - ALTER TABLE recipes ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP; - END IF; - END $$; - - -- Create indexes - CREATE INDEX IF NOT EXISTS idx_recipes_meal_type ON recipes (meal_type); - CREATE INDEX IF NOT EXISTS idx_recipes_time_minutes ON recipes (time_minutes); - CREATE INDEX IF NOT EXISTS idx_recipes_made_by ON recipes (made_by); - CREATE INDEX IF NOT EXISTS idx_recipes_user_id ON recipes (user_id); - CREATE INDEX IF NOT EXISTS idx_users_username ON users (username); - CREATE INDEX IF NOT EXISTS idx_users_email ON users (email); - - -- Verify schema - SELECT 'Users table:' as info; - SELECT column_name, data_type - FROM information_schema.columns - WHERE table_name = 'users' - ORDER BY ordinal_position; - - SELECT 'Recipes table:' as info; - SELECT column_name, data_type - FROM information_schema.columns - WHERE table_name = 'recipes' - ORDER BY ordinal_position;