Files

220 lines
10 KiB
Markdown

# Implementation Plan: Document Export API Route
**Branch**: `002-document-export` | **Date**: 2026-03-09 | **Spec**: [spec.md](spec.md)
**Input**: Feature specification from `/specs/002-document-export/spec.md`
**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/plan-template.md` for the execution workflow.
## Summary
Implement a new `/documents/:documentId` HTTP route in the proxy script that exports Google Drive documents in multiple formats. The route fetches document metadata from Google Drive API, selects the best available export format (Markdown > HTML > PDF) based on availability, and streams the content with appropriate headers. Native PDF files are streamed directly. Error handling covers all edge cases with specific HTTP status codes (401, 403, 404, 413, 500, 502, 504) and enforces a 10MB size limit with 30-second timeout.
## Technical Context
**Language/Version**: Node.js >=18.0.0 (ES modules)
**Primary Dependencies**: axios (HTTP client), jsonwebtoken (JWT for Google auth), uuid (request IDs), xmlbuilder2 (sitemap generation)
**Storage**: N/A (stateless proxy, no database)
**Testing**: Node.js built-in test runner (`node --test`), organized by contract/integration/unit
**Target Platform**: Linux/macOS server (Node.js runtime)
**Project Type**: Web service proxy (HTTP-to-Google Drive API adapter)
**Performance Goals**: <5 seconds for documents <10MB, 50 concurrent requests without degradation, 99% success rate
**Constraints**: 30-second timeout per request, 10MB document size limit, monolithic architecture (all logic in proxy.js via vm.Script isolation)
**Scale/Scope**: Single proxy instance serving document exports from Google Drive, isolated VM context execution per request
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
### ✅ Monolithic Architecture (NON-NEGOTIABLE)
- **Status**: PASS
- **Implementation**: All business logic will be in `src/proxyScripts/proxy.js` loaded via `vm.Script`
- **Details**: New `/documents/:documentId` route, Google Drive API calls, format selection, and streaming logic will be added to existing proxy.js monolith
- **Helper Functions**: Document format selection and filename extension mapping may be extracted to `src/globalVariables/googleDriveAdapterHelper.js` if they improve code organization (pure utilities only)
### ✅ Zero External Imports/Exports (NON-NEGOTIABLE)
- **Status**: PASS
- **Implementation**: proxy.js continues to have zero imports/exports, all dependencies injected via VM context
- **Dependencies**: axios (HTTP), jwt (auth), crypto (signatures) already injected by server.js
- **Data Access**: Uses existing global variables pattern (google_drive_settings) for credentials
### ✅ Test-First Development (NON-NEGOTIABLE)
- **Status**: PASS
- **Implementation**: Contract tests → Integration tests → Unit tests → Implementation
- **Test Structure**:
- Contract tests: Verify `/documents/:documentId` endpoint behavior against spec requirements
- Integration tests: Test Google Drive API integration with mock responses
- Unit tests: Test format selection logic, header generation, error mapping
- **Coverage Target**: ≥80% code coverage
### ✅ API-First Design
- **Status**: PASS
- **Implementation**: HTTP endpoint contract defined before implementation
- **Contract**: `/documents/:documentId` route with documented request/response formats
- **Documentation**: OpenAPI-style contract in contracts/ directory
### ✅ Security & Privacy by Default
- **Status**: PASS
- **Implementation**: Leverages existing Google Drive OAuth2/service account authentication
- **Access Control**: Google Drive API permissions enforced (returns 401 for unauthorized)
- **Data Privacy**: No caching, documents streamed directly from Google Drive to client
### ✅ Semantic Versioning
- **Status**: PASS
- **Implementation**: New feature added to existing v1.0.0 (minor version bump to v1.1.0)
- **Backward Compatibility**: New route doesn't affect existing sitemap functionality
### ✅ Simplicity & YAGNI
- **Status**: PASS
- **Implementation**: No caching, no retry logic, no rate limiting - only what's specified
- **Scope**: Single document export only (no batch operations)
## Project Structure
### Documentation (this feature)
```text
specs/002-document-export/
├── spec.md # Feature specification (completed)
├── plan.md # This file (/speckit.plan command output)
├── research.md # Phase 0 output (Google Drive export API patterns)
├── data-model.md # Phase 1 output (Document/ExportRequest/ExportFormat entities)
├── quickstart.md # Phase 1 output (How to use the new /documents/:documentId route)
├── contracts/ # Phase 1 output (API contracts)
│ └── documents-export-api.md # HTTP endpoint contract for document export
├── requirements-checklist.md # Specification quality validation
└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
```
### Source Code (repository root)
```text
src/
├── proxyScripts/
│ └── proxy.js # Main business logic (ADD: /documents/:documentId route handler)
├── globalVariables/
│ ├── google_drive_settings.json # Existing: Google Drive credentials
│ └── googleDriveAdapterHelper.js # UPDATE: Add format selection helpers (optional)
├── logger.js # Existing: Structured logging
└── server.js # Existing: HTTP server bootstrap (no changes needed)
config/
└── default.json # Existing: Infrastructure settings (no changes)
tests/
├── contract/
│ └── documents-export.test.js # NEW: Contract tests for /documents/:documentId
├── integration/
│ └── google-drive-export.test.js # NEW: Integration tests with Google Drive API mocks
└── unit/
├── format-selection.test.js # NEW: Unit tests for format selection logic
└── export-headers.test.js # NEW: Unit tests for Content-Type/Content-Disposition
```
**Structure Decision**: Single-project architecture maintained per constitution. All new business logic (route handling, format selection, streaming) added to existing `src/proxyScripts/proxy.js` monolith. Pure utility functions for format mapping and filename generation may be extracted to `googleDriveAdapterHelper.js` if they improve code organization. Tests organized by contract/integration/unit following existing pattern.
## Complexity Tracking
> **Fill ONLY if Constitution Check has violations that must be justified**
No violations - all constitutional principles satisfied.
---
## Phase 0: Research (COMPLETE)
**Generated**: `research.md`
**Key Decisions**:
1. Google Drive Files.get API with field selection for metadata
2. Priority-based format selection: Markdown > HTML > PDF
3. Native PDF streaming using alt=media parameter
4. Content-Disposition inline with filename sanitization
5. Error mapping from Google Drive API to HTTP status codes
6. 30-second timeout via axios, 10MB size limit via Content-Length
7. Streaming content directly without buffering
---
## Phase 1: Design & Contracts (COMPLETE)
**Generated**:
- `data-model.md` - Document, ExportRequest, ExportFormat entities
- `contracts/documents-export-api.md` - HTTP endpoint contract
- `quickstart.md` - User guide for the new endpoint
**Agent Context Updated**: GitHub Copilot context file updated with Node.js, axios, and project details
### Post-Design Constitution Re-Check
All constitutional principles remain satisfied:
-**Monolithic Architecture**: New route logic in proxy.js
-**Zero Imports/Exports**: VM context injection maintained
-**Test-First Development**: Contract → Integration → Unit test structure defined
-**API-First Design**: Endpoint contract documented before implementation
-**Security**: Leverages existing Google Drive authentication
-**Simplicity**: No caching, no retry, no rate limiting - only specified features
---
## Phase 2: Implementation Planning (Ready for /speckit.tasks)
**Next Steps**:
1. Run `/speckit.tasks` to generate `tasks.md` with:
- Dependency-ordered implementation tasks
- Test-first workflow (write tests before implementation)
- Tasks grouped by user story (P1, P2, P3)
- Independent testability per story
2. Implementation will add to `src/proxyScripts/proxy.js`:
- Route handler for `/documents/:documentId`
- Google Drive metadata fetch logic
- Format selection algorithm
- Content streaming with headers
- Error handling for all edge cases
3. Optional helper extraction to `src/globalVariables/googleDriveAdapterHelper.js`:
- Format priority mapping
- Filename sanitization
- Content-Disposition header generation
- Error status code mapping
4. Tests will be created in:
- `tests/contract/documents-export.test.js`
- `tests/integration/google-drive-export.test.js`
- `tests/unit/format-selection.test.js`
- `tests/unit/export-headers.test.js`
---
## Summary
**Feature**: Document Export API Route
**Branch**: `002-document-export`
**Status**: Planning Complete ✅
**Constitution Compliance**: All gates passed ✅
**Artifacts Generated**:
- ✅ spec.md (feature specification)
- ✅ plan.md (this file)
- ✅ research.md (technical decisions)
- ✅ data-model.md (entities & relationships)
- ✅ contracts/documents-export-api.md (HTTP endpoint contract)
- ✅ quickstart.md (user guide)
- ⏭️ tasks.md (run `/speckit.tasks` to generate)
**Ready for**: `/speckit.tasks` command to generate implementation tasks
**Implementation Approach**:
1. Test-first development (TDD)
2. Monolithic architecture (all logic in proxy.js)
3. Streaming content (no buffering)
4. Comprehensive error handling
5. 80%+ code coverage target
**Performance Targets**:
- <5 seconds for documents <10MB
- 50+ concurrent requests
- 99% success rate
- <1MB memory per request