Files
Celes Renata ebea70573b phase 0+1: project scaffold, k8s manifests, CI pipeline, steering, hooks, tests
- 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
2026-04-11 03:25:08 -07:00

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);