# Architecture Decision Records

> **Purpose**: Record WHY decisions were made. Critical for future AI agents.  
> **Last Updated**: 2025-01-12

## ADR-001: Hybrid Authentication Approach

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Need to authenticate with Filevine API without requiring users to manually log in again.

**Decision**: Use hybrid authentication - extract tokens from active Filevine session via content script, then use those tokens in background service worker for API calls.

**Reasoning**:
- Zero-friction user experience - no additional login required
- Leverages existing Filevine session
- Tokens already available in page context
- Background worker can make API calls without CORS issues
- More secure than storing credentials

**Alternatives Considered**:
- **OAuth flow**: Requires user to manually authenticate, poor UX
- **API keys**: Not available from Filevine, would require manual setup
- **Session cookies**: Cannot access from extension context reliably

**Consequences**:
- Dependency on Filevine page structure (may break if they change)
- Requires content script injection
- Token extraction may fail on some page configurations
- Need multiple extraction strategies for reliability

**Related**: `DATA_FLOW.md#authentication-flow`, `SERVICES.md#tokenextractor`

---

## ADR-002: IndexedDB for File Storage

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Need to store downloaded files locally for offline viewing and viewer access.

**Decision**: Use IndexedDB to store file blobs and metadata.

**Reasoning**:
- Can store large binary data (files can be 100MB+)
- Persistent storage across extension restarts
- Fast access for viewer opening
- No size limits like chrome.storage
- Native browser API, no dependencies

**Alternatives Considered**:
- **chrome.storage**: 10MB limit, not suitable for files
- **chrome.downloads API**: Downloads to user's Downloads folder, not accessible programmatically
- **External storage**: Would require server, adds complexity

**Consequences**:
- Need to manage storage cleanup (auto-expire old files)
- IndexedDB can be complex to work with
- Storage grows unbounded without cleanup
- Files persist even after extension uninstall (unless explicitly cleared)

**Related**: `SERVICES.md#downloadmanager`, `DATA_FLOW.md#download-flow`

---

## ADR-003: Background Service Worker for API Calls

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Need to make API calls to Filevine without CORS issues.

**Decision**: All API calls happen from background service worker, not from popup or content scripts.

**Reasoning**:
- Background service worker has no CORS restrictions
- Centralized API client management
- Can implement rate limiting and retry logic in one place
- Tokens stored securely in background context
- Single point of failure/management

**Alternatives Considered**:
- **Popup API calls**: Would hit CORS restrictions
- **Content script API calls**: Same CORS issues, plus tokens exposed to page
- **External proxy**: Adds infrastructure complexity

**Consequences**:
- All API operations require message passing
- Slight latency overhead for message routing
- Background worker can be terminated by browser (need to handle re-initialization)

**Related**: `SERVICES.md#backgroundservice`, `SERVICES.md#filevineclient`

---

## ADR-004: Numeric User ID Requirement

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Filevine API requires numeric user ID, but JWT contains UUID in `sub` claim.

**Decision**: Always call `GetUserOrgsWithToken` to get numeric user ID, never use JWT `sub` claim.

**Reasoning**:
- Filevine API endpoints require numeric user ID in `x-fv-userid` header
- JWT `sub` claim contains UUID, not numeric ID
- API will reject requests with wrong user ID format
- Discovered through testing (not in public docs)

**Alternatives Considered**:
- **Use JWT sub**: Would cause API failures
- **Hardcode user ID**: Not possible, varies per user

**Consequences**:
- Extra API call required during authentication
- Must parse `user.userId.native` from response
- Critical to get right or all API calls fail

**Related**: `SERVICES.md#authmanager`, `TROUBLESHOOTING.md#api-errors`

---

## ADR-005: PascalCase API Endpoints

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Filevine API endpoints use PascalCase, not lowercase REST conventions.

**Decision**: Use PascalCase for all API endpoints (e.g., `/Projects` not `/projects`).

**Reasoning**:
- Filevine API requires PascalCase
- Discovered through testing
- Not documented in public API docs
- Using lowercase causes 404 errors

**Alternatives Considered**:
- **Lowercase REST**: Would cause 404 errors
- **Try both**: Adds complexity, slower

**Consequences**:
- Must remember PascalCase convention
- Easy to make mistakes (typos cause 404s)
- Documented in constants.js for reference

**Related**: `SERVICES.md#filevineclient`, `src/lib/constants.js`

---

## ADR-006: Chrome Extension MV3

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Choose between MV2 (deprecated) and MV3 (current standard).

**Decision**: Use Manifest V3 for Chrome extension.

**Reasoning**:
- MV2 is deprecated and will be removed
- MV3 is current standard
- Better security model
- Required for future Chrome versions
- Service workers are more efficient than background pages

**Alternatives Considered**:
- **MV2**: Deprecated, not future-proof

**Consequences**:
- Service workers can be terminated by browser
- Need to handle re-initialization
- Some MV2 APIs not available (but not needed here)

**Related**: `ARCHITECTURE.md`, `manifest.json`

---

## ADR-007: Vanilla JavaScript (No Framework)

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Choose UI framework for popup and viewers.

**Decision**: Use vanilla JavaScript, HTML, and CSS - no framework.

**Reasoning**:
- Simpler for v1 - no build step required
- Smaller bundle size
- Faster load times
- No dependency management
- Easy to understand and modify

**Alternatives Considered**:
- **React**: Adds complexity, build step, larger bundle
- **Preact**: Lighter but still adds complexity
- **Vue**: Similar to React considerations

