feat: Phase 0 bootstrap — Qdrant deploy e schema PostgreSQL
- README.md: contesto ALPHA_PROJECT, architettura multi-agent, stack infrastrutturale - CHANGELOG.md: documenta deploy Qdrant v1.17.0 e creazione database pompeo - db/postgres.sql: schema DDL database pompeo (user_profile, memory_facts, finance_documents, behavioral_context, agent_messages) con multi-tenancy user_id - db/qdrant.sh: script per creazione/ripristino collections Qdrant (episodes, knowledge, preferences) con payload indexes Design decisions: - Multi-tenancy via user_id su Qdrant e PostgreSQL (estendibile a nuovi utenti senza modifiche infrastrutturali) - agent_messages come blackboard persistente per il Proactive Arbiter Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
170
db/postgres.sql
Normal file
170
db/postgres.sql
Normal file
@@ -0,0 +1,170 @@
|
||||
-- =============================================================================
|
||||
-- ALPHA_PROJECT — Database "pompeo" — Schema iniziale
|
||||
-- =============================================================================
|
||||
-- Applicare su: postgresql://martin@postgres.persistence.svc.cluster.local:5432/pompeo
|
||||
--
|
||||
-- Esecuzione dal cluster:
|
||||
-- sudo microk8s kubectl run psql-pompeo --rm -it \
|
||||
-- --image=postgres:17-alpine --namespace=persistence \
|
||||
-- --env="PGPASSWORD=<password>" --restart=Never \
|
||||
-- -- psql "postgresql://martin@postgres:5432/pompeo" -f /dev/stdin < postgres.sql
|
||||
--
|
||||
-- Esecuzione via port-forward:
|
||||
-- sudo microk8s kubectl port-forward svc/postgres -n persistence 5432:5432
|
||||
-- psql "postgresql://martin@localhost:5432/pompeo" -f postgres.sql
|
||||
-- =============================================================================
|
||||
|
||||
\c pompeo
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- Estensioni
|
||||
-- ---------------------------------------------------------------------------
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- full-text similarity search su subject/detail
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 1. USER_PROFILE
|
||||
-- Preferenze statiche per utente. Aggiornata manualmente o via agent action.
|
||||
-- user_id 'shared' = preferenze della casa (visibili a tutti).
|
||||
-- =============================================================================
|
||||
CREATE TABLE IF NOT EXISTS user_profile (
|
||||
user_id TEXT PRIMARY KEY,
|
||||
display_name TEXT,
|
||||
language TEXT NOT NULL DEFAULT 'it',
|
||||
timezone TEXT NOT NULL DEFAULT 'Europe/Rome',
|
||||
notification_style TEXT NOT NULL DEFAULT 'concise', -- 'concise' | 'verbose'
|
||||
quiet_start TIME NOT NULL DEFAULT '23:00',
|
||||
quiet_end TIME NOT NULL DEFAULT '07:00',
|
||||
preferences JSONB, -- freeform: soglie, preferenze extra per agente
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- Utenti iniziali
|
||||
INSERT INTO user_profile (user_id, display_name) VALUES
|
||||
('martin', 'Martin'),
|
||||
('shared', 'Shared')
|
||||
ON CONFLICT (user_id) DO NOTHING;
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 2. MEMORY_FACTS
|
||||
-- Fatti episodici prodotti da tutti gli agenti. TTL tramite expires_at.
|
||||
-- qdrant_id: riferimento al punto vettoriale corrispondente nella collection "episodes".
|
||||
-- =============================================================================
|
||||
CREATE TABLE IF NOT EXISTS memory_facts (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id TEXT NOT NULL DEFAULT 'martin',
|
||||
source TEXT NOT NULL, -- 'email' | 'calendar' | 'iot' | 'paperless' | 'n8n' | ...
|
||||
category TEXT, -- 'finance' | 'personal' | 'work' | 'health' | ...
|
||||
subject TEXT,
|
||||
detail JSONB, -- payload flessibile per-source
|
||||
action_required BOOLEAN NOT NULL DEFAULT false,
|
||||
action_text TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT now(),
|
||||
expires_at TIMESTAMP, -- NULL = permanente
|
||||
qdrant_id UUID -- FK logico → collection "episodes"
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_memory_facts_user_source_cat
|
||||
ON memory_facts(user_id, source, category);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_memory_facts_expires
|
||||
ON memory_facts(expires_at)
|
||||
WHERE expires_at IS NOT NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_memory_facts_action
|
||||
ON memory_facts(user_id, action_required)
|
||||
WHERE action_required = true;
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 3. FINANCE_DOCUMENTS
|
||||
-- Documenti finanziari strutturati (bollette, fatture, cedolini).
|
||||
-- paperless_doc_id: riferimento al documento in Paperless-ngx.
|
||||
-- =============================================================================
|
||||
CREATE TABLE IF NOT EXISTS finance_documents (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id TEXT NOT NULL DEFAULT 'martin',
|
||||
paperless_doc_id INT, -- ID documento in Paperless-ngx
|
||||
correspondent TEXT,
|
||||
amount NUMERIC(10,2),
|
||||
currency TEXT NOT NULL DEFAULT 'EUR',
|
||||
doc_date DATE,
|
||||
doc_type TEXT, -- 'bolletta' | 'fattura' | 'cedolino' | ...
|
||||
tags TEXT[],
|
||||
raw_text TEXT, -- testo OCR grezzo (per embedding)
|
||||
created_at TIMESTAMP NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_finance_docs_user_date
|
||||
ON finance_documents(user_id, doc_date DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_finance_docs_correspondent
|
||||
ON finance_documents(user_id, correspondent);
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 4. BEHAVIORAL_CONTEXT
|
||||
-- Contesto comportamentale prodotto dall'IoT Agent e dal Calendar Agent.
|
||||
-- Usato dal Proactive Arbiter per rispettare DND e stimare presence.
|
||||
-- =============================================================================
|
||||
CREATE TABLE IF NOT EXISTS behavioral_context (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id TEXT NOT NULL DEFAULT 'martin',
|
||||
event_type TEXT, -- 'sport_event' | 'dog_walk' | 'work_session' | 'commute' | ...
|
||||
start_at TIMESTAMP,
|
||||
end_at TIMESTAMP,
|
||||
do_not_disturb BOOLEAN NOT NULL DEFAULT false,
|
||||
home_presence_expected BOOLEAN,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_behavioral_ctx_user_time
|
||||
ON behavioral_context(user_id, start_at, end_at);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_behavioral_ctx_dnd
|
||||
ON behavioral_context(user_id, do_not_disturb)
|
||||
WHERE do_not_disturb = true;
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 5. AGENT_MESSAGES
|
||||
-- Blackboard: ogni agente pubblica qui le proprie osservazioni.
|
||||
-- Il Proactive Arbiter legge, decide (notify/defer/discard) e aggiorna.
|
||||
-- Corrisponde al message schema definito in alpha/README.md.
|
||||
-- =============================================================================
|
||||
CREATE TABLE IF NOT EXISTS agent_messages (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
agent TEXT NOT NULL, -- 'mail' | 'calendar' | 'iot' | 'finance' | 'infra' | ...
|
||||
priority TEXT NOT NULL, -- 'low' | 'high'
|
||||
event_type TEXT NOT NULL, -- 'new_fact' | 'reminder' | 'alert' | 'behavioral_observation'
|
||||
user_id TEXT NOT NULL DEFAULT 'martin',
|
||||
subject TEXT,
|
||||
detail JSONB,
|
||||
source_ref TEXT, -- ID record Postgres o ref esterna
|
||||
expires_at TIMESTAMP,
|
||||
arbiter_decision TEXT, -- NULL (pending) | 'notify' | 'defer' | 'discard'
|
||||
arbiter_reason TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT now(),
|
||||
processed_at TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_msgs_pending
|
||||
ON agent_messages(user_id, priority, created_at)
|
||||
WHERE arbiter_decision IS NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_msgs_agent_type
|
||||
ON agent_messages(agent, event_type, created_at);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_msgs_expires
|
||||
ON agent_messages(expires_at)
|
||||
WHERE expires_at IS NOT NULL AND arbiter_decision IS NULL;
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- Fine script
|
||||
-- =============================================================================
|
||||
\echo '✅ Schema pompeo applicato correttamente.'
|
||||
\echo ' Tabelle: user_profile, memory_facts, finance_documents, behavioral_context, agent_messages'
|
||||
Reference in New Issue
Block a user