Files
Mattsson 7c36d471b5 fix(sandbox): use posting engine and recover failed seeds (#2297)
* fix(sandbox): seed through posting engine and recover failed attempts

* test(sandbox): align CI auth schema for anonymous users
2026-09-05 10:42:14 +02:00

81 lines
3.3 KiB
PL/PgSQL

-- pg-real CI bootstrap.
--
-- The Supabase Postgres image ships a partial `storage` schema; the remaining
-- columns and functions are provisioned at runtime by the storage-api
-- service, which we do not run in CI. This bootstrap aligns the schema with
-- what our migrations expect so the replay loop succeeds. It is idempotent
-- and safe to run against a freshly-initialised container.
CREATE SCHEMA IF NOT EXISTS storage;
CREATE TABLE IF NOT EXISTS storage.buckets (
id text PRIMARY KEY,
name text NOT NULL,
owner uuid,
created_at timestamptz DEFAULT now(),
updated_at timestamptz DEFAULT now()
);
ALTER TABLE storage.buckets
ADD COLUMN IF NOT EXISTS public boolean DEFAULT false,
ADD COLUMN IF NOT EXISTS file_size_limit bigint,
ADD COLUMN IF NOT EXISTS allowed_mime_types text[];
CREATE TABLE IF NOT EXISTS storage.objects (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
bucket_id text REFERENCES storage.buckets(id) ON DELETE CASCADE,
name text,
owner uuid,
created_at timestamptz DEFAULT now(),
updated_at timestamptz DEFAULT now(),
last_accessed_at timestamptz DEFAULT now(),
metadata jsonb,
version text,
owner_id text
);
ALTER TABLE storage.objects ENABLE ROW LEVEL SECURITY;
-- storage.foldername(): splits a slash-delimited object name into segments.
-- Migrations use `(storage.foldername(name))[n]` to derive tenant scoping
-- from the object path.
CREATE OR REPLACE FUNCTION storage.foldername(name text)
RETURNS text[]
LANGUAGE sql
IMMUTABLE
AS $$
SELECT string_to_array(name, '/');
$$;
-- auth.identities is created by GoTrue at startup, not by the Postgres
-- image. Likewise, GoTrue's 20240214120130 migration adds is_anonymous;
-- sandbox authorization reads this server-owned flag, not user metadata.
ALTER TABLE auth.users
ADD COLUMN IF NOT EXISTS is_anonymous boolean NOT NULL DEFAULT false;
-- auth.identities is created by GoTrue at startup, not by the Postgres
-- image, and GoTrue does not run in CI. Triggers on auth.users that touch
-- identities (20260903110000 unlink_old_address_identities) need the table
-- to exist so an email change in a pg-real test does not fail with 42P01.
-- Shape mirrors GoTrue's migration (same PK, unique key, generated email).
CREATE TABLE IF NOT EXISTS auth.identities (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
provider_id text NOT NULL,
user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
identity_data jsonb NOT NULL,
provider text NOT NULL,
last_sign_in_at timestamptz,
created_at timestamptz,
updated_at timestamptz,
email text GENERATED ALWAYS AS (lower(identity_data ->> 'email')) STORED,
CONSTRAINT identities_provider_id_provider_unique UNIQUE (provider_id, provider)
);
CREATE INDEX IF NOT EXISTS identities_user_id_idx ON auth.identities (user_id);
-- auth.audit_log_entries ships in the Postgres image without the ip_address
-- column GoTrue adds on first boot (NOT NULL DEFAULT '' on every hosted
-- project). unlink_old_address_identities writes GoTrue's audit table with
-- that column, so the CI double must carry it too.
ALTER TABLE IF EXISTS auth.audit_log_entries
ADD COLUMN IF NOT EXISTS ip_address varchar(64) NOT NULL DEFAULT '';