Compare commits

..

No commits in common. "a5fc28111bf3c9c55c9538f2cf5da3eec4a00e6c" and "c0ec6b635ec61741010f6db61f6534fe46dbbc95" have entirely different histories.

5 changed files with 29 additions and 129 deletions

View File

@ -58,16 +58,6 @@ spec:
secretKeyRef: secretKeyRef:
name: {{ include "invy.fullname" . }}-secrets name: {{ include "invy.fullname" . }}-secrets
key: google-client-secret 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 }} {{- range $key, $value := .Values.backend.env }}
- name: {{ $key }} - name: {{ $key }}
value: {{ $value | quote }} value: {{ $value | quote }}

View File

@ -7,120 +7,39 @@ metadata:
app.kubernetes.io/component: database app.kubernetes.io/component: database
data: data:
init.sql: | init.sql: |
-- Invy — Full Database Init Schema -- Wedding Guest List Database Schema
-- Runs only on a FRESH (empty) data directory.
-- For existing production DBs run migrate_production.sql manually.
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE TABLE IF NOT EXISTS guests (
id SERIAL PRIMARY KEY,
-- ── Users ────────────────────────────────────────────────────────────── first_name VARCHAR(100) NOT NULL,
CREATE TABLE IF NOT EXISTS users ( last_name VARCHAR(100) NOT NULL,
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), email VARCHAR(255) UNIQUE,
email TEXT NOT NULL UNIQUE, phone_number VARCHAR(50),
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP rsvp_status VARCHAR(20) DEFAULT 'pending' CHECK (rsvp_status IN ('pending', 'accepted', 'declined')),
); meal_preference VARCHAR(50),
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); has_plus_one BOOLEAN DEFAULT FALSE,
plus_one_name VARCHAR(200),
-- ── Events ───────────────────────────────────────────────────────────── owner VARCHAR(50),
CREATE TABLE IF NOT EXISTS events ( notes TEXT,
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), table_number INTEGER,
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);
-- ── 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, created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP WITH TIME ZONE, updated_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 indexes for better query performance
CREATE OR REPLACE FUNCTION _update_updated_at() CREATE INDEX IF NOT EXISTS idx_guests_email ON guests(email);
RETURNS TRIGGER LANGUAGE plpgsql AS $$ 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);
-- Create trigger to update updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN BEGIN
NEW.updated_at = CURRENT_TIMESTAMP; NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW; RETURN NEW;
END; END;
$$; $$ language 'plpgsql';
DO $$ BEGIN CREATE TRIGGER update_guests_updated_at BEFORE UPDATE ON guests
CREATE TRIGGER trg_guests_v2_updated_at FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
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 $$;

View File

@ -12,5 +12,3 @@ stringData:
database-url: "postgresql://{{ .Values.postgres.user }}:{{ .Values.postgres.password }}@{{ include "invy.fullname" . }}-db:{{ .Values.postgres.port }}/{{ .Values.postgres.database }}" 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-id: {{ .Values.backend.googleClientId | quote }}
google-client-secret: {{ .Values.backend.googleClientSecret | quote }} google-client-secret: {{ .Values.backend.googleClientSecret | quote }}
whatsapp-access-token: {{ .Values.backend.whatsappAccessToken | quote }}
whatsapp-phone-number-id: {{ .Values.backend.whatsappPhoneNumberId | quote }}

View File

@ -33,10 +33,6 @@ backend:
googleClientId: "YOUR_GOOGLE_CLIENT_ID" googleClientId: "YOUR_GOOGLE_CLIENT_ID"
googleClientSecret: "YOUR_GOOGLE_CLIENT_SECRET" googleClientSecret: "YOUR_GOOGLE_CLIENT_SECRET"
# WhatsApp Cloud API credentials (set these values!)
whatsappAccessToken: "YOUR_WHATSAPP_ACCESS_TOKEN"
whatsappPhoneNumberId: "YOUR_WHATSAPP_PHONE_NUMBER_ID"
ingress: ingress:
enabled: true enabled: true
className: "traefik" className: "traefik"

View File

@ -8,7 +8,7 @@ backend:
image: image:
repository: harbor.dvirlabs.com/my-apps/invy-backend repository: harbor.dvirlabs.com/my-apps/invy-backend
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
tag: "master-71b6828" tag: "master-d4270ea"
service: service:
type: ClusterIP type: ClusterIP
port: 8000 port: 8000
@ -27,9 +27,6 @@ backend:
# Google OAuth credentials # Google OAuth credentials
googleClientId: "97702229450-ivi5rvj0drai08k5svm7sekqdijj6953.apps.googleusercontent.com" googleClientId: "97702229450-ivi5rvj0drai08k5svm7sekqdijj6953.apps.googleusercontent.com"
googleClientSecret: "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" googleClientSecret: "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"
# WhatsApp Cloud API credentials
whatsappAccessToken: "EAAMdmYX7DJUBQ5Hc07NUTSgvu1ZCF51FfQRrrUNuuZBpaRLpoT2BzXa6rFcsZC8BJZCHS7j7rJFpFAwlKlwm0LsRgDpQRMU0MDcqaOIPzJ56Xp2ueBArGaPn2gGyj9dp1X7VPt0N8bZCBcUPOsTpKTflWjj09Y1NahbtZAQ5msXo2JV1wVTnaQrzKN7wYwkpLxNAZDZD"
whatsappPhoneNumberId: "1028674740318926"
ingress: ingress:
enabled: true enabled: true
className: "traefik" className: "traefik"
@ -53,7 +50,7 @@ frontend:
image: image:
repository: harbor.dvirlabs.com/my-apps/invy-frontend repository: harbor.dvirlabs.com/my-apps/invy-frontend
pullPolicy: IfNotPresent pullPolicy: IfNotPresent
tag: "master-71b6828" tag: "master-d4270ea"
service: service:
type: ClusterIP type: ClusterIP
port: 80 port: 80