ebea70573b
- Repository structure for all services, infra, lakehouse, dashboards - K8s manifests targeting stonks-oracle namespace with GHCR images - Ingress via Traefik with ca-issuer TLS for internal services - ConfigMap wired to existing cluster services (pg, redis, minio, ollama) - GitHub Actions workflow for lint, test, multi-service container builds - Dockerfile with build-arg CMD per service - Makefile for local build/push/deploy - Steering rules for TDD workflow, K8s conventions, project context - Agent hooks for lint-on-save, test-on-save, k8s-validate, phase-commit - Ruff linter config, all lint issues fixed - 14 passing tests for schemas, config, redis keys - PostgreSQL migrations, Trino catalogs, Superset config, MinIO lifecycle
100 lines
3.6 KiB
SQL
100 lines
3.6 KiB
SQL
-- Stonks Oracle - Initial PostgreSQL Schema
|
|
-- Phase 1: Core data model
|
|
|
|
-- Extensions
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
|
|
|
|
-- ============================================================
|
|
-- Companies and Watchlists
|
|
-- ============================================================
|
|
|
|
CREATE TABLE companies (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
ticker VARCHAR(20) NOT NULL,
|
|
legal_name VARCHAR(500) NOT NULL,
|
|
exchange VARCHAR(50),
|
|
sector VARCHAR(200),
|
|
industry VARCHAR(200),
|
|
market_cap_bucket VARCHAR(50),
|
|
active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE(ticker, exchange)
|
|
);
|
|
|
|
CREATE TABLE company_aliases (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
alias VARCHAR(500) NOT NULL,
|
|
alias_type VARCHAR(50) NOT NULL DEFAULT 'brand',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
CREATE INDEX idx_company_aliases_company ON company_aliases(company_id);
|
|
CREATE INDEX idx_company_aliases_alias ON company_aliases(alias);
|
|
|
|
CREATE TABLE watchlists (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
name VARCHAR(200) NOT NULL UNIQUE,
|
|
description TEXT,
|
|
active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE TABLE watchlist_members (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
watchlist_id UUID NOT NULL REFERENCES watchlists(id) ON DELETE CASCADE,
|
|
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
added_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
UNIQUE(watchlist_id, company_id)
|
|
);
|
|
|
|
-- ============================================================
|
|
-- Sources and Credentials
|
|
-- ============================================================
|
|
|
|
CREATE TABLE sources (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
company_id UUID NOT NULL REFERENCES companies(id) ON DELETE CASCADE,
|
|
source_type VARCHAR(50) NOT NULL,
|
|
source_name VARCHAR(200) NOT NULL,
|
|
config JSONB NOT NULL DEFAULT '{}',
|
|
credibility_score FLOAT DEFAULT 0.5,
|
|
retention_days INTEGER DEFAULT 365,
|
|
access_policy VARCHAR(50) DEFAULT 'internal',
|
|
active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
CREATE INDEX idx_sources_company ON sources(company_id);
|
|
CREATE INDEX idx_sources_type ON sources(source_type);
|
|
|
|
CREATE TABLE api_credentials_refs (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
provider VARCHAR(100) NOT NULL UNIQUE,
|
|
secret_ref VARCHAR(500) NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- Ingestion Tracking
|
|
-- ============================================================
|
|
|
|
CREATE TABLE ingestion_runs (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
source_id UUID REFERENCES sources(id),
|
|
company_id UUID REFERENCES companies(id),
|
|
source_type VARCHAR(50) NOT NULL,
|
|
status VARCHAR(50) NOT NULL DEFAULT 'pending',
|
|
started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
completed_at TIMESTAMPTZ,
|
|
items_fetched INTEGER DEFAULT 0,
|
|
items_new INTEGER DEFAULT 0,
|
|
error_message TEXT,
|
|
retry_count INTEGER DEFAULT 0,
|
|
next_retry_at TIMESTAMPTZ
|
|
);
|
|
CREATE INDEX idx_ingestion_runs_status ON ingestion_runs(status);
|
|
CREATE INDEX idx_ingestion_runs_source ON ingestion_runs(source_id);
|