Files
goclaw/migrations/000046_vault_nullable_agent_id.up.sql
viettranx 9f77bfe711 feat(vault): tenant-wide rescan with nullable agent_id + media preview
Vault rescan redesigned from per-agent to tenant-wide:
- POST /v1/vault/rescan replaces POST /v1/agents/{id}/vault/rescan
- agent_id nullable in vault_documents (PG migration 046 + SQLite v14)
- Path-based scope inference: agents/{key}/ → personal, teams/{uuid}/ → team, root → shared
- Interceptor sets agent_id=NULL for team-scoped file writes
- Enrichment worker batch key handles empty agent_id
- web-fetch/ directory excluded from vault scan at any depth
- Media preview: images render via authenticated blob URL, binary files show metadata
- Scan button no longer requires agent selection
2026-04-10 16:32:54 +07:00

42 lines
1.6 KiB
PL/PgSQL

-- Make agent_id nullable so team-scoped and tenant-shared files can exist
-- without an owning agent.
-- 1. Drop NOT NULL on agent_id.
ALTER TABLE vault_documents ALTER COLUMN agent_id DROP NOT NULL;
-- 2. Change FK from CASCADE to SET NULL (agent deletion preserves docs).
ALTER TABLE vault_documents DROP CONSTRAINT vault_documents_agent_id_fkey;
ALTER TABLE vault_documents ADD CONSTRAINT vault_documents_agent_id_fkey
FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE SET NULL;
-- 3. Replace unique index: add tenant_id as leading column, COALESCE both nullable cols.
DROP INDEX IF EXISTS uq_vault_docs_agent_team_scope_path;
CREATE UNIQUE INDEX uq_vault_docs_agent_team_scope_path
ON vault_documents (
tenant_id,
COALESCE(agent_id, '00000000-0000-0000-0000-000000000000'),
COALESCE(team_id, '00000000-0000-0000-0000-000000000000'),
scope,
path
);
-- 4. Trigger: when agent deleted (SET NULL) and no team -> scope='shared'.
CREATE OR REPLACE FUNCTION vault_docs_agent_null_scope_fix()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.agent_id IS NULL AND OLD.agent_id IS NOT NULL AND NEW.team_id IS NULL THEN
NEW.scope := 'shared';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_vault_docs_agent_null_scope
BEFORE UPDATE OF agent_id ON vault_documents
FOR EACH ROW
EXECUTE FUNCTION vault_docs_agent_null_scope_fix();
-- 5. Partial index for agent-scoped queries (skip NULLs).
DROP INDEX IF EXISTS idx_vault_docs_agent_scope;
CREATE INDEX idx_vault_docs_agent_scope ON vault_documents(agent_id, scope) WHERE agent_id IS NOT NULL;