Files
google-drive-content-adapter/specs/001-gdrive-url-header/tasks.md
Peter.Morton 9286ee8927 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>
2026-03-27 16:04:54 -05:00

11 KiB

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

  • T001 Verify Node.js test framework (node:test) is available and working
  • 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

  • T003 [P] [US1] Create contract test for X-Verint-KAB-Original-URL header presence in tests/contract/response-headers.test.js
  • 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

  • T005 [US1] Add X-Verint-KAB-Original-URL header in src/proxyScripts/proxy.js at line ~377-383 in handleDocumentExportRequest
  • 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)

  • T007 [US2] Add test for PDF export format in tests/contract/response-headers.test.js
  • T008 [US2] Add test for DOCX export format in tests/contract/response-headers.test.js
  • T009 [US2] Add test for plain text export format in tests/contract/response-headers.test.js

Implementation for User Story 2

  • T010 [US2] Verify existing implementation handles all export formats (no code changes needed - same code path)
  • 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)

  • T012 [US3] Add test for private document export in tests/integration/header-integration.test.js
  • T013 [US3] Add test for shared document export in tests/integration/header-integration.test.js
  • T014 [US3] Add test for organization-wide shared document in tests/integration/header-integration.test.js

Implementation for User Story 3

  • T015 [US3] Verify existing implementation handles all permission levels (no code changes needed - permissions don't affect header)
  • 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

  • T017 [P] Validate quickstart.md examples work with implementation
  • T018 [P] Run full test suite and verify 100% pass rate for header feature
  • T019 [P] Verify header absent on error responses (404, 401, 403, 413, 5xx)
  • T020 Performance test: Verify header addition overhead < 5ms per request
  • T021 Validate header format matches contract specification exactly
  • 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

# 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)