From a863807cf2a73e46a994037c97bff0096f56d98e Mon Sep 17 00:00:00 2001 From: busya Date: Sat, 24 Jan 2026 16:21:43 +0300 Subject: [PATCH] tasks ready --- .kilocode/rules/specify-rules.md | 4 +- .../checklists/requirements.md | 34 ++++++ specs/014-file-storage-ui/checklists/ux.md | 35 ++++++ specs/014-file-storage-ui/contracts/api.md | 74 ++++++++++++ specs/014-file-storage-ui/data-model.md | 34 ++++++ specs/014-file-storage-ui/plan.md | 105 ++++++++++++++++++ specs/014-file-storage-ui/quickstart.md | 31 ++++++ specs/014-file-storage-ui/research.md | 17 +++ specs/014-file-storage-ui/spec.md | 94 ++++++++++++++++ specs/014-file-storage-ui/tasks.md | 84 ++++++++++++++ 10 files changed, 511 insertions(+), 1 deletion(-) create mode 100644 specs/014-file-storage-ui/checklists/requirements.md create mode 100644 specs/014-file-storage-ui/checklists/ux.md create mode 100644 specs/014-file-storage-ui/contracts/api.md create mode 100644 specs/014-file-storage-ui/data-model.md create mode 100644 specs/014-file-storage-ui/plan.md create mode 100644 specs/014-file-storage-ui/quickstart.md create mode 100644 specs/014-file-storage-ui/research.md create mode 100644 specs/014-file-storage-ui/spec.md create mode 100644 specs/014-file-storage-ui/tasks.md diff --git a/.kilocode/rules/specify-rules.md b/.kilocode/rules/specify-rules.md index 2295440..f3111f9 100644 --- a/.kilocode/rules/specify-rules.md +++ b/.kilocode/rules/specify-rules.md @@ -27,6 +27,8 @@ Auto-generated from all feature plans. Last updated: 2025-12-19 - SQLite (for config/history), Filesystem (local Git repositories) (011-git-integration-dashboard) - Node.js 18+ (Frontend Build), Svelte 5.x + SvelteKit, Tailwind CSS, `date-fns` (existing) (013-unify-frontend-css) - LocalStorage (for language preference) (013-unify-frontend-css) +- Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI (Backend), SvelteKit (Frontend) (014-file-storage-ui) +- Local Filesystem (for artifacts), Config (for storage path) (014-file-storage-ui) - Python 3.9+ (Backend), Node.js 18+ (Frontend Build) (001-plugin-arch-svelte-ui) @@ -47,9 +49,9 @@ cd src; pytest; ruff check . Python 3.9+ (Backend), Node.js 18+ (Frontend Build): Follow standard conventions ## Recent Changes +- 014-file-storage-ui: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI (Backend), SvelteKit (Frontend) - 013-unify-frontend-css: Added Node.js 18+ (Frontend Build), Svelte 5.x + SvelteKit, Tailwind CSS, `date-fns` (existing) - 011-git-integration-dashboard: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, GitPython (or CLI git), Pydantic, SQLAlchemy, Superset API -- 011-git-integration-dashboard: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI, SvelteKit, GitPython (or CLI git), Pydantic, SQLAlchemy, Superset API diff --git a/specs/014-file-storage-ui/checklists/requirements.md b/specs/014-file-storage-ui/checklists/requirements.md new file mode 100644 index 0000000..fb22439 --- /dev/null +++ b/specs/014-file-storage-ui/checklists/requirements.md @@ -0,0 +1,34 @@ +# Specification Quality Checklist: File Storage Management & UI + +**Purpose**: Validate specification completeness and quality before proceeding to planning +**Created**: 2026-01-24 +**Feature**: [Link to spec.md](../spec.md) + +## Content Quality + +- [x] No implementation details (languages, frameworks, APIs) +- [x] Focused on user value and business needs +- [x] Written for non-technical stakeholders +- [x] All mandatory sections completed + +## Requirement Completeness + +- [x] No [NEEDS CLARIFICATION] markers remain +- [x] Requirements are testable and unambiguous +- [x] Success criteria are measurable +- [x] Success criteria are technology-agnostic (no implementation details) +- [x] All acceptance scenarios are defined +- [x] Edge cases are identified +- [x] Scope is clearly bounded +- [x] Dependencies and assumptions identified + +## Feature Readiness + +- [x] All functional requirements have clear acceptance criteria +- [x] User scenarios cover primary flows +- [x] Feature meets measurable outcomes defined in Success Criteria +- [x] No implementation details leak into specification + +## Notes + +- Items marked incomplete require spec updates before `/speckit.clarify` or `/speckit.plan` \ No newline at end of file diff --git a/specs/014-file-storage-ui/checklists/ux.md b/specs/014-file-storage-ui/checklists/ux.md new file mode 100644 index 0000000..6e337ca --- /dev/null +++ b/specs/014-file-storage-ui/checklists/ux.md @@ -0,0 +1,35 @@ +# Checklist: File Storage UX & Configuration + +**Purpose**: Validate implementation of User Experience and Configuration Flexibility requirements. +**Created**: 2026-01-24 +**Feature**: [File Storage Management & UI](../spec.md) + +## User Experience (File Management) + +- [ ] CHK001 Are loading states displayed while fetching the file list? [Completeness] +- [ ] CHK002 Is visual feedback provided immediately after file upload starts? [Clarity] +- [ ] CHK003 Are error messages user-friendly when upload fails (e.g., "File too large" vs "Error 413")? [Clarity] +- [ ] CHK004 Is a confirmation modal shown before permanently deleting a file? [Safety] +- [ ] CHK005 Does the UI clearly distinguish between "Backups" and "Repositories" tabs? [Clarity] +- [ ] CHK006 Is the file list sortable by Date and Name? [Usability] +- [ ] CHK007 Are file sizes formatted in human-readable units (KB, MB, GB)? [Usability] +- [ ] CHK008 Is the download action easily accessible for each file item? [Accessibility] +- [ ] CHK009 Does the upload component support drag-and-drop interactions? [Usability] +- [ ] CHK010 Is the "Upload" button disabled or hidden when no category is selected? [Consistency] + +## Configuration Flexibility + +- [ ] CHK011 Can the storage root path be configured to any writable directory on the server? [Flexibility] +- [ ] CHK012 Does the system support defining custom directory structures using variables like `{environment}`? [Flexibility] +- [ ] CHK013 Does the system support defining custom filename patterns using variables like `{timestamp}`? [Flexibility] +- [ ] CHK014 Are the supported pattern variables (e.g., `{dashboard_name}`) clearly documented in the UI? [Clarity] +- [ ] CHK015 Can the configuration be updated without restarting the application? [Usability] +- [ ] CHK016 Is the current resolved path shown as a preview when editing patterns? [Usability] +- [ ] CHK017 Does the system allow reverting configuration to default values? [Recovery] + +## Edge Cases & Error Handling + +- [ ] CHK018 Is the UI behavior defined for an empty file list (zero state)? [Coverage] +- [ ] CHK019 Is the behavior defined when the configured storage path becomes inaccessible? [Resilience] +- [ ] CHK020 Are long filenames handled gracefully in the UI (e.g., truncation with tooltip)? [Layout] +- [ ] CHK021 Is the behavior defined for uploading a file with a duplicate name? [Conflict Resolution] \ No newline at end of file diff --git a/specs/014-file-storage-ui/contracts/api.md b/specs/014-file-storage-ui/contracts/api.md new file mode 100644 index 0000000..c96ed36 --- /dev/null +++ b/specs/014-file-storage-ui/contracts/api.md @@ -0,0 +1,74 @@ +# API Contracts: File Storage Management & UI + +## Endpoints + +### GET /api/storage/files +List all files in the storage system. + +**Query Parameters:** +- `category` (optional): Filter by category (`backup` or `repository`). + +**Response:** +- `200 OK`: List of `StoredFile` objects. + +```json +[ + { + "name": "dashboard_backup_20260124.zip", + "path": "backups/dashboard_backup_20260124.zip", + "size": 102400, + "created_at": "2026-01-24T12:00:00Z", + "category": "backup", + "mime_type": "application/zip" + } +] +``` + +### POST /api/storage/upload +Upload a file to the storage system. + +**Form Data:** +- `file`: The file content. +- `category`: Target category (`backup` or `repository`). + +**Response:** +- `201 Created`: The uploaded `StoredFile` object. +- `400 Bad Request`: Invalid category or file. + +### DELETE /api/storage/files/{category}/{filename} +Delete a file from storage. + +**Path Parameters:** +- `category`: `backup` or `repository`. +- `filename`: Name of the file to delete. + +**Response:** +- `204 No Content`: File deleted successfully. +- `404 Not Found`: File does not exist. + +### GET /api/storage/download/{category}/{filename} +Download a file. + +**Path Parameters:** +- `category`: `backup` or `repository`. +- `filename`: Name of the file to download. + +**Response:** +- `200 OK`: File stream. +- `404 Not Found`: File does not exist. + +### GET /api/settings/storage +Get current storage configuration. + +**Response:** +- `200 OK`: `StorageConfig` object. + +### PUT /api/settings/storage +Update storage configuration. + +**Body:** +- `StorageConfig` object. + +**Response:** +- `200 OK`: Updated `StorageConfig`. +- `400 Bad Request`: Invalid path or not writable. \ No newline at end of file diff --git a/specs/014-file-storage-ui/data-model.md b/specs/014-file-storage-ui/data-model.md new file mode 100644 index 0000000..6f45f25 --- /dev/null +++ b/specs/014-file-storage-ui/data-model.md @@ -0,0 +1,34 @@ +# Data Model: File Storage Management & UI + +## Entities + +### StorageConfig +*Configuration for the storage system.* + +| Field | Type | Description | Constraints | +|---|---|---|---| +| `root_path` | `string` | Absolute path to the storage root directory. | Must be a valid, writable path. Default: `../ss-tools-storage` | +| `backup_structure_pattern` | `string` | Pattern for backup directory structure. | Default: `{category}/` | +| `repo_structure_pattern` | `string` | Pattern for repository directory structure. | Default: `{category}/` | +| `filename_pattern` | `string` | Pattern for filenames. | Default: `{name}_{timestamp}` | + +### StoredFile +*Representation of a file in the storage system.* + +| Field | Type | Description | Constraints | +|---|---|---|---| +| `name` | `string` | Name of the file (including extension). | No path separators. | +| `path` | `string` | Relative path from storage root. | | +| `size` | `integer` | Size of the file in bytes. | >= 0 | +| `created_at` | `datetime` | Creation timestamp. | | +| `category` | `enum` | Category of the file. | `backup`, `repository` | +| `mime_type` | `string` | MIME type of the file. | Optional | + +## Directory Structure + +```text +{root_path}/ +├── backups/ +│ └── {filename}.zip +└── repositories/ + └── {filename}.zip \ No newline at end of file diff --git a/specs/014-file-storage-ui/plan.md b/specs/014-file-storage-ui/plan.md new file mode 100644 index 0000000..9928b4b --- /dev/null +++ b/specs/014-file-storage-ui/plan.md @@ -0,0 +1,105 @@ +# Implementation Plan: File Storage Management & UI + +**Branch**: `014-file-storage-ui` | **Date**: 2026-01-24 | **Spec**: [specs/014-file-storage-ui/spec.md](../014-file-storage-ui/spec.md) +**Input**: Feature specification from `specs/014-file-storage-ui/spec.md` + +## Summary + +This feature implements a managed file storage system for dashboard backups and exported repositories. It introduces a configurable storage root (defaulting to outside the workspace) and a Web UI to list, upload, download, and delete files. The system enforces a structured layout with `backups/` and `repositories/` subdirectories to keep artifacts organized, while allowing flexible configuration of directory structures and filename patterns. + +## Technical Context + +**Language/Version**: Python 3.9+ (Backend), Node.js 18+ (Frontend) +**Primary Dependencies**: FastAPI (Backend), SvelteKit (Frontend) +**Storage**: Local Filesystem (for artifacts), Config (for storage path) +**Testing**: pytest (Backend), vitest/playwright (Frontend - implied) +**Target Platform**: Linux server +**Project Type**: Web application +**Performance Goals**: File list load < 1s for 100 files, supports 50MB+ uploads +**Constraints**: Must prevent path traversal, must not pollute git repo +**Scale/Scope**: ~2-3 backend endpoints, 1-2 frontend pages/components + +## Constitution Check + +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* + +- **I. Semantic Protocol Compliance**: + - **Status**: PASSED + - **Check**: Will use `[DEF]` anchors and `@RELATION` tags. + - **Check**: Will follow File Structure Standard. + +- **II. Causal Validity (Contracts First)**: + - **Status**: PASSED + - **Check**: Contracts will be defined in `specs/014-file-storage-ui/contracts/` before implementation. + +- **III. Immutability of Architecture**: + - **Status**: PASSED + - **Check**: No changes to immutable architectural constraints expected. + +- **IV. Design by Contract (DbC)**: + - **Status**: PASSED + - **Check**: Functions will define `@PRE` and `@POST` conditions. + +- **V. Belief State Logging**: + - **Status**: PASSED + - **Check**: Will use standard logging patterns. + +- **VI. Fractal Complexity Limit**: + - **Status**: PASSED + - **Check**: Feature scope is small, unlikely to exceed complexity limits. + +- **VII. Everything is a Plugin**: + - **Status**: PASSED + - **Check**: New functionality will be implemented as a `StoragePlugin` (or similar) inheriting from `PluginBase`. + +## Project Structure + +### Documentation (this feature) + +```text +specs/014-file-storage-ui/ +├── plan.md # This file +├── research.md # Phase 0 output +├── data-model.md # Phase 1 output +├── quickstart.md # Phase 1 output +├── contracts/ # Phase 1 output +└── tasks.md # Phase 2 output +``` + +### Source Code (repository root) + +```text +backend/ +├── src/ +│ ├── api/ +│ │ └── routes/ +│ │ └── storage.py # New route handler +│ ├── plugins/ +│ │ └── storage.py # New plugin implementation +│ └── models/ +│ └── storage.py # Pydantic models (StoredFile, StorageConfig) +└── tests/ + └── test_storage.py # Backend tests + +frontend/ +├── src/ +│ ├── routes/ +│ │ └── storage/ +│ │ └── +page.svelte # Main storage UI +│ ├── components/ +│ │ └── storage/ +│ │ ├── FileList.svelte # Component for listing files +│ │ └── FileUpload.svelte # Component for uploading +│ └── services/ +│ └── storageService.js # Frontend API client +``` + +**Structure Decision**: Standard Web Application structure (Backend + Frontend) with Plugin architecture for the backend logic. + +## Complexity Tracking + +> **Fill ONLY if Constitution Check has violations that must be justified** + +| Violation | Why Needed | Simpler Alternative Rejected Because | +|-----------|------------|-------------------------------------| +| N/A | | | diff --git a/specs/014-file-storage-ui/quickstart.md b/specs/014-file-storage-ui/quickstart.md new file mode 100644 index 0000000..3b14c16 --- /dev/null +++ b/specs/014-file-storage-ui/quickstart.md @@ -0,0 +1,31 @@ +# Quickstart: File Storage Management & UI + +## Usage Guide + +1. **Access File Storage**: Navigate to the "Tools" > "File Storage" section in the main navigation. +2. **View Files**: You will see two tabs: "Backups" and "Repositories". Click on a tab to view files in that category. +3. **Upload File**: + - Click the "Upload" button. + - Select a file from your computer. + - Choose the target category (Backup or Repository). + - Click "Upload" to start the transfer. +4. **Download File**: Click the "Download" icon next to any file in the list. +5. **Delete File**: Click the "Trash" icon next to any file to delete it permanently. +6. **Configure Storage Path**: + - Go to "Settings". + - Locate the "File Storage" section. + - Enter a new absolute path for the storage root. + - Click "Save". The system will verify write access to the new path. + +## Development + +### Backend + +- **Plugin**: `backend/src/plugins/storage.py` +- **API Routes**: `backend/src/api/routes/storage.py` +- **Models**: `backend/src/models/storage.py` + +### Frontend + +- **Page**: `frontend/src/routes/tools/storage/+page.svelte` +- **Components**: `frontend/src/components/storage/*` \ No newline at end of file diff --git a/specs/014-file-storage-ui/research.md b/specs/014-file-storage-ui/research.md new file mode 100644 index 0000000..5a8abcd --- /dev/null +++ b/specs/014-file-storage-ui/research.md @@ -0,0 +1,17 @@ +# Research: File Storage Management & UI + +**Decision**: Use Python's built-in `pathlib` and `shutil` for filesystem operations. +**Rationale**: Standard library, robust, cross-platform (though target is Linux), and sufficient for local file management. No external dependencies needed. +**Alternatives considered**: `os` module (lower level, less ergonomic), `pyfilesystem2` (external dependency, unnecessary overhead for simple local storage). + +**Decision**: Use `pydantic` for configuration and file metadata models. +**Rationale**: Already used in the project, provides validation and serialization. + +**Decision**: Use `multipart/form-data` for file uploads. +**Rationale**: Standard web practice for file uploads. FastAPI supports `UploadFile` natively. + +**Decision**: Default storage path strategy. +**Rationale**: The default path will be `../ss-tools-storage` (relative to workspace root) or similar to ensure it sits outside the git repository by default, but allows configuration override. + +**Decision**: Path Traversal Prevention. +**Rationale**: Will use `os.path.commonpath` or `pathlib.Path.resolve()` to strictly validate that any accessed file path is a child of the configured storage root. \ No newline at end of file diff --git a/specs/014-file-storage-ui/spec.md b/specs/014-file-storage-ui/spec.md new file mode 100644 index 0000000..7649db4 --- /dev/null +++ b/specs/014-file-storage-ui/spec.md @@ -0,0 +1,94 @@ +# Feature Specification: File Storage Management & UI + +**Feature Branch**: `014-file-storage-ui` +**Created**: 2026-01-24 +**Status**: Draft +**Input**: User description: "Я хочу проработать механизм хранения файлов и доступа к ним - бекапов дашбордов и репозиториев дашбордов. Во первых, нужно иметь указывать место хранения, по умолчанию оно должно быть за файловой системой сервера (чтобы не влиять на git репозиторий. Во вторых, нужен web ui для базового доступа ко всем файлам - возможность скачивания/удаления, информация о датах создания, возможность загрузки" + +## User Scenarios & Testing *(mandatory)* + +### User Story 1 - File Management Dashboard (Priority: P1) + +Users need a visual interface to manage the artifacts generated by the system (dashboard backups, exported repositories) without needing direct server access. This ensures that non-technical users or users without SSH access can still retrieve or clean up data. + +**Why this priority**: Core functionality requested. Without the UI, the storage mechanism is opaque and hard to use. + +**Independent Test**: Can be fully tested by opening the new "File Storage" page, uploading a test file, verifying it appears in the list with correct metadata, downloading it, and then deleting it. + +**Acceptance Scenarios**: + +1. **Given** the File Storage page is open, **When** I view the list, **Then** I see all files in the configured storage directory with their names, sizes, and creation dates. +2. **Given** a file exists in the list, **When** I click "Download", **Then** the file is downloaded to my local machine. +3. **Given** a file exists in the list, **When** I click "Delete" and confirm, **Then** the file is removed from the list and the server filesystem. +4. **Given** I have a file locally, **When** I drag and drop it or use the "Upload" button, **Then** the file is uploaded to the server storage and appears in the list. + +--- + +### User Story 2 - Storage Location Configuration (Priority: P2) + +Administrators need to control where potentially large or sensitive files are stored. Crucially, these files must not accidentally pollute the source code repository or the application's working directory. + +**Why this priority**: Essential for system stability and cleanliness (preventing git pollution), but the system could theoretically start with a hardcoded safe default. + +**Independent Test**: Change the storage path in Settings, generate a file (or upload one), and verify it exists in the new location on the server disk. + +**Acceptance Scenarios**: + +1. **Given** I am in the Settings page, **When** I enter a new absolute path for "File Storage Path" and save, **Then** the system updates the configuration. +2. **Given** the default configuration, **When** the system starts, **Then** the storage path defaults to a location outside the project's git scope (or is properly ignored). +3. **Given** an invalid path (e.g., no write permissions), **When** I try to save, **Then** the system shows an error message. + +--- + +### Edge Cases + +- **File Name Conflicts**: What happens when uploading a file that already exists? (System should likely rename or ask to overwrite). +- **Storage Quota/Disk Space**: What happens if the disk is full during upload? +- **Path Traversal**: Ensure users cannot access files outside the configured storage directory via the API. +- **Large Files**: Handling uploads/downloads of large backup archives (e.g., > 100MB). + +## Clarifications + +### Session 2026-01-24 + +- Q: Should the system enforce a structure to keep backups and repositories separate? → A: **Structured**: System creates and enforces `backups/` and `repositories/` folders; UI separates them. + +### Session 2026-01-24 (Update) + +- Q: Should the system allow advanced configuration of file structure and naming conventions? → A: **Yes**: Users should be able to configure the directory structure (e.g., include dashboard/environment names) and file naming patterns (e.g., include timestamps). + +## Requirements *(mandatory)* + +### Functional Requirements + +- **FR-001**: System MUST allow configuring a local filesystem root path for storing artifacts. +- **FR-002**: The default storage path MUST be configured such that it does not interfere with the application's git repository (e.g., a directory outside the workspace or explicitly git-ignored). +- **FR-003**: System MUST enforce a directory structure within the storage root: `backups/` for dashboard backups and `repositories/` for exported repositories. +- **FR-004**: System MUST provide a Web UI to list files, organized by their type (Backup vs Repository). +- **FR-005**: System MUST display file metadata in the UI: Filename, Size, Creation Date. +- **FR-006**: System MUST allow users to download files from the storage directory via the Web UI. +- **FR-007**: System MUST allow users to delete files from the storage directory via the Web UI. +- **FR-008**: System MUST allow users to upload files to the storage directory via the Web UI, requiring them to select the target category (Backup or Repository). +- **FR-009**: System MUST validate that the configured storage path is accessible and writable. +- **FR-010**: System MUST prevent access to files outside the configured storage directory (Path Traversal protection). +- **FR-011**: System MUST allow configuring the directory structure pattern for backups and repositories (e.g., `{environment}/{dashboard_name}/`). +- **FR-012**: System MUST allow configuring the filename pattern for generated files (e.g., `{dashboard_name}_{timestamp}.zip`). + +### Key Entities + +- **StorageConfig**: Settings defining the root directory path. +- **StoredFile**: Conceptual representation of a file (Name, Path, Size, CreatedAt, MimeType). + +### Assumptions + +- The application server has access to a writable local filesystem. +- Users utilizing this feature have appropriate permissions within the application to manage system-wide storage settings and files. + +## Success Criteria *(mandatory)* + +### Measurable Outcomes + +- **SC-001**: Users can successfully upload and then download a file of at least 50MB size. +- **SC-002**: Files created or uploaded via the system do not appear in the application's `git status` output by default. +- **SC-003**: File list loads in under 1 second for a directory containing 100 files. +- **SC-004**: Users can delete a file via UI and confirm it is physically removed from the disk. diff --git a/specs/014-file-storage-ui/tasks.md b/specs/014-file-storage-ui/tasks.md new file mode 100644 index 0000000..63bf205 --- /dev/null +++ b/specs/014-file-storage-ui/tasks.md @@ -0,0 +1,84 @@ +# Tasks: File Storage Management & UI + +**Branch**: `014-file-storage-ui` | **Spec**: [specs/014-file-storage-ui/spec.md](../014-file-storage-ui/spec.md) + +## Phase 1: Setup +*Goal: Initialize backend plugin structure and frontend route scaffolding.* + +- [ ] T001 Create storage plugin directory and `__init__.py` in `backend/src/plugins/storage/` +- [ ] T002 Create storage models file `backend/src/models/storage.py` with `StorageConfig` and `StoredFile` Pydantic models +- [ ] T003 Create empty storage route handler `backend/src/api/routes/storage.py` and register in `backend/src/api/routes/__init__.py` +- [ ] T004 Create frontend storage route directory `frontend/src/routes/tools/storage/` and empty `+page.svelte` +- [ ] T005 Create frontend service `frontend/src/services/storageService.js` stub + +## Phase 2: Foundational +*Goal: Implement core backend logic for storage management, configuration, and security.* + +- [ ] T006 Implement `StoragePlugin` class in `backend/src/plugins/storage/plugin.py` inheriting from `PluginBase` +- [ ] T007 Implement `get_storage_root()` method in `StoragePlugin` with default path logic (`../ss-tools-storage`) +- [ ] T008 Implement `ensure_directories()` method to create `backups/` and `repositories/` subfolders on init +- [ ] T009 Implement path traversal protection helper `validate_path(path)` in `StoragePlugin` +- [ ] T010 Implement `list_files(category)` method in `StoragePlugin` returning `StoredFile` objects +- [ ] T011 Implement `save_file(file, category)` method in `StoragePlugin` handling uploads +- [ ] T012 Implement `delete_file(category, filename)` method in `StoragePlugin` +- [ ] T013 Implement `get_file_path(category, filename)` method in `StoragePlugin` for downloads +- [ ] T014 Register `StoragePlugin` in `backend/src/core/plugin_loader.py` (if manual registration needed) + +## Phase 3: User Story 1 - File Management Dashboard (Priority: P1) +*Goal: Enable users to list, upload, download, and delete files via Web UI.* + +### Backend Endpoints +- [ ] T015 [US1] Implement `GET /api/storage/files` endpoint in `backend/src/api/routes/storage.py` using `StoragePlugin.list_files` +- [ ] T016 [US1] Implement `POST /api/storage/upload` endpoint in `backend/src/api/routes/storage.py` using `StoragePlugin.save_file` +- [ ] T017 [US1] Implement `DELETE /api/storage/files/{category}/{filename}` endpoint in `backend/src/api/routes/storage.py` +- [ ] T018 [US1] Implement `GET /api/storage/download/{category}/{filename}` endpoint in `backend/src/api/routes/storage.py` + +### Frontend Implementation +- [ ] T019 [US1] Implement `listFiles`, `uploadFile`, `deleteFile`, `downloadFileUrl` in `frontend/src/services/storageService.js` +- [ ] T020 [US1] Create `frontend/src/components/storage/FileList.svelte` to display files in a table with metadata +- [ ] T021 [US1] Create `frontend/src/components/storage/FileUpload.svelte` with category selection and drag-drop support +- [ ] T022 [US1] Implement main logic in `frontend/src/routes/tools/storage/+page.svelte` to fetch files and handle tabs (Backups vs Repositories) +- [ ] T023 [US1] Integrate `FileList` and `FileUpload` components into `+page.svelte` + +## Phase 4: User Story 2 - Storage Location Configuration (Priority: P2) +*Goal: Allow administrators to configure the storage root path via Settings.* + +### Backend +- [ ] T024 [US2] Add `storage_path` field to main configuration model in `backend/src/core/config_models.py` (if not using separate storage config) +- [ ] T025 [US2] Implement `GET /api/settings/storage` and `PUT /api/settings/storage` endpoints in `backend/src/api/routes/settings.py` (or `storage.py`) +- [ ] T026 [US2] Update `StoragePlugin` to read root path from global configuration instead of hardcoded default +- [ ] T027 [US2] Add validation logic to `PUT` endpoint to ensure new path is writable + +### Frontend +- [ ] T028 [US2] Add `getStorageConfig` and `updateStorageConfig` to `frontend/src/services/storageService.js` +- [ ] T029 [US2] Create configuration section in `frontend/src/routes/settings/+page.svelte` (or dedicated Storage Settings component) +- [ ] T030 [US2] Implement form to update storage path with validation feedback +- [ ] T031 [US2] Add configuration fields for directory structure and filename patterns in `backend/src/models/storage.py` and `frontend/src/routes/settings/+page.svelte` +- [ ] T032 [US2] Implement logic in `StoragePlugin` to resolve dynamic paths based on configured patterns + +## Phase 5: Polish & Cross-Cutting +*Goal: Finalize UI/UX and ensure robustness.* + +- [ ] T033 Add link to "File Storage" in main navigation `frontend/src/components/Navbar.svelte` +- [ ] T034 Add error handling toasts for failed uploads or file operations +- [ ] T035 Verify large file upload support (50MB+) in Nginx/FastAPI config if applicable +- [ ] T036 Add confirmation modal for file deletion + +## Dependencies + +1. **Phase 1 (Setup)**: No dependencies. +2. **Phase 2 (Foundational)**: Depends on Phase 1. +3. **Phase 3 (US1)**: Depends on Phase 2. +4. **Phase 4 (US2)**: Depends on Phase 2. Can run parallel to Phase 3. +5. **Phase 5 (Polish)**: Depends on Phase 3 and 4. + +## Parallel Execution Examples + +- **Backend/Frontend Split**: T015-T018 (Backend Endpoints) can be developed in parallel with T020-T021 (Frontend Components) using mock data. +- **Story Split**: US1 (File Management) and US2 (Configuration) are largely independent after Phase 2 is complete. + +## Implementation Strategy + +1. **MVP**: Complete Phases 1, 2, and 3. This delivers a working file manager with a default storage location. +2. **Full Feature**: Complete Phase 4 to allow path configuration. +3. **Polish**: Complete Phase 5 for better UX. \ No newline at end of file