Files
mcp-outline-postgresql/migrations/001_indexes.sql
Emanuel Almeida b4ba42cbf1 feat: Add production-ready utilities and performance improvements
Security & Data Integrity:
- Centralized transaction helper with deadlock retry (exponential backoff)
- SafeQueryBuilder for safe parameterized queries
- Zod-based input validation middleware
- Audit logging to Outline's events table

Performance:
- Cursor-based pagination for large datasets
- Pool monitoring with configurable alerts
- Database index migrations for optimal query performance

Changes:
- Refactored bulk-operations, desk-sync, export-import to use centralized transaction helper
- Added 7 new utility modules (audit, monitoring, pagination, query-builder, transaction, validation)
- Created migrations/001_indexes.sql with 40+ recommended indexes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 15:23:32 +00:00

341 lines
12 KiB
SQL

-- MCP Outline PostgreSQL - Recommended Indexes
-- These indexes improve query performance for common MCP operations
-- @author Descomplicar® | @link descomplicar.pt | @copyright 2026
--
-- IMPORTANT: Review these indexes before applying to production.
-- Some may already exist in your Outline installation.
-- Run with: psql -d outline -f migrations/001_indexes.sql
-- ============================================================================
-- DOCUMENTS - Core document queries
-- ============================================================================
-- Full-text search index (GIN for performance)
-- Improves: outline_search_documents, outline_advanced_search
CREATE INDEX IF NOT EXISTS idx_documents_search
ON documents USING gin(to_tsvector('english', title || ' ' || COALESCE(text, '')));
-- Collection listing (most common query)
-- Improves: outline_list_documents, outline_list_collection_documents
CREATE INDEX IF NOT EXISTS idx_documents_collection_id
ON documents("collectionId")
WHERE "deletedAt" IS NULL;
-- Published documents (for public views)
-- Improves: queries filtering by publication status
CREATE INDEX IF NOT EXISTS idx_documents_published
ON documents("publishedAt" DESC)
WHERE "deletedAt" IS NULL AND "publishedAt" IS NOT NULL;
-- Recent documents (created at)
-- Improves: outline_list_recent, analytics queries
CREATE INDEX IF NOT EXISTS idx_documents_created
ON documents("createdAt" DESC)
WHERE "deletedAt" IS NULL;
-- Updated documents
-- Improves: outline_list_viewed_documents, activity tracking
CREATE INDEX IF NOT EXISTS idx_documents_updated
ON documents("updatedAt" DESC)
WHERE "deletedAt" IS NULL;
-- Archived documents
-- Improves: outline_list_drafts with archive filter
CREATE INDEX IF NOT EXISTS idx_documents_archived
ON documents("archivedAt" DESC)
WHERE "archivedAt" IS NOT NULL AND "deletedAt" IS NULL;
-- Parent document hierarchy
-- Improves: document tree traversal, outline_move_document
CREATE INDEX IF NOT EXISTS idx_documents_parent
ON documents("parentDocumentId")
WHERE "deletedAt" IS NULL;
-- Template documents
-- Improves: outline_list_templates
CREATE INDEX IF NOT EXISTS idx_documents_template
ON documents("collectionId", "createdAt" DESC)
WHERE template = true AND "deletedAt" IS NULL;
-- Author lookup
-- Improves: outline_get_user_activity, user document listings
CREATE INDEX IF NOT EXISTS idx_documents_created_by
ON documents("createdById", "createdAt" DESC)
WHERE "deletedAt" IS NULL;
-- ============================================================================
-- COLLECTIONS - Collection management
-- ============================================================================
-- Active collections
-- Improves: outline_list_collections
CREATE INDEX IF NOT EXISTS idx_collections_active
ON collections("createdAt" DESC)
WHERE "deletedAt" IS NULL;
-- Team collections
-- Improves: team-scoped collection queries
CREATE INDEX IF NOT EXISTS idx_collections_team
ON collections("teamId")
WHERE "deletedAt" IS NULL;
-- ============================================================================
-- MEMBERSHIPS - Permission lookups (CRITICAL for performance)
-- ============================================================================
-- Collection user memberships
-- Improves: outline_list_collection_memberships, permission checks
CREATE INDEX IF NOT EXISTS idx_collection_users_lookup
ON collection_users("collectionId", "userId");
-- User's collections
-- Improves: user permission verification
CREATE INDEX IF NOT EXISTS idx_collection_users_user
ON collection_users("userId");
-- Collection group memberships
-- Improves: outline_list_collection_group_memberships
CREATE INDEX IF NOT EXISTS idx_collection_groups_lookup
ON collection_group_memberships("collectionId", "groupId");
-- Group user memberships
-- Improves: outline_list_group_members
CREATE INDEX IF NOT EXISTS idx_group_users_lookup
ON group_users("groupId", "userId");
-- Document memberships
-- Improves: outline_list_document_memberships
CREATE INDEX IF NOT EXISTS idx_document_users_lookup
ON user_permissions("documentId", "userId");
-- ============================================================================
-- USERS - User management
-- ============================================================================
-- Active users by role
-- Improves: outline_list_users with filter
CREATE INDEX IF NOT EXISTS idx_users_active_role
ON users(role, "createdAt" DESC)
WHERE "deletedAt" IS NULL AND "suspendedAt" IS NULL;
-- Email lookup (for authentication)
-- Improves: user search by email
CREATE INDEX IF NOT EXISTS idx_users_email
ON users(email)
WHERE "deletedAt" IS NULL;
-- Team users
-- Improves: team-scoped user queries
CREATE INDEX IF NOT EXISTS idx_users_team
ON users("teamId")
WHERE "deletedAt" IS NULL;
-- ============================================================================
-- GROUPS - Group management
-- ============================================================================
-- Active groups
-- Improves: outline_list_groups
CREATE INDEX IF NOT EXISTS idx_groups_active
ON groups("createdAt" DESC)
WHERE "deletedAt" IS NULL;
-- ============================================================================
-- STARS, PINS, VIEWS - User interaction tracking
-- ============================================================================
-- User stars (bookmarks)
-- Improves: outline_stars_list
CREATE INDEX IF NOT EXISTS idx_stars_user
ON stars("userId", "createdAt" DESC);
-- Document stars
-- Improves: document bookmark count
CREATE INDEX IF NOT EXISTS idx_stars_document
ON stars("documentId")
WHERE "deletedAt" IS NULL;
-- Pins by collection
-- Improves: outline_pins_list
CREATE INDEX IF NOT EXISTS idx_pins_collection
ON pins("collectionId", index);
-- Document views
-- Improves: outline_views_list, view analytics
CREATE INDEX IF NOT EXISTS idx_views_document
ON views("documentId", "createdAt" DESC);
-- User views
-- Improves: outline_list_viewed_documents
CREATE INDEX IF NOT EXISTS idx_views_user
ON views("userId", "createdAt" DESC);
-- ============================================================================
-- COMMENTS - Comment system
-- ============================================================================
-- Document comments
-- Improves: outline_comments_list
CREATE INDEX IF NOT EXISTS idx_comments_document
ON comments("documentId", "createdAt" DESC)
WHERE "deletedAt" IS NULL;
-- Unresolved comments
-- Improves: comment resolution tracking
CREATE INDEX IF NOT EXISTS idx_comments_unresolved
ON comments("documentId", "createdAt" DESC)
WHERE "deletedAt" IS NULL AND "resolvedAt" IS NULL;
-- ============================================================================
-- SHARES - Document sharing
-- ============================================================================
-- Document shares
-- Improves: outline_shares_list
CREATE INDEX IF NOT EXISTS idx_shares_document
ON shares("documentId")
WHERE "revokedAt" IS NULL;
-- Share URL lookup
-- Improves: public share access
CREATE INDEX IF NOT EXISTS idx_shares_url
ON shares("urlId")
WHERE "revokedAt" IS NULL;
-- ============================================================================
-- REVISIONS - Version history
-- ============================================================================
-- Document revisions
-- Improves: outline_revisions_list
CREATE INDEX IF NOT EXISTS idx_revisions_document
ON revisions("documentId", "createdAt" DESC);
-- ============================================================================
-- EVENTS - Audit log (CRITICAL for analytics)
-- ============================================================================
-- Actor events (who did what)
-- Improves: outline_events_list with actor filter, user activity
CREATE INDEX IF NOT EXISTS idx_events_actor
ON events("actorId", "createdAt" DESC);
-- Model events (what happened to what)
-- Improves: outline_events_list with document/collection filter
CREATE INDEX IF NOT EXISTS idx_events_model
ON events("modelId", "createdAt" DESC);
-- Event name (type of event)
-- Improves: outline_events_list with name filter, analytics
CREATE INDEX IF NOT EXISTS idx_events_name
ON events(name, "createdAt" DESC);
-- Team events
-- Improves: team-scoped audit queries
CREATE INDEX IF NOT EXISTS idx_events_team
ON events("teamId", "createdAt" DESC);
-- Date range queries
-- Improves: analytics date filtering
CREATE INDEX IF NOT EXISTS idx_events_created
ON events("createdAt" DESC);
-- ============================================================================
-- ATTACHMENTS - File management
-- ============================================================================
-- Document attachments
-- Improves: outline_attachments_list
CREATE INDEX IF NOT EXISTS idx_attachments_document
ON attachments("documentId")
WHERE "deletedAt" IS NULL;
-- ============================================================================
-- FILE OPERATIONS - Import/Export jobs
-- ============================================================================
-- User file operations
-- Improves: outline_file_operations_list
CREATE INDEX IF NOT EXISTS idx_file_operations_user
ON file_operations("userId", "createdAt" DESC);
-- ============================================================================
-- SEARCH QUERIES - Search analytics
-- ============================================================================
-- Search query analytics
-- Improves: outline_search_queries_list, search analytics
CREATE INDEX IF NOT EXISTS idx_search_queries_created
ON search_queries("createdAt" DESC);
-- Popular searches
-- Improves: search suggestions
CREATE INDEX IF NOT EXISTS idx_search_queries_query
ON search_queries(query, "createdAt" DESC);
-- ============================================================================
-- BACKLINKS - Document references
-- ============================================================================
-- Document backlinks
-- Improves: outline_backlinks_list
CREATE INDEX IF NOT EXISTS idx_backlinks_document
ON backlinks("documentId");
-- Reverse backlinks (what links to this)
-- Improves: linked document lookup
CREATE INDEX IF NOT EXISTS idx_backlinks_reverse
ON backlinks("reverseDocumentId");
-- ============================================================================
-- NOTIFICATIONS - User notifications
-- ============================================================================
-- User notifications
-- Improves: outline_notifications_list
CREATE INDEX IF NOT EXISTS idx_notifications_user
ON notifications("userId", "createdAt" DESC);
-- Unread notifications
-- Improves: notification count
CREATE INDEX IF NOT EXISTS idx_notifications_unread
ON notifications("userId", "createdAt" DESC)
WHERE "readAt" IS NULL;
-- ============================================================================
-- SUBSCRIPTIONS - Document subscriptions
-- ============================================================================
-- User subscriptions
-- Improves: outline_subscriptions_list
CREATE INDEX IF NOT EXISTS idx_subscriptions_user
ON subscriptions("userId", "createdAt" DESC);
-- Document subscriptions
-- Improves: subscriber notifications
CREATE INDEX IF NOT EXISTS idx_subscriptions_document
ON subscriptions("documentId");
-- ============================================================================
-- COMPOSITE INDEXES for complex queries
-- ============================================================================
-- Collection documents with sorting
-- Improves: outline_list_collection_documents with sort
CREATE INDEX IF NOT EXISTS idx_documents_collection_title
ON documents("collectionId", title)
WHERE "deletedAt" IS NULL;
-- User activity by date
-- Improves: outline_get_user_activity
CREATE INDEX IF NOT EXISTS idx_events_actor_date
ON events("actorId", name, "createdAt" DESC);
-- ============================================================================
-- VERIFY INDEXES
-- ============================================================================
-- List all indexes created by this migration
-- SELECT indexname, tablename FROM pg_indexes
-- WHERE indexname LIKE 'idx_%' ORDER BY tablename, indexname;