# DashboardPage Division Map

## Goal

Dejar `DashboardPage.jsx` como coordinador de pantalla y de flujos cruzados, no como dueño directo de subdominios completos.

## Line Budget Heuristic

- Usar `~1000` líneas por archivo como techo blando, no como regla mecánica.
- El objetivo real es ownership claro por dominio; si un archivo queda algo por encima pero sigue siendo coherente, eso es preferible a fragmentarlo artificialmente.
- A fecha 2026-04-07, el promedio de `frontend/src/**/*.js,jsx` ya está por debajo de ese umbral: `47` archivos, `33362` líneas, promedio `709.83`.
- `dashboardHelpers.js` ya se rebajó de `2571` a `954` líneas separando `dashboardCoreHelpers.js` (`213`), `dashboardSequenceModelHelpers.js` (`728`), `dashboardSequenceTimelineHelpers.js` (`650`) y `dashboardLocalStorageHelpers.js` (`162`).
- Los siguientes cortes deben atacar outliers, no perseguir el promedio global: `DashboardPage.jsx`, `dashboardEditorialHelpers.js` y `SplitReviewModal`.

## Status Legend

- `done`: ya extraído o ya asignado a un módulo estable.
- `active`: siguiente corte recomendado.
- `pending`: corte rentable, pero no el inmediato.
- `keep`: debe seguir en `DashboardPage.jsx` porque conecta dominios distintos.

## Progress Map

