# Modernize: Copy Requirement Specification (`reqSpecCopy`) - **Issue:** [#1797](https://github.com/sebiboga/testlink-upgraded/issues/1797) (enhancement) — bugs found while testing: [#1798](https://github.com/sebiboga/testlink-upgraded/issues/1798), [#1799](https://github.com/sebiboga/testlink-upgraded/issues/1799), [#1800](https://github.com/sebiboga/testlink-upgraded/issues/1800) - **Legacy screen:** `lib/requirements/reqSpecEdit.php` actions `copy` / `doCopy` → `gui/templates/dashio/requirements/reqSpecCopy.tpl` - **Modern screen:** `gui/templates/requirements/reqSpecCopy.html` - **BFF:** `api/reqspeccopy/index.php` - **Entry point:** a new **Copy Requirement Specification** button on the modern Requirement Specification Viewer (`gui/templates/requirements/reqSpecView.html`) + `$actions->reqSpecCopy` ## Why this screen The TODO section of `docs/MODERNIZATION-STATUS.md` is empty (every ASIDE entry maps to a modern screen), so the smallest coherent legacy-only slice was picked: the requirement-specification **copy popup**, the last un-ported `reqSpecEdit.php` action. Two things made it worth doing on its own: 1. **The capability had been silently dropped in 2.0.1.** The legacy `gui/templates/dashio/requirements/reqSpecView.tpl:52` rendered a *Copy Req. Spec* button pointing at `reqSpecEdit.php?doAction=copy`. No modern screen replaced it, so after the modernization the modern Requirement Specification Viewer had **no copy-specification entry point at all**. 2. **The legacy write was unsafe.** `reqSpecEdit.php` runs `checkRights()` against the **SESSION** context only, while `containerID` and `tproject_id` came straight out of the request body — a copy could be aimed at any node of any test project. It also offered the source specification as its own destination, and its `target_position` (top / bottom) radio pair was **dead UI**: `doCopy()` called `copy_to()` with four arguments and never read the position. ## Legacy behaviour carried over | Legacy | Modern | |---|---| | Source card: doc id, title, test project, prefix, author, scope | same, scope rendered as **escaped plain text** (`stripHtml`) | | Destination = the test project that owns the source | kept as the default, but a project **switcher** is offered | | Container `