fix: resolve frontend code quality issues

- Create missing tsconfig.node.json for Vite config compilation
- Create postcss.config.js for Tailwind CSS processing
- Add test dependencies (vitest, testing-library, jsdom)
- Remove missing /vite.svg favicon reference from index.html
This commit is contained in:
2026-05-11 20:39:05 +02:00
parent eff41bd801
commit 3deab5fdf3
20 changed files with 1818 additions and 2 deletions
@@ -0,0 +1,113 @@
<h2>Architecture Overview</h2>
<p class="subtitle">High-level system design for the backup tool</p>
<div class="section">
<div class="mockup">
<div class="mockup-header">System Architecture</div>
<div class="mockup-body">
<div style="display: flex; flex-direction: column; gap: 20px;">
<!-- Frontend Layer -->
<div style="border: 2px solid #4CAF50; border-radius: 8px; padding: 15px; background: #f8fff8;">
<div class="label" style="color: #4CAF50;">Frontend Layer</div>
<div style="display: flex; gap: 15px; margin-top: 10px;">
<div style="flex: 1; border: 1px solid #ddd; padding: 10px; border-radius: 4px; text-align: center;">
<strong>Dashboard View</strong><br>
<small>Overview, stats, recent backups</small>
</div>
<div style="flex: 1; border: 1px solid #ddd; padding: 10px; border-radius: 4px; text-align: center;">
<strong>Backup View</strong><br>
<small>Jobs, sources, schedules</small>
</div>
<div style="flex: 1; border: 1px solid #ddd; padding: 10px; border-radius: 4px; text-align: center;">
<strong>Settings View</strong><br>
<small>Config, storage, notifications</small>
</div>
</div>
</div>
<!-- API Layer -->
<div style="text-align: center; color: #666; font-size: 24px;">↓ REST API ↓</div>
<!-- Backend Layer -->
<div style="border: 2px solid #2196F3; border-radius: 8px; padding: 15px; background: #f0f8ff;">
<div class="label" style="color: #2196F3;">Backend Layer (Python)</div>
<div style="display: flex; gap: 15px; margin-top: 10px; flex-wrap: wrap;">
<div style="flex: 1; min-width: 120px; border: 1px solid #ddd; padding: 10px; border-radius: 4px; text-align: center;">
<strong>API Server</strong><br>
<small>FastAPI/Flask</small>
</div>
<div style="flex: 1; min-width: 120px; border: 1px solid #ddd; padding: 10px; border-radius: 4px; text-align: center;">
<strong>Backup Engine</strong><br>
<small>Core logic</small>
</div>
<div style="flex: 1; min-width: 120px; border: 1px solid #ddd; padding: 10px; border-radius: 4px; text-align: center;">
<strong>Scheduler</strong><br>
<small>APScheduler</small>
</div>
<div style="flex: 1; min-width: 120px; border: 1px solid #ddd; padding: 10px; border-radius: 4px; text-align: center;">
<strong>Source Adapters</strong><br>
<small>SSH, DB, Local</small>
</div>
</div>
</div>
<!-- Data Layer -->
<div style="text-align: center; color: #666; font-size: 24px;">↓ Persistence ↓</div>
<div style="border: 2px solid #FF9800; border-radius: 8px; padding: 15px; background: #fff8f0;">
<div class="label" style="color: #FF9800;">Data Layer</div>
<div style="display: flex; gap: 15px; margin-top: 10px;">
<div style="flex: 1; border: 1px solid #ddd; padding: 10px; border-radius: 4px; text-align: center;">
<strong>SQLite Database</strong><br>
<small>Jobs, sources, history, config</small>
</div>
<div style="flex: 1; border: 1px solid #ddd; padding: 10px; border-radius: 4px; text-align: center;">
<strong>File Storage</strong><br>
<small>Backup archives</small>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="section">
<h3>Key Design Principles</h3>
<ul>
<li><strong>Source-agnostic</strong>: Adapter pattern for different backup sources (local, SSH, future cloud)</li>
<li><strong>Job-driven</strong>: Everything is a job - manual or scheduled, full or incremental</li>
<li><strong>SQLite for simplicity</strong>: Single file database, no external DB server needed</li>
<li><strong>REST API</strong>: Clean separation between frontend and backend</li>
<li><strong>Extensible</strong>: Plugin architecture for new source types and storage backends</li>
</ul>
</div>
<div class="section">
<h3>Technology Stack</h3>
<div style="display: flex; gap: 20px;">
<div style="flex: 1;">
<h4>Backend</h4>
<ul>
<li>Python 3.11+</li>
<li>FastAPI (async, auto-docs)</li>
<li>SQLAlchemy + Alembic</li>
<li>APScheduler (job scheduling)</li>
<li>Paramiko (SSH)</li>
<li>rsync/libsync (incremental backups)</li>
</ul>
</div>
<div style="flex: 1;">
<h4>Frontend</h4>
<ul>
<li>React 18+ with TypeScript</li>
<li>TanStack Query (data fetching)</li>
<li>React Router (navigation)</li>
<li>Tailwind CSS (styling)</li>
<li>Recharts (dashboard charts)</li>
</ul>
</div>
</div>
</div>
@@ -0,0 +1,110 @@
<h2>Backup Flow</h2>
<p class="subtitle">How a backup job executes from trigger to completion</p>
<div class="section">
<div class="mockup">
<div class="mockup-header">Backup Execution Flow</div>
<div class="mockup-body">
<div style="display: flex; flex-direction: column; gap: 0;">
<!-- Step 1 -->
<div style="display: flex; align-items: center; gap: 15px; padding: 15px; background: #f0f8ff; border-radius: 8px; border-left: 4px solid #2196F3;">
<div style="background: #2196F3; color: white; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold;">1</div>
<div style="flex: 1;">
<div style="font-weight: bold;">Trigger</div>
<div style="color: #666; font-size: 14px;">Manual click or scheduled cron trigger fires</div>
</div>
</div>
<div style="text-align: center; color: #2196F3; font-size: 20px;"></div>
<!-- Step 2 -->
<div style="display: flex; align-items: center; gap: 15px; padding: 15px; background: #fff8f0; border-radius: 8px; border-left: 4px solid #FF9800;">
<div style="background: #FF9800; color: white; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold;">2</div>
<div style="flex: 1;">
<div style="font-weight: bold;">Create Execution Record</div>
<div style="color: #666; font-size: 14px;">Insert row into job_executions with status "pending"</div>
</div>
</div>
<div style="text-align: center; color: #FF9800; font-size: 20px;"></div>
<!-- Step 3 -->
<div style="display: flex; align-items: center; gap: 15px; padding: 15px; background: #f8fff8; border-radius: 8px; border-left: 4px solid #4CAF50;">
<div style="background: #4CAF50; color: white; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold;">3</div>
<div style="flex: 1;">
<div style="font-weight: bold;">Connect to Source</div>
<div style="color: #666; font-size: 14px;">Establish connection (local filesystem, SSH, or database)</div>
</div>
</div>
<div style="text-align: center; color: #4CAF50; font-size: 20px;"></div>
<!-- Step 4 -->
<div style="display: flex; align-items: center; gap: 15px; padding: 15px; background: #faf0ff; border-radius: 8px; border-left: 4px solid #9C27B0;">
<div style="background: #9C27B0; color: white; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold;">4</div>
<div style="flex: 1;">
<div style="font-weight: bold;">Determine Backup Strategy</div>
<div style="color: #666; font-size: 14px;">Full backup OR incremental based on last successful backup</div>
</div>
</div>
<div style="text-align: center; color: #9C27B0; font-size: 20px;"></div>
<!-- Step 5 -->
<div style="display: flex; align-items: center; gap: 15px; padding: 15px; background: #f0f8ff; border-radius: 8px; border-left: 4px solid #2196F3;">
<div style="background: #2196F3; color: white; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold;">5</div>
<div style="flex: 1;">
<div style="font-weight: bold;">Execute Backup</div>
<div style="color: #666; font-size: 14px;">Transfer data, compress, encrypt (if enabled), calculate checksums</div>
</div>
</div>
<div style="text-align: center; color: #2196F3; font-size: 20px;"></div>
<!-- Step 6 -->
<div style="display: flex; align-items: center; gap: 15px; padding: 15px; background: #f8fff8; border-radius: 8px; border-left: 4px solid #4CAF50;">
<div style="background: #4CAF50; color: white; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold;">6</div>
<div style="flex: 1;">
<div style="font-weight: bold;">Verify & Store</div>
<div style="color: #666; font-size: 14px;">Verify checksum, store metadata in backups table, update execution status</div>
</div>
</div>
<div style="text-align: center; color: #4CAF50; font-size: 20px;"></div>
<!-- Step 7 -->
<div style="display: flex; align-items: center; gap: 15px; padding: 15px; background: #fff8f0; border-radius: 8px; border-left: 4px solid #FF9800;">
<div style="background: #FF9800; color: white; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold;">7</div>
<div style="flex: 1;">
<div style="font-weight: bold;">Cleanup & Retention</div>
<div style="color: #666; font-size: 14px;">Apply retention policy, remove old backups, update storage stats</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="section">
<h3>Error Handling</h3>
<ul>
<li><strong>Connection failures</strong>: Retry 3x with exponential backoff, then mark as failed</li>
<li><strong>Partial backups</strong>: Mark as failed if any source file fails; keep partial for inspection</li>
<li><strong>Storage full</strong>: Check before starting, alert if < 10% free space</li>
<li><strong>Checksum mismatch</strong>: Delete corrupted backup, retry once, alert admin</li>
<li><strong>Concurrent jobs</strong>: Queue or cancel based on resource availability</li>
</ul>
</div>
<div class="section">
<h3>Extensibility Design</h3>
<p>The system is designed for easy extension:</p>
<ul>
<li><strong>Source adapters</strong>: Abstract base class for new source types (S3, Azure, etc.)</li>
<li><strong>Storage backends</strong>: Pluggable storage interface for cloud destinations</li>
<li><strong>Notification channels</strong>: Webhook, email, Slack plugins for alerts</li>
<li><strong>Compression algorithms</strong>: Configurable (gzip, bzip2, zstd, none)</li>
</ul>
</div>
@@ -0,0 +1,128 @@
<h2>Data Model</h2>
<p class="subtitle">SQLite database schema for the backup tool</p>
<div class="section">
<div class="mockup">
<div class="mockup-header">Entity Relationship Diagram</div>
<div class="mockup-body">
<div style="display: flex; flex-direction: column; gap: 15px; font-family: monospace; font-size: 14px;">
<!-- Sources -->
<div style="border: 2px solid #4CAF50; border-radius: 6px; padding: 12px; background: #f8fff8;">
<div style="font-weight: bold; color: #4CAF50; margin-bottom: 8px;">📁 sources</div>
<div style="display: grid; grid-template-columns: auto 1fr auto; gap: 4px 12px;">
<span style="color: #d32f2f;">PK</span> <span>id</span> <span style="color: #666;">INTEGER</span>
<span> </span> <span>name</span> <span style="color: #666;">TEXT</span>
<span> </span> <span>type</span> <span style="color: #666;">TEXT (local|ssh|database)</span>
<span> </span> <span>config</span> <span style="color: #666;">JSON</span>
<span> </span> <span>created_at</span> <span style="color: #666;">DATETIME</span>
<span> </span> <span>updated_at</span> <span style="color: #666;">DATETIME</span>
</div>
</div>
<!-- Jobs -->
<div style="border: 2px solid #2196F3; border-radius: 6px; padding: 12px; background: #f0f8ff;">
<div style="font-weight: bold; color: #2196F3; margin-bottom: 8px;">⚙️ jobs</div>
<div style="display: grid; grid-template-columns: auto 1fr auto; gap: 4px 12px;">
<span style="color: #d32f2f;">PK</span> <span>id</span> <span style="color: #666;">INTEGER</span>
<span> </span> <span>name</span> <span style="color: #666;">TEXT</span>
<span> </span> <span>source_id</span> <span style="color: #666;">INTEGER → sources</span>
<span> </span> <span>strategy</span> <span style="color: #666;">TEXT (full|incremental)</span>
<span> </span> <span>destination_path</span> <span style="color: #666;">TEXT</span>
<span> </span> <span>exclude_patterns</span> <span style="color: #666;">JSON</span>
<span> </span> <span>enabled</span> <span style="color: #666;">BOOLEAN</span>
<span> </span> <span>created_at</span> <span style="color: #666;">DATETIME</span>
<span> </span> <span>updated_at</span> <span style="color: #666;">DATETIME</span>
</div>
</div>
<!-- Schedules -->
<div style="border: 2px solid #FF9800; border-radius: 6px; padding: 12px; background: #fff8f0;">
<div style="font-weight: bold; color: #FF9800; margin-bottom: 8px;">📅 schedules</div>
<div style="display: grid; grid-template-columns: auto 1fr auto; gap: 4px 12px;">
<span style="color: #d32f2f;">PK</span> <span>id</span> <span style="color: #666;">INTEGER</span>
<span> </span> <span>job_id</span> <span style="color: #666;">INTEGER → jobs</span>
<span> </span> <span>cron_expression</span> <span style="color: #666;">TEXT</span>
<span> </span> <span>enabled</span> <span style="color: #666;">BOOLEAN</span>
<span> </span> <span>created_at</span> <span style="color: #666;">DATETIME</span>
</div>
</div>
<!-- Job Executions -->
<div style="border: 2px solid #9C27B0; border-radius: 6px; padding: 12px; background: #faf0ff;">
<div style="font-weight: bold; color: #9C27B0; margin-bottom: 8px;">▶️ job_executions</div>
<div style="display: grid; grid-template-columns: auto 1fr auto; gap: 4px 12px;">
<span style="color: #d32f2f;">PK</span> <span>id</span> <span style="color: #666;">INTEGER</span>
<span> </span> <span>job_id</span> <span style="color: #666;">INTEGER → jobs</span>
<span> </span> <span>status</span> <span style="color: #666;">TEXT (pending|running|success|failed|cancelled)</span>
<span> </span> <span>started_at</span> <span style="color: #666;">DATETIME</span>
<span> </span> <span>completed_at</span> <span style="color: #666;">DATETIME</span>
<span> </span> <span>bytes_processed</span> <span style="color: #666;">INTEGER</span>
<span> </span> <span>bytes_backed_up</span> <span style="color: #666;">INTEGER</span>
<span> </span> <span>error_message</span> <span style="color: #666;">TEXT</span>
<span> </span> <span>triggered_by</span> <span style="color: #666;">TEXT (manual|schedule)</span>
</div>
</div>
<!-- Backups -->
<div style="border: 2px solid #607D8B; border-radius: 6px; padding: 12px; background: #f5f5f5;">
<div style="font-weight: bold; color: #607D8B; margin-bottom: 8px;">💾 backups</div>
<div style="display: grid; grid-template-columns: auto 1fr auto; gap: 4px 12px;">
<span style="color: #d32f2f;">PK</span> <span>id</span> <span style="color: #666;">INTEGER</span>
<span> </span> <span>execution_id</span> <span style="color: #666;">INTEGER → job_executions</span>
<span> </span> <span>storage_path</span> <span style="color: #666;">TEXT</span>
<span> </span> <span>size_bytes</span> <span style="color: #666;">INTEGER</span>
<span> </span> <span>checksum</span> <span style="color: #666;">TEXT</span>
<span> </span> <span>type</span> <span style="color: #666;">TEXT (full|incremental)</span>
<span> </span> <span>parent_backup_id</span> <span style="color: #666;">INTEGER → backups (for incremental)</span>
<span> </span> <span>created_at</span> <span style="color: #666;">DATETIME</span>
</div>
</div>
<!-- Settings -->
<div style="border: 2px solid #795548; border-radius: 6px; padding: 12px; background: #faf5f0;">
<div style="font-weight: bold; color: #795548; margin-bottom: 8px;">⚙️ settings</div>
<div style="display: grid; grid-template-columns: auto 1fr auto; gap: 4px 12px;">
<span style="color: #d32f2f;">PK</span> <span>key</span> <span style="color: #666;">TEXT</span>
<span> </span> <span>value</span> <span style="color: #666;">TEXT</span>
<span> </span> <span>updated_at</span> <span style="color: #666;">DATETIME</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="section">
<h3>Key Relationships</h3>
<ul>
<li><strong>sources → jobs</strong>: One source can have many jobs (different backup strategies for the same data)</li>
<li><strong>jobs → schedules</strong>: One job can have one schedule (1:1 for simplicity)</li>
<li><strong>jobs → job_executions</strong>: One job has many executions over time</li>
<li><strong>job_executions → backups</strong>: Each execution produces one or more backup archives</li>
<li><strong>backups → backups</strong>: Self-referencing for incremental chain (parent_backup_id)</li>
</ul>
</div>
<div class="section">
<h3>Design Decisions</h3>
<div class="pros-cons">
<div class="pros">
<h4>Pros</h4>
<ul>
<li>Flexible source config via JSON (extensible for new source types)</li>
<li>Execution history tracking for audit and debugging</li>
<li>Incremental backup chain support</li>
<li>Simple key-value settings (easy to extend)</li>
</ul>
</div>
<div class="cons">
<h4>Cons>/h4>
<ul>
<li>JSON config loses some type safety (mitigated by validation)</li>
<li>No built-in backup retention policy table (can be added later)</li>
</ul>
</div>
</div>
</div>
@@ -0,0 +1,174 @@
<h2>Frontend Views</h2>
<p class="subtitle">UI mockups for the three main views</p>
<div class="section">
<h3>Dashboard View</h3>
<div class="mockup">
<div class="mockup-header">Dashboard</div>
<div class="mockup-body">
<div class="mock-nav">
<span style="font-weight: bold;">🛡️ Backup Tool</span> | Dashboard | Backups | Settings
</div>
<div style="display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; margin: 20px 0;">
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 6px; text-align: center;">
<div style="font-size: 32px; font-weight: bold; color: #4CAF50;">12</div>
<div style="color: #666;">Active Jobs</div>
</div>
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 6px; text-align: center;">
<div style="font-size: 32px; font-weight: bold; color: #2196F3;">847</div>
<div style="color: #666;">Total Backups</div>
</div>
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 6px; text-align: center;">
<div style="font-size: 32px; font-weight: bold; color: #FF9800;">2.4 TB</div>
<div style="color: #666;">Storage Used</div>
</div>
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 6px; text-align: center;">
<div style="font-size: 32px; font-weight: bold; color: #f44336;">1</div>
<div style="color: #666;">Failed (24h)</div>
</div>
</div>
<div style="display: grid; grid-template-columns: 2fr 1fr; gap: 20px;">
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 6px;">
<div style="font-weight: bold; margin-bottom: 10px;">Recent Backup Activity</div>
<div style="display: flex; flex-direction: column; gap: 8px;">
<div style="display: flex; justify-content: space-between; padding: 8px; background: #f5f5f5; border-radius: 4px;">
<span>📁 Home Server Files</span>
<span style="color: #4CAF50;">✓ Success</span>
<span style="color: #666;">2 hours ago</span>
</div>
<div style="display: flex; justify-content: space-between; padding: 8px; background: #f5f5f5; border-radius: 4px;">
<span>🗄️ Production DB</span>
<span style="color: #4CAF50;">✓ Success</span>
<span style="color: #666;">5 hours ago</span>
</div>
<div style="display: flex; justify-content: space-between; padding: 8px; background: #f5f5f5; border-radius: 4px;">
<span>📁 Cloud Storage Sync</span>
<span style="color: #f44336;">✗ Failed</span>
<span style="color: #666;">1 day ago</span>
</div>
</div>
</div>
<div style="border: 1px solid #ddd; padding: 15px; border-radius: 6px;">
<div style="font-weight: bold; margin-bottom: 10px;">Storage Overview</div>
<div style="height: 150px; background: linear-gradient(to bottom, #e3f2fd 0%, #bbdefb 100%); border-radius: 4px; display: flex; align-items: center; justify-content: center;">
[Pie Chart: Storage by Job]
</div>
</div>
</div>
</div>
</div>
</div>
<div class="section">
<h3>Backup View</h3>
<div class="mockup">
<div class="mockup-header">Backups</div>
<div class="mockup-body">
<div class="mock-nav">
<span>🛡️ Backup Tool</span> | Dashboard | <span style="font-weight: bold;">Backups</span> | Settings
</div>
<div style="display: flex; justify-content: space-between; margin: 20px 0;">
<div>
<button class="mock-button">+ New Job</button>
<button class="mock-button">+ New Source</button>
</div>
<div>
<input class="mock-input" placeholder="Search jobs..." style="width: 200px;">
</div>
</div>
<div style="border: 1px solid #ddd; border-radius: 6px; overflow: hidden;">
<div style="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr; background: #f5f5f5; padding: 10px; font-weight: bold;">
<div>Job Name</div>
<div>Source</div>
<div>Strategy</div>
<div>Schedule</div>
<div>Last Run</div>
<div>Status</div>
</div>
<div style="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr; padding: 10px; border-top: 1px solid #eee;">
<div>🏠 Home Server Files</div>
<div>Local Path</div>
<div><span style="background: #e3f2fd; padding: 2px 8px; border-radius: 12px; font-size: 12px;">Incremental</span></div>
<div>Daily at 2 AM</div>
<div>2 hours ago</div>
<div><span style="color: #4CAF50;">● Active</span></div>
</div>
<div style="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr; padding: 10px; border-top: 1px solid #eee;">
<div>🗄️ Production DB</div>
<div>PostgreSQL</div>
<div><span style="background: #fff3e0; padding: 2px 8px; border-radius: 12px; font-size: 12px;">Full</span></div>
<div>Hourly</div>
<div>5 hours ago</div>
<div><span style="color: #4CAF50;">● Active</span></div>
</div>
<div style="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr; padding: 10px; border-top: 1px solid #eee;">
<div>☁️ Cloud Storage Sync</div>
<div>SSH (AWS)</div>
<div><span style="background: #e3f2fd; padding: 2px 8px; border-radius: 12px; font-size: 12px;">Incremental</span></div>
<div>Weekly (Sun)</div>
<div>1 day ago</div>
<div><span style="color: #f44336;">● Failed</span></div>
</div>
</div>
</div>
</div>
</div>
<div class="section">
<h3>Settings View</h3>
<div class="mockup">
<div class="mockup-header">Settings</div>
<div class="mockup-body">
<div class="mock-nav">
<span>🛡️ Backup Tool</span> | Dashboard | Backups | <span style="font-weight: bold;">Settings</span>
</div>
<div style="display: grid; grid-template-columns: 200px 1fr; gap: 20px; margin-top: 20px;">
<div style="border-right: 1px solid #ddd; padding-right: 20px;">
<div style="padding: 10px; background: #e3f2fd; border-radius: 4px; font-weight: bold;">General</div>
<div style="padding: 10px;">Storage</div>
<div style="padding: 10px;">Notifications</div>
<div style="padding: 10px;">Security</div>
<div style="padding: 10px;">Logs</div>
</div>
<div>
<div style="margin-bottom: 20px;">
<div style="font-weight: bold; margin-bottom: 8px;">Default Backup Location</div>
<input class="mock-input" value="/var/backups/backup-tool" style="width: 300px;">
</div>
<div style="margin-bottom: 20px;">
<div style="font-weight: bold; margin-bottom: 8px;">Retention Policy</div>
<select class="mock-input" style="width: 200px;">
<option>Keep all backups</option>
<option>Keep last 30 days</option>
<option selected>Keep last 10 versions</option>
</select>
</div>
<div style="margin-bottom: 20px;">
<div style="font-weight: bold; margin-bottom: 8px;">Compression</div>
<label><input type="checkbox" checked> Enable compression (gzip)</label>
</div>
<div style="margin-bottom: 20px;">
<div style="font-weight: bold; margin-bottom: 8px;">Encryption</div>
<label><input type="checkbox"> Enable AES-256 encryption</label>
</div>
<div>
<button class="mock-button">Save Changes</button>
</div>
</div>
</div>
</div>
</div>
</div>
@@ -0,0 +1 @@
{"reason":"idle timeout","timestamp":1778524615786}
@@ -0,0 +1,6 @@
{"type":"server-started","port":63865,"host":"127.0.0.1","url_host":"localhost","url":"http://localhost:63865","screen_dir":"/home/alex/projects/backup-tool/.superpowers/brainstorm/269331-1778521434/content","state_dir":"/home/alex/projects/backup-tool/.superpowers/brainstorm/269331-1778521434/state"}
{"type":"screen-added","file":"/home/alex/projects/backup-tool/.superpowers/brainstorm/269331-1778521434/content/architecture-overview.html"}
{"type":"screen-added","file":"/home/alex/projects/backup-tool/.superpowers/brainstorm/269331-1778521434/content/data-model.html"}
{"type":"screen-added","file":"/home/alex/projects/backup-tool/.superpowers/brainstorm/269331-1778521434/content/frontend-views.html"}
{"type":"screen-added","file":"/home/alex/projects/backup-tool/.superpowers/brainstorm/269331-1778521434/content/backup-flow.html"}
{"type":"server-stopped","reason":"idle timeout"}
@@ -0,0 +1 @@
269339