feat: supabase schema migrations + kong gateway config
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
_format_version: "2.1"
|
||||
|
||||
services:
|
||||
- name: postgrest
|
||||
url: http://rest:3000
|
||||
routes:
|
||||
- name: rest-v1
|
||||
paths:
|
||||
- /rest/v1/
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<'EOSQL'
|
||||
|
||||
-- Create authenticator role (no-login, used by PostgREST)
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'authenticator') THEN
|
||||
CREATE ROLE authenticator NOLOGIN;
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
-- Grant authenticator usage on public schema and read access to all tables
|
||||
GRANT USAGE ON SCHEMA public TO authenticator;
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA public TO authenticator;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO authenticator;
|
||||
|
||||
EOSQL
|
||||
@@ -0,0 +1,103 @@
|
||||
-- ============================================================
|
||||
-- willhaben-tracker — initial schema migration
|
||||
-- ============================================================
|
||||
|
||||
-- -----------------------------------------------------------
|
||||
-- 1. users (whitelisted Telegram users)
|
||||
-- -----------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
telegram_id bigint UNIQUE NOT NULL,
|
||||
username text,
|
||||
first_name text,
|
||||
is_active boolean NOT NULL DEFAULT true,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- -----------------------------------------------------------
|
||||
-- 2. search_queries (saved searches per user)
|
||||
-- -----------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS search_queries (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid REFERENCES users(id) ON DELETE CASCADE NOT NULL,
|
||||
keyword text NOT NULL,
|
||||
interval_minutes int NOT NULL DEFAULT 60,
|
||||
is_active boolean NOT NULL DEFAULT true,
|
||||
last_scraped_at timestamptz,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- -----------------------------------------------------------
|
||||
-- 3. ads (raw ad snapshots, globally deduplicated by wh_ad_id)
|
||||
-- -----------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS ads (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
wh_ad_id text UNIQUE NOT NULL,
|
||||
raw_json jsonb NOT NULL,
|
||||
title text NOT NULL,
|
||||
price numeric,
|
||||
location text,
|
||||
url text,
|
||||
published_at timestamptz,
|
||||
first_seen_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- -----------------------------------------------------------
|
||||
-- 4. query_ads (junction: which query found which ad)
|
||||
-- -----------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS query_ads (
|
||||
search_query_id uuid REFERENCES search_queries(id) ON DELETE CASCADE NOT NULL,
|
||||
ad_id uuid REFERENCES ads(id) ON DELETE CASCADE NOT NULL,
|
||||
first_seen_at timestamptz NOT NULL DEFAULT now(),
|
||||
is_notified boolean NOT NULL DEFAULT false,
|
||||
PRIMARY KEY (search_query_id, ad_id)
|
||||
);
|
||||
|
||||
-- -----------------------------------------------------------
|
||||
-- 5. notifications (audit log of sent Telegram messages)
|
||||
-- -----------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS notifications (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id uuid REFERENCES users(id) ON DELETE CASCADE NOT NULL,
|
||||
ad_id uuid REFERENCES ads(id) ON DELETE SET NULL,
|
||||
message_id int,
|
||||
sent_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- -----------------------------------------------------------
|
||||
-- 6. scrape_logs (worker health / debugging)
|
||||
-- -----------------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS scrape_logs (
|
||||
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
search_query_id uuid REFERENCES search_queries(id) ON DELETE CASCADE NOT NULL,
|
||||
status text NOT NULL CHECK (status IN ('success', 'error', 'rate_limited')),
|
||||
ads_found int NOT NULL DEFAULT 0,
|
||||
new_ads int NOT NULL DEFAULT 0,
|
||||
error_message text,
|
||||
scraped_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- ============================================================
|
||||
-- Indexes
|
||||
-- ============================================================
|
||||
|
||||
-- Users: fast lookup by telegram_id (unique constraint already implies an index)
|
||||
|
||||
-- Search queries: user membership lookups
|
||||
CREATE INDEX IF NOT EXISTS idx_search_queries_user_id ON search_queries(user_id);
|
||||
|
||||
-- Scheduler polling: active queries ordered by last scraped time
|
||||
CREATE INDEX IF NOT EXISTS idx_search_queries_active_scraped
|
||||
ON search_queries(is_active, last_scraped_at) WHERE is_active = true;
|
||||
|
||||
-- Notifier lookups: un-notified ads per query
|
||||
CREATE INDEX IF NOT EXISTS idx_query_ads_notified
|
||||
ON query_ads(search_query_id, is_notified) WHERE is_notified = false;
|
||||
|
||||
-- Notifications: recent messages per user
|
||||
CREATE INDEX IF NOT EXISTS idx_notifications_user_sent
|
||||
ON notifications(user_id, sent_at DESC);
|
||||
|
||||
-- Scrape logs: latest runs per query
|
||||
CREATE INDEX IF NOT EXISTS idx_scrape_logs_query_at
|
||||
ON scrape_logs(search_query_id, scraped_at DESC);
|
||||
@@ -0,0 +1,8 @@
|
||||
-- ============================================================
|
||||
-- post-boot — runs after all migrations have been applied.
|
||||
-- Grants INSERT/UPDATE to authenticator on user-facing tables.
|
||||
-- (Run after 01-init.sql so tables exist.)
|
||||
-- ============================================================
|
||||
|
||||
GRANT INSERT, UPDATE ON search_queries TO authenticator;
|
||||
GRANT INSERT, UPDATE ON notifications TO authenticator;
|
||||
Reference in New Issue
Block a user