Svdvd-349 !exclusive!

The applications of SVD are vast and diverse, spanning multiple fields, including:

: A compact, rack-mountable design (1U) with integrated cooling for 24/7 continuous operation. Firmware Support SVDVD-349

| File | Purpose | |------|---------| | AttachmentToolbar.tsx | Render the button; conditionally show based on attachments.length . | | useDownloadAll.ts | Hook that triggers the fetch, handles loading state, error toast, and forces browser download via hidden <a> with download attribute. | | api/attachments.ts | Export downloadAllAttachments(docId: string): Promise<void> that returns a Blob and triggers download. | | tests/AttachmentToolbar.test.tsx | Unit tests for rendering, disabled state, click handling. | | e2e/attachment-download.cy.ts | Cypress test: open doc, click button, verify ZIP download, inspect manifest via unzip (Node adm-zip ). | The applications of SVD are vast and diverse,

| Element | Interpretation | |---------|-----------------| | | Usually denotes the production label S1 No. 1 Style or a closely affiliated studio. In some cataloging systems the “S” can also stand for “Soft” or “S‑Series”, but the most common usage in recent years points to S1. | | DVD | Indicates the format of the release (DVD). In the era when Blu‑ray and digital streaming began to dominate, many companies kept the “DVD” suffix for legacy cataloging continuity. | | 349 | The 349th title released under that label’s DVD line. The number increments with each new product, making it a straightforward way for retailers, distributors, and fans to locate a specific film. | | | api/attachments

| # | Given | When | Then | |---|-------|------|------| | | A document with ≥ 2 attachments is opened in the viewer. | The UI renders. | The toolbar shows a primary‑styled button labelled “Download All Attachments”. | | AC‑2 | The button is clicked. | The client calls the zip‑endpoint. | A download prompt appears with filename Document_<docId>_attachments_<timestamp>.zip . | | AC‑3 | The zip contains every attachment (including hidden ones the user can view). | The download completes. | The ZIP’s internal structure mirrors the original ordering (e.g., attachments/001‑Invoice.pdf ). | | AC‑4 | The total size of all attachments exceeds 500 MB . | The user clicks the button. | The API returns HTTP 413 with JSON error: "PayloadTooLarge", message: "Attachments exceed 500 MB limit." and the UI shows a toast: “Too many files – please download individually or request a larger bundle via Support.” | | AC‑5 | The request is made by a user lacking download permission for one of the attachments. | The API processes the request. | The response is HTTP 403, and the UI disables the button (grayed out) with tooltip “You do not have permission to download all files.” | | AC‑6 | The request is made on a mobile Safari browser. | The response returns a streaming ZIP. | The browser shows the native “Share / Save to Files” dialog (no “download‑blocked” warnings). | | AC‑7 | The zip is generated successfully. | The user opens it locally. | A manifest.txt file exists at the root, containing lines: <checksum> <size> <relative‑path> . | | AC‑8 | Automated test suite runs. | All unit, integration, and end‑to‑end tests pass. | Coverage for the new endpoint ≥ 90 %, UI interaction tests pass on Chrome, Firefox, Safari, Edge. |