--- phase: 02-data-persistence-file-management plan: "02" type: execute wave: 1 depends_on: [] files_modified: - src/app.py - src/templates/files.html autonomous: true requirements: - FILE-03 - FILE-05 must_haves: truths: - "User can navigate file list (scroll up/down) to find specific files" - "User can generate tidEDA formatted files for data transmission" artifacts: - path: "src/app.py" provides: "tidEDA export API endpoint" exports: ["POST /api/files/export"] - path: "src/templates/files.html" provides: "Scroll navigation and export functionality" key_links: - from: "src/templates/files.html" to: "/api/files/export" via: "fetch POST" pattern: "fetch.*api/files/export" --- Add scroll navigation to file list and tidEDA export functionality. @./.planning/phases/02-data-persistence-file-management/02-CONTEXT.md @./.planning/phases/02-data-persistence-file-management/02-RESEARCH.md @./.planning/phases/02-data-persistence-file-management/02-01-PLAN.md @./src/app.py task 1: Add scroll navigation to file list src/templates/files.html Enhance src/templates/files.html with scroll navigation: 1. If file list exceeds viewport: - Enable native scroll (overflow-y: auto) - Or add pagination controls (Previous/Next buttons) 2. For touch-optimized scrolling on 7" display: - Ensure smooth scrolling with -webkit-overflow-scrolling: touch - Minimum touch target size: 48px for all interactive elements 3. Add file count display: - "Showing X of Y files" - Update after scroll/filter 4. Optional enhancements: - Sort by date (newest first) - Filter by filename search - These are "OpenCode's Discretion" - implement if straightforward The key requirement is FILE-03: User can navigate file list (scroll up/down) to find specific files. Test by loading files page with multiple files and verifying scroll works User can scroll through file list to find specific files task 2: Add tidEDA export API endpoint src/app.py Add POST /api/files/export endpoint to src/app.py: ```python @app.route('/api/files/export', methods=['POST']) def api_files_export(): """Generate tidEDA formatted export from CSV file""" data = request.get_json() or {} filename = data.get('filename') if not filename: return jsonify({"error": "filename required"}), 400 # Validate filename (security: prevent path traversal) if '..' in filename or '/' in filename or '\\' in filename: return jsonify({"error": "invalid filename"}), 400 # Ensure .csv extension if not filename.endswith('.csv'): filename = filename + '.csv' # Read the CSV file file_path = os.path.join(LOGGER_DIR, filename) if not os.path.exists(file_path): return jsonify({"error": "file not found"}), 404 # Generate tidEDA format # Structure: # $STATION,{station_id} # $DATETIME,{timestamp} # $DATA # {original_csv_content} # $END settings = load_settings() station_id = settings.get("station", {}).get("id", "UNKNOWN") with open(file_path, 'r') as f: csv_content = f.read() tideda_content = f"$STATION,{station_id}\n" tideda_content += f"$DATETIME,{datetime.now().isoformat()}\n" tideda_content += "$DATA\n" tideda_content += csv_content tideda_content += "$END\n" return jsonify({ "filename": filename.replace('.csv', '.tideda'), "content": tideda_content, "format": "tidEDA v1.0" }) ``` Add LOGGER_DIR constant at top of file: ```python LOGGER_DIR = os.path.join(os.path.dirname(__file__), 'data', 'logger') os.makedirs(LOGGER_DIR, exist_ok=True) ``` curl -s -X POST -H "Content-Type: application/json" -d '{"filename":"test.csv"}' http://localhost:8080/api/files/export API returns tidEDA formatted content with $STATION, $DATETIME, $DATA, $END structure task 3: Add export button to files UI src/templates/files.html Enhance src/templates/files.html with export functionality: 1. Add "Export" button next to each file or as a bulk action: - Button with download icon - Calls POST /api/files/export 2. Handle export response: - Receive tidEDA formatted content - Trigger browser download as .tideda file 3. Add JavaScript download helper: ```javascript function downloadFile(filename, content) { const blob = new Blob([content], {type: 'text/plain'}); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; a.click(); URL.revokeObjectURL(url); } ``` 4. Add "Generate tidEDA" button at top of page for exporting selected/all files This satisfies FILE-05: User can generate tidEDA formatted files for data transmission. Verify export button exists in UI and triggers download User can generate and download tidEDA formatted files - Scroll navigation works smoothly - tidEDA export generates correct format - Download works in browser User can navigate file list with scrolling and generate tidEDA formatted files for transmission After completion, create `.planning/phases/02-data-persistence-file-management/02-02-SUMMARY.md`