# Task 30: Image Preview in Document Cards

**Date:** 2026-02-19 18:25
**Status:** Completed
**Related Task ID:** 33, 34

## 1. Context
User requested a "Visual Pop" for the document list, finding the text-only card view too dry. They wanted to see images (like YouTube thumbnails) directly in the cards.
A 9-Agent Deep Dive meeting (`docs/plans/260219-9-agent-image-preview-meeting.md`) was held to discuss the UX and technical constraints (specifically Google Drive security).

## 2. Decision: Serverless Drive Proxy
To balance visual impact with the "Files in Drive" security model, we adopted a **Proxy** strategy.

-   **Problem:** Google Drive images are private/cors-restricted and cannot be used in plain `<img>` tags.
-   **Solution:** A Next.js API route (`/api/drive-image/[fileId]`) that acts as a secure stream proxy.
    -   It uses the server-side Service Account to fetch the file.
    -   It streams the binary data to the client with caching headers.
    -   This allows standard `<img src="/api/drive-image/...">` usage without exposing private Drive links.

## 3. Implementation Details

### A. Backend (Proxy API)
-   **Path:** `src/app/api/drive-image/[fileId]/route.ts`
-   **Function:**
    -   Validates `fileId`.
    -   Checks mimeType (must be image).
    -   Streams content from Drive.
    -   Sets `Cache-Control: public, max-age=31536000` (1 year) for performance.

### B. Database (Firestore Schema)
-   **Update:** Added `coverImage` field to `Document` (and `WikiDocument` type).
-   **Type:** `string | null` (Stores the Google Drive File ID).

### C. Logic (Auto-Extraction)
-   **Path:** `src/app/docs/[id]/DocumentClient.tsx`
-   **Trigger:** `handleSave`
-   **Mechanism:**
    -   Parses the Markdown content.
    -   Finds the first image syntax `![alt](url)`.
    -   Extracts the File ID (supporting both `drive.google.com` links and existing `/api/drive-image/` links).
    -   Saves this ID to `coverImage` field in Firestore.

### D. Frontend (UI)
-   **Path:** `src/app/page.tsx`
-   **Layout:** "Top Hero" Card Style.
    -   If `doc.coverImage` exists: Renders a 160px height image at the top of the card.
    -   If not: Falls back to the existing "Premium Gradient Blob" decoration.
-   **Interaction:** Hover zoom effect (`scale-105`) for a dynamic feel.

## 4. Verification
-   **Test:** Created a document, added an image, saved.
-   **Result:** `coverImage` field populated in Firestore. Main page card correctly displayed the image via the proxy.
-   **Performance:** Image loaded successfully with lazy loading.

## 5. Next Steps
-   Monitor Vercel bandwidth usage (Proxy consumes bandwidth).
-   Consider generating optimal thumbnails (Resize) if bandwidth becomes an issue.