| Status | Area | Brief Description | Representative Functions / State | Target / Owner File |
| --- | --- | --- | --- | --- |
| `done` | Shared helper clusters | Helpers puros de estado, editorial, preview y utilería transversal. La base de `dashboardHelpers.js` ya quedó partida por ownership (`core`, `sequence model`, `sequence timeline`, `local storage`) y el archivo original quedó como fachada/persistencia. | `buildOpenAITraceConsoleEntries`, `buildPreviewSubtitleCues`, `normalizeEditorialAgentState`, `resolveTimelineMediaUrl`, `buildSequenceParagraphs`, `buildSourcePosition`, `saveEditorSession` | `frontend/src/pages/dashboardStatusHelpers.js`, `frontend/src/pages/dashboardPreviewHelpers.js`, `frontend/src/pages/dashboardEditorialHelpers.js`, `frontend/src/pages/dashboardCoreHelpers.js`, `frontend/src/pages/dashboardSequenceModelHelpers.js`, `frontend/src/pages/dashboardSequenceTimelineHelpers.js`, `frontend/src/pages/dashboardLocalStorageHelpers.js`, `frontend/src/pages/dashboardHelpers.js` |
| `done` | Overlay and heavy UI blocks | UI pesada ya fuera del page controller. | export modal, transcription modal, crop modal, depuration modal, editorial modal, preview subtitle menu, classic preview panel | `frontend/src/components/DashboardOverlayModals.jsx`, `frontend/src/components/DepurateModal.jsx`, `frontend/src/components/EditorialAgentModal.jsx`, `frontend/src/components/PreviewSubtitleMenu.jsx`, `frontend/src/components/ClassicEditorPreviewPanel.jsx`, `frontend/src/components/EditorialAgentMiniTimeline.jsx` |
| `done` | Library project shell | Navegación del shell de proyecto, active word/paragraph, centrado y auto-scroll de transcript. | `libraryProjectActiveParagraphId`, `libraryProjectPreviewSourceMs`, centering/selection del transcript de proyecto | `frontend/src/pages/useLibraryProjectShell.js` |
| `done` | Editor history | Undo/redo, snapshots y persistencia de historia del editor. | `pushUndoSnapshot`, `handleUndo`, `handleRedo`, `commitHistoryIfNeeded` | `frontend/src/pages/useDashboardHistory.js` |
| `done` | Transcription modal local session | Estado local del modal de transcripción y mutación de entradas de consola/session trace. | `transcriptionModalSession`, `patchTranscriptionModalSession`, `appendTranscriptionModalSessionEntry`, `upsertTranscriptionModalSessionEntry` | `frontend/src/pages/useTranscriptionModalSession.js` |
| `done` | Editorial preview transport | Transporte y playback del preview editorial, con refs propias, progresión por bloques y continuidad multipart. | `stopEditorialAgentPreview`, `cueEditorialAgentPreviewBlock`, `handleToggleEditorialAgentPreview`, `handleEditorialAgentPreviewTimeUpdate`, `handleEditorialAgentPreviewEnded`, `editorialAgentPreviewPlayback` | `frontend/src/pages/useEditorialAgentPreview.js` |
| `done` | Editorial range selection | Estado del modal de ampliación de rango, selección de párrafos, drag selection y candidatos compartidos. | `editorialRangeModalModel`, `editorialRangeSelectedParagraphs`, `handleOpenEditorialRangeModal`, `handleCloseEditorialRangeModal`, `handleToggleEditorialRangeParagraph`, `handleStartEditorialRangeSelection`, `handleHoverEditorialRangeSelection`, `handleEndEditorialRangeSelection` | `frontend/src/pages/useEditorialRangeSelection.js` |
| `done` | Editorial agent workflow | El workflow editorial pesado ya salió del page controller hacia un hook dedicado: reapertura de revisiones guardadas, persistencia del split review, review/aprobación/descarte, regeneración/ajustes IA y reapertura de sugeridas en editor clásico. El page conserva solo wiring de estado y derivaciones visuales. | `handleOpenEditorialWorkspaceReview`, `handleCloseEditorialWorkspaceReview`, `handleSelectEditorialAgentCandidate`, `handleApplyEditorialRangeExpansion`, `handleApproveEditorialAgentCandidate`, `handleDiscardEditorialAgentCandidate`, `handleApproveEditorialSplitCollection`, `handleOpenSavedSuggestedSequences`, `handleOpenSuggestedSequenceInClassicEditor`, `handleRestoreEditorialSplitFromAi`, `handleApplyEditorialAgentAdjustments`, `handleGenerateSuggestion`, `handleCopyEditorialAgentConsole`, `persistSplitReviewSession*`, `restoreSavedSplitReviewSession` | `frontend/src/pages/useEditorialAgentWorkflow.js` |
| `done` | Project transcription workflow | La transcripción real del proyecto ya salió a un hook propio: polling, control cooperativo, retranscripción, limpieza/restores y seguimiento de auto-open/runtime del modal. DashboardPage conserva solo estado derivado y wiring visual del modal. | `pollTranscription`, `handleTranscriptionProcessControl`, `handleRetranscribe`, `handleClearTranscription`, `handleRestoreRetranscribeBackup`, `handleRestoreAppendBackup`, `transcriptionStatusWasSavingRef`, `transcriptionModalAutoOpenSuppressed` | `frontend/src/pages/useProjectTranscriptionWorkflow.js` |
| `done` | Project intake and source preparation | El dominio de intake ya salió de `DashboardPage.jsx`: `useProjectIntakeWorkflow.js` concentra los handlers operativos y el hook exportado `useProjectIntakeState(...)` ahora es dueño del estado transitorio de upload, preview local, locks y target selection. DashboardPage conserva solo wiring visual y consumo de ese estado. | `handleFileSelected`, `handleAppendVideoToProjectClick`, `handleAppendProjectVideoFileSelected`, `handleExtractProjectPart`, `handleCreateProjectFromSelectedVideo`; estado `uploadForm`, `uploadVideoPreviewUrl`, `isUploadingProject`, `isAppendingProjectVideo`, `appendProjectVideoTarget`, `extractingProjectPartId` | `frontend/src/pages/useProjectIntakeWorkflow.js` |
| `active` | Sequence editor workspace | Estado y handlers del editor clásico: ya salieron el estado base de selección/zoom/overlay/drag del timeline, la capa de interacción `pointer/wheel/clip-select`, la capa de borrado/merge/arranque de trim, el cluster de split y la coordinación principal de trim/teclado del timeline. Quedan bordes menores del editor, pero el grueso de este dominio ya está consolidado en el hook. | `handleToggleSelection`, `handleToggleSubtitleVisibility`, `handleToggleSentenceBreak`, `handleSplitAtPlayheadWithMode`, `handleDeleteSelectedTimelineBlock`, `handleTimelineClipSelect`, `handleMergeBlocks`, `handleTrimHandlePointerDown`, `handleTimelineZoomSliderChange`, `handleTimelinePointerDown`, `handleTimelineWheel`, `adjustSelectedTimelineBlockBoundaryByWord`, `handleTimelineArrowShortcut`, `moveSelectedTimelineBlockByOffset`, `selectTimelineBlockByIndex`; estado `selectedTimelineBlockId`, `timelineDraggedBlockId`, `timelineZoom`, `timelineOverlay` | `frontend/src/pages/useSequenceEditorWorkspace.js` |
| `active` | Classic preview transport | Quinto subcorte ya hecho en `useClassicPreviewTransport.js`: el hook ya concentra playback core, `slot router`, `jumpVideo(...)`, la sync mounted/idle y también la capa de media source/seek (`buildSequencePreviewMediaSource`, `seekSequencePreviewVideo`, `playSequencePreviewVideo`, `assignSequencePreviewVideoSource`, etc.). En `DashboardPage.jsx` quedan sobre todo remates de wiring con interacción/crop/multipart y algunos efectos que consumen esos helpers. | `playSequenceFromCurrentOrStart`, `stopPlayback`, `syncSecondaryPlayback`, `jumpVideo`, `buildSequencePreviewMediaSource`, `seekSequencePreviewVideo`, `playSequencePreviewVideo`, `syncMountedAuxiliaryPreviewVideos`, `syncIdlePrimaryPreviewVideos`, `videoSlotARef`, `videoSlotBRef`, `primaryVideoSlotRef`, `backdropActiveSlotRef`, `previewBackdrop*`, `splitSecondaryVideoRef` | `frontend/src/pages/useClassicPreviewTransport.js` |
| `active` | Preview and crop interaction | Primer corte ya hecho en `usePreviewInteractionWorkspace.jsx`: el hook ya concentra el estado del preview editable (`previewSnapGuides`, `previewSelectionVisible`, `previewCropModalOpen`, `previewCropTrackingDrawMode`), la coordinación global de pointer drag y los handlers principales de crop/tracking/display mode. Quedan bordes de wiring con multipart, overlays y algunos estados compartidos del preview, pero el grueso del dominio ya salió del page controller. | `handlePreviewSurfacePointerDown`, `handlePreviewScalePointerDown`, `handleOpenCropModal`, `handleApplyCropModal`, `handleCropRectPointerDown`, `handleCropResizePointerDown`, `handleSelectedClipDisplayModeChange`, `renderPreviewSnapGuides`; estado `previewCropModalOpen`, `previewSnapGuides`, `previewSelectionVisible`, `previewCropTrackingDrawMode` | `frontend/src/pages/usePreviewInteractionWorkspace.jsx` |
| `active` | Multipart video transport | Primer corte ya hecho en `useMultipartPreviewTransport.js`: el hook ya es dueño de los `partIndex` del preview fuente/editorial/range-detail, la resolución `global/local` multipart, `seek/playMultipartVideo(...)`, el sync automático de parte activa y el transporte del preview de detalle por rango. Quedan fuera por ahora el scrubbing principal del preview clásico y algunos remates de wiring con `Classic preview transport` y editor preview. | `resolveMultipartPartIndex`, `getMultipartPartAtTime`, `seekMultipartVideo`, `playMultipartVideo`, `handleRangeDetailPreviewToggle`, `handleRangeDetailPreviewScrub`; estado `sequencePreviewPartIndex`, `sourcePreviewPartIndex`, `rangeDetailPreviewPartIndex`, `rangeDetailPreviewPlayback` | `frontend/src/pages/useMultipartPreviewTransport.js` |
| `keep` | Final orchestration layer | Conecta dominios, pasa props a componentes, decide layout visible y resuelve cruces entre shell, editor, sugeridas, preview y export. | composición JSX, selección de paneles, wiring entre hooks, memos derivados multi-dominio | `frontend/src/pages/DashboardPage.jsx` |

## Function Catalog By Area

### 1. Editorial Agent Workflow

- Abre y cierra el workspace editorial y recompone el contexto de revisión.
- Controla preview editorial, review index, decisions map y expansión de rango.
- Aprueba, descarta o convierte candidatas en secuencias utilizables.
- Archivo destino: `frontend/src/pages/useEditorialAgentWorkflow.js`.

### 1.a. Editorial Range Selection

- Ya extraído como submódulo del flujo editorial.
- Es dueño del modal de ampliación de rango, sus párrafos disponibles, la selección por drag y el cálculo de candidatos compartidos.
- Archivo actual: `frontend/src/pages/useEditorialRangeSelection.js`.

### 1.b. Editorial Preview Transport

- Ya extraído como submódulo del flujo editorial.
- Es dueño del transporte del preview editorial, refs de video, progreso por bloque y continuidad multipart entre partes de fuente.
- Archivo actual: `frontend/src/pages/useEditorialAgentPreview.js`.

### 2. Project Transcription Workflow

- Lanza y monitorea transcripción backend.
- Coordina pause, cancel, resume y sincroniza estado con `bootstrap` cuando corresponde.
- Ya extraído. Mantiene separado el workflow operativo de la sesión local del modal (`useTranscriptionModalSession.js`).
- Archivo actual: `frontend/src/pages/useProjectTranscriptionWorkflow.js`.

### 3. Project Intake Workflow

- Sube archivos, crea proyectos, hace append de nuevas partes y dispara preparación inicial.
- Ya extraído: `useProjectIntakeWorkflow.js` concentra los handlers operativos y exporta `useProjectIntakeState(...)` para el estado transitorio del intake.
- Archivo actual: `frontend/src/pages/useProjectIntakeWorkflow.js`.

### 4. Sequence Editor Workspace

- Controla el editor clásico: selección, split, merge, trim, timeline zoom, drag y teclado.
- Primer corte ya hecho en `useSequenceEditorWorkspace.js`: estado base del timeline/editor (`selectedTimelineBlockId`, `presentedPlaybackBlockId`, `timelineZoom`, viewport/scroll, overlay y flags de drag/reorder) más los helpers `updateTimelineOverlay(...)`, `updateTimelineZoom(...)` y `handleTimelineZoomSliderChange(...)`.
- Segundo corte ya hecho en el mismo hook: `handleTimelinePointerDown(...)`, `handleTimelineWheel(...)` y `handleTimelineClipSelect(...)`, usando getters diferidos para evitar TDZ con `derivedBlocks`, `sequenceDurationMs` y `effectiveTimelineZoom`.
- Tercer corte ya hecho en el mismo hook: `handleDeleteSelectedTimelineBlock(...)`, `handleMergeBlocks(...)` y `handleTrimHandlePointerDown(...)`, con getters diferidos adicionales para `pushUndoSnapshot`, `activeSequence`, selección activa y contexto editorial.
- Cuarto corte ya hecho en el mismo hook: `handleSplitAtPlayhead(...)`, `handlePreciseSplitAtPlayhead(...)`, `handleVisualOnlySplitAtPlayhead(...)` y `handleSplitAtPlayheadWithMode(...)`.
- Quinto corte ya hecho en el mismo hook: `selectTimelineBlockByIndex(...)`, `moveSelectedTimelineBlockByOffset(...)`, `adjustSelectedTimelineBlockBoundaryByWord(...)`, `handleTranscriptBoundaryArrowShortcut(...)` y `handleTimelineArrowShortcut(...)`.
- Siguiente frontera recomendada: empezar `useClassicPreviewTransport.js`; el `Sequence editor workspace` ya dejó de ser el cuello principal.
- Es el bloque más grande del editor luego del flujo editorial.
- Archivo destino: `frontend/src/pages/useSequenceEditorWorkspace.js`.

### 5. Preview and Crop Interaction

- Primer corte ya extraído: `usePreviewInteractionWorkspace.jsx` ya contiene el estado del preview editable, la coordinación global de pointer drag y los handlers principales de crop/tracking/display mode.
- Sigue activo porque aún quedan bordes de wiring con multipart, overlays y algunos estados compartidos del preview.
- Archivo actual: `frontend/src/pages/usePreviewInteractionWorkspace.jsx`.

### 6. Classic Preview Transport

- Ya contiene cinco capas extraídas: playback core, `slot router`, `jumpVideo(...)`, sync mounted/idle y la capa de media source/seek del preview clásico.
- Sigue activo solo por remates de wiring final con interacción/crop/multipart; ya no es el mayor cuello del plan.
- Archivo actual: `frontend/src/pages/useClassicPreviewTransport.js`.

### 7. Multipart Preview Transport

- Primer corte ya hecho: `useMultipartPreviewTransport.js` ya concentra los `partIndex` del preview multipart, la resolución `global/local`, `seek/playMultipartVideo(...)` y el transporte de `range detail preview`.
- Sigue activo porque el scrubbing principal del preview clásico y parte del wiring con `Classic preview transport` aún viven en `DashboardPage.jsx`.
- Archivo actual: `frontend/src/pages/useMultipartPreviewTransport.js`.

## Recommended Extraction Order

1. `usePreviewInteractionWorkspace.jsx` (cerrar wiring restante y bordes compartidos del preview)
2. `useMultipartPreviewTransport.js` (mover scrubbing principal y remates de continuity)
3. Remates finales de `useClassicPreviewTransport.js` dentro de `DashboardPage.jsx` si siguen valiendo el coste

## Exit Criteria

- `DashboardPage.jsx` conserva composición, wiring y derivaciones multi-dominio.
- Cada hook nuevo es dueño de un subdominio completo con su estado y handlers.
- Ningún helper o handler vuelve inline si ya tiene owner definido en este mapa.