release: promote EPIC-08 Paperless-ngx Document Integration to main#385
Merged
Conversation
…pes, and config (#361) Design and scaffold the EPIC-08 Paperless-ngx document integration: Schema: - Add document_links table (migration 0009) with polymorphic entity_type discriminator for linking Paperless-ngx docs to work items, household items, and invoices - Add documentLinks to Drizzle ORM schema API contract: - Proxy endpoints: GET /api/paperless/{status,documents,documents/:id, documents/:id/thumb,documents/:id/preview,tags} - Document link CRUD: POST/GET/DELETE /api/document-links - New error codes: PAPERLESS_NOT_CONFIGURED, PAPERLESS_UNREACHABLE, PAPERLESS_ERROR, DUPLICATE_DOCUMENT_LINK Shared types: - PaperlessDocument, PaperlessTag, PaperlessSearchHit - DocumentLink, DocumentLinkWithMetadata - Request/response types for all new endpoints Config: - Add PAPERLESS_URL and PAPERLESS_API_TOKEN environment variables - Add paperlessEnabled derived flag - Update config test expectations Wiki: - ADR-015: Paperless-ngx Integration Architecture - Updated Architecture.md, API-Contract.md, Schema.md, ADR-Index.md Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
Co-authored-by: Frank Steiler <frank@steiler.dev>
* feat(paperless): implement Paperless-ngx proxy service and routes (#354) Add the Paperless-ngx proxy backend for EPIC-08. The server now proxies all document browsing and binary requests through /api/paperless/* endpoints, keeping the API token server-side at all times. Fixes #354 Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> * fix(paperless): address PR #362 security and quality review findings - config.ts: validate PAPERLESS_URL scheme (http/https only) to prevent SSRF attacks via file://, ftp://, and other non-HTTP schemes - paperless.ts: add MIME type allowlist for thumb/preview binary endpoints; disallowed upstream content-types fall back to application/octet-stream - paperless.ts: add pattern constraint '^\\d+(,\\d+)*$' to tags query param to enforce comma-separated integer format - paperlessService.ts: sanitize IP addresses and hostname:port from error messages in getStatus() to prevent information disclosure - paperlessService.ts: remove duplicate local ListDocumentsQuery interface; use shared PaperlessDocumentListQuery instead - .env.example: add PAPERLESS_URL and PAPERLESS_API_TOKEN (commented out) - Tests updated: config.test.ts, paperless.test.ts, paperlessService.test.ts cover all new validation logic, sanitization, and allowlist behavior Fixes #354 Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> * chore: update review metrics for PR #362 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com>
* feat(paperless): implement document links CRUD API (Story #355) Adds the document links backend for EPIC-08, enabling users to associate Paperless-ngx documents with work items and invoices. - documentLinkService: createLink, getLinksForEntity (with metadata enrichment), deleteLink, deleteLinksForEntity for cascade delete - documentLinks route: POST/GET/DELETE /api/document-links with JSON schema validation - Cascade delete: workItemService and invoiceService now delete document links before deleting the parent entity (polymorphic FK enforced at app layer) - Service tests: 28 unit tests covering all service functions including Paperless metadata enrichment and error paths - Route integration tests: 20 integration tests covering all endpoints, auth enforcement, validation, and cascade delete Fixes #355 Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com> * fix(paperless): fix import formatting in documentLinkService.test.ts ESLint auto-fix during pre-commit split the AppError import into two statements with missing space before closing brace, causing CI format:check to fail. Consolidate into a single properly-formatted import. Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> * fix(paperless): fix document links service and test helper issues - documentLinkService.createLink: resolve userId against users table before inserting; store null if user no longer exists to avoid FK constraint failure (document_links.created_by is nullable with ON DELETE SET NULL) - documentLinks.test.ts: fix createWorkItem helper to use correct response shape (POST /api/work-items returns work item directly, not { workItem: {...} }) Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> * docs(security): update wiki submodule ref for PR #363 security review Records three new findings on the Security Audit page: - Low: No ownership check on DELETE /api/document-links/:id - Informational: deleteLinkSchema params lacks additionalProperties: false - Informational: entityId field has no maxLength bound Co-Authored-By: Claude security-engineer (Sonnet 4.6) <noreply@anthropic.com> * chore: update review metrics for PR #363 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com>
* feat(paperless): Document Browser & Search UI (Story #356) Implements the Document Browser page for Paperless-ngx integration: - `client/src/lib/paperlessApi.ts`: API client for status, list, get, tags, thumbnail URL, preview URL - `client/src/hooks/usePaperless.ts`: React hook managing status/documents/tags/pagination/search/filter state - `client/src/components/documents/DocumentBrowser.tsx`: Main reusable component with page/modal modes, search bar, tag filter strip, document grid, detail panel, and pagination - `client/src/components/documents/DocumentCard.tsx`: Individual card with thumbnail, title, date, tags, accessible button role - `client/src/components/documents/DocumentDetailPanel.tsx`: Expanded detail panel with metadata, content snippet, external link - `client/src/components/documents/DocumentSkeleton.tsx`: Loading skeleton cards with shimmer animation - All CSS modules use design tokens, no hardcoded hex values, responsive grid (3/2/1 col) - Replaces stub DocumentsPage with full implementation delegating to DocumentBrowser - Tests for all new modules (95%+ coverage target) Fixes #356 Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com> * fix(paperless): fix ESLint import() type annotations in test files Replace inline import() type annotations with top-level import type * patterns to satisfy @typescript-eslint/consistent-type-imports rule. Also fix TypeScript type assertion for mock call args in usePaperless.test.tsx. Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> * fix(paperless): apply Prettier formatting to document browser components Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> * fix(paperless): fix overly broad date regex in DocumentCard test The test `does not render date when created is null` used `/2025/` which also matched the document title "Test Invoice 2025". Narrowed to a pattern matching formatted date strings (e.g. "Mar 15, 2025") only. Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> --------- Co-authored-by: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com>
) * chore(agents): enforce strict delegation to Haiku in dev-team-lead Implement layered controls to ensure the dev-team-lead agent delegates all production code changes to Haiku developer agents instead of writing code directly: - Restructure dev-team-lead prompt with procedural workflow, tool usage policy table, and common failure modes table replacing negative rules - Add mandatory delegation report to dev-team-lead return format - Add pre-commit trailer verification step - Insert delegation audit (step 6a) in develop skill between implementation and PR verification - Add delegation audit to fix loop (step 9) in develop skill - Add delegation reminder to dev-team-lead launch context - Add Delegation Enforcement cross-team convention to CLAUDE.md - Create pre-seeded dev-team-lead agent memory with delegation reminders Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: track agent memory in source control Remove .claude/agent-memory/ from .gitignore so agent memory files are version-controlled and shared across sessions and environments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: add all agent memory files to source control Copy agent memory from 9 agents (backend-developer, dev-team-lead, docs-writer, frontend-developer, product-architect, product-owner, qa-integration-tester, security-engineer, ux-designer) into version control. The dev-team-lead MEMORY.md merges the new delegation enforcement reminders with existing operational knowledge. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(agents): fix consistency issues across delegation enforcement files - Remove delegation bypass instruction in dev-team-lead memory that told agents to implement directly instead of using the Agent tool - Fix conflicting Prettier directory advice in backend-developer memory (must run from worktree, not project root) - Remove unsanctioned test exception in frontend-developer memory that allowed devs to fix tests inline (QA owns all tests, no exceptions) - Align CLAUDE.md production file definition with agent definition (any file under server/client/shared, not just specific extensions) - Expand delegation reminder in develop skill to mention both trailers and delegation report as audit mechanisms - Fix wrong model attribution in docs workflow (frontend-developer is Haiku, not Sonnet) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* chore(agents): enforce strict delegation to Haiku in dev-team-lead Implement layered controls to ensure the dev-team-lead agent delegates all production code changes to Haiku developer agents instead of writing code directly: - Restructure dev-team-lead prompt with procedural workflow, tool usage policy table, and common failure modes table replacing negative rules - Add mandatory delegation report to dev-team-lead return format - Add pre-commit trailer verification step - Insert delegation audit (step 6a) in develop skill between implementation and PR verification - Add delegation audit to fix loop (step 9) in develop skill - Add delegation reminder to dev-team-lead launch context - Add Delegation Enforcement cross-team convention to CLAUDE.md - Create pre-seeded dev-team-lead agent memory with delegation reminders Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: track agent memory in source control Remove .claude/agent-memory/ from .gitignore so agent memory files are version-controlled and shared across sessions and environments. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: add all agent memory files to source control Copy agent memory from 9 agents (backend-developer, dev-team-lead, docs-writer, frontend-developer, product-architect, product-owner, qa-integration-tester, security-engineer, ux-designer) into version control. The dev-team-lead MEMORY.md merges the new delegation enforcement reminders with existing operational knowledge. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(agents): fix consistency issues across delegation enforcement files - Remove delegation bypass instruction in dev-team-lead memory that told agents to implement directly instead of using the Agent tool - Fix conflicting Prettier directory advice in backend-developer memory (must run from worktree, not project root) - Remove unsanctioned test exception in frontend-developer memory that allowed devs to fix tests inline (QA owns all tests, no exceptions) - Align CLAUDE.md production file definition with agent definition (any file under server/client/shared, not just specific extensions) - Expand delegation reminder in develop skill to mention both trailers and delegation report as audit mechanisms - Fix wrong model attribution in docs workflow (frontend-developer is Haiku, not Sonnet) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore(skills): add /epic-run autonomous orchestration skill Add a new /epic-run skill that chains the entire epic lifecycle (plan → develop all stories → close) into a single autonomous session. AUTO_MODE auto-approves intermediate gates (plan approval, bug specs, PR merges, UAT) while preserving promotion-to-main as a mandatory human checkpoint. Changes: - Create .claude/skills/epic-run/SKILL.md with 3-phase orchestration - Add AUTO_MODE conditional blocks to epic-start (step 5), develop (steps 2 and 10), and epic-close (step 6) - Update CLAUDE.md with /epic-run in skills table, AUTO_MODE convention section, and updated lifecycle descriptions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…kens, a11y (#368) * fix(paperless): address review feedback — paperlessUrl passthrough, design tokens, a11y - Add paperlessUrl field to PaperlessStatusResponse shared type - Expose paperlessUrl in server status endpoint and propagate through service, hook, and component props so "View in Paperless-ngx" link renders - Replace hardcoded spacing/padding/font-size/border-radius values with CSS custom properties (design tokens) across all document components - Fix card border weight (2px → 1px), grid breakpoint overlap (1024 → 1023), and selected-card box-shadow to use primary-bg ring - Add focus-visible states with shadow-focus-subtle on buttons - Add aria-label on tag filter chips, aria-expanded/aria-controls on cards, id on detail panel for accessible pairing - Add 44px min-height touch targets for tag chips on mobile - Add prefers-reduced-motion: reduce media query for skeleton shimmer - Fix deferred type imports in test files (after mock registration) - Add tests for paperlessUrl passthrough and null cases Fixes #356 Co-Authored-By: Claude <noreply@anthropic.com> * fix(paperless): apply Prettier formatting to 4 files Pre-commit lint-staged was skipped due to corrupted git index in worktree. Apply Prettier line-length fixes to pass CI format check. Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
…re (#371) Replace nested agent invocation (orchestrator → dev-team-lead → Haiku agents) with a flat model where the orchestrator launches all agents directly using specs produced by the dev-team-lead. The dev-team-lead now operates in three modes: - [MODE: spec] — reads wiki/codebase, returns structured implementation specs - [MODE: review] — reads modified files, returns VERDICT with fix specs - [MODE: commit] — stages, commits with trailers, pushes, creates PR, watches CI This eliminates the unreliable nested Agent tool calls that caused the dev-team-lead to write production code directly. Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
#372) * feat(documents): add document linking section to work item detail page Adds a Documents section to the work item detail page that allows users to link, view, and unlink Paperless-ngx documents. Includes document picker modal, inline detail panel, loading/error/empty states, and full accessibility support. Fixes #357 Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> Co-Authored-By: Claude backend-developer (Haiku 4.5) <noreply@anthropic.com> Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com> Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com> * fix(documents): resolve CI failures — TypeScript ordering, Prettier format, CSS tokens - Move closePicker declaration before useEffect that references it (TS2448/TS2454) - Fix Prettier formatting in LinkedDocumentsSection.test.tsx - Replace remaining hardcoded CSS values with design tokens in responsive breakpoint Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com> * fix(documents): address review findings — badge tokens, focus-visible, mobile modal - Change count badge to neutral tokens (--color-bg-tertiary, --color-text-muted) - Add :focus-visible styles to retryButton, modalClose, modalCancelButton, modalDeleteButton - Make mobile modal full-viewport sheet at <768px - Fix notConfiguredTitle font-size to var(--font-size-sm) - Adjust modalContentLarge max-width to match UX spec (860px) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com> * chore: update review metrics for PR #372 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
* feat(documents): Add invoice support to document linking - Updated useDocumentLinks hook to accept entityType and entityId instead of hardcoded workItemId - Changed LinkedDocumentsSection to support work_item, household_item, and invoice entity types - Added entity-specific copy for empty states, picker subtitle, and unlink confirmations - Removed margin-top from LinkedDocumentsSection.section CSS (parent gap handles spacing) - Updated WorkItemDetailPage to pass entityType="work_item" and entityId - Added LinkedDocumentsSection to InvoiceDetailPage to display documents linked to invoices Fixes #358 Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com> * test(documents): update and add unit tests for Story #358 document linking for invoices Update useDocumentLinks.test.ts to match new 2-arg signature (entityType + entityId), add tests for invoice entity type, and fix waitFor conditions that relied on isLoading starting as true (it starts as false). Update LinkedDocumentsSection.test.tsx to match new props (entityType + entityId instead of workItemId), add invoice entity type tests and work_item backwards-compatibility tests, and add makeInvoiceLink helper fixture. Create InvoiceDetailPage.test.tsx covering loading/error states, successful render, and LinkedDocumentsSection integration (entityType=invoice, entityId=invoiceId). Fixes #358 Co-Authored-By: Claude qa-integration-tester (Sonnet 4.6) <noreply@anthropic.com> * style(documents): fix Prettier formatting in test files Co-Authored-By: Claude qa-integration-tester (Sonnet 4.6) <noreply@anthropic.com> * fix(documents): fix 3 test assertions blocking CI for Story #358 - useDocumentLinks: include isLoading check inside waitFor to avoid race condition with async state updates - InvoiceDetailPage: use getAllByText for status badge since it renders in two places (page header + info list) - LinkedDocumentsSection: skip invoice unlink copy test pending fix for bug #379 (hardcoded "this work item" in unlink modal) Co-Authored-By: Claude qa-integration-tester (Sonnet 4.6) <noreply@anthropic.com> * fix(documents): use entity-specific copy in unlink confirmation modal The unlink confirmation dialog hardcoded "this work item" instead of using the entity-specific copy from entityCopy[entityType].unlinkBody. This caused invoice document unlink dialogs to incorrectly say "will be removed from this work item" instead of "this invoice". Also unskips the previously-skipped test for this scenario. Fixes #379 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: update review metrics for PR #378 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
…ntegration (#380) * feat(documents): add responsive design and accessibility polish for document integration - Add touch scrolling and tablet breakpoints for DocumentBrowser, DocumentCard, and LinkedDocumentsSection - Replace hardcoded pixel values with CSS custom properties (design token compliance) - Add ARIA attributes, focus trap, keyboard navigation, and screen reader support to document components - Add reduced motion support via prefers-reduced-motion media query - Fix DocumentDetailPanel CSS for responsive layout on mobile viewports - Update DocumentsPage CSS for consistent spacing across breakpoints - Add and update unit tests for a11y and responsive behaviour coverage Fixes #360 Co-Authored-By: Claude frontend-developer (Haiku 4.5) <noreply@anthropic.com> Co-Authored-By: Claude qa-integration-tester (Haiku 4.5) <noreply@anthropic.com> Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> * style(documents): fix Prettier formatting in DocumentBrowser and LinkedDocumentsSection test Co-Authored-By: Claude dev-team-lead (Sonnet 4.6) <noreply@anthropic.com> * chore: update review metrics for PR #380 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
…ations (#381) - Backend: add additionalProperties: false and maxLength: 36 to documentLinks schemas - Frontend: replace template literal query construction with URLSearchParams; add mobile touch target for modal close button - QA: add validation tests for maxLength constraints and URLSearchParams encoding Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
* test(e2e): add EPIC-08 document integration E2E test coverage - Update DocumentsPage POM from stub to full implementation with locators for the DocumentBrowser "not configured" state - Remove Documents test from stub-pages.spec.ts (page graduated to full feature in EPIC-08) - Add e2e/tests/documents/documents-browser.spec.ts covering 8 scenarios: page load smoke, not-configured state rendering, env var instructions, navigation, responsive layout, dark mode, accessibility, and API status - Add e2e/tests/documents/documents-linked-sections.spec.ts covering 10 scenarios: LinkedDocumentsSection on work item detail (6) and invoice detail (4) — heading visibility, disabled add button, not-configured banner, aria-labelledby, responsive layout, dark mode All tests validate against the "not configured" state since PAPERLESS_URL and PAPERLESS_API_TOKEN are not set in the E2E testcontainer environment. Fixes #360 Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com> * chore: update qa-integration-tester memory with EPIC-08 E2E findings Records DocumentBrowser state machine, LinkedDocumentsSection selectors, invoice detail route URL pattern, and Paperless API endpoints for future test sessions. Co-Authored-By: Claude qa-integration-tester (Sonnet 4.5) <noreply@anthropic.com> --------- Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
…te (#383) Add a new Documents guide section covering Paperless-ngx setup, document browsing, and document linking to work items and invoices. Update the landing page, roadmap, configuration, and README to reflect EPIC-08 completion. Write RELEASE_SUMMARY.md for the epic promotion. Also fix pre-existing broken screenshot image references in work-items and tags pages by replacing them with admonition blocks. Fixes #360 Co-authored-by: Claude product-architect (Opus 4.6) <noreply@anthropic.com>
Owner
Author
UAT Validation CriteriaPrerequisites
Manual Testing Steps1. Not Configured State (Scenario A)
2. Document Browser (Scenario B)
3. Document Linking — Work Items (Scenario B)
4. Document Linking — Invoices (Scenario B)
5. Cascade Deletion
6. Responsive Design
7. Accessibility
8. Dark Mode
|
Contributor
|
🎉 This PR is included in version 1.11.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
EPIC-08: Paperless-ngx Document Integration — Cornerstone now integrates with Paperless-ngx for document management. Browse your entire document archive from within Cornerstone, and link invoices, contracts, permits, and receipts directly to work items and vendor invoices.
Highlights
Configuration
Stories Included
Additional PRs
Epic Metrics
UAT Validation
All UAT scenarios produced — see validation report on EPIC-08 issue #8.
🤖 Generated with Claude Code