ALTER TABLE "app_notification_templates" ADD COLUMN "code" text DEFAULT '' NOT NULL, ADD COLUMN "name" text DEFAULT '' NOT NULL, ADD COLUMN "subject_template" text, ADD COLUMN "body_format" text DEFAULT 'plain' NOT NULL, ADD COLUMN "language" text DEFAULT 'th' NOT NULL, ADD COLUMN "variables" jsonb, ADD COLUMN "version" integer DEFAULT 1 NOT NULL; --> statement-breakpoint UPDATE "app_notification_templates" SET "code" = CASE WHEN "code" = '' THEN replace("event_type", '.', '_') || '_' || "channel" ELSE "code" END, "name" = CASE WHEN "name" = '' THEN "event_type" || ' (' || "channel" || ')' ELSE "name" END, "subject_template" = COALESCE("subject_template", "title_template"), "variables" = COALESCE("variables", '[]'::jsonb); --> statement-breakpoint CREATE TABLE "app_notification_dispatches" ( "id" text PRIMARY KEY NOT NULL, "organization_id" text NOT NULL, "event_id" text NOT NULL, "template_id" text, "entity_type" text NOT NULL, "entity_id" text NOT NULL, "channel" text NOT NULL, "provider_key" text NOT NULL, "status" text DEFAULT 'pending' NOT NULL, "recipient_to" jsonb NOT NULL, "recipient_cc" jsonb, "recipient_bcc" jsonb, "reply_to" text, "subject" text NOT NULL, "body_text" text NOT NULL, "body_html" text, "attachments" jsonb, "recipient_user_id" text, "recipient_address" text, "requested_by" text NOT NULL, "metadata" jsonb, "last_error" text, "retry_count" integer DEFAULT 0 NOT NULL, "max_retry_count" integer DEFAULT 3 NOT NULL, "last_attempt_at" timestamp with time zone, "sent_at" timestamp with time zone, "created_at" timestamp with time zone DEFAULT now() NOT NULL, "updated_at" timestamp with time zone DEFAULT now() NOT NULL ); --> statement-breakpoint CREATE UNIQUE INDEX "app_notification_dispatches_org_event_channel_recipient_idx" ON "app_notification_dispatches" USING btree ( "organization_id", "event_id", "channel", "recipient_address" );