feat: Add X-Verint-KAB-Original-URL header to document exports

Adds HTTP response header containing original Google Drive URL
for exported documents to enable content traceability and auditing.

- Adds X-Verint-KAB-Original-URL header to successful export responses
- Header format: https://drive.google.com/file/d/{fileId}
- Present for all export formats (PDF, DOCX, plain text)
- Header omitted on error responses (4xx/5xx)
- 18 new tests (9 contract + 9 integration)
- Zero new dependencies
- Performance: 0.000019ms overhead per request

Implements:
- FR-001: Header present on successful exports (200 OK)
- FR-002: Header absent on error responses
- FR-003: Standard header name X-Verint-KAB-Original-URL
- FR-004: Standard URL format with file ID
- FR-005: Uses validated document.id from Google Drive API
- FR-006: Header present regardless of file accessibility
- FR-007: Consistent across all export formats
- FR-008: Minimal performance impact (< 5ms requirement)

Testing:
- Contract tests validate header presence, format, and error handling
- Integration tests verify behavior across formats and permissions
- All 18 tests passing
- 100% requirements coverage

Documentation:
- Feature specification (specs/001-gdrive-url-header/spec.md)
- Implementation plan (plan.md)
- Technical research (research.md)
- Data model (data-model.md)
- API contract (contracts/response-headers.md)
- User guide (quickstart.md)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-03-27 16:04:54 -05:00
parent 2641afaabe
commit 9286ee8927
11 changed files with 2681 additions and 0 deletions

View File

