postgres/init.sql
Rama main · réplica de lectura del repositorio original.
-- hiai-docs unified init.sql
-- Runs on first PostgreSQL startup via docker-entrypoint-initdb.d.
--
-- Bootstraps database infrastructure: required extensions plus owner-role
-- database/search_path configuration. Graph objects, labels, graph indexes,
-- and all application tables / indexes / FKs are applied later via Drizzle
-- migrations (packages/db/src/migrations). This script MUST NOT create
-- application or GraphRAG objects or grant their runtime privileges.
-- Vector search + StreamingDiskANN (pgvectorscale requires pgvector).
CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS vectorscale;
-- Knowledge graph (Apache AGE). The ag_catalog schema is created
-- automatically by the extension. Graph objects are deliberately owned by
-- the Drizzle migration journal, not by this bootstrap script.
CREATE EXTENSION IF NOT EXISTS age;
-- Load the AGE shared library into every new session so cypher() works.
-- CREATE EXTENSION installs the SQL definitions but does NOT load the
-- .so into the process. Without this, cypher() raises "unhandled
-- cypher(cstring) function call" because AGE's parser/planner hooks
-- are never registered. This must be a database-level setting (not
-- session-local) so it applies to every connection in the pool.
DO $$
BEGIN
EXECUTE format('ALTER DATABASE %I SET session_preload_libraries = %L', current_database(), 'age');
END
$$;
-- Trigram indexes for fuzzy / similarity search on document titles and
-- tag names (used by `/api/search/suggest` and tag autocomplete).
CREATE EXTENSION IF NOT EXISTS pg_trgm;
-- Grant privileges on the current database dynamically. The database
-- name is set via POSTGRES_DB at container start and may differ between
-- local (`hiai_docs`), CI (`hiai_docs_test`), or any other environment,
-- so we resolve it at runtime rather than hardcoding it.
DO $$
BEGIN
EXECUTE format('GRANT ALL PRIVILEGES ON DATABASE %I TO aiuser', current_database());
END
$$;
GRANT ALL PRIVILEGES ON SCHEMA public TO aiuser;
GRANT ALL PRIVILEGES ON SCHEMA ag_catalog TO aiuser;
-- Pin the search_path for every connection owned by `aiuser`. ORDER
-- MATTERS: `public` must come first so that Drizzle/Better Auth
-- resolve unqualified table names like `documents` to
-- `public.documents` instead of `ag_catalog.documents`. `ag_catalog`
-- is kept second so that AGE's `agtype`/`graphid_ops` still resolve
-- without the schema prefix. The session-local `SET search_path`
-- above only affects the current docker-entrypoint-initdb.d session;
-- this ALTER ROLE persists across the connection pool.
ALTER ROLE aiuser SET search_path = public, ag_catalog;
-- The non-superuser runtime role is created by 01-runtime-role.sh with the
-- operator-provided HIAI_APP_PASSWORD before Drizzle migrations run. The
-- role's grants and search_path are finalized by migration 0012.