# Scratchpad — Bidirectional Task-Ticket Creation

- Plan slug: `2026-02-05-bidirectional-task-ticket`
- Created: `2026-02-05`

## Decisions

- (2026-02-05) Priorities are NOT transferred between tasks and tickets — they are separate systems with separate priority tables (`item_type = 'project_task'` vs `item_type = 'ticket'`).
- (2026-02-05) Client for ticket creation is mapped from `IProject.client_id` at the project level, not the task level. Tasks don't have clients.
- (2026-02-05) Auto-linking is optional via a checkbox/toggle (default: on).
- (2026-02-05) Task `estimated_hours` is stored in MINUTES in the database. Display and ticket values are in HOURS. Must convert when mapping.
- (2026-02-05) Ticket `description` is NOT on `ITicket` interface but IS stored in the DB and accessible via FormData / consolidated ticket data attributes.
- (2026-02-05) Use render-prop injection pattern for cross-package composition (TicketDetails → MspTicketDetailsContainerClient), consistent with `renderContactDetails` and `associatedAssets` patterns.

## Progress

- (2026-02-05) Implemented `mapTicketToTaskFields` mapping utility in `packages/projects/src/lib/taskTicketMapping.ts` for ticket→task prefill defaults (safe defaults, due date parsing, estimated hours passthrough).
- (2026-02-05) Added `mapTaskToTicketPrefill` in `packages/projects/src/lib/taskTicketMapping.ts` to derive ticket prefill data from tasks and project client (minutes→hours conversion, client id/name).
- (2026-02-05) Explicitly ignored `priority_id` in both mapping directions to enforce non-mapping of priorities.
- (2026-02-05) Added `PrefillFromTicketDialog` component with searchable `TicketSelect` and lazy ticket list loading.
- (2026-02-05) Added auto-link checkbox (default on) to `PrefillFromTicketDialog` to control link creation.
- (2026-02-05) Prefill dialog now fetches consolidated ticket data and returns mapped task prefill fields via `mapTicketToTaskFields`.
- (2026-02-05) Added `prefillData` support in `TaskForm` to initialize fields and pending ticket link for create-mode prefill.
- (2026-02-05) Added create-mode-only Ticket icon button with tooltip "Create from ticket" next to Task Name label.
- (2026-02-05) Wired `PrefillFromTicketDialog` into `TaskForm` to populate fields and optionally add a pending ticket link.
- (2026-02-05) Added `prefilledTitle` support in `QuickAddTicket` for title initialization and resets.
- (2026-02-05) Added `prefilledAssignedTo` support in `QuickAddTicket` for assigned user initialization and resets.
- (2026-02-05) Added `prefilledDueDate` support in `QuickAddTicket` with safe date parsing for the date picker.
- (2026-02-05) Added `prefilledEstimatedHours` support and an Estimated Hours input in `QuickAddTicket`.
- (2026-02-05) QuickAddTicket now appends `estimated_hours` to FormData when provided.
- (2026-02-05) Parsed `estimated_hours` in `addTicket` and plumbed it through `ticketModel` creation/schema.
- (2026-02-05) Added `taskData` prop to `TaskTicketLinks` for passing current task field values.
- (2026-02-05) TaskTicketLinks now fetches project client data before opening QuickAddTicket.
- (2026-02-05) TaskTicketLinks now maps task data to QuickAddTicket prefill props (title/description/assignee/due date/estimated hours + client).
- (2026-02-05) TaskForm now passes edit-mode field values as `taskData` (minutes) into TaskTicketLinks.
- (2026-02-05) Added `CreateTaskFromTicketDialog` with project selector and supporting state for project-driven task creation.
- (2026-02-05) CreateTaskFromTicketDialog now refreshes phases/statuses whenever the selected project changes.
- (2026-02-05) Phase selector now derives options from fetched phases and disables when none are available.
- (2026-02-05) Status selector now derives options from fetched statuses and disables when none are available.
- (2026-02-05) CreateTaskFromTicketDialog resets auto-link checkbox to on when opened.
- (2026-02-05) CreateTaskFromTicketDialog now opens TaskQuickAdd in a drawer with ticket-derived prefill data and optional pending link.
- (2026-02-05) TaskQuickAdd now accepts `prefillData` and forwards it into TaskForm.
- (2026-02-05) Added `renderCreateProjectTask` render prop hook in `TicketDetails` header area.
- (2026-02-05) TicketDetailsContainer now forwards `renderCreateProjectTask` to TicketDetails.
- (2026-02-05) MSP ticket container now injects CreateTaskFromTicketDialog via `renderCreateProjectTask`.
- (2026-02-05) Exported CreateTaskFromTicketDialog from projects components index.
- (2026-02-05) Added initial unit test for `mapTicketToTaskFields` title→task_name mapping.
- (2026-02-05) Added unit test for `mapTicketToTaskFields` description mapping.
- (2026-02-05) Added unit test for `mapTicketToTaskFields` assigned_to mapping.
- (2026-02-05) Added unit test for `mapTicketToTaskFields` due_date ISO→Date conversion.
- (2026-02-05) Added unit test for `mapTicketToTaskFields` estimated hours passthrough.
- (2026-02-05) Added unit test ensuring `mapTicketToTaskFields` defaults null/undefined safely.
- (2026-02-05) Added unit test for `mapTaskToTicketPrefill` task_name→title mapping.
- (2026-02-05) Added unit test for `mapTaskToTicketPrefill` estimated hours minutes→hours conversion.
- (2026-02-05) Added unit test verifying `mapTaskToTicketPrefill` includes project client metadata.
- (2026-02-05) Added tests ensuring priority_id is not included in either mapping output.
- (2026-02-05) Added PrefillFromTicketDialog test for search input and dropdown rendering.
- (2026-02-05) Added PrefillFromTicketDialog test ensuring ticket fetch occurs on open.
- (2026-02-05) Added PrefillFromTicketDialog test for auto-link checkbox default state.
- (2026-02-05) Added PrefillFromTicketDialog test ensuring unchecked auto-link yields shouldLink=false.
- (2026-02-05) Added PrefillFromTicketDialog test verifying consolidated ticket fetch on confirm.
- (2026-02-05) Added PrefillFromTicketDialog test ensuring mapped fields returned to onPrefill.
- (2026-02-05) Added TaskForm prefill tests: task_name, description, assigned_to, due_date, estimated_hours, and pending ticket link initialization.
- (2026-02-05) Added TaskForm create-from-ticket tests: auto-link on/off link handling and field population.
- (2026-02-05) Added MSP container test for CreateTaskFromTicketDialog injection.
- (2026-02-05) Added E2E-style TaskForm create-from-ticket test (prefill + link on save).
- (2026-02-05) Added E2E-style TaskTicketLinks test for create-ticket prefill props.
- (2026-02-05) Added E2E-style CreateTaskFromTicketDialog test for drawer open flow.
- (2026-02-05) Added test ensuring priority is not prefilled in create-ticket flow.

