b34697660d
- 新增 AuthSessionInvalidated 事件处理 token 失效场景 - ApiInterceptor 新增 authFailureCallback 单飞机制 - AuthBloc 区分 manual logout 与 auto expiry 语义 - 新增 startup recovery fallback 防止启动卡死 feat: 重构 Calendar DayWeek 视图事件布局引擎 - 新增 DayEventLayoutEngine 解耦事件计算与渲染 - 新增 DayTimelineMetrics 统一时间轴常量 - 新增 DayViewScale 支持捏合缩放 feat: 新增 Settings 页面共享 UI 组件 - 新增 BackTitlePageHeader 统一页面 header - 新增 DetailHeaderActionMenu 统一操作菜单 - 新增 DestructiveActionSheet 统一删除确认 - 新增 AppToggleSwitch 统一开关组件 feat: Chat UI Schema 支持导航操作 - 支持 navigation 类型 action 触发内部路由跳转 - 新增路径验证与参数处理 chore: 更新相关测试覆盖 auth 失效路径
8.7 KiB
8.7 KiB
Flutter Mobile Development Constraints
This document defines hard constraints for Flutter mobile development. Treat all items as non-negotiable unless explicitly overridden.
0) Scope and Precedence (MUST)
- This file applies to all changes under
apps/**. - It extends root routing rules in
AGENTS.mdand workspace global runtime rules. - It also incorporates the visual design language from
apps/rules/visual_design_language.mdas a binding constraint. - If rules conflict, apply the stricter requirement.
- Keep Flutter-specific constraints in this file; avoid duplicating them in root
AGENTS.md.
1) Design Tokens (MUST)
- MUST use design tokens from
apps/lib/core/theme/design_tokens.dart:- Colors:
AppColors.* - Spacing:
AppSpacing.* - Radius:
AppRadius.*
- Colors:
- MUST NOT hardcode any visual values.
- Design tokens are the single source of truth for all visual values. Any missing visual semantics should be added to tokens, not approximated locally.
- This ensures consistency with the visual design language defined in
apps/rules/visual_design_language.md.
2) Component Architecture (MUST)
- SHOULD extract repeated UI patterns into reusable components.
- SHOULD prefer existing shared components before creating new ones.
- SHOULD place reusable components in
apps/lib/shared/widgets/following existing naming conventions. - MUST NOT introduce parallel UI systems (e.g., custom button styles, custom loading indicators) that duplicate existing shared components.
- When creating new UI components, ensure they follow the design tokens and visual design language.
2.1) Navigation/Header Reuse Rules (MUST)
- For page groups with clear parent-child relationships (e.g., Settings and its subpages), MUST use one shared header pattern: back button + page title.
- MUST extract shared page scaffolds/header wrappers instead of duplicating
SafeArea + header + scrollstructures across sibling pages. - Detail-page right-side actions (edit/delete/share etc.) MUST use a shared action-menu component, not per-page ad-hoc button groups.
- Header action menus MUST NOT overlap the trigger button area; menu surfaces should open below/right-aligned to the trigger and preserve title readability.
2.2) Interaction Surface Reuse Rules (MUST)
- Repeated state-switch controls (toggle/switch UI) MUST be extracted into shared widgets.
- Destructive confirmations (delete/remove) MUST use shared project-style confirmation surfaces (e.g., unified action sheet), not platform-default dialog styles.
- MUST NOT use raw platform-default popup/dialog/dropdown visuals when they break project visual language; use token-driven shared components instead.
3) Layout Mapping & Alignment (MUST)
- MUST explicitly set
crossAxisAlignmentfor everyRow/Column(do not rely on defaults). - MUST preserve layout semantics from root to leaf:
- alignment/justification intent must be explicitly represented in Flutter widgets.
- MUST NOT skip necessary container layers if doing so loses layout meaning or makes mapping non-traceable.
4) Centering & Visual Balance (MUST)
- MUST evaluate centering within
SafeAreausable bounds (not full-screen bounds). - MUST NOT rely on
Spacer/ proportional flex as the only centering mechanism for critical content. - If persistent header/footer regions exist, MUST center primary content within the remaining usable region.
- MUST prioritize visual centering over purely geometric centering when they differ.
5) Testing Strategy (MUST)
Follow lightweight testing strategy - prioritize value over coverage:
Write tests for:
- Model / DTO parsing (json → model)
- Service layer logic (business rules, API call handling)
- Complex custom widgets with rich interactions
Skip for:
- Simple UI pages, regular buttons, basic layouts
6) UI Feedback System (MUST)
- All user-facing feedback MUST use the Toast system.
- Transient notifications:
Toast.show(...) - Persistent inline form errors:
AppBanner
- Transient notifications:
- MUST NOT create custom SnackBar/Dialog/Banner feedback components.
- MUST NOT use raw
ScaffoldMessengerfor feedback messaging.
6.1) Loading Indicator System (MUST)
- All loading spinners MUST use
AppLoadingIndicatorfromapps/lib/shared/widgets/app_loading_indicator.dart. - MUST NOT use raw
CircularProgressIndicatordirectly in feature/page code. - Use variants consistently:
- page/surface loading:
AppLoadingVariant.surface - inline small loading (list/search/section):
AppLoadingVariant.inline - button loading:
AppLoadingVariant.button
- page/surface loading:
- If visual semantics are missing, extend
AppLoadingIndicatorvariant mapping first; do not create ad-hoc loading styles in feature files.
7) Agent Chat (AG-UI Protocol) (MUST)
Agent chat functionality MUST follow the AG-UI protocol. Use the ag-ui skill for protocol reference and implementation guidance.
- MUST use Server-Sent Events (SSE) for streaming.
- MUST emit required lifecycle events:
RUN_STARTEDis required for every run- End with exactly one of:
RUN_FINISHEDorRUN_ERROR
- MUST follow standard text streaming flow:
TEXT_MESSAGE_START→TEXT_MESSAGE_CONTENT(delta) →TEXT_MESSAGE_END
- MUST support the standard AG-UI event type set as defined in the spec.
- MUST NOT return non-streaming responses for agent chat.
- MUST NOT omit required lifecycle events.
- MUST NOT use non-AG-UI event formats (except where the spec explicitly allows).
8) Visual Design Language (MUST)
All UI/UX work MUST follow the visual design language defined in apps/rules/visual_design_language.md.
- MUST ensure screens feel like a premium personal assistant product, not a wireframe, admin console, or document page.
- MUST apply the surface-based design system (background, primary, secondary, interactive surfaces).
- MUST follow the motion and interaction feel guidelines (soft, responsive, premium).
- MUST achieve visual hierarchy through spacing, surface grouping, radius, depth, density, contrast, scale, and motion—not color alone.
- MUST prioritize compact informational delivery in top bars: when the page purpose can be clearly expressed by a concise header title, avoid repeating equivalent explanatory hints in the body.
- MUST NOT duplicate page identity text between header and first content block unless the repeated text introduces new decision-critical information.
- MUST follow the screen-level decision rules:
- What is the primary focus?
- What is the surface hierarchy?
- What needs strongest emphasis?
- What should be grouped?
- What should be lightweight/secondary?
- Where should motion reinforce understanding?
- How can the result feel more like a premium assistant app and less like a document page?
- MUST NOT create UIs that match the anti-patterns listed in the visual design language document:
- plain document page, white slab with blue buttons, spreadsheet-like admin panel
- low-fidelity wireframe, default Flutter demo app, generic template marketplace screen
- full-screen flat white blocks, arbitrary shadow usage, inconsistent card treatments
- raw container stacking without surface semantics
Before finalizing any UI, mentally verify:
- Does this feel like a product, not a page?
- Is there clear hierarchy?
- Do surfaces feel intentional?
- Does the screen feel calm and premium?
- Is the assistant identity visually present?
- Would this look plausible in a polished shipping app?
9) Auth Global Module Rules (MUST)
Auth is a global module. All auth/session behavior MUST follow a single state machine.
- MUST treat
AuthBlocas the single source of truth for authentication state. - MUST NOT implement ad-hoc auth state in feature modules (no parallel flags, no local auth caches).
- MUST route all 401 refresh-failure handling through the global callback chain:
ApiInterceptor -> ApiClient auth failure callback -> AuthBloc(AuthSessionInvalidated). - MUST NOT clear tokens directly inside feature/page code.
- MUST NOT navigate to login directly from feature code on token errors; rely on router redirect driven by global auth state.
- MUST distinguish logout semantics:
- manual logout: revoke server session + clear local session
- auto expiry/logout on refresh failure: clear local session only
- MUST ensure startup session recovery has exception fallback and never leaves app stuck in boot/loading state.
- MUST add/maintain tests for:
- startup recovery fallback
- concurrent 401 refresh failure singleflight
- session invalidation -> unauthenticated redirect path
If a new auth-related requirement cannot fit this model, update this section first, then implement code.