Feature Summary
Add the ability to move and/or copy test cases from one project to another within TestPlanIt, without needing to go through an export/import cycle.
Problem Statement
Current Situation
When users need to transfer test cases between projects, the only option is to export cases from the source project (as CSV or Markdown) and then re-import them into the target project using the import wizard. This workflow has several pain points:
- Multi-step manual process: Export to file, open import wizard in target project, configure field mappings, select folder placement, and import — even for a single test case.
- Loss of fidelity: Custom field values may not map cleanly if the target project uses a different template, and relationships like linked cases, comments, and version history are lost.
- No move option: There is no way to relocate a test case (removing it from the source project). Users must export, import, then manually delete or archive the original.
- Scales poorly: Moving a handful of cases between projects — a common reorganization task — requires the same heavyweight workflow as a bulk data migration.
Desired Outcome
Users should be able to select one or more test cases in a project and move or copy them to another project directly from the UI, with intelligent handling of templates, workflow states, folder placement, and custom field values.
Proposed Solution
Add a "Move/Copy to Project" action available from the test case context menu and the bulk actions toolbar in the repository view. This would open a dialog where the user selects:
- Target project — from a list of projects the user has write access to.
- Operation — Move (removes from source) or Copy (leaves source unchanged).
- Target folder — a folder picker for the destination project's repository.
- Templates — if the target project does not use the same template(s) as any of the selected test cases, let the user choose to automatically assign the templates to the destination project. This option is the default. If they choose to not do that or do not have access to do it, warn the user that the cases will be moved/copied, but they will be connected to a template not available in that project. Project Admins and Admins have access to connect Templates to projects. Everyone else will not have the option but will see the warning.
- Workflow state — If a selected test case uses a workflow not assigned to the destination project, let the user choose to associate any missing workflow states with the destination project. If the user does not have access (not Project Admin or Admin), show a warning that any cases assigned a workflow state that the destination project does not have associated with it will be set to the destination project's default workflow state.
User Story
As a QA Engineer, I want to move or copy test cases directly from one project to another so that I can reorganize test coverage across projects without manual export/import cycles.
Acceptance Criteria
Design Mockups
Not applicable — to be designed during implementation.
Alternative Solutions
Option 1: Shared / Cross-Project Test Case Library
Instead of moving/copying, introduce a global test case library that projects can reference. Cases would live in a shared repository and be linked into project-specific test runs. This is a larger architectural change but would eliminate duplication entirely.
Option 2: Improve Export/Import with "Transfer" Preset
Add a streamlined "Transfer to Project" option in the export dialog that bundles export + import into a single flow, auto-populating the import wizard with the exported data and pre-mapping fields. Lower implementation effort but still fundamentally file-based.
Technical Considerations
Key data model constraints to address:
- Template compatibility:
RepositoryCases.templateId is a FK to Templates. The target project must have the template assigned via TemplateProjectAssignment, or the user must select an alternate template and map fields.
- Workflow state:
RepositoryCases.stateId maps to Workflows, which are assigned per-project via ProjectWorkflowAssignment. The target project's default state should be used, with fallback to user selection.
- Repository ID: Each project has exactly one active
Repositories record. The target case must be assigned the target project's repository ID.
- Unique constraint:
@@unique([projectId, name, className, source]) on RepositoryCases — copying to a different project is fine (different projectId), but naming collisions must be handled.
- Steps: Stored in a separate
Steps table with testCaseId FK — new step records must be created for copied cases.
- Custom field values:
CaseFieldValues reference both testCaseId and fieldId. Fields are global but template-scoped, so values can be preserved when templates match.
- Attachments:
Attachments store S3/MinIO URLs. New attachment records can reference the same storage objects (no re-upload needed).
- Tags: Tags are global (no
projectId), so reconnecting tags across projects is straightforward.
- Version history:
RepositoryCaseVersions are per-case snapshots. Copies should start fresh at version 1.
- Linked cases:
RepositoryCaseLink records reference cases by ID — cross-project links would need policy decisions (preserve if both cases exist, drop otherwise).
Dependencies
Performance Impact
Bulk move/copy of many cases (100+) should be handled as an async operation (potentially via BullMQ job queue) with progress feedback, similar to how the import endpoint streams SSE progress events today.
Security Considerations
- Must enforce ZenStack access policies: the user must have read access to the source project and write access to the target project.
- For move operations, the user must also have delete/update permission in the source project.
- Attachment URLs should not be exposed to users who don't have access to the source project — for copy operations, this is inherently safe since the user must have access to both.
Business Value
Priority
Affected User Groups
Expected Usage
Implementation Effort
Related Issues/Features
- Related to existing export/import functionality (
ExportModal.tsx, /api/repository/import/route.ts)
- Related to existing in-project drag-and-drop move (folder reassignment in
TreeView.tsx)
- Related to test run duplication (
DuplicateTestRunDialog.tsx) — similar UX pattern for the copy dialog
Additional Context
The existing import endpoint (/api/repository/import/route.ts) already handles most of the creation logic needed — creating cases, steps, field values, tags, attachments, and version snapshots. A cross-project copy/move feature could reuse much of this logic, wrapping it in a more streamlined UX that reads directly from the source project's data rather than requiring a file intermediary.
Examples from Other Tools
- TestRail: Supports "Move Cases" and "Copy Cases" between projects/suites via right-click context menu, with folder selection in the target.
- Zephyr Scale (Jira): Allows cloning test cases across projects with field mapping for custom fields.
- qTest: Provides a "Copy to" action that copies cases between projects and modules with a tree picker.
Checklist
Community Interest
No community discussions yet — this is a new feature request.
Feature Summary
Add the ability to move and/or copy test cases from one project to another within TestPlanIt, without needing to go through an export/import cycle.
Problem Statement
Current Situation
When users need to transfer test cases between projects, the only option is to export cases from the source project (as CSV or Markdown) and then re-import them into the target project using the import wizard. This workflow has several pain points:
Desired Outcome
Users should be able to select one or more test cases in a project and move or copy them to another project directly from the UI, with intelligent handling of templates, workflow states, folder placement, and custom field values.
Proposed Solution
Add a "Move/Copy to Project" action available from the test case context menu and the bulk actions toolbar in the repository view. This would open a dialog where the user selects:
User Story
As a QA Engineer, I want to move or copy test cases directly from one project to another so that I can reorganize test coverage across projects without manual export/import cycles.
Acceptance Criteria
projectId + name + className + source) gracefully — prompting the user if a naming conflict exists in the target projectDesign Mockups
Not applicable — to be designed during implementation.
Alternative Solutions
Option 1: Shared / Cross-Project Test Case Library
Instead of moving/copying, introduce a global test case library that projects can reference. Cases would live in a shared repository and be linked into project-specific test runs. This is a larger architectural change but would eliminate duplication entirely.
Option 2: Improve Export/Import with "Transfer" Preset
Add a streamlined "Transfer to Project" option in the export dialog that bundles export + import into a single flow, auto-populating the import wizard with the exported data and pre-mapping fields. Lower implementation effort but still fundamentally file-based.
Technical Considerations
Key data model constraints to address:
RepositoryCases.templateIdis a FK toTemplates. The target project must have the template assigned viaTemplateProjectAssignment, or the user must select an alternate template and map fields.RepositoryCases.stateIdmaps toWorkflows, which are assigned per-project viaProjectWorkflowAssignment. The target project's default state should be used, with fallback to user selection.Repositoriesrecord. The target case must be assigned the target project's repository ID.@@unique([projectId, name, className, source])onRepositoryCases— copying to a different project is fine (differentprojectId), but naming collisions must be handled.Stepstable withtestCaseIdFK — new step records must be created for copied cases.CaseFieldValuesreference bothtestCaseIdandfieldId. Fields are global but template-scoped, so values can be preserved when templates match.Attachmentsstore S3/MinIO URLs. New attachment records can reference the same storage objects (no re-upload needed).projectId), so reconnecting tags across projects is straightforward.RepositoryCaseVersionsare per-case snapshots. Copies should start fresh at version 1.RepositoryCaseLinkrecords reference cases by ID — cross-project links would need policy decisions (preserve if both cases exist, drop otherwise).Dependencies
Performance Impact
Bulk move/copy of many cases (100+) should be handled as an async operation (potentially via BullMQ job queue) with progress feedback, similar to how the import endpoint streams SSE progress events today.
Security Considerations
Business Value
Priority
Affected User Groups
Expected Usage
Implementation Effort
Related Issues/Features
ExportModal.tsx,/api/repository/import/route.ts)TreeView.tsx)DuplicateTestRunDialog.tsx) — similar UX pattern for the copy dialogAdditional Context
The existing import endpoint (
/api/repository/import/route.ts) already handles most of the creation logic needed — creating cases, steps, field values, tags, attachments, and version snapshots. A cross-project copy/move feature could reuse much of this logic, wrapping it in a more streamlined UX that reads directly from the source project's data rather than requiring a file intermediary.Examples from Other Tools
Checklist
Community Interest
No community discussions yet — this is a new feature request.