Files
cursornew2026/参考计费/.cursor/rules/architecture.mdc
ccdojox-crypto 73a71f198f 蜂鸟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>
2025-12-18 11:21:52 +08:00

109 lines
6.9 KiB
Plaintext

---
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.