蜂鸟Pro v2.0.1 - 基础框架版本 (待完善)
## 当前状态 - 插件界面已完成重命名 (cursorpro → hummingbird) - 双账号池 UI 已实现 (Auto/Pro 卡片) - 后端已切换到 MySQL 数据库 - 添加了 Cursor 官方用量 API 文档 ## 已知问题 (待修复) 1. 激活时检查账号导致无账号时激活失败 2. 未启用无感换号时不应获取账号 3. 账号用量模块不显示 (seamless 未启用时应隐藏) 4. 积分显示为 0 (后端未正确返回) 5. Auto/Pro 双密钥逻辑混乱,状态不同步 6. 账号添加后无自动分析功能 ## 下一版本计划 - 重构数据模型,优化账号状态管理 - 实现 Cursor API 自动分析账号 - 修复激活流程,不依赖账号 - 启用无感时才分配账号 - 完善账号用量实时显示 ## 文件说明 - docs/系统设计文档.md - 完整架构设计 - cursor 官方用量接口.md - Cursor API 文档 - 参考计费/ - Vibeviewer 开源项目参考 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
108
参考计费/.cursor/rules/architecture.mdc
Normal file
108
参考计费/.cursor/rules/architecture.mdc
Normal file
@@ -0,0 +1,108 @@
|
||||
---
|
||||
alwaysApply: true
|
||||
title: Vibeviewer Architecture Guidelines
|
||||
---
|
||||
|
||||
## Background
|
||||
|
||||
- The project uses a layered, modular Swift Package architecture with goals: minimal public surface, one-way dependencies, single responsibility, testability, and replaceability.
|
||||
- Layers and dependency direction (top-down only):
|
||||
- Core/Shared → common utilities and extensions (no business-layer dependencies)
|
||||
- Model → pure data/DTO/domain entities (may depend on Core)
|
||||
- API/Service → networking/IO/3rd-party orchestration and DTO→domain mapping (depends on Model + 3rd-party)
|
||||
- Feature/UI → SwiftUI views and interactions (depends on API-exposed service protocols and domain models; must not depend on networking libraries)
|
||||
- Architectural style: Native SwiftUI MV (not MVVM). State via @State/@Observable; dependency injection via @Environment; concurrency with async/await and @MainActor.
|
||||
|
||||
## Do (Recommended)
|
||||
|
||||
- Module placement & responsibilities
|
||||
- Before adding code, decide whether it belongs to UI/Service/Model/Core and place it in the corresponding package/directory; one type/responsibility per file.
|
||||
- The API layer exposes only “service protocol + default implementation”; networking library/targets/plugins are encapsulated internally.
|
||||
- Service functions return domain models (Model-layer entities) or clear error types; avoid leaking DTOs to the UI.
|
||||
|
||||
- Domain models & mapping
|
||||
- Abstract API response DTOs into domain entities (e.g., UserProfile / UsageOverview / TeamSpendOverview / UsageEvent / FilteredUsageHistory).
|
||||
- Perform DTO→domain mapping in the API layer; UI consumes domain-only.
|
||||
|
||||
- Dependencies & visibility
|
||||
- One-way: Core ← Model ← API ← Feature.
|
||||
- Default to internal; use public only for cross-package use; prefer protocols over concrete types.
|
||||
|
||||
- SwiftUI & concurrency
|
||||
- Inject services via @Environment; place side effects in .task / .onChange so they automatically cancel with the view lifecycle.
|
||||
- UI updates occur on @MainActor; networking/IO on background using async/await; cross-isolation types must be Sendable.
|
||||
|
||||
- Testing & replaceability
|
||||
- Provide an injectable network client interface for services; separate default implementation from testable construction paths.
|
||||
- Put utilities/algorithms into Core; prefer pure functions for unit testing and reuse.
|
||||
|
||||
- Troble Shooting
|
||||
- if you facing an lint error by "can't not found xxx in scope" when you edit/new/delete some interface on Package, that means you need to call XCodeBuildMCP to rebuild that package, so that other package can update the codebase to fix that error
|
||||
|
||||
## Don't (Avoid)
|
||||
|
||||
- UI directly depending on networking libraries, triggering requests, or being exposed to backend error details.
|
||||
- Feature depending on API internals (e.g., Targets/Plugins/concrete networking implementations).
|
||||
- Exposing API DTOs directly to the UI (causes global coupling and fragility).
|
||||
- Reverse dependencies (e.g., Model depends on Feature; API depends on UI).
|
||||
- Introducing MVVM/ViewModel as the default; or using Task { } in onAppear (use .task instead).
|
||||
- Overusing public types/initializers; placing multiple unrelated types in one file.
|
||||
|
||||
## Review checklist
|
||||
|
||||
1) Quadrant self-check (placement)
|
||||
- UI/interaction/rendering → Feature/UI
|
||||
- Networking/disk/auth/3rd-party → API/Service
|
||||
- Pure data/DTO/state aggregation → Model
|
||||
- Utilities/extensions/algorithms → Core
|
||||
|
||||
2) Surface area & replaceability
|
||||
- Can it be exposed via protocol to hide details? Is internal sufficient by default?
|
||||
- Do services return only domain models/error enums? Is it easy to replace/mock?
|
||||
|
||||
3) Dependency direction & coupling
|
||||
- Any violation of Core ← Model ← API ← Feature one-way dependency?
|
||||
- Does the UI still reference DTOs or networking implementations? If yes, move mapping/abstraction to the API layer.
|
||||
|
||||
4) Concurrency & thread safety
|
||||
- Are UI updates on @MainActor? Are cross-isolation types Sendable? Are we using async/await?
|
||||
- Should serialization-required persistence/cache be placed within an Actor boundary?
|
||||
|
||||
5) File organization & naming
|
||||
- Clear directories (Feature/Views, API/Service, API/Targets, API/Plugins, Model/Entities, Core/Extensions).
|
||||
- One type per file; names reflect layer and responsibility (e.g., FeatureXView, FeatureXService, GetYAPI, ZResponse).
|
||||
- Package directory structure: Sources/<PackageName>/ organized by feature subfolders; avoid dumping all source at one level.
|
||||
- Suggested subfolders:
|
||||
- API: Service / Targets / Plugins / Mapping (DTO→Domain mapping)
|
||||
- Feature: Views / Components / Scenes / Modifiers
|
||||
- Model: Entities
|
||||
- Core: Extensions / Utils
|
||||
- Consistent naming: use a shared prefix/suffix for similar features for discoverability.
|
||||
- Suffix examples: …Service, …API, …Response, …Request, …View, …Section, …Window, …Plugin, …Mapper.
|
||||
- Use a consistent domain/vendor prefix where needed (e.g., Cursor…).
|
||||
- File name equals type name: each file contains only one primary type; exact case-sensitive match.
|
||||
- Protocol/implementation convention: protocol uses FooService; default implementation uses DefaultFooService (or LiveFooService). Expose only protocols and inject implementations.
|
||||
|
||||
- Model-layer naming (Entities vs DTOs):
|
||||
- Entities (exposed to business/UI):
|
||||
- Use domain-oriented neutral nouns; avoid vendor prefixes by default (e.g., UserProfile, UsageOverview, TeamSpendOverview, UsageEvent, FilteredUsageHistory, AppSettings, Credentials, DashboardSnapshot).
|
||||
- If source domain must be shown (e.g., “Cursor”), use a consistent prefix within that domain (e.g., CursorCredentials, CursorDashboardSnapshot) for consistency and discoverability.
|
||||
- Suggested suffixes: …Overview, …Snapshot, …History, …Event, …Member, …RoleCount.
|
||||
- Prefer struct, value semantics, and Sendable; expose public types/members only when needed cross-package.
|
||||
- File name equals type name; single-type files.
|
||||
- DTOs (API layer only, under API/Mapping/DTOs):
|
||||
- Use vendor/source prefix + semantic suffix: e.g., Cursor…Request, Cursor…Response, Cursor…Event.
|
||||
- Default visibility is internal; do not expose to Feature/UI; map to domain in the API layer only.
|
||||
- File name equals type name; single-type files; field names mirror backend responses (literal), adapted to domain naming via mapping.
|
||||
- Mapping lives in the API layer (Service/Mapping); UI/Feature must never depend on DTOs.
|
||||
|
||||
## Pre-PR checks
|
||||
- Remove unnecessary public modifiers; check for reverse dependencies across layers.
|
||||
- Ensure UI injects services via @Environment and contains no networking details.
|
||||
- Ensure DTO→domain mapping is complete, robust, and testable.
|
||||
|
||||
Note: When using iOS 26 features, follow availability checks and progressive enhancement; ensure reasonable fallbacks for older OS versions.
|
||||
|
||||
## FAQ
|
||||
- After adding/removing module code, if lint reports a missing class but you are sure it exists, rebuild the package with XcodeBuild MCP and try again.
|
||||
|
||||
Reference in New Issue
Block a user