## Discoveries / Constraints

- (2026-02-05) `TicketSelect` component already exists at `packages/projects/src/components/TicketSelect.tsx` — reusable for ticket search in Scenario 1.
- (2026-02-05) `QuickAddTicket` already has `prefilledClient`, `prefilledContact`, `prefilledDescription` props. Need to add: `prefilledTitle`, `prefilledAssignedTo`, `prefilledDueDate`, `prefilledEstimatedHours`.
- (2026-02-05) `addTicket` server action does NOT parse `estimated_hours` from FormData (line ~220 in ticketActions.ts). Must add.
- (2026-02-05) `TaskForm` has `prefillData`-like initialization already: `useState(task?.task_name || '')`. Can extend with a `prefillData` prop.
- (2026-02-05) No `ProjectPicker` or `PhasePicker` components exist. Use `CustomSelect` with `getProjects()` and `getProjectTreeData()`.
- (2026-02-05) `useDrawer` hook supports opening TaskForm in a drawer with full history management.
- (2026-02-05) `TaskQuickAdd` wraps `TaskForm` — need to pass `prefillData` through.
- (2026-02-05) React synthetic events propagate through portals. QAT form submit was bubbling to TaskForm — fixed with `e.stopPropagation()`.

## Commands / Runbooks

- Build check: `npx tsc --noEmit -p packages/projects/tsconfig.json && npx tsc --noEmit -p packages/tickets/tsconfig.json`
- Run dev: `npm run dev`

## Links / References

- Key files:
  - `packages/projects/src/components/TaskForm.tsx` — main task form (create/edit)
  - `packages/projects/src/components/TaskTicketLinks.tsx` — ticket linking in task form
  - `packages/projects/src/components/TicketSelect.tsx` — searchable ticket selector
  - `packages/tickets/src/components/QuickAddTicket.tsx` — inline ticket creation
  - `packages/tickets/src/components/ticket/TicketDetails.tsx` — ticket detail view
  - `packages/tickets/src/components/ticket/TicketDetailsContainer.tsx` — container with injection props
  - `packages/msp-composition/src/tickets/MspTicketDetailsContainerClient.tsx` — MSP composition layer
  - `packages/tickets/src/actions/ticketActions.ts` — addTicket server action
  - `packages/projects/src/actions/projectActions.ts` — getProjects, getProjectTreeData
  - `packages/projects/src/actions/projectTaskActions.ts` — addTicketLinkAction
  - `packages/types/src/interfaces/ticket.interfaces.ts` — ITicket
  - `packages/types/src/interfaces/project.interfaces.ts` — IProjectTask

## Open Questions

- None currently — all clarified with user.