@@ -0,0 +1,244 @@
# Tasks: Google Drive Original URL Header
**Input**: Design documents from `/specs/001-gdrive-url-header/`
**Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/response-headers.md, quickstart.md
**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
## Format: `[ID] [P?] [Story] Description`
- **[P]**: Can run in parallel (different files, no dependencies)
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
- Include exact file paths in descriptions
---
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Project initialization - verify existing structure is ready
- [X] T001 Verify Node.js test framework (node:test) is available and working
- [X] T002 Review src/proxyScripts/proxy.js structure for implementation location (lines 374-389)
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: No foundational infrastructure changes needed - feature uses existing proxy.js architecture
**⚠️ CRITICAL**: This feature requires no new infrastructure. Existing Google Drive API integration and response handling are sufficient.
**Checkpoint**: Foundation ready (existing) - user story implementation can begin
---
## Phase 3: User Story 1 - Client Retrieves Source Document Location (Priority: P1) 🎯 MVP
**Goal**: Enable clients to retrieve the original Google Drive URL via HTTP response header for successful document exports
**Independent Test**: Make a document export request and verify the response contains X-Verint-KAB-Original-URL header with a valid Google Drive URL that links to the source document
### Tests for User Story 1 (TDD - Write FIRST)
> **NOTE: Write these tests FIRST, ensure they FAIL before implementation**
- [X] T003 [P] [US1] Create contract test for X-Verint-KAB-Original-URL header presence in tests/contract/response-headers.test.js
- [X] T004 [P] [US1] Create integration test for header with real Drive API responses in tests/integration/header-integration.test.js
### Implementation for User Story 1
- [X] T005 [US1] Add X-Verint-KAB-Original-URL header in src/proxyScripts/proxy.js at line ~377-383 in handleDocumentExportRequest
- [X] T006 [US1] Verify tests pass and header is included in all successful export responses
**Checkpoint**: User Story 1 complete - header present on successful exports, tests pass
---
## Phase 4: User Story 2 - Header Included for Different Export Formats (Priority: P2)
**Goal**: Ensure X-Verint-KAB-Original-URL header is consistently included regardless of export format (PDF, DOCX, plain text, etc.)
**Independent Test**: Request exports in different supported formats and verify each response includes the header with the same source URL
### Tests for User Story 2 (TDD - Write FIRST)
- [X] T007 [US2] Add test for PDF export format in tests/contract/response-headers.test.js
- [X] T008 [US2] Add test for DOCX export format in tests/contract/response-headers.test.js
- [X] T009 [US2] Add test for plain text export format in tests/contract/response-headers.test.js
### Implementation for User Story 2
- [X] T010 [US2] Verify existing implementation handles all export formats (no code changes needed - same code path)
- [X] T011 [US2] Run all format tests to confirm header consistency across export types
**Checkpoint**: User Story 2 complete - header present for all export formats
---
## Phase 5: User Story 3 - Header Handling for Shared and Private Documents (Priority: P3)
**Goal**: Include X-Verint-KAB-Original-URL header for both privately-owned and shared Google Drive documents regardless of sharing permissions
**Independent Test**: Export documents with different permission levels (private, shared with specific users, organization-wide) and verify the header is always present
### Tests for User Story 3 (TDD - Write FIRST)
- [X] T012 [US3] Add test for private document export in tests/integration/header-integration.test.js
- [X] T013 [US3] Add test for shared document export in tests/integration/header-integration.test.js
- [X] T014 [US3] Add test for organization-wide shared document in tests/integration/header-integration.test.js
### Implementation for User Story 3
- [X] T015 [US3] Verify existing implementation handles all permission levels (no code changes needed - permissions don't affect header)
- [X] T016 [US3] Run all permission tests to confirm header consistency across sharing states
**Checkpoint**: User Story 3 complete - header present regardless of document sharing permissions
---
## Phase 6: Polish & Cross-Cutting Concerns
**Purpose**: Validation, documentation, and quality improvements
- [X] T017 [P] Validate quickstart.md examples work with implementation
- [X] T018 [P] Run full test suite and verify 100% pass rate for header feature
- [X] T019 [P] Verify header absent on error responses (404, 401, 403, 413, 5xx)
- [X] T020 Performance test: Verify header addition overhead < 5ms per request
- [X] T021 Validate header format matches contract specification exactly
- [X] T022 Code review: Ensure implementation follows monolithic architecture principles
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: No dependencies - can start immediately
- **Foundational (Phase 2)**: No work needed - existing infrastructure sufficient
- **User Stories (Phase 3-5)**: Can proceed in priority order (P1 → P2 → P3)
- **US1 (P1)**: Core functionality - write tests, implement header, verify
- **US2 (P2)**: Format consistency - add format-specific tests, verify existing code handles all formats
- **US3 (P3)**: Permission consistency - add permission tests, verify existing code handles all permissions
- **Polish (Phase 6)**: Depends on all user stories being complete
### User Story Dependencies
- **User Story 1 (P1)**: No dependencies - can start immediately after Setup
- **User Story 2 (P2)**: Depends on US1 implementation (tests verify same code path works for all formats)
- **User Story 3 (P3)**: Depends on US1 implementation (tests verify same code path works for all permissions)
### Within Each User Story
1. **Tests MUST be written FIRST** and FAIL before implementation
2. **Implementation** follows tests
3. **Verification** confirms tests pass
4. **Story complete** before moving to next priority
### Parallel Opportunities
- **Phase 1**: Both tasks (T001, T002) can run in parallel
- **US1 Tests**: T003 and T004 can be written in parallel (different files)
- **US2 Tests**: T007, T008, T009 can be written in parallel (different test cases)
- **US3 Tests**: T012, T013, T014 can be written in parallel (different test cases)
- **Polish Phase**: T017, T018, T019 can run in parallel (different validation activities)
**Note**: User Stories 2 and 3 should be sequential after US1 because they verify the same implementation with different test scenarios.
---
## Parallel Example: User Story 1
```bash
# Launch all tests for User Story 1 together (TDD - write first):
Task T003: "Create contract test for header presence in tests/contract/response-headers.test.js"
Task T004: "Create integration test for header in tests/integration/header-integration.test.js"
# After tests written and failing, implement:
Task T005: "Add header in src/proxyScripts/proxy.js"
# Verify:
Task T006: "Verify tests pass"
```
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Complete Phase 1: Setup (verify environment ready)
2. Skip Phase 2: Foundational (no infrastructure changes needed)
3. Complete Phase 3: User Story 1
- Write tests FIRST (T003, T004)
- Implement header addition (T005)
- Verify tests pass (T006)
4. **STOP and VALIDATE**: Test User Story 1 independently with various document exports
5. Deploy/demo if ready - core feature is functional
### Incremental Delivery
1. Complete Setup → Verify environment ready
2. Add User Story 1 → Test independently → **Deploy/Demo (MVP!)**
- This is the core feature: header present on success
3. Add User Story 2 → Test format consistency → Deploy/Demo
- Validates header works for PDF, DOCX, plain text
4. Add User Story 3 → Test permission consistency → Deploy/Demo
- Validates header works for private, shared, org-wide documents
5. Each story adds confidence without changing implementation
### Implementation Notes
**Key Implementation Details** (from research.md):
- **Location**: src/proxyScripts/proxy.js, line ~377-383 (in handleDocumentExportRequest function)
- **Code**: Add after line 377 (Content-Type, X-Request-Id, Content-Disposition headers)
- **Format**: `res.setHeader("X-Verint-KAB-Original-URL", `https://drive.google.com/file/d/${document.id}`);`
- **Timing**: After metadata fetch (line 278) but before content streaming (line 389)
- **Error Handling**: Omit header on error responses (no changes to error handlers needed)
**Validation Points**:
- Header name: Exactly `X-Verint-KAB-Original-URL`
- Header value: Exactly `https://drive.google.com/file/d/${document.id}` (no variations)
- Use `document.id` (validated by Google Drive API), not `documentId` (route parameter)
- Header only on 200 OK responses, absent on 4xx/5xx errors
---
## Expected Outcomes
**Success Criteria** (from spec.md):
- SC-001: ✅ 100% of successful document export responses include the X-Verint-KAB-Original-URL header
- SC-002: ✅ 100% of header values are valid, well-formed Google Drive URLs
- SC-003: ✅ Clients can successfully extract and use the header value to navigate to source document
- SC-004: ✅ Header is consistently present across all supported export formats
- SC-005: ✅ No export response time degradation (< 5ms overhead)
**Test Coverage**:
- Contract tests verify header presence and format
- Integration tests verify header with real Drive API responses
- Format tests verify consistency across PDF, DOCX, plain text
- Permission tests verify consistency across private, shared, org-wide documents
- Error tests verify header absent on 404, 401, 403, 413, 5xx responses
**Code Changes**:
- **1 file modified**: src/proxyScripts/proxy.js (add 1 line)
- **3 test files created**: tests/contract/response-headers.test.js, tests/integration/header-integration.test.js
- **0 new dependencies**: Uses existing Node.js HTTP APIs
---
## Notes
- Implementation is a single-line change (one `res.setHeader()` call)
- All three user stories share the same implementation code path
- US2 and US3 are primarily test validation stories (no additional code changes)
- Tests ensure header works correctly across all scenarios (formats, permissions, errors)
- TDD approach: Write failing tests first, then implement, then verify tests pass
- Follow existing patterns: res.setHeader() calls at lines 375-383 in proxy.js
- Use template literals for URL construction: `` `https://drive.google.com/file/d/${document.id}` ``
- Commit after each logical task or group of related tasks
- No helper functions needed (per constitution: simple operations stay in proxy.js)