# Vue3 + Python Notepad 应用 - 全栈架构文档 **文档版本**: 1.0 **创建日期**: 2025-12-18 **作者**: BMad Architect **项目状态**: Greenfield (全新开发) --- ## 1. Introduction This document outlines the complete fullstack architecture for Vue3 + Python Notepad 应用, including backend systems, frontend implementation, and their integration. It serves as the single source of truth for AI-driven development, ensuring consistency across the entire technology stack. This unified approach combines what would traditionally be separate backend and frontend architecture documents, streamlining the development process for modern fullstack applications where these concerns are increasingly intertwined. ### 1.1 Starter Template or Existing Project N/A - Greenfield project ### 1.2 Change Log | 日期 | 版本 | 描述 | 作者 | |------|------|------|------| | 2025-12-18 | 1.0 | 初始全栈架构文档创建 | BMad Architect | --- ## 2. High Level Architecture ### 2.1 Technical Summary This application uses a modern monolithic architecture with a Vue3 frontend and Python FastAPI backend, deployed via Docker containers on Ubuntu infrastructure. The system provides real-time text editing with automatic saving through WebSocket communication, while maintaining simplicity through file-based storage without database complexity. The architecture prioritizes performance, security, and ease of deployment while supporting URL-driven document access and secure file management. ### 2.2 Platform and Infrastructure Choice **Platform:** Self-hosted Docker deployment **Key Services:** Docker, Nginx, Python FastAPI, Node.js **Deployment Host and Regions:** Ubuntu物理机部署,单区域部署 Rationale: Self-hosted approach provides maximum control over file storage and security while keeping infrastructure costs minimal. Docker containerization ensures consistent development and production environments. ### 2.3 Repository Structure **Repository Structure:** Simple frontend/backend separation **Monorepo Tool:** None (simplified structure) **Package Organization:** - `frontend`: Vue3 frontend application - `backend`: Python FastAPI backend Rationale: Simplified structure reduces complexity for this focused application, making it easier to understand and maintain. ### 2.4 Architecture Diagram ```mermaid graph TD A[用户浏览器] --> B[Nginx反向代理] B --> C[Vue3前端应用] B --> D[FastAPI后端] D --> E[WebSocket服务] D --> F[文件存储系统] F --> G[./data/notes目录] C --> H[Vue Router] C --> I[Pinia状态管理] C --> J[WebSocket客户端] J --> E ``` ### 2.5 Architectural Patterns - **Monolithic Architecture:** Single deployable unit with clear frontend/backend separation - _Rationale:_ Simplifies deployment and debugging for this focused application - **Component-Based UI:** Reusable Vue3 components with TypeScript - _Rationale:_ Maintainability and type safety across the codebase - **WebSocket Communication:** Real-time bidirectional communication - _Rationale:_ Enables instant auto-save without polling overhead - **File-Based Storage:** Direct file system storage instead of database - _Rationale:_ Simplifies deployment and aligns with the notepad metaphor - **Repository Pattern:** Abstract file operations - _Rationale:_ Enables testing and future storage migration - **JWT Authentication:** Token-based authentication for file list access - _Rationale:_ Stateless authentication suitable for this simple use case --- ## 3. Tech Stack ### 3.1 Technology Stack Table | Category | Technology | Version | Purpose | Rationale | |----------|------------|---------|---------|-----------| | Frontend Language | TypeScript | 5.0+ | 类型安全的JavaScript开发 | 提供编译时类型检查,提高代码质量 | | Frontend Framework | Vue 3 | 3.3+ | 构建响应式用户界面 | 轻量级、高性能、易学易用 | | UI Component Library | 自定义组件 | - | 构建应用特定UI组件 | 避免过度工程化,保持轻量 | | State Management | Pinia | 2.1+ | Vue状态管理 | Vue官方推荐,简单直观 | | Backend Language | Python | 3.10+ | 后端服务开发 | 丰富的生态系统,易于部署 | | Backend Framework | FastAPI | 0.104+ | 构建高性能API | 自动API文档,内置WebSocket支持 | | API Style | REST + WebSocket | - | 前后端通信协议 | REST用于标准操作,WebSocket用于实时通信 | | Database | 无 | - | 不使用数据库 | 简化架构,直接使用文件系统 | | Cache | 内存缓存 | - | 提高文件读取性能 | 减少重复的文件系统操作 | | File Storage | 本地文件系统 | - | 存储文本文件 | 简单直接,符合notepad概念 | | Authentication | JWT | - | 文件列表访问验证 | 无状态,适合简单认证需求 | | Frontend Testing | Vitest | 1.0+ | 前端单元测试 | Vite集成,快速测试 | | Backend Testing | pytest | 7.4+ | 后端单元测试 | Python标准测试框架 | | E2E Testing | Playwright | 1.40+ | 端到端测试 | 跨浏览器测试支持 | | Build Tool | Vite | 5.0+ | 前端构建工具 | 快速开发服务器和构建 | | Bundler | Rollup | - | 前端打包 | Vite内置,优化打包 | | IaC Tool | Docker Compose | 2.20+ | 基础设施即代码 | 简化部署和环境管理 | | CI/CD | GitHub Actions | - | 持续集成和部署 | 与代码仓库集成 | | Monitoring | 自定义日志 | - | 应用监控 | 轻量级日志记录 | | Logging | Python logging + 自定义 | - | 日志记录 | 结构化日志,便于调试 | | CSS Framework | 自定义CSS | - | 样式管理 | 避免外部依赖,保持轻量 | --- ## 4. Data Models ### 4.1 TextFile **Purpose:** 表示存储在系统中的文本文件 **Key Attributes:** - filename: string - 文件名(包含.txt扩展名) - content: string - 文件内容 - created_at: datetime - 创建时间 - updated_at: datetime - 最后更新时间 - size: number - 文件大小(字符数) #### TypeScript Interface ```typescript interface TextFile { filename: string; content: string; created_at: Date; updated_at: Date; size: number; } ``` #### Relationships - 无关系 - 独立实体 ### 4.2 FileListItem **Purpose:** 文件列表页面显示的文件信息 **Key Attributes:** - filename: string - 文件名 - created_at: datetime - 创建时间 - size: number - 文件大小 #### TypeScript Interface ```typescript interface FileListItem { filename: string; created_at: Date; size: number; } ``` #### Relationships - 无关系 - 聚合数据 ### 4.3 AuthToken **Purpose:** 认证令牌 **Key Attributes:** - token: string - JWT令牌 - expires_at: datetime - 过期时间 #### TypeScript Interface ```typescript interface AuthToken { token: string; expires_at: Date; } ``` #### Relationships - 无关系 - 临时认证数据 --- ## 5. API Specification ### 5.1 REST API Specification ```yaml openapi: 3.0.0 info: title: Vue3 + Python Notepad API version: 1.0.0 description: 简单的文本编辑器API,支持文件读写和列表功能 servers: - url: http://localhost:8000/api description: 开发环境服务器 - url: https://your-domain.com/api description: 生产环境服务器 paths: /notes/{filename}: get: summary: 获取文件内容 parameters: - name: filename in: path required: true schema: type: string description: 文件名(包含.txt扩展名) responses: '200': description: 成功返回文件内容 content: application/json: schema: $ref: '#/components/schemas/TextFile' '404': description: 文件不存在 '400': description: 文件名无效 post: summary: 保存文件内容 parameters: - name: filename in: path required: true schema: type: string description: 文件名(包含.txt扩展名) requestBody: required: true content: application/json: schema: type: object properties: content: type: string description: 文件内容 responses: '200': description: 保存成功 content: application/json: schema: $ref: '#/components/schemas/TextFile' '413': description: 文件过大 '400': description: 文件名无效或内容为空 /files/list: get: summary: 获取文件列表 security: - bearerAuth: [] parameters: - name: page in: query schema: type: integer default: 1 description: 页码 - name: limit in: query schema: type: integer default: 50 description: 每页文件数 responses: '200': description: 成功返回文件列表 content: application/json: schema: type: object properties: files: type: array items: $ref: '#/components/schemas/FileListItem' total: type: integer page: type: integer limit: type: integer '401': description: 未授权访问 '403': description: 令牌无效或过期 /files/verify-password: post: summary: 验证访问口令 requestBody: required: true content: application/json: schema: type: object properties: password: type: string description: 访问口令 responses: '200': description: 验证成功 content: application/json: schema: $ref: '#/components/schemas/AuthToken' '401': description: 口令错误 /health: get: summary: 健康检查 responses: '200': description: 服务正常 content: application/json: schema: type: object properties: status: type: string example: "healthy" components: schemas: TextFile: type: object properties: filename: type: string example: "note.txt" content: type: string example: "这是文件内容" created_at: type: string format: date-time updated_at: type: string format: date-time size: type: integer example: 6 FileListItem: type: object properties: filename: type: string example: "note.txt" created_at: type: string format: date-time size: type: integer example: 6 AuthToken: type: object properties: token: type: string example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." expires_at: type: string format: date-time securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT ``` ### 5.2 WebSocket API #### 连接端点 `ws://localhost:8000/ws/{filename}` #### 消息格式 **客户端发送保存请求:** ```json { "type": "save", "content": "文件内容", "timestamp": "2023-12-18T10:30:00Z" } ``` **服务器响应:** ```json { "type": "save_response", "status": "success|error", "message": "保存成功|错误信息", "timestamp": "2023-12-18T10:30:00Z" } ``` --- ## 6. Components ### 6.1 Frontend Components #### TextEditor **Responsibility:** 提供文本编辑功能和自动保存机制 **Key Interfaces:** - `props.filename`: string - 要编辑的文件名 - `props.initialContent`: string - 初始文件内容 - `emits.save`: (content: string) => void - 保存事件 - `emits.contentChange`: (content: string) => void - 内容变化事件 **Dependencies:** WebSocket客户端,Pinia store **Technology Stack:** Vue 3 Composition API, TypeScript, CSS #### FileList **Responsibility:** 显示文件列表并提供导航功能 **Key Interfaces:** - `props.files`: FileListItem[] - 文件列表数据 - `props.loading`: boolean - 加载状态 - `emits.fileSelect`: (filename: string) => void - 文件选择事件 **Dependencies:** API客户端,Vue Router **Technology Stack:** Vue 3 Composition API, TypeScript, CSS #### AuthForm **Responsibility:** 处理口令验证表单 **Key Interfaces:** - `emits.authSuccess`: (token: string) => void - 认证成功事件 - `emits.authError`: (message: string) => void - 认证失败事件 **Dependencies:** API客户端,本地存储 **Technology Stack:** Vue 3 Composition API, TypeScript, CSS ### 6.2 Backend Components #### FileService **Responsibility:** 处理文件读写操作 **Key Interfaces:** - `readFile(filename: string): TextFile` - 读取文件 - `writeFile(filename: string, content: string): TextFile` - 写入文件 - `listFiles(page: number, limit: number): FileListItem[]` - 列出文件 - `validateFilename(filename: string): boolean` - 验证文件名 **Dependencies:** 文件系统,验证模块 **Technology Stack:** Python 3.10+, OS模块 #### AuthService **Responsibility:** 处理认证和授权 **Key Interfaces:** - `verifyPassword(password: string): AuthToken` - 验证口令 - `validateToken(token: string): boolean` - 验证令牌 - `generateToken(): string` - 生成令牌 **Dependencies:** JWT库,环境变量 **Technology Stack:** Python 3.10+, PyJWT #### WebSocketHandler **Responsibility:** 处理WebSocket连接和消息 **Key Interfaces:** - `handleConnection(websocket: WebSocket, filename: string)` - 处理连接 - `handleMessage(websocket: WebSocket, message: dict)` - 处理消息 - `broadcastUpdate(filename: string, content: string)` - 广播更新 **Dependencies:** FastAPI WebSocket,FileService **Technology Stack:** Python 3.10+, FastAPI --- ## 7. External APIs N/A - 本项目不依赖外部API服务 --- ## 8. Core Workflows ### 8.1 文件编辑和自动保存 ```mermaid sequenceDiagram participant User participant Browser participant VueApp participant WebSocket participant FastAPI participant FileSystem User->>Browser: 访问/notes/file.txt Browser->>VueApp: 加载编辑页面 VueApp->>FastAPI: GET /api/notes/file.txt FastAPI->>FileSystem: 读取文件 FileSystem-->>FastAPI: 返回文件内容 FastAPI-->>VueApp: 返回TextFile对象 VueApp-->>Browser: 显示编辑界面 User->>Browser: 输入文本 Browser->>VueApp: 触发input事件 VueApp->>VueApp: 防抖处理(500ms) VueApp->>WebSocket: 发送保存消息 WebSocket->>FastAPI: 处理WebSocket消息 FastAPI->>FileSystem: 写入文件 FileSystem-->>FastAPI: 写入成功 FastAPI-->>WebSocket: 返回保存响应 WebSocket-->>VueApp: 更新保存状态 VueApp-->>Browser: 显示"已保存"状态 ``` ### 8.2 文件列表访问认证 ```mermaid sequenceDiagram participant User participant Browser participant VueApp participant API participant AuthService User->>Browser: 访问/file-list Browser->>VueApp: 加载文件列表页面 VueApp->>VueApp: 检查本地令牌 alt 令牌存在且有效 VueApp->>API: GET /api/files/list (带令牌) API->>AuthService: 验证令牌 AuthService-->>API: 令牌有效 API->>API: 获取文件列表 API-->>VueApp: 返回文件列表 VueApp-->>Browser: 显示文件列表 else 令牌不存在或无效 VueApp-->>Browser: 显示口令输入表单 User->>Browser: 输入口令 Browser->>VueApp: 提交口令 VueApp->>API: POST /api/files/verify-password API->>AuthService: 验证口令 AuthService-->>API: 生成令牌 API-->>VueApp: 返回令牌 VueApp->>VueApp: 保存令牌到本地 VueApp->>API: GET /api/files/list (带新令牌) API-->>VueApp: 返回文件列表 VueApp-->>Browser: 显示文件列表 end ``` --- ## 9. Database Schema N/A - 本项目使用文件系统存储,不使用数据库 --- ## 10. Frontend Architecture ### 10.1 Component Architecture #### Component Organization ``` src/ ├── components/ # 可复用组件 │ ├── common/ # 通用组件 │ │ ├── Button.vue │ │ ├── Modal.vue │ │ └── StatusIndicator.vue │ ├── editor/ # 编辑器相关组件 │ │ ├── TextEditor.vue │ │ └── SaveStatus.vue │ └── files/ # 文件管理组件 │ ├── FileList.vue │ ├── FileListItem.vue │ └── AuthForm.vue ├── views/ # 页面组件 │ ├── EditorView.vue │ └── FileListView.vue ├── stores/ # Pinia状态管理 │ ├── editor.ts │ ├── files.ts │ └── auth.ts ├── services/ # API服务 │ ├── api.ts │ ├── websocket.ts │ └── storage.ts ├── router/ # 路由配置 │ └── index.ts ├── utils/ # 工具函数 │ ├── validation.ts │ └── helpers.ts └── styles/ # 样式文件 ├── main.css └── components.css ``` #### Component Template ```vue