Add initial project structure and documentation
- Created architecture documentation outlining high-level design, module organization, data flow, security model, performance considerations, testing strategy, and deployment architecture. - Added pyproject.toml for project metadata and dependencies management. - Introduced requirements files for development and production dependencies. - Set up testing configuration with pytest and tox. - Established basic directory structure for source code and tests, including __init__.py files. - Implemented a sample web application (index.html) for drag-and-drop functionality. - Configured VS Code workspace settings for Python development.
This commit is contained in:
commit
61aa33633c
34 changed files with 5342 additions and 0 deletions
777
DEVELOPMENT_PLAN.md
Normal file
777
DEVELOPMENT_PLAN.md
Normal file
|
|
@ -0,0 +1,777 @@
|
|||
# WebDrop Bridge - Professional Development Plan
|
||||
|
||||
**Version**: 1.0
|
||||
**Last Updated**: January 2026
|
||||
**Status**: Pre-Release Development
|
||||
|
||||
## Executive Summary
|
||||
|
||||
This document outlines the development roadmap for WebDrop Bridge, a professional Qt-based desktop application that converts web-based drag-and-drop text paths into native file operations for seamless integration with professional desktop software (InDesign, Word, Notepad++, etc.).
|
||||
|
||||
### Key Differences from PoC
|
||||
|
||||
| Aspect | PoC | Production |
|
||||
|--------|-----|-----------|
|
||||
| **Structure** | Monolithic | Modular, scalable |
|
||||
| **Testing** | Ad-hoc | Comprehensive (unit/integration/e2e) |
|
||||
| **Documentation** | Minimal | Full API docs, user guides |
|
||||
| **Error Handling** | Basic | Robust with recovery |
|
||||
| **Logging** | Console only | File + structured logging |
|
||||
| **Security** | Basic validation | Enhanced, configurable |
|
||||
| **Distribution** | Source code | MSI (Windows), DMG (macOS) |
|
||||
| **CI/CD** | Manual | Automated GitHub Actions |
|
||||
| **Versioning** | Single version | Semantic versioning, auto-updates |
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Foundation (Weeks 1-4)
|
||||
|
||||
### 1.1 Core Architecture Refinement
|
||||
|
||||
**Objectives:**
|
||||
- Refactor PoC code into production-quality modules
|
||||
- Implement proper logging and error handling
|
||||
- Create configuration management system
|
||||
|
||||
**Tasks:**
|
||||
|
||||
#### 1.1.1 Configuration System (`src/webdrop_bridge/config.py`)
|
||||
```python
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
@dataclass
|
||||
class Config:
|
||||
"""Application configuration."""
|
||||
app_name: str
|
||||
app_version: str
|
||||
log_level: str
|
||||
allowed_roots: List[Path]
|
||||
webapp_url: str
|
||||
window_width: int
|
||||
window_height: int
|
||||
enable_logging: bool
|
||||
|
||||
@classmethod
|
||||
def from_env(cls):
|
||||
"""Load configuration from environment."""
|
||||
load_dotenv()
|
||||
allowed_roots_str = os.getenv("ALLOWED_ROOTS", "Z:/,C:/Users/Public")
|
||||
allowed_roots = [Path(p.strip()) for p in allowed_roots_str.split(",")]
|
||||
|
||||
return cls(
|
||||
app_name=os.getenv("APP_NAME", "WebDrop Bridge"),
|
||||
app_version=os.getenv("APP_VERSION", "1.0.0"),
|
||||
log_level=os.getenv("LOG_LEVEL", "INFO"),
|
||||
allowed_roots=allowed_roots,
|
||||
webapp_url=os.getenv("WEBAPP_URL", "file:///./webapp/index.html"),
|
||||
window_width=int(os.getenv("WINDOW_WIDTH", "1024")),
|
||||
window_height=int(os.getenv("WINDOW_HEIGHT", "768")),
|
||||
enable_logging=os.getenv("ENABLE_LOGGING", "true").lower() == "true",
|
||||
)
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] `src/webdrop_bridge/config.py` - Configuration management
|
||||
- [ ] `.env.example` - Environment template
|
||||
- [ ] Validation for all config parameters
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- Config loads from `.env` file
|
||||
- All environment variables have sensible defaults
|
||||
- Invalid values raise `ConfigurationError`
|
||||
|
||||
---
|
||||
|
||||
#### 1.1.2 Logging System (`src/webdrop_bridge/utils/logging.py`)
|
||||
|
||||
```python
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
def setup_logging(
|
||||
level: str = "INFO",
|
||||
log_file: Optional[Path] = None,
|
||||
format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
) -> logging.Logger:
|
||||
"""Configure application-wide logging."""
|
||||
logger = logging.getLogger("webdrop_bridge")
|
||||
logger.setLevel(getattr(logging, level))
|
||||
|
||||
# Console handler
|
||||
console = logging.StreamHandler()
|
||||
console.setFormatter(logging.Formatter(format))
|
||||
logger.addHandler(console)
|
||||
|
||||
# File handler (if enabled)
|
||||
if log_file:
|
||||
log_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
file_handler = logging.FileHandler(log_file)
|
||||
file_handler.setFormatter(logging.Formatter(format))
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
return logger
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] `src/webdrop_bridge/utils/logging.py` - Logging utilities
|
||||
- [ ] Logs directory with `.gitkeep`
|
||||
- [ ] Log rotation policy
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- Logs written to `logs/webdrop_bridge.log`
|
||||
- Console output matches log file
|
||||
- Log level configurable via environment
|
||||
|
||||
---
|
||||
|
||||
### 1.2 Drag Interceptor Component
|
||||
|
||||
**Objectives:**
|
||||
- Implement robust drag-and-drop interception
|
||||
- Validate paths against whitelist
|
||||
- Create MimeData with proper file URLs
|
||||
|
||||
**Tasks:**
|
||||
|
||||
#### 1.2.1 Path Validator (`src/webdrop_bridge/core/validator.py`)
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
class PathValidator:
|
||||
"""Validates file paths against security policies."""
|
||||
|
||||
def __init__(self, allowed_roots: List[Path]):
|
||||
self.allowed_roots = [p.resolve() for p in allowed_roots]
|
||||
|
||||
def is_allowed(self, path: Path) -> bool:
|
||||
"""Check if path is within allowed roots."""
|
||||
try:
|
||||
resolved = path.resolve()
|
||||
return any(
|
||||
self._is_relative_to(resolved, root)
|
||||
for root in self.allowed_roots
|
||||
)
|
||||
except (ValueError, OSError):
|
||||
return False
|
||||
|
||||
def is_valid_file(self, path: Path) -> bool:
|
||||
"""Check if path is allowed and exists as file."""
|
||||
return self.is_allowed(path) and path.exists() and path.is_file()
|
||||
|
||||
@staticmethod
|
||||
def _is_relative_to(path: Path, other: Path) -> bool:
|
||||
"""Backcompat for Path.is_relative_to (Python 3.9+)."""
|
||||
try:
|
||||
path.relative_to(other)
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] `src/webdrop_bridge/core/validator.py` - Path validation
|
||||
- [ ] Unit tests for `PathValidator`
|
||||
- [ ] Security documentation
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- All paths resolved to absolute
|
||||
- Whitelist enforcement working
|
||||
- Symlink handling documented
|
||||
|
||||
---
|
||||
|
||||
#### 1.2.2 Drag Interceptor Widget (`src/webdrop_bridge/core/drag_interceptor.py`)
|
||||
|
||||
```python
|
||||
from PySide6.QtCore import Qt, QUrl, QMimeData, pyqtSignal
|
||||
from PySide6.QtGui import QDrag
|
||||
from PySide6.QtWidgets import QWidget
|
||||
from pathlib import Path
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class DragInterceptor(QWidget):
|
||||
"""Intercepts and converts text drags to file drags."""
|
||||
|
||||
file_dropped = pyqtSignal(Path)
|
||||
|
||||
def __init__(self, validator, parent=None):
|
||||
super().__init__(parent)
|
||||
self.validator = validator
|
||||
self.setAcceptDrops(True)
|
||||
|
||||
def dragEnterEvent(self, event):
|
||||
"""Handle drag enter."""
|
||||
if event.mimeData().hasText():
|
||||
text = event.mimeData().text().strip()
|
||||
path = Path(text.replace("\\", "/"))
|
||||
|
||||
if self.validator.is_valid_file(path):
|
||||
event.acceptProposedAction()
|
||||
logger.debug(f"Drag accepted: {path}")
|
||||
self._start_file_drag(path)
|
||||
else:
|
||||
event.ignore()
|
||||
logger.warning(f"Invalid path rejected: {text}")
|
||||
|
||||
def _start_file_drag(self, path: Path):
|
||||
"""Convert to native file drag."""
|
||||
mime_data = QMimeData()
|
||||
url = QUrl.fromLocalFile(str(path))
|
||||
mime_data.setUrls([url])
|
||||
|
||||
drag = QDrag(self)
|
||||
drag.setMimeData(mime_data)
|
||||
|
||||
# Use move for typical file operations
|
||||
drag.exec(Qt.MoveAction | Qt.CopyAction)
|
||||
self.file_dropped.emit(path)
|
||||
logger.info(f"File dragged: {path}")
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] `src/webdrop_bridge/core/drag_interceptor.py` - Drag handling
|
||||
- [ ] Unit tests with mocking
|
||||
- [ ] Platform-specific tests (Windows/macOS)
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- Drag events properly intercepted
|
||||
- File URLs created correctly
|
||||
- Signals emit appropriately
|
||||
- Cross-platform compatibility verified
|
||||
|
||||
---
|
||||
|
||||
### 1.3 Main Application Window
|
||||
|
||||
**Tasks:**
|
||||
|
||||
#### 1.3.1 Main Window (`src/webdrop_bridge/ui/main_window.py`)
|
||||
|
||||
```python
|
||||
from PySide6.QtWidgets import QMainWindow, QVBoxLayout, QWidget
|
||||
from PySide6.QtWebEngineWidgets import QWebEngineView
|
||||
from PySide6.QtCore import QUrl
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
"""Application main window."""
|
||||
|
||||
def __init__(self, config):
|
||||
super().__init__()
|
||||
self.config = config
|
||||
self.setWindowTitle(config.app_name)
|
||||
self.setGeometry(100, 100, config.window_width, config.window_height)
|
||||
|
||||
# Create web engine view
|
||||
self.web_view = QWebEngineView()
|
||||
self._configure_web_engine()
|
||||
|
||||
# Set as central widget
|
||||
self.setCentralWidget(self.web_view)
|
||||
|
||||
logger.info(f"Loading webapp from: {config.webapp_url}")
|
||||
self.web_view.load(QUrl(config.webapp_url))
|
||||
|
||||
def _configure_web_engine(self):
|
||||
"""Configure WebEngine settings for local file access."""
|
||||
settings = self.web_view.settings()
|
||||
from PySide6.QtWebEngineCore import QWebEngineSettings
|
||||
|
||||
settings.setAttribute(
|
||||
QWebEngineSettings.LocalContentCanAccessFileUrls, True
|
||||
)
|
||||
settings.setAttribute(
|
||||
QWebEngineSettings.LocalContentCanAccessRemoteUrls, False
|
||||
)
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] `src/webdrop_bridge/ui/main_window.py`
|
||||
- [ ] UI tests
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- Window opens with correct title
|
||||
- WebEngine loads correctly
|
||||
- Responsive to resize events
|
||||
|
||||
---
|
||||
|
||||
### 1.4 Application Entry Point
|
||||
|
||||
**Tasks:**
|
||||
|
||||
#### 1.4.1 Main Entry (`src/webdrop_bridge/main.py`)
|
||||
|
||||
```python
|
||||
import sys
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6.QtWidgets import QApplication
|
||||
from webdrop_bridge.config import Config
|
||||
from webdrop_bridge.utils.logging import setup_logging
|
||||
from webdrop_bridge.core.validator import PathValidator
|
||||
from webdrop_bridge.core.drag_interceptor import DragInterceptor
|
||||
from webdrop_bridge.ui.main_window import MainWindow
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def main():
|
||||
"""Application entry point."""
|
||||
# Load configuration
|
||||
config = Config.from_env()
|
||||
|
||||
# Setup logging
|
||||
log_file = Path("logs") / "webdrop_bridge.log" if config.enable_logging else None
|
||||
setup_logging(config.log_level, log_file)
|
||||
|
||||
logger.info(f"Starting {config.app_name} v{config.app_version}")
|
||||
|
||||
# Create application
|
||||
app = QApplication(sys.argv)
|
||||
app.setApplicationName(config.app_name)
|
||||
|
||||
# Create validator and interceptor
|
||||
validator = PathValidator(config.allowed_roots)
|
||||
interceptor = DragInterceptor(validator)
|
||||
|
||||
# Create main window
|
||||
window = MainWindow(config)
|
||||
window.show()
|
||||
|
||||
logger.info("Application started")
|
||||
sys.exit(app.exec())
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] `src/webdrop_bridge/main.py`
|
||||
- [ ] Entry point tested
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- Application starts without errors
|
||||
- Configuration loaded correctly
|
||||
- Logging initialized
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Testing & Quality (Weeks 5-6)
|
||||
|
||||
### 2.1 Unit Tests
|
||||
|
||||
**Files to create:**
|
||||
- [ ] `tests/unit/test_config.py`
|
||||
- [ ] `tests/unit/test_validator.py`
|
||||
- [ ] `tests/unit/test_drag_interceptor.py`
|
||||
- [ ] `tests/unit/test_main_window.py`
|
||||
|
||||
**Target Coverage**: 80%+ line coverage
|
||||
|
||||
---
|
||||
|
||||
### 2.2 Integration Tests
|
||||
|
||||
**Files to create:**
|
||||
- [ ] `tests/integration/test_drag_workflow.py`
|
||||
- [ ] `tests/integration/test_webapp_loading.py`
|
||||
- [ ] `tests/integration/test_end_to_end.py`
|
||||
|
||||
**Test Scenarios:**
|
||||
1. Start app → Load webapp → Verify ready
|
||||
2. Initiate drag → Validate → Drop file → Verify received
|
||||
3. Invalid path → Reject → No file created
|
||||
|
||||
---
|
||||
|
||||
### 2.3 Code Quality
|
||||
|
||||
**Checklist:**
|
||||
- [ ] Black formatting: `tox -e format`
|
||||
- [ ] Ruff linting: `tox -e lint`
|
||||
- [ ] Type checking: `tox -e type`
|
||||
- [ ] Coverage report: `pytest --cov=src/webdrop_bridge`
|
||||
- [ ] Security scan: `pip audit`
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Build & Distribution (Weeks 7-8)
|
||||
|
||||
### 3.1 Windows Installer (MSI)
|
||||
|
||||
**Setup:**
|
||||
```bash
|
||||
pip install pyinstaller
|
||||
```
|
||||
|
||||
**Build Script** (`build/scripts/build_windows.py`):
|
||||
- Compile with PyInstaller
|
||||
- Create MSI with WiX (optional: advanced features)
|
||||
- Code signing (optional: professional deployment)
|
||||
- Output: `WebDropBridge-1.0.0-Setup.exe`
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- Executable runs standalone
|
||||
- Installer installs to Program Files
|
||||
- Uninstaller removes all files
|
||||
- Shortcuts created in Start Menu
|
||||
|
||||
---
|
||||
|
||||
### 3.2 macOS DMG Package
|
||||
|
||||
**Build Script** (`build/scripts/build_macos.sh`):
|
||||
- Compile with PyInstaller
|
||||
- Create `.app` bundle
|
||||
- Generate DMG image
|
||||
- Code signing (optional)
|
||||
- Output: `WebDropBridge-1.0.0.dmg`
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- App bundle signed (if applicable)
|
||||
- DMG opens in Finder
|
||||
- Drag-to-Applications works
|
||||
- Notarization passes (if applicable)
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Professional Features (Weeks 9-12)
|
||||
|
||||
### 4.1 Enhanced Logging & Monitoring
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] Structured logging (JSON format option)
|
||||
- [ ] Log rotation/archival
|
||||
- [ ] Performance metrics collection
|
||||
- [ ] Crash reporting (optional)
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Advanced Configuration
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] UI settings dialog
|
||||
- [ ] Configuration validation schema
|
||||
- [ ] Profile support (work, personal, etc.)
|
||||
- [ ] Export/import settings
|
||||
|
||||
---
|
||||
|
||||
### 4.3 User Documentation
|
||||
|
||||
**Deliverables:**
|
||||
- [ ] User manual (PDF, HTML)
|
||||
- [ ] Video tutorials
|
||||
- [ ] Troubleshooting guide
|
||||
- [ ] API documentation for developers
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Post-Release (Months 2-3)
|
||||
|
||||
### 5.1 Auto-Update System
|
||||
|
||||
**Requirements:**
|
||||
- Check for updates on startup
|
||||
- Download in background
|
||||
- Staged rollout support
|
||||
- Rollback capability
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Analytics & Monitoring
|
||||
|
||||
**Metrics:**
|
||||
- App usage statistics
|
||||
- Error/crash reporting
|
||||
- Feature usage tracking
|
||||
|
||||
---
|
||||
|
||||
### 5.3 Community Support
|
||||
|
||||
**Channels:**
|
||||
- GitHub Issues
|
||||
- Discussions forum
|
||||
- Community Slack
|
||||
- Email support
|
||||
|
||||
---
|
||||
|
||||
## Technical Specifications
|
||||
|
||||
### Supported Platforms
|
||||
|
||||
```
|
||||
┌─────────────────┬──────────┬────────┬────────────┐
|
||||
│ Platform │ Version │ Arch │ Status │
|
||||
├─────────────────┼──────────┼────────┼────────────┤
|
||||
│ Windows │ 10, 11 │ x64 │ Primary │
|
||||
│ macOS │ 12-14 │ Intel │ Primary │
|
||||
│ macOS │ 12-14 │ ARM64 │ Primary │
|
||||
│ Linux │ Ubuntu │ x64 │ Experimental│
|
||||
└─────────────────┴──────────┴────────┴────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Dependencies
|
||||
|
||||
**Core:**
|
||||
- PySide6 6.6.0+
|
||||
- Python 3.10+
|
||||
|
||||
**Optional:**
|
||||
- PyInstaller (building)
|
||||
- Sphinx (documentation)
|
||||
- pytest (testing)
|
||||
|
||||
---
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
webdrop-bridge/
|
||||
│
|
||||
├── src/webdrop_bridge/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py ← Entry point
|
||||
│ ├── config.py ← Configuration
|
||||
│ ├── core/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── validator.py ← Path validation
|
||||
│ │ ├── drag_interceptor.py ← Drag handling
|
||||
│ │ └── errors.py ← Custom exceptions
|
||||
│ ├── ui/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── main_window.py ← Main UI
|
||||
│ │ ├── widgets.py ← Reusable widgets
|
||||
│ │ └── styles.py ← UI styling
|
||||
│ └── utils/
|
||||
│ ├── __init__.py
|
||||
│ ├── logging.py ← Logging setup
|
||||
│ ├── constants.py ← App constants
|
||||
│ └── helpers.py ← Utility functions
|
||||
│
|
||||
├── tests/
|
||||
│ ├── __init__.py
|
||||
│ ├── conftest.py ← Pytest fixtures
|
||||
│ ├── unit/ ← Unit tests
|
||||
│ ├── integration/ ← Integration tests
|
||||
│ └── fixtures/ ← Test data
|
||||
│
|
||||
├── build/
|
||||
│ ├── windows/ ← Windows build config
|
||||
│ ├── macos/ ← macOS build config
|
||||
│ └── scripts/
|
||||
│ ├── build_windows.py
|
||||
│ └── build_macos.sh
|
||||
│
|
||||
├── webapp/ ← Embedded web app
|
||||
│ └── index.html
|
||||
│
|
||||
├── resources/
|
||||
│ ├── icons/ ← App icons
|
||||
│ └── stylesheets/ ← Qt stylesheets
|
||||
│
|
||||
├── docs/ ← Documentation
|
||||
│ ├── architecture.md
|
||||
│ ├── api.md
|
||||
│ └── troubleshooting.md
|
||||
│
|
||||
└── Configuration Files
|
||||
├── pyproject.toml ← Modern Python packaging
|
||||
├── setup.py ← Backwards compatibility
|
||||
├── pytest.ini ← Test config
|
||||
├── tox.ini ← Automation config
|
||||
└── .github/workflows/ ← CI/CD
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Risk Analysis & Mitigation
|
||||
|
||||
| Risk | Probability | Impact | Mitigation |
|
||||
|------|-------------|--------|-----------|
|
||||
| Qt/PySide6 API changes | Low | High | Lock versions, monitor releases |
|
||||
| macOS code signing | Medium | Medium | Use Apple Developer account, automate |
|
||||
| Drag performance issues | Low | Medium | Performance testing early, profiling |
|
||||
| Cross-platform bugs | Medium | Medium | Extensive testing on both platforms |
|
||||
| Security vulnerabilities | Low | High | Regular audits, dependency scanning |
|
||||
| User adoption | Medium | Medium | Clear documentation, community engagement |
|
||||
|
||||
---
|
||||
|
||||
## Success Metrics
|
||||
|
||||
| Metric | Target | Timeline |
|
||||
|--------|--------|----------|
|
||||
| Code coverage | 80%+ | Week 6 |
|
||||
| Test pass rate | 100% | Continuous |
|
||||
| Build time | <2 min | Week 8 |
|
||||
| Application startup | <1 sec | Week 8 |
|
||||
| Installer size | <150 MB | Week 8 |
|
||||
| Documentation completeness | 100% | Week 12 |
|
||||
| Community contributions | 5+ | Month 3 |
|
||||
|
||||
---
|
||||
|
||||
## Milestones & Timeline
|
||||
|
||||
```
|
||||
January 2026
|
||||
├── Week 1-2: Core Architecture (config, logging, validator)
|
||||
├── Week 3-4: UI Components (main window, drag interceptor)
|
||||
├── Week 5-6: Testing & Quality Assurance
|
||||
├── Week 7-8: Build & Installer Creation
|
||||
├── Week 9-10: Advanced Features & Polish
|
||||
├── Week 11-12: Documentation & Release
|
||||
│
|
||||
February 2026
|
||||
└── Post-release: Auto-updates, Analytics, Community Support
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Open Questions & Decisions
|
||||
|
||||
### Decision: Embedded Web App vs. External URL
|
||||
|
||||
**Options:**
|
||||
1. Embed static web app (current PoC approach)
|
||||
2. Load from remote server
|
||||
3. Hybrid: Support both
|
||||
|
||||
**Decision**: **Hybrid approach**
|
||||
- Default: Load from `WEBAPP_URL` (local file)
|
||||
- Configurable: Allow remote URLs for advanced users
|
||||
- Security: Validate origins against whitelist
|
||||
|
||||
---
|
||||
|
||||
### Decision: Update Mechanism
|
||||
|
||||
**Options:**
|
||||
1. Manual downloads from website
|
||||
2. Auto-update with staged rollout
|
||||
3. Package manager (Chocolatey, Brew)
|
||||
|
||||
**Decision**: **GitHub Releases + PyInstaller**
|
||||
- Phase 1: Manual downloads
|
||||
- Phase 5: Auto-update via custom launcher
|
||||
|
||||
---
|
||||
|
||||
### Decision: Telemetry
|
||||
|
||||
**Options:**
|
||||
1. No telemetry
|
||||
2. Anonymous usage statistics
|
||||
3. Detailed crash reporting
|
||||
|
||||
**Decision**: **Opt-in telemetry**
|
||||
- No data collection by default
|
||||
- Users can enable for error reporting
|
||||
- Full transparency about data collected
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Immediate** (This week):
|
||||
- [ ] Set up project directories ✅
|
||||
- [ ] Create configuration system
|
||||
- [ ] Implement path validator
|
||||
- [ ] Set up CI/CD
|
||||
|
||||
2. **Near term** (Next 2 weeks):
|
||||
- [ ] Complete core components
|
||||
- [ ] Write comprehensive tests
|
||||
- [ ] Build installers
|
||||
|
||||
3. **Medium term** (Weeks 5-8):
|
||||
- [ ] Code review & QA
|
||||
- [ ] Performance optimization
|
||||
- [ ] Documentation
|
||||
|
||||
4. **Long term** (Months 2-3):
|
||||
- [ ] Advanced features
|
||||
- [ ] Community engagement
|
||||
- [ ] Auto-update system
|
||||
|
||||
---
|
||||
|
||||
## Document Control
|
||||
|
||||
| Version | Date | Author | Changes |
|
||||
|---------|------|--------|---------|
|
||||
| 1.0 | Jan 28, 2026 | Team | Initial plan |
|
||||
|
||||
---
|
||||
|
||||
## Appendices
|
||||
|
||||
### A. Technology Stack Justification
|
||||
|
||||
**PySide6 over PyQt5/6:**
|
||||
- Modern LGPL licensing
|
||||
- Excellent Windows & macOS support
|
||||
- Strong community and documentation
|
||||
- Built-in WebEngine
|
||||
|
||||
**PyInstaller over Briefcase/Nuitka:**
|
||||
- Mature, stable, well-tested
|
||||
- Excellent one-file executable support
|
||||
- Cross-platform build scripts
|
||||
|
||||
**pytest over unittest:**
|
||||
- Modern, expressive syntax
|
||||
- Powerful fixtures and plugins
|
||||
- Better integration with CI/CD
|
||||
|
||||
---
|
||||
|
||||
### B. Security Considerations
|
||||
|
||||
**Path Validation:**
|
||||
- Only allow whitelisted directories
|
||||
- Resolve paths to prevent symlink attacks
|
||||
- Validate file existence before drag
|
||||
|
||||
**Web Engine:**
|
||||
- Disable remote URL loading by default
|
||||
- Implement CSP headers
|
||||
- Regular security audits
|
||||
|
||||
**User Data:**
|
||||
- No personally identifiable information stored
|
||||
- Configuration stored locally
|
||||
- Encrypted settings (future)
|
||||
|
||||
---
|
||||
|
||||
### C. Performance Targets
|
||||
|
||||
```
|
||||
- Application startup: < 1 second
|
||||
- Drag interception: < 10ms
|
||||
- File drag initiation: < 50ms
|
||||
- Memory usage: < 200MB baseline
|
||||
- Memory/file size ratio: < 2MB per 100 files
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**For updates or clarifications, see the main README.md or open an issue on GitHub.**
|
||||
Loading…
Add table
Add a link
Reference in a new issue