82 lines
3.5 KiB
SQL
82 lines
3.5 KiB
SQL
-- mail_summary schema.
|
|
-- Seeds a fresh Postgres container on first boot.
|
|
-- The backend also runs equivalent idempotent CREATE TABLE IF NOT EXISTS at startup.
|
|
|
|
CREATE TABLE IF NOT EXISTS analysis_jobs (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
-- pending | extracting | filtering | analyzing | completed | failed
|
|
mailbox_scope TEXT NOT NULL DEFAULT 'both',
|
|
-- inbox | sent | both
|
|
date_from DATE NOT NULL,
|
|
date_to DATE NOT NULL,
|
|
model TEXT NOT NULL DEFAULT '',
|
|
inbox_zip_name TEXT,
|
|
sent_zip_name TEXT,
|
|
inbox_count INTEGER NOT NULL DEFAULT 0,
|
|
sent_count INTEGER NOT NULL DEFAULT 0,
|
|
filtered_inbox_count INTEGER NOT NULL DEFAULT 0,
|
|
filtered_sent_count INTEGER NOT NULL DEFAULT 0,
|
|
progress_pct INTEGER NOT NULL DEFAULT 0,
|
|
progress_label TEXT NOT NULL DEFAULT '',
|
|
progress_detail TEXT NOT NULL DEFAULT '',
|
|
error_message TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
started_at TIMESTAMPTZ,
|
|
completed_at TIMESTAMPTZ,
|
|
CONSTRAINT analysis_jobs_status_chk CHECK (
|
|
status IN ('pending', 'extracting', 'filtering', 'analyzing', 'completed', 'failed')
|
|
),
|
|
CONSTRAINT analysis_jobs_scope_chk CHECK (
|
|
mailbox_scope IN ('inbox', 'sent', 'both')
|
|
),
|
|
CONSTRAINT analysis_jobs_date_chk CHECK (date_from <= date_to)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_analysis_jobs_created_at
|
|
ON analysis_jobs (created_at DESC);
|
|
CREATE INDEX IF NOT EXISTS idx_analysis_jobs_status
|
|
ON analysis_jobs (status);
|
|
|
|
-- Mail metadata + cleaned body for the selected analysis window.
|
|
-- Prefer storing identifiers/summary over full raw .eml content.
|
|
CREATE TABLE IF NOT EXISTS mails (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
job_id BIGINT NOT NULL REFERENCES analysis_jobs(id) ON DELETE CASCADE,
|
|
mailbox TEXT NOT NULL,
|
|
-- inbox | sent
|
|
message_id TEXT,
|
|
thread_key TEXT,
|
|
subject TEXT NOT NULL DEFAULT '',
|
|
from_addr TEXT NOT NULL DEFAULT '',
|
|
to_addrs TEXT NOT NULL DEFAULT '',
|
|
cc_addrs TEXT NOT NULL DEFAULT '',
|
|
mailed_at TIMESTAMPTZ,
|
|
attachment_names JSONB NOT NULL DEFAULT '[]'::jsonb,
|
|
body_text TEXT,
|
|
body_purged BOOLEAN NOT NULL DEFAULT FALSE,
|
|
summary JSONB,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT mails_mailbox_chk CHECK (mailbox IN ('inbox', 'sent'))
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_mails_job_id ON mails (job_id);
|
|
CREATE INDEX IF NOT EXISTS idx_mails_job_mailed_at ON mails (job_id, mailed_at);
|
|
CREATE INDEX IF NOT EXISTS idx_mails_thread_key ON mails (job_id, thread_key);
|
|
CREATE INDEX IF NOT EXISTS idx_mails_message_id ON mails (job_id, message_id);
|
|
|
|
-- Final weekly work report for a job.
|
|
CREATE TABLE IF NOT EXISTS weekly_reports (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
job_id BIGINT NOT NULL UNIQUE REFERENCES analysis_jobs(id) ON DELETE CASCADE,
|
|
model TEXT NOT NULL DEFAULT '',
|
|
scope_note TEXT NOT NULL DEFAULT '',
|
|
report JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
report_markdown TEXT,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_weekly_reports_created_at
|
|
ON weekly_reports (created_at DESC);
|