);
}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 4a8c05a344..b6c66ef6b6 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -22,10 +22,10 @@ const inter = Inter({
export const metadata: Metadata = {
title: {
- default: "wacrm",
- template: "%s — wacrm",
+ default: "waivy",
+ template: "%s — waivy",
},
- description: "Self-hostable CRM template for WhatsApp.",
+ description: "waivy — CRM inteligente para WhatsApp.",
robots: {
index: false,
follow: false,
diff --git a/supabase/.gitignore b/supabase/.gitignore
new file mode 100644
index 0000000000..ad9264f0b1
--- /dev/null
+++ b/supabase/.gitignore
@@ -0,0 +1,8 @@
+# Supabase
+.branches
+.temp
+
+# dotenvx
+.env.keys
+.env.local
+.env.*.local
diff --git a/supabase/config.toml b/supabase/config.toml
new file mode 100644
index 0000000000..666d49e710
--- /dev/null
+++ b/supabase/config.toml
@@ -0,0 +1,414 @@
+# For detailed configuration reference documentation, visit:
+# https://supabase.com/docs/guides/local-development/cli/config
+# A string used to distinguish different Supabase projects on the same host. Defaults to the
+# working directory name when running `supabase init`.
+project_id = "wacria"
+
+[api]
+enabled = true
+# Port to use for the API URL.
+port = 54321
+# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API
+# endpoints. `public` and `graphql_public` schemas are included by default.
+schemas = ["public", "graphql_public"]
+# Extra schemas to add to the search_path of every request.
+extra_search_path = ["public", "extensions"]
+# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size
+# for accidental or malicious requests.
+max_rows = 1000
+# Controls whether new tables, views, sequences and functions created in the `public` schema by
+# `postgres` are reachable through the Data API roles (`anon`, `authenticated`, `service_role`)
+# without explicit GRANTs. When unset, new entities are NOT auto-exposed, matching the new cloud
+# default. Set to `true` to keep the legacy behaviour of auto-exposing new entities; this is
+# deprecated and the field is removed on 2026-10-30 once the always-revoked behaviour is permanent.
+# auto_expose_new_tables = true
+
+[api.tls]
+# Enable HTTPS endpoints locally using a self-signed certificate.
+enabled = false
+# Paths to self-signed certificate pair.
+# cert_path = "../certs/my-cert.pem"
+# key_path = "../certs/my-key.pem"
+
+[db]
+# Port to use for the local database URL.
+port = 54322
+# Port used by db diff command to initialize the shadow database.
+shadow_port = 54320
+# Maximum amount of time to wait for health check when starting the local database.
+health_timeout = "2m"
+# The database major version to use. This has to be the same as your remote database's. Run `SHOW
+# server_version;` on the remote database to check.
+major_version = 17
+
+[db.pooler]
+enabled = false
+# Port to use for the local connection pooler.
+port = 54329
+# Specifies when a server connection can be reused by other clients.
+# Configure one of the supported pooler modes: `transaction`, `session`.
+pool_mode = "transaction"
+# How many server connections to allow per user/database pair.
+default_pool_size = 20
+# Maximum number of client connections allowed.
+max_client_conn = 100
+
+# [db.vault]
+# secret_key = "env(SECRET_VALUE)"
+
+[db.migrations]
+# If disabled, migrations will be skipped during a db push or reset.
+enabled = true
+# Specifies an ordered list of schema files, directories, or glob patterns that describe your database.
+# Supports paths relative to supabase directory: "./schemas/*.sql", "./database".
+schema_paths = []
+
+[db.seed]
+# If enabled, seeds the database after migrations during a db reset.
+enabled = true
+# Specifies an ordered list of seed files to load during db reset.
+# Supports glob patterns relative to supabase directory: "./seeds/*.sql"
+sql_paths = ["./seed.sql"]
+
+[db.network_restrictions]
+# Enable management of network restrictions.
+enabled = false
+# List of IPv4 CIDR blocks allowed to connect to the database.
+# Defaults to allow all IPv4 connections. Set empty array to block all IPs.
+allowed_cidrs = ["0.0.0.0/0"]
+# List of IPv6 CIDR blocks allowed to connect to the database.
+# Defaults to allow all IPv6 connections. Set empty array to block all IPs.
+allowed_cidrs_v6 = ["::/0"]
+
+# Uncomment to reject non-secure connections to the database.
+# [db.ssl_enforcement]
+# enabled = true
+
+[realtime]
+enabled = true
+# Bind realtime via either IPv4 or IPv6. (default: IPv4)
+# ip_version = "IPv6"
+# The maximum length in bytes of HTTP request headers. (default: 4096)
+# max_header_length = 4096
+
+[studio]
+enabled = true
+# Port to use for Supabase Studio.
+port = 54323
+# External URL of the API server that frontend connects to.
+api_url = "http://127.0.0.1"
+# OpenAI API Key to use for Supabase AI in the Supabase Studio.
+openai_api_key = "env(OPENAI_API_KEY)"
+
+# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they
+# are monitored, and you can view the emails that would have been sent from the web interface.
+[local_smtp]
+enabled = true
+# Port to use for the email testing server web interface.
+port = 54324
+# Uncomment to expose additional ports for testing user applications that send emails.
+# smtp_port = 54325
+# pop3_port = 54326
+# admin_email = "admin@email.com"
+# sender_name = "Admin"
+
+[storage]
+enabled = true
+# The maximum file size allowed (e.g. "5MB", "500KB").
+file_size_limit = "50MiB"
+
+# Uncomment to configure local storage buckets
+# [storage.buckets.images]
+# public = false
+# file_size_limit = "50MiB"
+# allowed_mime_types = ["image/png", "image/jpeg"]
+# objects_path = "./images"
+
+# Allow connections via S3 compatible clients
+[storage.s3_protocol]
+enabled = true
+
+# Image transformation API is available to Supabase Pro plan.
+# [storage.image_transformation]
+# enabled = true
+
+# Store analytical data in S3 for running ETL jobs over Iceberg Catalog
+# This feature is only available on the hosted platform.
+[storage.analytics]
+enabled = false
+max_namespaces = 5
+max_tables = 10
+max_catalogs = 2
+
+# Analytics Buckets is available to Supabase Pro plan.
+# [storage.analytics.buckets.my-warehouse]
+
+# Store vector embeddings in S3 for large and durable datasets
+[storage.vector]
+enabled = true
+max_buckets = 10
+max_indexes = 5
+
+# Vector Buckets is available to Supabase Pro plan.
+# [storage.vector.buckets.documents-openai]
+
+[auth]
+enabled = true
+# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
+# in emails.
+site_url = "http://127.0.0.1:3000"
+# The public URL that Auth serves on. Defaults to the API external URL with `/auth/v1` appended.
+# external_url = ""
+# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
+additional_redirect_urls = ["https://127.0.0.1:3000"]
+# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
+jwt_expiry = 3600
+# JWT issuer URL. If not set, defaults to auth.external_url.
+# jwt_issuer = ""
+# Path to JWT signing key. DO NOT commit your signing keys file to git.
+# signing_keys_path = "./signing_keys.json"
+# If disabled, the refresh token will never expire.
+enable_refresh_token_rotation = true
+# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds.
+# Requires enable_refresh_token_rotation = true.
+refresh_token_reuse_interval = 10
+# Allow/disallow new user signups to your project.
+enable_signup = true
+# Allow/disallow anonymous sign-ins to your project.
+enable_anonymous_sign_ins = false
+# Allow/disallow testing manual linking of accounts
+enable_manual_linking = false
+# Passwords shorter than this value will be rejected as weak. Minimum 6, recommended 8 or more.
+minimum_password_length = 6
+# Passwords that do not meet the following requirements will be rejected as weak. Supported values
+# are: `letters_digits`, `lower_upper_letters_digits`, `lower_upper_letters_digits_symbols`
+password_requirements = ""
+
+# Configure passkey sign-ins.
+# [auth.passkey]
+# enabled = false
+
+# Configure WebAuthn relying party settings (required when passkey is enabled).
+# [auth.webauthn]
+# rp_display_name = "Supabase"
+# rp_id = "localhost"
+# rp_origins = ["http://127.0.0.1:3000"]
+
+[auth.rate_limit]
+# Number of emails that can be sent per hour. Requires auth.email.smtp to be enabled.
+email_sent = 2
+# Number of SMS messages that can be sent per hour. Requires auth.sms to be enabled.
+sms_sent = 30
+# Number of anonymous sign-ins that can be made per hour per IP address. Requires enable_anonymous_sign_ins = true.
+anonymous_users = 30
+# Number of sessions that can be refreshed in a 5 minute interval per IP address.
+token_refresh = 150
+# Number of sign up and sign-in requests that can be made in a 5 minute interval per IP address (excludes anonymous users).
+sign_in_sign_ups = 30
+# Number of OTP / Magic link verifications that can be made in a 5 minute interval per IP address.
+token_verifications = 30
+# Number of Web3 logins that can be made in a 5 minute interval per IP address.
+web3 = 30
+
+# Configure one of the supported captcha providers: `hcaptcha`, `turnstile`.
+# [auth.captcha]
+# enabled = true
+# provider = "hcaptcha"
+# secret = ""
+
+[auth.email]
+# Allow/disallow new user signups via email to your project.
+enable_signup = true
+# If enabled, a user will be required to confirm any email change on both the old, and new email
+# addresses. If disabled, only the new email is required to confirm.
+double_confirm_changes = true
+# If enabled, users need to confirm their email address before signing in.
+enable_confirmations = false
+# If enabled, users will need to reauthenticate or have logged in recently to change their password.
+secure_password_change = false
+# Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email.
+max_frequency = "1s"
+# Number of characters used in the email OTP.
+otp_length = 6
+# Number of seconds before the email OTP expires (defaults to 1 hour).
+otp_expiry = 3600
+
+# Use a production-ready SMTP server
+# [auth.email.smtp]
+# enabled = true
+# host = "smtp.sendgrid.net"
+# port = 587
+# user = "apikey"
+# pass = "env(SENDGRID_API_KEY)"
+# admin_email = "admin@email.com"
+# sender_name = "Admin"
+
+# Uncomment to customize email template
+# [auth.email.template.invite]
+# subject = "You have been invited"
+# content_path = "./supabase/templates/invite.html"
+
+# Uncomment to customize notification email template
+# [auth.email.notification.password_changed]
+# enabled = true
+# subject = "Your password has been changed"
+# content_path = "./templates/password_changed_notification.html"
+
+[auth.sms]
+# Allow/disallow new user signups via SMS to your project.
+enable_signup = false
+# If enabled, users need to confirm their phone number before signing in.
+enable_confirmations = false
+# Template for sending OTP to users
+template = "Your code is {{ `{{ .Code }}` }}"
+# Controls the minimum amount of time that must pass before sending another sms otp.
+max_frequency = "5s"
+
+# Use pre-defined map of phone number to OTP for testing.
+# [auth.sms.test_otp]
+# 4152127777 = "123456"
+
+# Configure logged in session timeouts.
+# [auth.sessions]
+# Force log out after the specified duration.
+# timebox = "24h"
+# Force log out if the user has been inactive longer than the specified duration.
+# inactivity_timeout = "8h"
+
+# This hook runs before a new user is created and allows developers to reject the request based on the incoming user object.
+# [auth.hook.before_user_created]
+# enabled = true
+# uri = "pg-functions://postgres/auth/before-user-created-hook"
+
+# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used.
+# [auth.hook.custom_access_token]
+# enabled = true
+# uri = "pg-functions:////"
+
+# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`.
+[auth.sms.twilio]
+enabled = false
+account_sid = ""
+message_service_sid = ""
+# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead:
+auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)"
+
+# Multi-factor-authentication is available to Supabase Pro plan.
+[auth.mfa]
+# Control how many MFA factors can be enrolled at once per user.
+max_enrolled_factors = 10
+
+# Control MFA via App Authenticator (TOTP)
+[auth.mfa.totp]
+enroll_enabled = false
+verify_enabled = false
+
+# Configure MFA via Phone Messaging
+[auth.mfa.phone]
+enroll_enabled = false
+verify_enabled = false
+otp_length = 6
+template = "Your code is {{ `{{ .Code }}` }}"
+max_frequency = "5s"
+
+# Configure MFA via WebAuthn
+# [auth.mfa.web_authn]
+# enroll_enabled = true
+# verify_enabled = true
+
+# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`,
+# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`,
+# `twitter`, `x`, `slack`, `spotify`, `workos`, `zoom`.
+[auth.external.apple]
+enabled = false
+client_id = ""
+# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead:
+secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)"
+# Overrides the default auth callback URL derived from auth.external_url.
+redirect_uri = ""
+# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure,
+# or any other third-party OIDC providers.
+url = ""
+# If enabled, the nonce check will be skipped. Required for local sign in with Google auth.
+skip_nonce_check = false
+# If enabled, it will allow the user to successfully authenticate when the provider does not return an email address.
+email_optional = false
+
+# Allow Solana wallet holders to sign in to your project via the Sign in with Solana (SIWS, EIP-4361) standard.
+# You can configure "web3" rate limit in the [auth.rate_limit] section and set up [auth.captcha] if self-hosting.
+[auth.web3.solana]
+enabled = false
+
+# Use Firebase Auth as a third-party provider alongside Supabase Auth.
+[auth.third_party.firebase]
+enabled = false
+# project_id = "my-firebase-project"
+
+# Use Auth0 as a third-party provider alongside Supabase Auth.
+[auth.third_party.auth0]
+enabled = false
+# tenant = "my-auth0-tenant"
+# tenant_region = "us"
+
+# Use AWS Cognito (Amplify) as a third-party provider alongside Supabase Auth.
+[auth.third_party.aws_cognito]
+enabled = false
+# user_pool_id = "my-user-pool-id"
+# user_pool_region = "us-east-1"
+
+# Use Clerk as a third-party provider alongside Supabase Auth.
+[auth.third_party.clerk]
+enabled = false
+# Obtain from https://clerk.com/setup/supabase
+# domain = "example.clerk.accounts.dev"
+
+# OAuth server configuration
+[auth.oauth_server]
+# Enable OAuth server functionality
+enabled = false
+# Path for OAuth consent flow UI
+authorization_url_path = "/oauth/consent"
+# Allow dynamic client registration
+allow_dynamic_registration = false
+
+[edge_runtime]
+enabled = true
+# Supported request policies: `oneshot`, `per_worker`.
+# `per_worker` (default) — enables hot reload during local development.
+# `oneshot` — fallback mode if hot reload causes issues (e.g. in large repos or with symlinks).
+policy = "per_worker"
+# Port to attach the Chrome inspector for debugging edge functions.
+inspector_port = 8083
+# The Deno major version to use.
+deno_version = 2
+
+# [edge_runtime.secrets]
+# secret_key = "env(SECRET_VALUE)"
+
+[analytics]
+enabled = true
+port = 54327
+# Configure one of the supported backends: `postgres`, `bigquery`.
+backend = "postgres"
+
+# Experimental features may be deprecated any time
+[experimental]
+# Configures Postgres storage engine to use OrioleDB (S3)
+orioledb_version = ""
+# Configures S3 bucket URL, eg. .s3-.amazonaws.com
+s3_host = "env(S3_HOST)"
+# Configures S3 bucket region, eg. us-east-1
+s3_region = "env(S3_REGION)"
+# Configures AWS_ACCESS_KEY_ID for S3 bucket
+s3_access_key = "env(S3_ACCESS_KEY)"
+# Configures AWS_SECRET_ACCESS_KEY for S3 bucket
+s3_secret_key = "env(S3_SECRET_KEY)"
+
+# pg-delta is the schema diff engine for db diff / db pull / db remote commit.
+# Set enabled = false to fall back to the legacy migra engine.
+[experimental.pgdelta]
+enabled = true
+# Directory under `supabase/` where declarative files are written.
+# declarative_schema_path = "./database"
+# JSON string passed through to pg-delta SQL formatting.
+# format_options = "{\"keywordCase\":\"upper\",\"indent\":2,\"maxWidth\":80,\"commaStyle\":\"trailing\"}"
diff --git a/supabase/migrations/001_initial_schema.sql b/supabase/migrations/001_initial_schema.sql
index 835782a5c9..cf21159058 100644
--- a/supabase/migrations/001_initial_schema.sql
+++ b/supabase/migrations/001_initial_schema.sql
@@ -11,7 +11,7 @@ CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- PROFILES
-- ============================================================
CREATE TABLE IF NOT EXISTS profiles (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
full_name TEXT NOT NULL,
email TEXT NOT NULL,
@@ -34,7 +34,7 @@ CREATE POLICY "Users can insert own profile" ON profiles FOR INSERT WITH CHECK (
-- CONTACTS
-- ============================================================
CREATE TABLE IF NOT EXISTS contacts (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
phone TEXT NOT NULL,
name TEXT,
@@ -56,7 +56,7 @@ CREATE POLICY "Users can manage own contacts" ON contacts FOR ALL USING (auth.ui
-- TAGS
-- ============================================================
CREATE TABLE IF NOT EXISTS tags (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
name TEXT NOT NULL,
color TEXT NOT NULL DEFAULT '#3b82f6',
@@ -71,7 +71,7 @@ CREATE POLICY "Users can manage own tags" ON tags FOR ALL USING (auth.uid() = us
-- CONTACT_TAGS (many-to-many)
-- ============================================================
CREATE TABLE IF NOT EXISTS contact_tags (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contact_id UUID NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
tag_id UUID NOT NULL REFERENCES tags(id) ON DELETE CASCADE,
created_at TIMESTAMPTZ DEFAULT NOW(),
@@ -90,7 +90,7 @@ CREATE POLICY "Users can manage contact tags" ON contact_tags FOR ALL
-- CUSTOM_FIELDS
-- ============================================================
CREATE TABLE IF NOT EXISTS custom_fields (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
field_name TEXT NOT NULL,
field_type TEXT NOT NULL DEFAULT 'text',
@@ -106,7 +106,7 @@ CREATE POLICY "Users can manage own custom fields" ON custom_fields FOR ALL USIN
-- CONTACT_CUSTOM_VALUES
-- ============================================================
CREATE TABLE IF NOT EXISTS contact_custom_values (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contact_id UUID NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
custom_field_id UUID NOT NULL REFERENCES custom_fields(id) ON DELETE CASCADE,
value TEXT,
@@ -123,7 +123,7 @@ CREATE POLICY "Users can manage custom values" ON contact_custom_values FOR ALL
-- CONTACT_NOTES
-- ============================================================
CREATE TABLE IF NOT EXISTS contact_notes (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
contact_id UUID NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
note_text TEXT NOT NULL,
@@ -138,7 +138,7 @@ CREATE POLICY "Users can manage own notes" ON contact_notes FOR ALL USING (auth.
-- CONVERSATIONS
-- ============================================================
CREATE TABLE IF NOT EXISTS conversations (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
contact_id UUID NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'pending', 'closed')),
@@ -161,7 +161,7 @@ CREATE POLICY "Users can manage own conversations" ON conversations FOR ALL USIN
-- MESSAGES
-- ============================================================
CREATE TABLE IF NOT EXISTS messages (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
conversation_id UUID NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
sender_type TEXT NOT NULL CHECK (sender_type IN ('customer', 'agent', 'bot')),
sender_id UUID,
@@ -188,7 +188,7 @@ CREATE POLICY "Service role can insert messages" ON messages FOR INSERT WITH CHE
-- WHATSAPP_CONFIG
-- ============================================================
CREATE TABLE IF NOT EXISTS whatsapp_config (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
phone_number_id TEXT NOT NULL,
waba_id TEXT,
@@ -209,7 +209,7 @@ CREATE POLICY "Users can manage own config" ON whatsapp_config FOR ALL USING (au
-- MESSAGE_TEMPLATES
-- ============================================================
CREATE TABLE IF NOT EXISTS message_templates (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
name TEXT NOT NULL,
category TEXT NOT NULL DEFAULT 'Marketing' CHECK (category IN ('Marketing', 'Utility', 'Authentication')),
@@ -232,7 +232,7 @@ CREATE POLICY "Users can manage own templates" ON message_templates FOR ALL USIN
-- PIPELINES
-- ============================================================
CREATE TABLE IF NOT EXISTS pipelines (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
name TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
@@ -246,7 +246,7 @@ CREATE POLICY "Users can manage own pipelines" ON pipelines FOR ALL USING (auth.
-- PIPELINE_STAGES
-- ============================================================
CREATE TABLE IF NOT EXISTS pipeline_stages (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
pipeline_id UUID NOT NULL REFERENCES pipelines(id) ON DELETE CASCADE,
name TEXT NOT NULL,
position INTEGER NOT NULL DEFAULT 0,
@@ -265,7 +265,7 @@ CREATE POLICY "Users can manage pipeline stages" ON pipeline_stages FOR ALL
-- DEALS
-- ============================================================
CREATE TABLE IF NOT EXISTS deals (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
pipeline_id UUID NOT NULL REFERENCES pipelines(id) ON DELETE CASCADE,
stage_id UUID NOT NULL REFERENCES pipeline_stages(id),
@@ -292,7 +292,7 @@ CREATE POLICY "Users can manage own deals" ON deals FOR ALL USING (auth.uid() =
-- BROADCASTS
-- ============================================================
CREATE TABLE IF NOT EXISTS broadcasts (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
name TEXT NOT NULL,
template_name TEXT NOT NULL,
@@ -319,7 +319,7 @@ CREATE POLICY "Users can manage own broadcasts" ON broadcasts FOR ALL USING (aut
-- BROADCAST_RECIPIENTS
-- ============================================================
CREATE TABLE IF NOT EXISTS broadcast_recipients (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
broadcast_id UUID NOT NULL REFERENCES broadcasts(id) ON DELETE CASCADE,
contact_id UUID NOT NULL REFERENCES contacts(id),
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'sent', 'delivered', 'read', 'replied', 'failed')),
diff --git a/supabase/migrations/006_automations.sql b/supabase/migrations/006_automations.sql
index a15940fe65..4b18e91481 100644
--- a/supabase/migrations/006_automations.sql
+++ b/supabase/migrations/006_automations.sql
@@ -12,7 +12,7 @@
-- AUTOMATIONS
-- ============================================================
CREATE TABLE IF NOT EXISTS automations (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
name TEXT NOT NULL,
description TEXT,
@@ -51,7 +51,7 @@ CREATE TRIGGER set_updated_at BEFORE UPDATE ON automations
-- 'yes' or 'no' identifying which path.
-- ============================================================
CREATE TABLE IF NOT EXISTS automation_steps (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
automation_id UUID NOT NULL REFERENCES automations(id) ON DELETE CASCADE,
parent_step_id UUID REFERENCES automation_steps(id) ON DELETE CASCADE,
branch TEXT CHECK (branch IN ('yes', 'no')),
@@ -85,7 +85,7 @@ CREATE POLICY "Users can manage steps of own automations" ON automation_steps FO
-- on broadcast_recipients / deals).
-- ============================================================
CREATE TABLE IF NOT EXISTS automation_logs (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
automation_id UUID NOT NULL REFERENCES automations(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
contact_id UUID REFERENCES contacts(id) ON DELETE SET NULL,
@@ -117,7 +117,7 @@ CREATE POLICY "Users can view own automation logs" ON automation_logs FOR ALL
-- the engine uses the service-role client. No user policy exposed.
-- ============================================================
CREATE TABLE IF NOT EXISTS automation_pending_executions (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
automation_id UUID NOT NULL REFERENCES automations(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
contact_id UUID REFERENCES contacts(id) ON DELETE SET NULL,
diff --git a/supabase/migrations/009_message_actions.sql b/supabase/migrations/009_message_actions.sql
index 323c59b4bf..1ca410b27e 100644
--- a/supabase/migrations/009_message_actions.sql
+++ b/supabase/migrations/009_message_actions.sql
@@ -40,7 +40,7 @@ CREATE INDEX IF NOT EXISTS idx_messages_reply_to
-- 2. message_reactions
-- ============================================================
CREATE TABLE IF NOT EXISTS message_reactions (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
message_id UUID NOT NULL REFERENCES messages(id) ON DELETE CASCADE,
conversation_id UUID NOT NULL REFERENCES conversations(id) ON DELETE CASCADE,
actor_type TEXT NOT NULL CHECK (actor_type IN ('customer', 'agent')),
diff --git a/supabase/migrations/010_flows.sql b/supabase/migrations/010_flows.sql
index bd9a82a318..7f9f87ca60 100644
--- a/supabase/migrations/010_flows.sql
+++ b/supabase/migrations/010_flows.sql
@@ -75,7 +75,7 @@ ALTER TABLE messages
-- 2. flows
-- ============================================================
CREATE TABLE IF NOT EXISTS flows (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
name TEXT NOT NULL,
description TEXT,
@@ -112,7 +112,7 @@ CREATE POLICY "Users can manage own flows" ON flows FOR ALL
-- 3. flow_nodes
-- ============================================================
CREATE TABLE IF NOT EXISTS flow_nodes (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
flow_id UUID NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
node_key TEXT NOT NULL,
node_type TEXT NOT NULL CHECK (node_type IN (
@@ -154,7 +154,7 @@ CREATE POLICY "Users manage nodes on their flows" ON flow_nodes FOR ALL
-- 4. flow_runs
-- ============================================================
CREATE TABLE IF NOT EXISTS flow_runs (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
flow_id UUID NOT NULL REFERENCES flows(id) ON DELETE CASCADE,
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
-- contact_id intentionally SET NULL on delete (matches the
@@ -214,7 +214,7 @@ CREATE POLICY "Users see own flow runs" ON flow_runs FOR SELECT
-- 5. flow_run_events
-- ============================================================
CREATE TABLE IF NOT EXISTS flow_run_events (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
flow_run_id UUID NOT NULL REFERENCES flow_runs(id) ON DELETE CASCADE,
event_type TEXT NOT NULL CHECK (event_type IN (
'started',
diff --git a/supabase/migrations/017_account_sharing.sql b/supabase/migrations/017_account_sharing.sql
index fae7cf37e5..3884df219b 100644
--- a/supabase/migrations/017_account_sharing.sql
+++ b/supabase/migrations/017_account_sharing.sql
@@ -58,7 +58,7 @@ END $$;
-- ACCOUNTS
-- ============================================================
CREATE TABLE IF NOT EXISTS accounts (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name TEXT NOT NULL,
-- owner_user_id is denormalised for fast "is this user the owner of
-- their account" reads and for the one-account-per-user invariant
@@ -88,7 +88,7 @@ CREATE TRIGGER set_updated_at BEFORE UPDATE ON accounts
-- once by the POST endpoint at creation time and never persisted.
-- ============================================================
CREATE TABLE IF NOT EXISTS account_invitations (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
account_id UUID NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
token_hash TEXT NOT NULL UNIQUE,
role account_role_enum NOT NULL CHECK (role <> 'owner'),
diff --git a/supabase/migrations/027_notifications.sql b/supabase/migrations/027_notifications.sql
index 475f33d064..357c87f188 100644
--- a/supabase/migrations/027_notifications.sql
+++ b/supabase/migrations/027_notifications.sql
@@ -2,7 +2,7 @@
-- NOTIFICATIONS
-- ============================================================
CREATE TABLE IF NOT EXISTS notifications (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
account_id UUID NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
-- Recipient — the agent this notification is for.
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
diff --git a/supabase/migrations/035_interactive_messages.sql b/supabase/migrations/035_interactive_messages.sql
index 7dcfbd7d1a..6816b7f884 100644
--- a/supabase/migrations/035_interactive_messages.sql
+++ b/supabase/migrations/035_interactive_messages.sql
@@ -22,7 +22,7 @@ ALTER TABLE messages
-- 2. Quick replies --------------------------------------------
CREATE TABLE IF NOT EXISTS quick_replies (
- id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- Tenancy. Every member of the account shares its quick replies.
account_id UUID NOT NULL REFERENCES accounts(id) ON DELETE CASCADE,
-- Author / audit only — never used for tenancy isolation.