From de9710c23dd9e300e9b34c726bc2ba2f4f6cd44f Mon Sep 17 00:00:00 2001 From: dvirlabs Date: Sun, 1 Mar 2026 02:49:43 +0200 Subject: [PATCH] Update Whatsapp credentials --- .../templates/backend-deployment.yaml | 10 ++ .../templates/db-schema-configmap.yaml | 135 ++++++++++++++---- charts/invy-chart/templates/secret.yaml | 2 + charts/invy-chart/values.yaml | 4 + manifests/invy/values.yaml | 5 +- 5 files changed, 128 insertions(+), 28 deletions(-) diff --git a/charts/invy-chart/templates/backend-deployment.yaml b/charts/invy-chart/templates/backend-deployment.yaml index 273ddbb..f6ed0cd 100644 --- a/charts/invy-chart/templates/backend-deployment.yaml +++ b/charts/invy-chart/templates/backend-deployment.yaml @@ -58,6 +58,16 @@ spec: secretKeyRef: name: {{ include "invy.fullname" . }}-secrets key: google-client-secret + - name: WHATSAPP_ACCESS_TOKEN + valueFrom: + secretKeyRef: + name: {{ include "invy.fullname" . }}-secrets + key: whatsapp-access-token + - name: WHATSAPP_PHONE_NUMBER_ID + valueFrom: + secretKeyRef: + name: {{ include "invy.fullname" . }}-secrets + key: whatsapp-phone-number-id {{- range $key, $value := .Values.backend.env }} - name: {{ $key }} value: {{ $value | quote }} diff --git a/charts/invy-chart/templates/db-schema-configmap.yaml b/charts/invy-chart/templates/db-schema-configmap.yaml index 818720c..163cce5 100644 --- a/charts/invy-chart/templates/db-schema-configmap.yaml +++ b/charts/invy-chart/templates/db-schema-configmap.yaml @@ -7,39 +7,120 @@ metadata: app.kubernetes.io/component: database data: init.sql: | - -- Wedding Guest List Database Schema + -- Invy — Full Database Init Schema + -- Runs only on a FRESH (empty) data directory. + -- For existing production DBs run migrate_production.sql manually. - CREATE TABLE IF NOT EXISTS guests ( - id SERIAL PRIMARY KEY, - first_name VARCHAR(100) NOT NULL, - last_name VARCHAR(100) NOT NULL, - email VARCHAR(255) UNIQUE, - phone_number VARCHAR(50), - rsvp_status VARCHAR(20) DEFAULT 'pending' CHECK (rsvp_status IN ('pending', 'accepted', 'declined')), - meal_preference VARCHAR(50), - has_plus_one BOOLEAN DEFAULT FALSE, - plus_one_name VARCHAR(200), - owner VARCHAR(50), - notes TEXT, - table_number INTEGER, - created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP WITH TIME ZONE + CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + + -- ── Users ────────────────────────────────────────────────────────────── + CREATE TABLE IF NOT EXISTS users ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + email TEXT NOT NULL UNIQUE, + created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP ); + CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); - -- Create indexes for better query performance - CREATE INDEX IF NOT EXISTS idx_guests_email ON guests(email); - CREATE INDEX IF NOT EXISTS idx_guests_rsvp_status ON guests(rsvp_status); - CREATE INDEX IF NOT EXISTS idx_guests_last_name ON guests(last_name); - CREATE INDEX IF NOT EXISTS idx_guests_owner ON guests(owner); + -- ── Events ───────────────────────────────────────────────────────────── + CREATE TABLE IF NOT EXISTS events ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + name TEXT NOT NULL, + date TIMESTAMP WITH TIME ZONE, + location TEXT, + partner1_name TEXT, + partner2_name TEXT, + venue TEXT, + event_time TEXT, + guest_link TEXT, + created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP + ); + CREATE INDEX IF NOT EXISTS idx_events_created_at ON events(created_at); + CREATE INDEX IF NOT EXISTS idx_events_guest_link ON events(guest_link); - -- Create trigger to update updated_at timestamp - CREATE OR REPLACE FUNCTION update_updated_at_column() - RETURNS TRIGGER AS $$ + -- ── Event members (authorization) ────────────────────────────────────── + CREATE TABLE IF NOT EXISTS event_members ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE, + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + role TEXT NOT NULL DEFAULT 'admin' + CHECK (role IN ('admin', 'editor', 'viewer')), + display_name TEXT, + created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, + UNIQUE(event_id, user_id) + ); + CREATE INDEX IF NOT EXISTS idx_event_members_event_id ON event_members(event_id); + CREATE INDEX IF NOT EXISTS idx_event_members_user_id ON event_members(user_id); + CREATE INDEX IF NOT EXISTS idx_event_members_event_user ON event_members(event_id, user_id); + + -- ── Guests v2 ────────────────────────────────────────────────────────── + CREATE TABLE IF NOT EXISTS guests_v2 ( + id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE, + added_by_user_id UUID NOT NULL REFERENCES users(id), + + first_name TEXT NOT NULL, + last_name TEXT NOT NULL DEFAULT '', + email TEXT, + phone TEXT, + phone_number TEXT, + + rsvp_status TEXT NOT NULL DEFAULT 'invited' + CHECK (rsvp_status IN ('invited', 'confirmed', 'declined')), + meal_preference TEXT, + + has_plus_one BOOLEAN DEFAULT FALSE, + plus_one_name TEXT, + + table_number TEXT, + side TEXT, + + owner_email TEXT, + source TEXT NOT NULL DEFAULT 'manual' + CHECK (source IN ('google', 'manual', 'self-service')), + + notes TEXT, + created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP + ); + CREATE INDEX IF NOT EXISTS idx_guests_v2_event_id ON guests_v2(event_id); + CREATE INDEX IF NOT EXISTS idx_guests_v2_added_by ON guests_v2(added_by_user_id); + CREATE INDEX IF NOT EXISTS idx_guests_v2_phone_number ON guests_v2(phone_number); + CREATE INDEX IF NOT EXISTS idx_guests_v2_event_phone ON guests_v2(event_id, phone_number); + CREATE INDEX IF NOT EXISTS idx_guests_v2_event_status ON guests_v2(event_id, rsvp_status); + CREATE INDEX IF NOT EXISTS idx_guests_v2_owner_email ON guests_v2(event_id, owner_email); + CREATE INDEX IF NOT EXISTS idx_guests_v2_source ON guests_v2(event_id, source); + + -- ── RSVP tokens ──────────────────────────────────────────────────────── + CREATE TABLE IF NOT EXISTS rsvp_tokens ( + token TEXT PRIMARY KEY, + event_id UUID NOT NULL REFERENCES events(id) ON DELETE CASCADE, + guest_id UUID REFERENCES guests_v2(id) ON DELETE SET NULL, + phone TEXT, + created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, + expires_at TIMESTAMP WITH TIME ZONE, + used_at TIMESTAMP WITH TIME ZONE + ); + CREATE INDEX IF NOT EXISTS idx_rsvp_tokens_event_id ON rsvp_tokens(event_id); + CREATE INDEX IF NOT EXISTS idx_rsvp_tokens_guest_id ON rsvp_tokens(guest_id); + + -- ── updated_at trigger ───────────────────────────────────────────────── + CREATE OR REPLACE FUNCTION _update_updated_at() + RETURNS TRIGGER LANGUAGE plpgsql AS $$ BEGIN NEW.updated_at = CURRENT_TIMESTAMP; RETURN NEW; END; - $$ language 'plpgsql'; + $$; - CREATE TRIGGER update_guests_updated_at BEFORE UPDATE ON guests - FOR EACH ROW EXECUTE FUNCTION update_updated_at_column(); + DO $$ BEGIN + CREATE TRIGGER trg_guests_v2_updated_at + BEFORE UPDATE ON guests_v2 + FOR EACH ROW EXECUTE FUNCTION _update_updated_at(); + EXCEPTION WHEN duplicate_object THEN NULL; END $$; + + DO $$ BEGIN + CREATE TRIGGER trg_events_updated_at + BEFORE UPDATE ON events + FOR EACH ROW EXECUTE FUNCTION _update_updated_at(); + EXCEPTION WHEN duplicate_object THEN NULL; END $$; diff --git a/charts/invy-chart/templates/secret.yaml b/charts/invy-chart/templates/secret.yaml index 8ed8519..8053f52 100644 --- a/charts/invy-chart/templates/secret.yaml +++ b/charts/invy-chart/templates/secret.yaml @@ -12,3 +12,5 @@ stringData: database-url: "postgresql://{{ .Values.postgres.user }}:{{ .Values.postgres.password }}@{{ include "invy.fullname" . }}-db:{{ .Values.postgres.port }}/{{ .Values.postgres.database }}" google-client-id: {{ .Values.backend.googleClientId | quote }} google-client-secret: {{ .Values.backend.googleClientSecret | quote }} + whatsapp-access-token: {{ .Values.backend.whatsappAccessToken | quote }} + whatsapp-phone-number-id: {{ .Values.backend.whatsappPhoneNumberId | quote }} diff --git a/charts/invy-chart/values.yaml b/charts/invy-chart/values.yaml index f131f95..94c6321 100644 --- a/charts/invy-chart/values.yaml +++ b/charts/invy-chart/values.yaml @@ -33,6 +33,10 @@ backend: googleClientId: "YOUR_GOOGLE_CLIENT_ID" googleClientSecret: "YOUR_GOOGLE_CLIENT_SECRET" + # WhatsApp Cloud API credentials (set these values!) + whatsappAccessToken: "YOUR_WHATSAPP_ACCESS_TOKEN" + whatsappPhoneNumberId: "YOUR_WHATSAPP_PHONE_NUMBER_ID" + ingress: enabled: true className: "traefik" diff --git a/manifests/invy/values.yaml b/manifests/invy/values.yaml index 04d7f31..333778c 100644 --- a/manifests/invy/values.yaml +++ b/manifests/invy/values.yaml @@ -27,6 +27,9 @@ backend: # Google OAuth credentials googleClientId: "97702229450-ivi5rvj0drai08k5svm7sekqdijj6953.apps.googleusercontent.com" googleClientSecret: "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" + # WhatsApp Cloud API credentials + whatsappAccessToken: "EAAMdmYX7DJUBQxcw1WmKVW8jKQalkPiCb7VZAQgh1mN69b6hNkPxAZAM7XRcZB0rKC6H77VxQ8q2pfEMaGvGpVEXALs4rq3lxLQJfAjfxyIJJFc2pIvJ4PEBTHpJQM3TxS6Oaz835rIGMk3exzvZA0ZCJp5YaLtdvZCeHmnn0QVluoZAfcNGlz9lUbcl7oHWOZB123rJDEaL6UL6uoRim4pCpKAl1J5ZAZB4kgEJAFhLOMsIZBZBQazkxbUvHKqtjxwtJJ5KmecxNGNDkCQXcALs4jElLkQKtQZDZD" + whatsappPhoneNumberId: "1028674740318926" ingress: enabled: true className: "traefik" @@ -50,7 +53,7 @@ frontend: image: repository: harbor.dvirlabs.com/my-apps/invy-frontend pullPolicy: IfNotPresent - tag: "master-e0169b8" + tag: "master-d4270ea" service: type: ClusterIP port: 80