Skip to content

Feature/comprehensive test coverage#145

Merged
therealbrad merged 8 commits intov0.17.0from
feature/comprehensive-test-coverage
Mar 21, 2026
Merged

Feature/comprehensive test coverage#145
therealbrad merged 8 commits intov0.17.0from
feature/comprehensive-test-coverage

Conversation

@therealbrad
Copy link
Contributor

Description

Add more test coverage

therealbrad and others added 8 commits March 21, 2026 11:26
12 tests covering rendering, metadata display, edit mode,
navigation, delete popover, and canEdit toggle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Archive v2.0 (phases 9-24): 16 phases, 44 plans covering E2E tests,
component tests, API route tests, hooks, and workers. Also marks
v0.17.0 Copy/Move (phases 28-33) as shipped. Collapses ROADMAP.md
from 538 to 84 lines.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Updated variable names in test files to prefix with an underscore for clarity and consistency.
- Adjusted notification text formatting in NotificationContent component for improved readability.
- Removed commented-out code in CopyMoveDialog test for cleaner codebase.
…t tests

- Added type definitions for attachments in AttachmentsCarousel tests for better type safety.
- Refactored variable names in copy-move endpoint tests for consistency and clarity.
- Updated test case creation to use new variable naming conventions, improving readability and maintainability.
- Introduced a mock for the useCountProjects hook to enhance test coverage and ensure consistent behavior during testing.
- Modified the CI workflow to include the --ignore-scripts flag during CLI dependency installation, ensuring that scripts are not executed during the install process.
@therealbrad therealbrad merged commit 435f9f7 into v0.17.0 Mar 21, 2026
1 check passed
@therealbrad therealbrad deleted the feature/comprehensive-test-coverage branch March 21, 2026 19:21
therealbrad added a commit that referenced this pull request Mar 22, 2026
… Between Projects and Per-Prompt LLM Configuration, along with worker audit logging, comprehensive test coverage improvements, and bug fixes (#147)

* docs: start milestone v0.17.0 Copy/Move Test Cases Between Projects

* docs: complete project research for v0.17.0 copy/move test cases

Adds STACK, FEATURES, ARCHITECTURE, PITFALLS, and SUMMARY research
files for the cross-project copy/move milestone. Zero new dependencies
required; all implementation patterns map to existing auto-tag worker
and import route precedents.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: define milestone v0.17.0 requirements

* docs: create milestone v0.17.0 roadmap (5 phases)

* docs(28): smart discuss context

* docs(phase-28): add validation strategy

* docs(28-queue-and-worker): create phase plan

* feat(28-01): register copy-move BullMQ queue infrastructure

- Add COPY_MOVE_QUEUE_NAME = "copy-move" constant to lib/queueNames.ts
- Add getCopyMoveQueue() lazy initializer to lib/queues.ts with attempts:1 (no retry)
- Re-export COPY_MOVE_QUEUE_NAME from lib/queues.ts
- Add copyMoveQueue to getAllQueues() return object
- Add worker:copy-move script to package.json
- Append pnpm worker:copy-move to the workers concurrently command

* feat(28-01): implement copyMoveWorker processor for cross-project copy/move

- Create workers/copyMoveWorker.ts with full copy/move data carry-over
- Exports CopyMoveJobData, CopyMoveJobResult, processor, startWorker
- resolveSharedStepGroup: recreates SharedStepGroups in target with deduplication
  map; respects reuse/create_new resolution per user choice (DATA-08, DATA-09)
- resolveFieldValue: resolves Dropdown/MultiSelect option IDs by name across
  templates; drops values with no matching option (DATA-02)
- fetchTemplateFields: fetches field definitions separately to avoid 63-char
  PostgreSQL alias limit
- processor: validates multi-tenant context, pre-fetches folderMaxOrder before
  loop to avoid race conditions
- Per-case prisma.$transaction with steps, field values, attachments, tags,
  issues, versions, and comments (move only)
- Copy path: creates version 1 via createTestCaseVersionInTransaction (DATA-07)
- Move path: replicates all RepositoryCaseVersions rows with updated projectId
  (DATA-06), copies comments with repositoryCaseId: newCase.id
- Rollback on failure: deleteMany createdTargetIds (cascade handles children)
- Move soft-deletes source cases only after all copies succeed
- ES sync (bulk, post-loop) via syncRepositoryCaseToElasticsearch
- Redis cancellation support between cases via cancelKey helper
- concurrency: 1 (locked to prevent ZenStack v3 deadlocks)
- Graceful SIGTERM/SIGINT shutdown

* docs(28-01): complete queue-and-worker plan 01 summary and state updates

- Create 28-01-SUMMARY.md documenting all tasks, decisions, and requirements
- Update STATE.md: phase 28 plan 01 complete, decisions recorded, metrics updated
- Update ROADMAP.md: phase 28 progress updated
- Mark DATA-01 through DATA-09 complete in REQUIREMENTS.md

* test(28-02): add comprehensive unit tests for copy-move worker processor

- DATA-01: verify steps created in target with correct content and order
- DATA-02: verify Dropdown option IDs resolved by name (target 600, not source 500)
- DATA-03/04: verify tags and issues connected by global ID
- DATA-05: verify attachment rows created with same S3 URL
- DATA-06: verify move recreates all version rows with target projectId, preserving staticProjectId/Name
- DATA-07: verify copy creates version 1 via createTestCaseVersionInTransaction
- DATA-08: verify shared step groups recreated in target; deduplication across cases
- DATA-09: verify reuse/create_new resolution for name collisions (copy suffix)
- Rollback: verify deleteMany called on createdTargetIds when any case fails
- Cancellation: verify pre-start and between-case cancellation with rollback
- Move source deletion: verify updateMany called only after all copies succeed
- ES sync: non-fatal failure does not throw; syncs all created case IDs

* docs(28-02): complete copy-move worker unit test plan

- Created 28-02-SUMMARY.md with test coverage documentation
- Updated STATE.md: plan 02 complete, 14% progress, added test pattern decisions
- Updated ROADMAP.md: Phase 28 marked Complete (2 of 2 plans done)

* docs(phase-28): complete phase execution

* docs(29): smart discuss context

* docs(phase-29): add validation strategy

* docs(29): create phase plan for API endpoints and access control

* feat(29-01): create shared Zod schemas and TypeScript types for copy-move endpoints

- preflightSchema with operation, caseIds, sourceProjectId, targetProjectId
- submitSchema with conflictResolution limited to skip/rename (no overwrite)
- submitSchema with sharedStepGroupResolution enum and optional target fields
- PreflightResponse interface with templateMismatch, workflowMappings, collisions fields

* feat(29-02): create status polling endpoint for copy-move jobs

- GET /api/repository/copy-move/status/[jobId] polls BullMQ job state
- Uses getCopyMoveQueue() with multi-tenant isolation check
- Returns state, progress, result, failedReason, timestamps
- 7 unit tests covering auth, 503, 404, tenant isolation, completed/failed/active states

* test(29-01): add failing tests for preflight endpoint

- 16 test cases covering: 401 unauth, 400 invalid body, 403 no source access,
  403 no target access, templateMismatch detection, canAutoAssignTemplates for
  ADMIN and PROJECTADMIN, workflowMappings name-match and default fallback,
  unmappedStates, collision detection, targetRepositoryId resolution,
  hasSourceDeleteAccess for move operation

* feat(29-01): implement preflight endpoint for copy-move compatibility checks

- Auth check: 401 if no session
- Zod validation: 400 on invalid body
- Source/target project access via enhance(db, { user }): 403 on missing access
- Move delete access check via repositoryCases.findFirst
- Template compatibility: detects missingTemplates, templateMismatch flag
- canAutoAssignTemplates for ADMIN and PROJECTADMIN users
- Workflow state mapping with name-match and default fallback
- unmappedStates list for states falling back to default
- Collision detection via OR query on (name, className, source)
- Resolves targetRepositoryId from active repository
- Returns full PreflightResponse with all required fields

* docs(29-01): complete preflight API endpoint plan

- SUMMARY.md: schemas + preflight route with 16 unit tests
- STATE.md: advanced to phase 29 plan 01 complete
- ROADMAP.md: phase 29 in progress (1/4 plans complete)
- REQUIREMENTS.md: COMPAT-01, COMPAT-03, COMPAT-04 marked complete

* feat(29-02): create cancel endpoint for copy-move jobs

- POST /api/repository/copy-move/cancel/[jobId] handles job cancellation
- Uses getCopyMoveQueue() with multi-tenant isolation check
- Only job submitter (userId match) can cancel their own job
- Sets Redis key 'copy-move:cancel:{jobId}' EX 3600 for active jobs (matches worker)
- Calls job.remove() directly for waiting/delayed jobs
- 8 unit tests covering auth, 503, 404, tenant isolation, 403, finished, waiting, active states

* docs(29-02): complete status and cancel endpoints plan

- SUMMARY.md: 2 tasks, 4 files, 15 tests, 9m duration
- STATE.md: advance to plan 02 complete, add Redis cancel key decision
- ROADMAP.md: phase 29 progress updated (2/4 plans complete)
- REQUIREMENTS.md: BULK-03 marked complete

* feat(29-03): add project admin access rules to TemplateProjectAssignment

- Added project.userPermissions SPECIFIC_ROLE Project Admin create/delete rule
- Added project.assignedUsers PROJECTADMIN create/delete rule
- Matches pattern from CaseExportTemplateProjectAssignment (blueprint model)
- Enables project admins to auto-assign templates on copy/move submit

* test(29-03): add failing tests for submit endpoint (RED)

- 15 test cases covering auth, validation, permissions, auto-assign, resolve IDs, job enqueue
- Tests for both ADMIN and PROJECTADMIN auto-assign paths
- Tests for silent skip when regular user attempts auto-assign
- Tests for conflictResolution=overwrite rejection (schema enforced)

* feat(29-03): implement submit endpoint with permission checks and job enqueue (GREEN)

- POST /api/repository/copy-move validates with submitSchema (rejects overwrite)
- Enforces source read, target write, and move delete permissions via ZenStack enhance
- Admin and PROJECTADMIN users can auto-assign missing templates to target project
- Regular users silently skip auto-assign (no error)
- Resolves targetRepositoryId, targetTemplateId, targetDefaultWorkflowStateId when not provided
- Enqueues CopyMoveJobData to BullMQ with userId and tenantId
- Returns { jobId } on success; all 15 unit tests pass

* docs(29-03): complete submit endpoint plan

- Created 29-03-SUMMARY.md with TDD deviation documentation
- Updated STATE.md position, decisions, metrics, and session
- Updated ROADMAP.md phase 29 progress (3/3 plans complete)
- Marked COMPAT-02 and BULK-01 requirements complete

* docs(phase-29): complete phase execution

* docs(30): smart discuss context

* docs(phase-30): add validation strategy

* docs(30): create phase plan

* docs: reassign DLGSEL-01/02 from Phase 30 to Phase 31

* feat(30-01): add useCopyMoveJob hook and COPY_MOVE_COMPLETE notification type

- Add COPY_MOVE_COMPLETE to NotificationType enum in schema.zmodel
- Run pnpm generate to sync Prisma/ZenStack client and OpenAPI schema
- Create useCopyMoveJob hook with preflight, submit, polling, cancel, reset
- Poll /api/repository/copy-move/status/{jobId} every 2s with progress equality check
- Create comprehensive unit tests (14 tests) covering full job lifecycle

* feat(30-01): send COPY_MOVE_COMPLETE notification and render in NotificationContent

- Import NotificationService in copyMoveWorker.ts
- Call NotificationService.createNotification at job completion (wrapped in try/catch)
- Add COPY_MOVE_COMPLETE handler in NotificationContent.tsx with Copy/ArrowRightLeft icons
- Link to target project repository from notification

* docs(30-01): complete useCopyMoveJob hook and notification delivery plan

* feat(30-02): build CopyMoveDialog three-step wizard component

- Create CopyMoveDialog with target/configure/progress steps
- Project picker using Command component, filters out source project
- Lazy-loaded folder picker using FolderSelect after project selection
- Copy/Move radio with re-triggering preflight on operation change
- Yellow alert banners for template mismatches and workflow fallbacks
- Scrollable collision list with skip/rename radio
- Shared step group resolution radio
- Progress bar with X of Y cases processed
- Results summary with success/failure counts and expandable error list
- Dialog close during progress continues job in background
- View in target project link on completion
- Add components.copyMove i18n keys to en-US.json

* test(30-02): add CopyMoveDialog component tests

- 16 tests covering all three wizard steps (target, configure, progress)
- Tests: DLGSEL-03 project picker, DLGSEL-04 lazy-loaded folders
- Tests: DLGSEL-05 Copy/Move radio, DLGSEL-06 collision list
- Tests: BULK-02 progress bar, BULK-04 results summary + error list
- Tests: permission warnings, template mismatch, shared step groups
- Tests: View in target project link, dialog close behavior
- Mock FolderSelect as plain HTML select for JSDOM compatibility
- Mock scrollIntoView for cmdk Command component in JSDOM

* fix(30): use soft-delete permission check, AsyncCombobox for pickers, wizard stepper pattern

- Change move permission from delete to update check (soft-delete = isDeleted: true)
- Rename hasSourceDeleteAccess -> hasSourceUpdateAccess across API, schemas, dialog, tests
- Replace inline Command with AsyncCombobox for project picker (proper popover close)
- Replace FolderSelect with AsyncCombobox for folder picker (searchable + hierarchical)
- Add wizard step indicator (numbered circles) matching ImportCasesWizard pattern
- Add DialogDescription per step, unified DialogFooter with ChevronLeft/ChevronRight
- Widen dialog to max-w-3xl with scrollable content area
- Fix AsyncCombobox placeholder contrast on hover (group-hover:text-accent-foreground)
- Add i18n keys for step descriptions and update source access error message

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(30-02): complete CopyMoveDialog wizard plan

* docs(phase-30): complete phase execution

* docs(31): smart discuss context

* docs(31-entry-points): create phase plan

* feat(31-01): wire CopyMoveDialog into toolbar and context menu entry points

- Add isCopyMoveOpen state and handleCopyMove callback in Cases.tsx
- Import CopyMoveDialog and render it with selectedCaseIdsForBulkEdit
- Add Copy/Move toolbar button between Create Test Run and Export
- Add onCopyMove parameter to getColumns and pass through to ActionsCell
- Add ArrowRightLeft icon and DropdownMenuItem in ActionsCell
- Add copyMoveToProject translation key under repository.cases in en-US.json

* feat(31-01): add Copy/Move button to BulkEditModal footer

- Add onCopyMove optional prop to BulkEditModalProps interface
- Add ArrowRightLeft icon to BulkEditModal lucide-react imports
- Render Copy/Move button in DialogFooter between Delete and Cancel/Save
- Pass onCopyMove to BulkEditModal in Cases.tsx (closes bulk edit, opens copy-move)
- Add CopyMoveDialog mock to Cases.test.tsx so existing tests pass

* docs(31-01): complete entry-points plan — CopyMoveDialog wired into all three UI entry points

* docs(phase-31): complete phase execution

* docs(32): smart discuss context

* docs(32): create phase plan for testing and documentation

* docs(32-02): create user documentation for copy/move test cases

- Covers all three entry points: toolbar, context menu, bulk edit modal
- Documents three-step wizard workflow (target selection, configure, progress)
- Explains template compatibility, workflow state mapping, and naming collision resolution
- Documents shared step group handling options (reuse vs create new)
- Includes data carry-over table and copy vs move differences table
- Adds troubleshooting section for common issues

* feat(32-01): add E2E API tests for copy-move endpoints

- Serial-mode test suite covering preflight, submit, status, and cancel endpoints
- Preflight tests verify templateMismatch, canAutoAssignTemplates, workflowMappings, and collision detection (TEST-02)
- Submit tests use 503/200 tolerance pattern for queue-dependent endpoints
- Copy data carry-over tests conditionally verify tags and steps in target (TEST-01)
- Move tests verify source case soft-deletion after operation (TEST-01)
- 24 test cases total across all copy-move API endpoints

* docs(32-02): complete copy/move documentation plan

- SUMMARY.md created for phase 32 plan 02
- STATE.md updated with decisions and session info
- ROADMAP.md updated with phase 32 plan progress
- REQUIREMENTS.md: DOCS-01 marked complete

* docs(32-01): complete E2E tests for copy-move API plan

- SUMMARY.md: 24-test E2E suite covering all copy-move endpoints (TEST-01 through TEST-04)
- STATE.md: advanced progress, recorded metrics and decisions
- ROADMAP.md: phase 32 marked complete
- REQUIREMENTS.md: TEST-01, TEST-02, TEST-03, TEST-04 marked complete

* docs(phase-32): complete phase execution

* fix: enforce conflictResolution in worker and fix stateId field name in preflight

- Worker now checks for existing case before create; skips or renames based
  on user's conflictResolution choice (was silently creating duplicates)
- Preflight route uses correct field name stateId (was workflowStateId which
  doesn't exist on RepositoryCases, causing undefined values in production
- Updated preflight test mocks to use stateId

Found during milestone audit integration check.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
EOF
)

* docs: milestone v0.17.0 audit — passed (31/31 requirements)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add copy/move test cases to sidebar under Repository

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use correct templateName field and resolve actual template names in preflight

- Fix TypeScript error: Templates model uses templateName, not name
- Fetch actual template names for missing templates instead of fallback "Template {id}"
- Add templates.findMany mock to preflight tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use RepositoryCaseSource enum type for collision detection query

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: shorten Copy/Move button text

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add inline folder creation in CopyMoveDialog

Users can type a new folder name and create it directly from the
copy/move dialog without leaving the wizard. The new folder is
created under the currently selected folder (or at root) and
auto-selected after creation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use relation connect for folder creation instead of scalar FK

ZenStack hooks require project/repository as relation connects, not
scalar projectId/repositoryId.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use parent relation connect for folder parentId

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: include folder node in View in target project link

Navigates directly to the target folder so users see their copied/moved cases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* style: add spacing between project and folder pickers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve TypeScript errors in CopyMoveDialog and worker tests

- Use `as any` for folder create data (ZenStack auto-injects creator)
- Guard created?.id before setting targetFolderId
- Widen makeMockJob data type to accept both copy/move operations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: show destination project/folder summary on Step 2

Displays a muted banner with folder icon showing "Project / Folder"
so users remember their Step 1 selection while configuring options.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: handle NULL className in collision detection and use incrementing rename suffix

- PostgreSQL NULL != NULL bypasses unique constraint, so collision queries
  now use { equals: null } for NULL className fields
- Rename suffix now increments: (copy), (copy 2), (copy 3)... instead of
  always using (copy) which would create duplicates on repeated operations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add export templates functionality and copy/move project feature

- Introduced export templates management, allowing users to assign templates to projects with relevant UI messages.
- Added copy/move functionality for test cases, including user guidance through a multi-step process and error handling for permissions and compatibility.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add Phase 33 — Folder Tree Copy/Move with TREE-01 through TREE-04 requirements

* docs(33): discuss context for folder tree copy/move

* docs(33): create phase plan for folder tree copy/move

* feat(33-01): extend copy-move worker with folder tree recreation logic

- Add FolderTreeNode interface and folderTree? field to CopyMoveJobData
- Add folderTree Zod validation in submitSchema
- Pass folderTree through in route.ts job data
- Recreate folder hierarchy in BFS order in worker processor
- Merge into existing same-name folders instead of creating duplicates
- Map each case to its correct target folder via sourceFolderToTargetFolderMap
- Use per-folder folderNextOrderMap for case order when folderTree present
- Update version history folderId to use mapped target folder
- Soft-delete source folders after case soft-delete on move operations

* test(33-01): add unit tests for folder tree worker logic

- Add repositoryFolders mock to mockPrisma
- Add folder tree operations describe block with 5 tests:
  - BFS order folder recreation with correct parentId chain
  - Merge behavior: reuse existing same-name folder, skip create
  - Move: soft-delete source folders after case processing
  - Version history folderId uses mapped target folder (not flat targetFolderId)
  - Regression guard: flat behavior unchanged when folderTree is absent

* docs(33-01): complete folder-tree-worker-support plan

* feat(33-02): add translation key and extend useCopyMoveJob with folderTree

- Add repository.folderActions.copyMove key to en-US.json
- Import FolderTreeNode type from copyMoveWorker in useCopyMoveJob
- Add optional folderTree param to submit args in interface and useCallback

* feat(33-02): extend CopyMoveDialog for folder mode, add TreeView entry point, wire in Cases

- Add sourceFolderId/sourceFolderName props to CopyMoveDialog
- Fetch source folder subtree and cases via useFindManyRepositoryFolders/useFindManyRepositoryCases
- Compute effectiveCaseIds (folder mode) and build BFS-ordered folderTree for submit
- Show folder name and case count in dialog header when in folder mode
- Add folderMode i18n key to components.copyMove in en-US.json
- Add onCopyMoveFolder optional prop to TreeView with Copy/Move context menu item
- Import Copy icon from lucide-react for the menu item
- Add copyMoveFolderId/Name props to Cases for folder dialog triggering
- Add useEffect in Cases to open dialog when copyMoveFolderId prop is set
- Lift folder copy/move state to ProjectRepository, wire TreeView -> Cases
- Fix CopyMoveDialog.test.tsx mock to include useFindManyRepositoryCases

* docs(33-02): complete folder-copy-move-ui-entry-point plan

- Add 33-02-SUMMARY.md with plan results and deviation notes
- Update STATE.md with decisions, metrics, and session info
- Update ROADMAP.md phase 33 progress (2/2 plans, Complete)
- Mark TREE-01 requirement complete in REQUIREMENTS.md

* docs(phase-33): complete phase execution

* style: match folder copy/move menu item to toolbar button

- Use ArrowRightLeft icon (same as toolbar button) instead of Copy
- Use same "Copy / Move" text key as toolbar button
- Move menu item above Delete Folder

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: update Copy/Move dialog instructions for consistency

- Change "Copy/Move to Project" to "Copy/Move" in toolbar, context menu, and bulk edit modal for uniformity.
- Adjust context menu instructions to reflect updated terminology.

* fix: remove orphaned DropdownMenuItem causing JSX parse error in TreeView

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: use proper placeholder text for project and folder pickers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: reuse existing i18n keys for project/folder placeholders, remove duplicates

- Project picker: uses navigation.projects.dropdown.selectProject
- Folder picker: uses repository.cases.importWizard.page1.selectFolderPlaceholder
- Removed duplicate selectProject and selectFolder keys from components.copyMove

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add folder tree E2E tests and documentation

- E2E: test folder tree copy recreates hierarchy with cases in correct folders
- E2E: test folder tree move soft-deletes source folders
- Docs: add folder context menu entry point section
- Docs: add Folder Tree Copy/Move section covering hierarchy, empty folders,
  merge behavior, and move cleanup

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: fix folder menu description — three-dot menu, not right-click

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: clarify what data is and is not carried over in copy/move

- Expanded table to show Copy vs Move columns for each data type
- Added "Data Not Included" section covering test run results, result
  field values, JUnit/automated results, cross-project links, and forecasts
- Updated Copy vs Move table to include comments difference

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* blog: add v0.17.0 Copy/Move Test Cases announcement post

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: only show copy/move when user has write access and multiple projects

- Toolbar button, context menu item, bulk edit button, and folder menu
  all gated on canAddEdit AND projectCount > 1
- No point showing copy/move if user only has access to one project

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add v0.17.0 upgrade notification for Copy/Move feature

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: correct upgrade notification — folder menu, not right-click

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: move useCountProjects hook before early returns (Rules of Hooks)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: update terminology for automated test results in copy/move documentation

- Changed "JUnit/automated test results" to "Automated test results" for clarity.
- Ensured consistency in the description of data not transferred during copy or move operations.

* feat: add audit logging for copy/move operations

Log CREATE events for each case created in target project and DELETE
events for source cases soft-deleted during move. Events include
sourceProjectId, targetProjectId, and jobId in metadata.

See #143 for the broader worker audit logging gap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: enhance UI interactions and improve accessibility

- Updated TreeView component to include hover text color changes for better visibility.
- Refactored Header component for improved readability and consistency in imports and JSX structure.
- Enhanced SearchIssuesDialog component with more descriptive class names for hover states.
- Added new "tools" terminology in English, Spanish, and French localization files.
- Introduced new folder action "copyMove" in localization files for better user guidance.

* feat(260321-fk3): add audit logging to testmoImportWorker

- Import captureAuditEvent from auditLog service
- Emit BULK_CREATE audit event on successful import completion
- Event includes entityProgress counts and duration metadata
- Best-effort (.catch(() => {})) — never blocks the import job

* feat(260321-fk3): add audit logging to syncWorker and forecastWorker

- syncWorker: BULK_UPDATE events for sync-issues and sync-project-issues
- syncWorker: UPDATE event for refresh-issue
- forecastWorker: UPDATE event for each milestone auto-completed with isCompleted change
- All calls use .catch(() => {}) pattern — best-effort, never blocks jobs

* fix(260321-fk3): correct jobId reference in testmoImportWorker audit event

- Use jobId (string parameter) instead of job.id (BullMQ Job not in scope)
- processImportMode function receives jobId as parameter, not the BullMQ Job object

* docs(260321-fk3): complete add-audit-logging-to-workers plan

- SUMMARY.md with task commits, deviations, and decisions

* docs(quick-260321-fk3): Fix issue #143 — add audit logging to workers

* fix: add useCountProjects mock to Cases.test.tsx

Missing mock caused all 15 Cases component tests to crash during render.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* perf: skip forecast DB writes when values have not changed

- updateRepositoryCaseForecast: fetch current values, only update if different
- updateTestRunForecast: compare before writing for both clear and set paths
- Reduces unnecessary DB writes during scheduled forecast recalculations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Fixes/worker audit logging (#144)

* feat(260321-fk3): add audit logging to testmoImportWorker

- Import captureAuditEvent from auditLog service
- Emit BULK_CREATE audit event on successful import completion
- Event includes entityProgress counts and duration metadata
- Best-effort (.catch(() => {})) — never blocks the import job

* feat(260321-fk3): add audit logging to syncWorker and forecastWorker

- syncWorker: BULK_UPDATE events for sync-issues and sync-project-issues
- syncWorker: UPDATE event for refresh-issue
- forecastWorker: UPDATE event for each milestone auto-completed with isCompleted change
- All calls use .catch(() => {}) pattern — best-effort, never blocks jobs

* fix(260321-fk3): correct jobId reference in testmoImportWorker audit event

- Use jobId (string parameter) instead of job.id (BullMQ Job not in scope)
- processImportMode function receives jobId as parameter, not the BullMQ Job object

* docs(260321-fk3): complete add-audit-logging-to-workers plan

- SUMMARY.md with task commits, deviations, and decisions

* docs(quick-260321-fk3): Fix issue #143 — add audit logging to workers

* fix: add useCountProjects mock to Cases.test.tsx

Missing mock caused all 15 Cases component tests to crash during render.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* perf: skip forecast DB writes when values have not changed

- updateRepositoryCaseForecast: fetch current values, only update if different
- updateTestRunForecast: compare before writing for both clear and set paths
- Reduces unnecessary DB writes during scheduled forecast recalculations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Feature/comprehensive test coverage (#145)

* docs: resume milestone v2.0 Comprehensive Test Coverage

* docs: mark v2.0 phases 10-24 complete in roadmap

* test: add AttachmentsCarousel component tests (REPO-11)

12 tests covering rendering, metadata display, edit mode,
navigation, delete popover, and canEdit toggle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: complete v2.0 Comprehensive Test Coverage milestone

Archive v2.0 (phases 9-24): 16 phases, 44 plans covering E2E tests,
component tests, API route tests, hooks, and workers. Also marks
v0.17.0 Copy/Move (phases 28-33) as shipped. Collapses ROADMAP.md
from 538 to 84 lines.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: rename variables for consistency in tests

- Updated variable names in test files to prefix with an underscore for clarity and consistency.
- Adjusted notification text formatting in NotificationContent component for improved readability.
- Removed commented-out code in CopyMoveDialog test for cleaner codebase.

* test: update AttachmentsCarousel tests and refactor copy-move endpoint tests

- Added type definitions for attachments in AttachmentsCarousel tests for better type safety.
- Refactored variable names in copy-move endpoint tests for consistency and clarity.
- Updated test case creation to use new variable naming conventions, improving readability and maintainability.

* test: add mock for useCountProjects in Cases.test.tsx

- Introduced a mock for the useCountProjects hook to enhance test coverage and ensure consistent behavior during testing.

* chore: update CLI dependency installation in CI workflow

- Modified the CI workflow to include the --ignore-scripts flag during CLI dependency installation, ensuring that scripts are not executed during the install process.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Feature/per prompt llm config (#146)

* docs: start milestone v0.17.0 Per-Prompt LLM Configuration

* docs: define milestone v0.17.0 requirements

* docs: create milestone v0.17.0 roadmap (6 phases)

* docs(34): smart discuss context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(34-schema-and-migration): create phase plan

* docs(34): plan phase 34 — schema and migration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(34-01): add llmIntegrationId and modelOverride fields to PromptConfigPrompt

- Add optional llmIntegrationId Int? FK field to PromptConfigPrompt
- Add LlmIntegration? relation on PromptConfigPrompt (no cascade delete)
- Add optional modelOverride String? field to PromptConfigPrompt
- Add @@index([llmIntegrationId]) on PromptConfigPrompt
- Add promptConfigPrompts[] reverse relation to LlmIntegration

* feat(34-01): regenerate ZenStack/Prisma artifacts with new PromptConfigPrompt fields

- prisma/schema.prisma updated with llmIntegrationId and modelOverride on PromptConfigPrompt
- lib/hooks regenerated with new relation hooks
- OpenAPI spec updated
- Database synced with new columns, FK constraint, and index

* docs(phase-34): complete phase execution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(35): smart discuss context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(35-resolution-chain): create phase plan

* docs(35): plan phase 35 — resolution chain

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(35-01): extend PromptResolver and add LlmManager.resolveIntegration

- Add llmIntegrationId and modelOverride optional fields to ResolvedPrompt interface
- Populate these fields from PromptConfigPrompt in project-specific and default branches
- Add resolveIntegration() to LlmManager implementing 3-tier chain:
  1. Project LlmFeatureConfig override (highest priority)
  2. Per-prompt PromptConfigPrompt.llmIntegrationId
  3. Project default integration (getProjectIntegration)
- Add tests for per-prompt LLM fields in ResolvedPrompt

* feat(35-01): update all call sites to use resolveIntegration chain

- tag-analysis.service: replace getProjectIntegration with resolveIntegration (3-tier chain)
- generate-test-cases/route: use resolveIntegration, pass resolved.model to LlmRequest
- magic-select-cases/route: use resolveIntegration, pass resolved.model to LlmRequest
- parse-markdown-test-cases/route: use resolveIntegration, pass resolved.model to LlmRequest
- export/ai-stream/route: use resolveIntegration, pass resolved.model to LlmRequest
- aiExportActions: use resolveIntegration in both generateAiExportBatch and generateAiExport
- tag-analysis.service.test: add resolveIntegration mock, update no-integration test
- Explicit-integration endpoints (chat, test, admin chat) intentionally unchanged

* docs(35-01): complete resolution-chain plan — 3-tier LLM integration chain with 6 call sites updated

* docs(phase-35): complete phase execution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(36,37): smart discuss context for admin UI and project overrides

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(37-project-ai-models-overrides): create phase plan

* docs(36-admin-prompt-editor-llm-selector): create phase plan

* docs(36,37): plan phases 36 and 37 — admin UI and project overrides

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(36-01): add LLM integration and model override selectors to PromptFeatureSection

- Import useFindManyLlmIntegration and Select components
- Fetch active integrations with llmProviderConfig
- Derive availableModels from selected integration providerConfig
- Add integration selector with Project Default placeholder and clear option
- Add model override selector disabled when no integration selected
- Add en-US.json translation keys for new selectors

* feat(36-02): add mixed-integration indicator column to prompt config table

- Add llmIntegrations column to columns.tsx showing Project Default, single name, or N LLMs badge
- Rename unused _t param to t in getColumns, use it in new column
- Add PromptConfigPromptWithIntegration interface for typed llmIntegration relation
- Update both useFindManyPromptConfig queries in page.tsx to include llmIntegration relation

* feat(36-01): wire llmIntegrationId and modelOverride into Add and Edit form schemas and submit handlers

- Add llmIntegrationId and modelOverride to createFormSchema in both dialogs
- Add null defaults for new fields in getDefaultPromptValues (Add)
- Update useEffect in Edit to populate fields from existing prompt data
- Update createPromptConfigPrompt call to pass new fields when set
- Update updatePromptConfigPrompt call to include both fields on save

* feat(37-01): integrate FeatureOverrides into AI Models settings page

- Import FeatureOverrides from ./feature-overrides
- Render FeatureOverrides as a third card section after Prompt Configuration
- Wire projectId, integrations, projectDefaultIntegration, and promptConfigId props

* docs(36-02): complete mixed-integration indicator column plan

- 36-02-SUMMARY.md (in .planning, gitignored but tracked via state files)
- STATE.md updated with decision and progress
- ROADMAP.md phase 36 marked complete (2/2 plans with summaries)
- REQUIREMENTS.md ADMIN-03 marked complete

* docs(36-01): complete admin prompt editor LLM selector plan

- Add 36-01-SUMMARY.md with task details and decisions
- Update STATE.md: position advanced to phase 36 plan 01 complete
- Update ROADMAP.md: phase 36 progress updated
- Mark ADMIN-01 and ADMIN-02 requirements complete

* docs(37-01): complete per-feature LLM overrides plan — FeatureOverrides component integrated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(phase-36,37): complete phase execution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(38): smart discuss context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(38): create phase plan

* docs(38): plan phase 38 — export/import and testing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test(38-02): add resolveIntegration unit tests for 3-tier resolution chain

- Add llmFeatureConfig and projectLlmIntegration to createMockPrisma
- Add resolveIntegration describe block with 12 tests covering:
  - Level 1 LlmFeatureConfig active, model, null model, deleted, inactive, null relation
  - Level 2 per-prompt with modelOverride, without modelOverride, inactive fallthrough
  - Level 3 project default and system default fallback
  - Null return when no integration found at any level

* feat(38-01): create prompt config export API route

- GET /api/admin/prompt-configs/export?id=xxx
- Returns JSON with name, description, isDefault, isActive, prompts
- Each prompt includes feature, systemPrompt, userPrompt, temperature, maxOutputTokens, llmIntegrationName (human-readable), modelOverride
- Requires ADMIN auth, returns 400 for missing id, 404 for not found
- 13 unit tests covering auth, validation, and export behavior

* docs(38-02): complete resolveIntegration unit tests plan

- Create 38-02-SUMMARY.md documenting 12 resolveIntegration tests
- Update STATE.md with position and decisions
- Update ROADMAP.md phase 38 progress
- Mark TEST-01, TEST-02 requirements complete

* feat(38-01): create prompt config import API route

- POST /api/admin/prompt-configs/import
- Validates body with Zod schema (name required, prompts array required)
- Fetches active LLM integrations to resolve llmIntegrationName to llmIntegrationId
- Gracefully handles unresolved integration names (sets to null, reports in response)
- Preserves modelOverride as-is from import payload
- Returns 201 with created config id, name, and unresolvedIntegrations array
- 16 unit tests covering auth, validation, resolution, and graceful degradation

* docs(38-01): complete prompt config export/import plan

- SUMMARY.md: export/import API routes with LLM field portability
- STATE.md: decisions from 38-01, updated progress
- ROADMAP.md: phase 38 progress updated
- REQUIREMENTS.md: EXPORT-01 marked complete

* feat(38-03): add E2E tests for admin prompt editor LLM selector

- Test: select LLM integration for a prompt feature, save, and verify persistence after reload
- Test: clear LLM integration (select Project Default), save, and verify cleared after reload
- Uses API fixtures to create prompt config and LLM integration for setup
- Uses PromptConfigurationsPage page object for navigation and dialog interaction
- Selects "Project Default (clear)" option (matches en-US translation for __clear__ sentinel)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(38-03): add E2E tests for project AI Models per-feature overrides

- Test: feature overrides table displays all 7 LLM features
- Test: assign per-feature LLM override, verify effective LLM and Project Override badge
- Test: clear per-feature override, verify badge and clear button disappear
- Creates project via api.createProject() for valid projectId (not hardcoded fixture)
- Links LLM to project via api.linkLlmToProject() before testing override select
- Pre-assigns override via API for the clear test to avoid manual UI setup steps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(38-03): complete prompt LLM selector and AI models overrides E2E tests plan

- SUMMARY.md: 2 tasks, 2 files created, 2 auto-fixed deviations documented
- STATE.md: decisions added for projectId fixture and __clear__ sentinel translation
- ROADMAP.md: phase 38 marked complete (3/3 summaries)
- REQUIREMENTS.md: TEST-03 and TEST-04 marked complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(phase-38): complete phase execution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(39): smart discuss context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(39-documentation): create phase plan

* docs(39): plan phase 39 — documentation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(39-01): add per-prompt LLM assignment section to prompt-configurations.md

- Add Per-Prompt LLM Assignment section with setup instructions and behavior notes
- Update Creating a Configuration step 3 to list LLM Integration and Model Override selectors
- Add cross-reference to AI Models LLM Resolution Chain

* docs(39-01): add per-feature overrides and resolution chain to llm-integrations.md

- Add Per-Feature LLM Overrides section with setup instructions and source badge reference
- Add LLM Resolution Chain section with three-level priority diagram
- Update Project Assignment to mention per-feature override capability
- Add cross-reference to prompt-configurations per-prompt LLM assignment

* docs(39-01): complete documentation plan — update planning state and summaries

- Update STATE.md: phase 39 complete, plan 39-01 complete, decisions recorded
- Update ROADMAP.md: phase 39 marked complete (1/1)
- Update REQUIREMENTS.md: DOCS-01 and DOCS-02 marked complete

* docs(phase-39): complete phase execution — all phases done

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Update build artifacts

* feat: show LLM integration name in prompt feature accordion title

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: show 'Project Default' in accordion title when no LLM assigned

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve lint errors — jsx literals, unused vars

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove unused baseURL from E2E test destructuring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove duplicate useCountProjects mock in Cases.test.tsx

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant