# PROJECT_PLAN.md — eng-pad Implementation Steps This file tracks all implementation steps. Check off steps as they are completed and log them in PROGRESS.md. ## Phase 0: Project Documents - [x] 0.1: Create DESIGN.md - [x] 0.2: Create PROJECT_PLAN.md (this file) - [x] 0.3: Create PROGRESS.md - [x] 0.4: Update CLAUDE.md with build commands and source tree ## Phase 1: Project Skeleton + Data Layer - [x] 1.1: Generate Android project with Gradle - `build.gradle.kts` (root), `app/build.gradle.kts`, `settings.gradle.kts` - Kotlin, Compose, Room KSP, minSdk 30, compileSdk/targetSdk 36 - [x] 1.2: Configure `gradle/libs.versions.toml` version catalog - Compose BOM, Room, Navigation, Lifecycle, Coroutines - [x] 1.3: Configure linting (`app/build.gradle.kts` Android Lint config) - [x] 1.4: Define Room entities - `data/model/Notebook.kt`, `Page.kt`, `Stroke.kt`, `PageSize.kt` - [x] 1.5: Implement type converters - `data/db/Converters.kt` — `FloatArray` <-> `ByteArray` - [x] 1.6: Define DAOs - `data/db/NotebookDao.kt`, `PageDao.kt`, `StrokeDao.kt` - [x] 1.7: Define Room database - `data/db/EngPadDatabase.kt` - [x] 1.8: Implement repositories - `data/repository/NotebookRepository.kt`, `PageRepository.kt` - [x] 1.9: Unit tests - `test/.../data/StrokeBlobTest.kt` — blob roundtrip - `test/.../data/PageSizeTest.kt` — page size enum - **Verify:** `./gradlew build` — PASSED (build + test + lint) ## Phase 2: Notebook List Screen - [x] 2.1: Set up `MainActivity` with Compose and `NavHost` - `MainActivity.kt`, `ui/navigation/NavGraph.kt`, `ui/theme/Theme.kt` - [x] 2.2: Implement `NotebookListViewModel` - `ui/notebooks/NotebookListViewModel.kt` - [x] 2.3: Implement `NotebookListScreen` - `ui/notebooks/NotebookListScreen.kt` — list, create dialog, delete confirmation - [x] 2.4: Auto-create page 1 on notebook creation - In `NotebookRepository.create()` - [x] 2.5: Navigation: tap notebook -> page list (stub screen) - **Verify:** `./gradlew build` — PASSED (build + test + lint) ## Phase 3: Canvas — Basic Drawing - [x] 3.1: Implement `PadCanvasView` — stylus event handling - `ui/editor/PadCanvasView.kt` — `onTouchEvent`, `getHistoricalX/Y` - [x] 3.2: Stroke rendering — `Path`/`Paint`, backing bitmap (screen resolution) - [x] 3.3: Grid drawing — 60pt spacing, drawn on screen only - [x] 3.4: Coordinate transform — canonical <-> screen via `Matrix` - [x] 3.5: Implement `CanvasState` - `ui/editor/CanvasState.kt` — zoom, pan, active tool, pen sizes, line styles - [x] 3.6: Implement `EditorViewModel` - `ui/editor/EditorViewModel.kt` — load/save strokes from Room - [x] 3.7: Implement `EditorScreen` + toolbar - `ui/editor/EditorScreen.kt`, `ui/editor/Toolbar.kt` - [x] 3.8: Wire navigation — notebook list -> pages -> editor (pages auto-navigates to first page) - **Verify:** `./gradlew build` — PASSED (build + test + lint). Manual on-device test pending. ## Phase 4: Zoom and Pan - [x] 4.1: `ScaleGestureDetector` for pinch-to-zoom (0.5x-4x) with focal-point zoom - [x] 4.2: Finger drag for pan with pointer tracking - [x] 4.3: Input routing — `TOOL_TYPE_STYLUS` -> draw, `TOOL_TYPE_FINGER` -> zoom/pan - **Verify:** `./gradlew build` — PASSED. Manual on-device test pending. ## Phase 5: Eraser - [x] 5.1: Eraser mode in `CanvasState` (already defined in Phase 3) - [x] 5.2: Hit testing — bounding box pre-filter (expanded by 42pt radius) - [x] 5.3: Stroke deletion + backing bitmap rebuild + DB sync - **Verify:** `./gradlew build` — PASSED. Manual test pending. ## Phase 6: Undo/Redo - [x] 6.1: `UndoableAction` interface + `AddStrokeAction`, `DeleteStrokeAction` - `undo/UndoableAction.kt`, `undo/StrokeActions.kt` - [x] 6.2: `UndoManager` — undo/redo stacks, depth 50 - `undo/UndoManager.kt` - [x] 6.3: Integrated with `EditorViewModel` + toolbar (undo/redo buttons) - [x] 6.4: Unit tests — 9 tests in `UndoManagerTest.kt` - **Verify:** `./gradlew build` — PASSED (19 tests total) ## Phase 7: Selection — Move, Copy, Delete - [x] 7.1: Selection mode — rectangle selection via stylus drag - [x] 7.2: Visual feedback — blue highlight on selected strokes, dashed selection rect - [x] 7.3: Operations — delete, drag-to-move, copy (toolbar buttons appear on selection) - [x] 7.4: Undo integration — DeleteMultipleStrokesAction, MoveStrokesAction, CopyStrokesAction - **Verify:** `./gradlew build` — PASSED ## Phase 8: Multi-Page Navigation - [x] 8.1: `PageListScreen` with page grid (aspect-ratio cards) - `ui/pages/PageListScreen.kt`, `PageListViewModel.kt` - [x] 8.2: Add new page FAB - [x] 8.3: NavGraph updated — pages route shows PageListScreen, tap page -> editor - **Verify:** `./gradlew build` — PASSED ## Phase 9: PDF Export - [x] 9.1: `PdfExporter` — Android `PdfDocument` API with 300->72 DPI scaling - `ui/export/PdfExporter.kt` - [x] 9.2: Share via `Intent.ACTION_SEND` + `FileProvider` - `res/xml/file_provider_paths.xml` already configured in Phase 1 - [x] 9.3: Export button (PDF) in editor toolbar - **Verify:** `./gradlew build` — PASSED. Manual PDF verification pending. ## Phase 10: Polish - [x] 10.1: E-ink optimizations — high-contrast theme with black/white/gray palette - [x] 10.2: Auto-save — strokes save on completion (since Phase 3) - [x] 10.3: Empty states (notebook list, page list), delete confirmations (notebooks) - [ ] 10.4: Performance profiling on target devices (requires on-device testing) ## Phase 11: Server Sync Integration - [ ] 11.1: Proto setup — add `protobuf-lite` dependency, generate Kotlin stubs from eng-pad-server proto definitions - [ ] 11.2: Implement `SyncClient` — gRPC client for eng-pad-server (password auth over TLS, notebook/page/stroke push/pull) - [ ] 11.3: Implement `SyncManager` — orchestrates sync operations, conflict resolution (last-write-wins or manual), tracks sync state per notebook - [ ] 11.4: Sync settings UI — server URL, credentials, TLS CA cert configuration screen - [ ] 11.5: Per-notebook sync button — manual sync trigger from editor or page list toolbar - [ ] 11.6: Sync-all — bulk sync from notebook list screen - [ ] 11.7: Status indicators — sync state badges on notebook list items (synced, pending, error) ## Phase 12: Notebook Backup/Export - [ ] 12.1: Define zip format — `notebook_title.engpad.zip` with `notebook.json` metadata and `pages/NNN.json` stroke data - [ ] 12.2: Implement export — serialize notebook + pages + strokes to zip, share via FileProvider + intents - [ ] 12.3: Implement import — parse zip, create notebook + pages + strokes in Room DB - [ ] 12.4: Export-all — single zip containing all notebooks for full backup - [ ] 12.5: UI integration — export/import buttons in notebook list and editor toolbar