-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-- Posimai Brain Full-Text Save Migration
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-- Purpose: Add full_text column to store article body from Reader
-- Date: 2026-03-01
-- Impact: Critical data loss prevention
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

-- ──────────────────────────────────────────────────────────────────────
-- STEP 1: Backup existing data
-- ──────────────────────────────────────────────────────────────────────
-- Before running migration, create backup:
-- pg_dump -U brain_user -d brain_db -t articles > /backup/articles_$(date +%Y%m%d).sql

-- ──────────────────────────────────────────────────────────────────────
-- STEP 2: Add full_text column
-- ──────────────────────────────────────────────────────────────────────
BEGIN;

-- Add full_text column for storing article body
ALTER TABLE articles
ADD COLUMN IF NOT EXISTS full_text TEXT;

-- Add images column (optional, for future use)
ALTER TABLE articles
ADD COLUMN IF NOT EXISTS images TEXT[];

-- Add updated_at if it doesn't exist
ALTER TABLE articles
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMP DEFAULT NOW();

COMMIT;

-- ──────────────────────────────────────────────────────────────────────
-- STEP 3: Create indexes for performance
-- ──────────────────────────────────────────────────────────────────────
BEGIN;

-- Full-text search index (Japanese language support)
-- This enables fast text search in Brain UI
CREATE INDEX IF NOT EXISTS idx_articles_full_text_search
ON articles USING gin(to_tsvector('english', COALESCE(full_text, '')));

-- Note: PostgreSQL doesn't have built-in Japanese tokenizer by default
-- For better Japanese search, consider installing pg_bigm extension:
-- CREATE EXTENSION IF NOT EXISTS pg_bigm;
-- CREATE INDEX IF NOT EXISTS idx_articles_full_text_bigm
-- ON articles USING gin(full_text gin_bigm_ops);

-- Index for finding articles without full_text (for migration/cleanup)
CREATE INDEX IF NOT EXISTS idx_articles_missing_full_text
ON articles (id) WHERE full_text IS NULL;

COMMIT;

-- ──────────────────────────────────────────────────────────────────────
-- STEP 4: Verify schema changes
-- ──────────────────────────────────────────────────────────────────────
-- \d articles

-- Expected output should include:
-- | Column      | Type      | Nullable | Description                    |
-- |-------------|-----------|----------|--------------------------------|
-- | id          | SERIAL    | NOT NULL | Primary key                    |
-- | user_id     | INTEGER   | NOT NULL | Foreign key to users table     |
-- | url         | TEXT      | NOT NULL | Original article URL           |
-- | title       | TEXT      | NOT NULL | Article title                  |
-- | full_text   | TEXT      | NULL     | ← NEW! Article body from Reader|
-- | summary     | TEXT      | NULL     | AI-generated 3-sentence summary|
-- | topics      | TEXT[]    | NULL     | AI-generated topic tags        |
-- | source      | TEXT      | NULL     | Source (reader/feed/bookmarklet)|
-- | reading_time| INTEGER   | NULL     | Estimated reading time (minutes)|
-- | favicon     | TEXT      | NULL     | Site favicon URL               |
-- | og_image    | TEXT      | NULL     | OGP image URL                  |
-- | images      | TEXT[]    | NULL     | ← NEW! Article images (future) |
-- | status      | TEXT      | NOT NULL | inbox/favorite/shared/archived |
-- | created_at  | TIMESTAMP | NOT NULL | Record creation time           |
-- | updated_at  | TIMESTAMP | NULL     | ← NEW! Record update time      |

-- ──────────────────────────────────────────────────────────────────────
-- STEP 5: Test query (verify columns exist)
-- ──────────────────────────────────────────────────────────────────────
SELECT
    id,
    title,
    LENGTH(full_text) as text_length,
    LEFT(full_text, 50) as text_preview,
    summary,
    topics,
    created_at
FROM articles
ORDER BY created_at DESC
LIMIT 5;

-- Expected: All existing articles will have NULL for full_text
-- New articles saved after API update will have full_text populated

-- ──────────────────────────────────────────────────────────────────────
-- STEP 6: Clean up old articles (optional)
-- ──────────────────────────────────────────────────────────────────────
-- If you want to delete old articles without full_text after migration:
-- (Run this ONLY after confirming new articles are saving correctly)

-- Count articles without full_text
SELECT COUNT(*) as articles_without_fulltext
FROM articles
WHERE full_text IS NULL;

-- Optionally delete old articles without full_text (BE CAREFUL!)
-- DELETE FROM articles WHERE full_text IS NULL AND created_at < NOW() - INTERVAL '30 days';

-- ──────────────────────────────────────────────────────────────────────
-- STEP 7: Add constraint for new articles (optional, recommended)
-- ──────────────────────────────────────────────────────────────────────
-- After confirming Reader is sending full_text correctly,
-- you can add a constraint to ensure all new articles have full_text:

-- ALTER TABLE articles
-- ADD CONSTRAINT full_text_required
-- CHECK (
--     (source = 'reader' AND full_text IS NOT NULL) OR
--     (source != 'reader')
-- );

-- This ensures Reader-sourced articles MUST have full_text

-- ──────────────────────────────────────────────────────────────────────
-- STEP 8: Grant permissions (if needed)
-- ──────────────────────────────────────────────────────────────────────
-- If using a separate API user, grant access to new columns:
-- GRANT SELECT, INSERT, UPDATE ON articles TO brain_api_user;

-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-- Migration Complete!
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-- Next steps:
-- 1. Update Brain API server code (see BRAIN_FULLTEXT_IMPLEMENTATION_GUIDE.md)
-- 2. Test saving an article from Reader
-- 3. Verify full_text is populated in database
-- 4. Deploy Brain API changes to production
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
