# lilian1 (FRANK-AI) Code Extraction Plan **Date:** 2025-10-19 **Purpose:** Extract clean, production-ready code from lilian1 prototype; discard experimental Frank-AI features **Target:** NaviDocs MVP with Meilisearch-inspired design --- ## Executive Summary lilian1 is a working boat manual assistant prototype called "FRANK-AI" with: - **Total size:** 2794 lines of JavaScript (7 files) - **Clean code:** ~940 lines worth extracting - **Frank-AI junk:** ~1850 lines to discard - **Documentation:** 56+ experimental markdown files to discard ### Key Decision: What to Extract vs Discard | Category | Extract | Discard | Reason | |----------|---------|---------|--------| | Manual management | ✅ | | Core upload/job polling logic is solid | | Figure zoom | ✅ | | Excellent UX, accessibility-first, production-ready | | Service worker | ✅ | | PWA pattern is valuable for offline boat manuals | | Quiz system | | ❌ | Gamification - not in NaviDocs MVP scope | | Persona system | | ❌ | AI personality - not needed | | Gamification | | ❌ | Points/achievements - not in MVP scope | | Debug overlay | | ❌ | Development tool - replace with proper logging | --- ## Files to Extract ### 1. app/js/manuals.js (451 lines) **What it does:** - Upload PDF to backend - Poll job status with progress tracking - Catalog loading (manuals list) - Modal controls for upload UI - Toast notifications **Clean patterns to port to Vue:** ```javascript // Job polling pattern (lines 288-322) async function startPolling(jobId) { pollInterval = setInterval(async () => { const response = await fetch(`${apiBase}/api/manuals/jobs/${jobId}`); const data = await response.json(); updateJobStatus(data); if (data.status === 'completed' || data.status === 'failed') { clearInterval(pollInterval); } }, 2000); } ``` **Port to NaviDocs as:** - `client/src/components/UploadModal.vue` - Upload UI - `client/src/composables/useJobPolling.js` - Polling logic - `client/src/composables/useManualsCatalog.js` - Catalog state **Discard:** - Line 184: `ingestFromUrl()` - Claude CLI integration (not in MVP) - Line 134: `findManuals()` - Claude search (replace with Meilisearch) --- ### 2. app/js/figure-zoom.js (299 lines) **What it does:** - Pan/zoom for PDF page images - Mouse wheel, drag, touch pinch controls - Keyboard shortcuts (+, -, 0) - Accessibility (aria-labels, prefers-reduced-motion) - Premium UX (spring easing) **This is EXCELLENT code - port as-is to Vue:** - `client/src/components/FigureZoom.vue` - Wrap in Vue component - Keep all logic: updateTransform, bindMouseEvents, bindTouchEvents - Keep accessibility features **Why it's good:** - Respects `prefers-reduced-motion` - Proper event cleanup - Touch support for mobile - Smooth animations with cubic-bezier easing --- ### 3. app/service-worker.js (192 lines) **What it does:** - PWA offline caching - Precache critical files (index.html, CSS, JS, data files) - Cache-first strategy for data, network-first for HTML - Background sync hooks (future) - Push notification hooks (future) **Port to NaviDocs as:** - `client/public/service-worker.js` - Adapt for Vue/Vite build - Update PRECACHE_URLS to match Vite build output - Keep cache-first strategy for manuals (important for boats with poor connectivity) **Changes needed:** ```javascript // OLD: FRANK-AI hardcoded paths const PRECACHE_URLS = ['/index.html', '/css/app.css', ...]; // NEW: Vite build output (generated from manifest) const PRECACHE_URLS = [ '/', '/assets/index-[hash].js', '/assets/index-[hash].css', '/data/manuals.json' ]; ``` --- ### 4. data/glossary.json (184 lines) **What it is:** - Boat manual terminology index - Maps terms to page numbers - Examples: "Bilge", "Blackwater", "Windlass", "Galley", "Seacock" **How to use:** - Extract unique terms - Add to Meilisearch synonyms config (we already have 40+, this adds more) - Use for autocomplete suggestions in search bar **Example extraction:** ```javascript // Terms we don't have yet in meilisearch-config.json: "seacock": ["through-hull", "thru-hull"], // ✅ Already have "demister": ["defroster", "windscreen demister"], // ➕ Add "reboarding": ["ladder", "swim platform"], // ➕ Add "mooring": ["docking", "tie-up"], // ➕ Add ``` --- ## Files to Discard ### Gamification / AI Persona (Frank-AI Experiments) | File | Lines | Reason to Discard | |------|-------|-------------------| | app/js/quiz.js | 209 | Quiz game - not in MVP scope | | app/js/persona.js | 209 | AI personality system - not needed | | app/js/gamification.js | 304 | Points/badges/achievements - not in MVP | | app/js/debug-overlay.js | ~100 | Dev tool - replace with proper logging | **Total discarded:** ~820 lines --- ### Documentation Files (56+ files to discard) All files starting with: - `CLAUDE_SUPERPROMPT_*.md` (8 files) - AI experiment prompts - `FRANK_AI_*.md` (3 files) - Frank-AI specific docs - `FIGURE_*.md` (6 files) - Figure implementation docs (interesting but not needed) - `TEST_*.md` (8 files) - Test reports (good to read, but don't copy) - `*_REPORT.md` (12 files) - Sprint reports - `*_SUMMARY.md` (10 files) - Session summaries - `SECURITY-*.md` (3 files) - Security audits (good insights, already captured in hardened-production-guide.md) - `UX-*.md` (3 files) - UX reviews **Keep for reference (read but don't copy):** - `README.md` - Understand the project - `CHANGES.md` - What was changed over time - `DEMO_ACCESS.txt` - How to run lilian1 **Total:** ~1200 lines of markdown to discard --- ## Migration Strategy ### Phase 1: Bootstrap NaviDocs Structure ```bash cd ~/navidocs # Create directories mkdir -p server/{routes,services,workers,db,config} mkdir -p client/{src/{components,composables,views,stores,assets},public} # Initialize package.json files ``` **server/package.json:** ```json { "name": "navidocs-server", "version": "1.0.0", "type": "module", "dependencies": { "express": "^5.0.0", "better-sqlite3": "^11.0.0", "meilisearch": "^0.41.0", "bullmq": "^5.0.0", "helmet": "^7.0.0", "express-rate-limit": "^7.0.0", "tesseract.js": "^5.0.0", "uuid": "^10.0.0", "bcrypt": "^5.1.0", "jsonwebtoken": "^9.0.0" } } ``` **client/package.json:** ```json { "name": "navidocs-client", "version": "1.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { "vue": "^3.5.0", "vue-router": "^4.4.0", "pinia": "^2.2.0", "pdfjs-dist": "^4.0.0" }, "devDependencies": { "@vitejs/plugin-vue": "^5.0.0", "vite": "^5.0.0", "tailwindcss": "^3.4.0", "autoprefixer": "^10.4.0", "postcss": "^8.4.0" } } ``` --- ### Phase 2: Port Clean Code #### Step 1: Figure Zoom Component **From:** lilian1/app/js/figure-zoom.js **To:** navidocs/client/src/components/FigureZoom.vue **Changes:** - Wrap in Vue component - Use Vue refs for state (`scale`, `translateX`, `translateY`) - Use Vue lifecycle hooks (`onMounted`, `onUnmounted`) - Keep all UX logic identical **Implementation:** ```vue + − ⟲ {{ Math.round(scale * 100) }}% ``` #### Step 2: Upload Modal Component **From:** lilian1/app/js/manuals.js (lines 228-263) **To:** navidocs/client/src/components/UploadModal.vue **Changes:** - Replace vanilla DOM manipulation with Vue reactivity - Use `