**Consequences**:
- More manual DOM manipulation
- No component reusability patterns
- Can refactor to framework later if needed

**Related**: `SERVICES.md#popupcontroller`

---

## ADR-008: Multiple Token Extraction Strategies

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Token extraction may fail with single method due to Filevine page variations.

**Decision**: Implement multiple extraction strategies in priority order: network interception > localStorage > sessionStorage > page state > OIDC patterns.

**Reasoning**:
- Network interception is most reliable but may not always work
- Storage methods vary by Filevine configuration
- Need fallbacks for reliability
- Different Filevine instances may use different storage patterns

**Alternatives Considered**:
- **Single method**: Would fail on some configurations
- **User manual entry**: Poor UX

**Consequences**:
- More complex extraction logic
- Slower extraction (tries multiple methods)
- Higher reliability

**Related**: `SERVICES.md#tokenextractor`, `DATA_FLOW.md#authentication-flow`

---

## ADR-009: Rate Limiting in Client

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Filevine API has rate limits (100/min burst, 600/hr sustained).

**Decision**: Implement basic rate limiting in FilevineClient with request spacing and retry logic.

**Reasoning**:
- Prevents hitting rate limits
- Better user experience (fewer errors)
- Retry logic handles temporary rate limit errors
- Simple implementation sufficient for v1

**Alternatives Considered**:
- **No rate limiting**: Would hit limits frequently
- **Server-side proxy**: Adds infrastructure complexity
- **Token bucket algorithm**: Overkill for v1

**Consequences**:
- Slight latency overhead for request spacing
- May need more sophisticated algorithm if usage grows
- Retry logic adds complexity

**Related**: `SERVICES.md#filevineclient`, `src/lib/constants.js`

---

## ADR-010: Viewer Registry Pattern

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Need extensible system for adding new file viewers (DICOM, PDF, etc.).

**Decision**: Use registry pattern - viewers register themselves, registry routes files to appropriate viewer.

**Reasoning**:
- Extensible - easy to add new viewers
- Separation of concerns
- Viewer-specific logic isolated
- Can support custom viewers in future

**Alternatives Considered**:
- **Hardcoded viewer selection**: Not extensible
- **Plugin system**: Overkill for v1

**Consequences**:
- Slight overhead for viewer lookup
- Need to maintain viewer registry
- Easy to add new viewers

**Related**: `SERVICES.md#viewerregistry`

---

## ADR-011: Cookie-Based Authentication for Web App API

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Token extraction from Filevine page wasn't working. Discovered that Filevine's web app uses HTTP-only cookies, not Bearer tokens.

**Decision**: Implement cookie-based authentication using Chrome's `chrome.cookies` API to read HTTP-only cookies, and create a separate `WebApiClient` for web app API endpoints.

**Reasoning**:
- Filevine's web app uses ASP.NET Application Cookies (HTTP-only)
- HTTP-only cookies cannot be accessed from JavaScript
- Must use Chrome's cookie API to read them
- Web app API endpoints differ from external API endpoints
- Need separate client to handle cookie-based requests

**Alternatives Considered**:
- **Bearer token extraction**: Not available in web app context
- **Single API client**: Would be confusing, endpoints are different
- **Manual cookie entry**: Poor UX

**Consequences**:
- Need `cookies` permission in manifest.json
- Must periodically check for cookie changes
- Need to verify cookie validity via API calls
- Separate API client adds complexity but improves clarity
- Cookie-based auth is more reliable than token extraction

**Related**: `SERVICES.md#webapiclient`, `SERVICES.md#cookieinterceptor`, `CHANGELOG.md`

---

## ADR-012: Content Script Bundling for MV3

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Chrome MV3 content scripts don't support ES6 modules (static or dynamic imports).

**Decision**: Bundle all content script dependencies into a single non-module file (`index.bundle.js`).

**Reasoning**:
- MV3 content scripts run in isolated world, no module support
- Dynamic imports also don't work in content scripts
- Bundling is the only way to use dependencies
- Keeps code organized while meeting MV3 requirements

**Alternatives Considered**:
- **Dynamic imports**: Don't work in content scripts
- **Global scripts**: Would pollute page context
- **No dependencies**: Too limiting

**Consequences**:
- Need build step to create bundle (or manual bundling)
- Larger content script file
- Must maintain both source and bundled versions
- Works reliably in MV3

**Related**: `src/content/index.bundle.js`, `TROUBLESHOOTING.md#content-script-module-error`

---

## ADR-013: Separate Network Interception Script

**Date**: 2025-01-12  
**Status**: Accepted  
**Context**: Content Security Policy blocks inline scripts. Network interception code needs to run in page context.

**Decision**: Move interception code to separate file (`interception.js`) and inject via `<script src>` tag.

**Reasoning**:
- CSP blocks inline scripts
- Separate file can be added to `web_accessible_resources`
- Injection via `<script src>` bypasses CSP
- Keeps interception code isolated

**Alternatives Considered**:
- **Inline script**: Blocked by CSP
- **Content script only**: Can't intercept page's fetch/XHR
- **Background script**: Can't access page context

**Consequences**:
- Need separate file for interception
- Must add to web_accessible_resources
- Slightly more complex injection process
- Works reliably with CSP

**Related**: `src/content/interception.js`, `TROUBLESHOOTING.md#csp-violation`

---

## Adding a New ADR

1. Use template above
2. Number sequentially (ADR-011, etc.)
3. Include date, status, context, decision, reasoning, alternatives, consequences
4. Link to related services and flows
5. Update this file's index if needed
