diff --git a/charts/my-recipes-chart/templates/db-schema-configmap.yaml b/charts/my-recipes-chart/templates/db-schema-configmap.yaml index c4b18be..1063dd9 100644 --- a/charts/my-recipes-chart/templates/db-schema-configmap.yaml +++ b/charts/my-recipes-chart/templates/db-schema-configmap.yaml @@ -1,50 +1,142 @@ apiVersion: v1 kind: ConfigMap metadata: - name: {{ .Release.Name }}-db-schema + name: {{ .Release.Name }}-db-migration namespace: {{ .Values.global.namespace }} data: - schema.sql: | - -- Create users table + 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, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + id SERIAL PRIMARY KEY, + username TEXT UNIQUE NOT NULL, + email TEXT UNIQUE NOT NULL, + password_hash TEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); + -- 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 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); - -- Create recipes table - CREATE TABLE IF NOT EXISTS recipes ( - id SERIAL PRIMARY KEY, - name TEXT NOT NULL, - meal_type TEXT NOT NULL, -- breakfast / lunch / dinner / snack - time_minutes INTEGER NOT NULL, - made_by TEXT, -- Person who created this recipe version - tags JSONB NOT NULL DEFAULT '[]', -- ["מהיר", "בריא"] - ingredients JSONB NOT NULL DEFAULT '[]', -- ["ביצה", "עגבניה", "מלח"] - steps JSONB NOT NULL DEFAULT '[]', -- ["לחתוך", "לבשל", ...] - image TEXT, -- Base64-encoded image or image URL - user_id INTEGER REFERENCES users(id) ON DELETE SET NULL, -- Recipe owner - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP - ); - - -- Optional: index for filters - 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_tags_jsonb - ON recipes USING GIN (tags); - - CREATE INDEX IF NOT EXISTS idx_recipes_ingredients_jsonb - ON recipes USING GIN (ingredients); + -- 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; +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Release.Name }}-db-migration-{{ .Release.Revision }} + namespace: {{ .Values.global.namespace }} + labels: + app: {{ .Release.Name }}-db-migration + component: migration + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "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