Imported from laichuiwoya/xiaowo_app (
AGENTS.md). Install upstream withnpx skills add laichuiwoya/xiaowo_app. Copyright stays with the author.
Project Rules For Agents
Scope
This project is a Flutter app named 小窝. Current development targets Android APK and Android/LDPlayer testing only. Do not spend effort on iOS, Web, desktop, CloudBase, or real chat unless the user explicitly changes scope. The only backend currently in scope is the local/hosted mood-summary proxy under server/.
Product Direction
- Healing-style mood journal and private personal space.
- UI should stay warm, cream-toned, young, spacious, and Material 3 based.
- Prefer large rounded cards, soft borders, and calm copy.
- Avoid marketing landing pages; build usable app screens directly.
Current Architecture
lib/app/xiaowo_app.dartstarts through a local auth startup gate.lib/features/shell/main_shell_page.dartowns the 5-tab bottom navigation: 首页、心情、小窝、聊天、我的.lib/features/auth/auth_page.dartowns local registration, login, register page, and switch-account page.lib/features/profile/profile_page.dartshows the profile summary and personal profile entry.lib/features/profile/profile_edit_page.dartedits local personal profile data.lib/features/mood/daily_mood_entry_page.dartasks for the entry mood and event note before entering the app.lib/features/mood/mood_page.dartlists local mood records, filters by dates that have records, can publish/unpublish a record to 小窝, and can open both published and private mood comment detail.lib/features/nest/nest_page.dartandlib/features/nest/nest_mood_detail_page.dartshow locally published mood posts from the current account and mutual local friends, plus local comments and unread comment badges.lib/features/chat/chat_page.dart,lib/features/chat/add_friend_page.dart,lib/features/chat/contacts_page.dart,lib/features/chat/friend_profile_page.dart, andlib/features/chat/friend_chat_page.dartown local mock friend requests, contacts, friend profiles, conversations, deletion, and one-to-one chat UI.lib/features/home/home_page.dartsummarizes today's mood locally, shows cached remote summaries, lets users add an extra mood from 首页, shows the latest mood record, and callsRemoteMoodSummaryServiceonly after the user taps the analysis button.lib/core/services/local_auth_store.dartstores local registration and login state.lib/core/services/local_account_scope.dartbuilds per-accountshared_preferenceskeys for local data isolation.lib/core/services/local_profile_store.dartstores local personal profile data.lib/core/services/local_mood_store.dartstores local mood records.lib/core/services/local_nest_store.dartstores locally published mood posts, private mood comment threads, comment seen state, and comments, sorted by publish time where applicable.lib/core/services/local_friend_store.dartstores local mock friend requests, accepted friends, one-way deletion, and mutual-friend checks.lib/core/services/local_chat_store.dartstores local mock chat messages, hidden conversation ids, unread state, failed outgoing messages, and system notices.lib/core/models/personal_profile.dartowns profile fields and constellation calculation.
Local Data Rules
shared_preferencesis the persistence layer for the current MVP.- Login state is separate from registered account data.
- Logout must clear only login state, not registered account or profile data.
LocalAuthStore.isLoggedIn()reloads preferences before checking persisted state.- Multiple local accounts may exist; each mobile number can register only one account.
- Each local account has its own 8-digit 小窝 ID and its own profile, mood records, published posts, comments, mood-summary cache, friends, chats, and hidden conversations.
LocalAccountScopeshould be used for new account-ownedshared_preferencesdata; do not store account-owned data under a shared global key.- Avatar storage currently saves a local image path selected by
image_picker; it does not copy the file into app-managed storage yet. - Mood records, published mood posts, private mood comment threads, comment seen state, and comments are local
shared_preferencesdata. - Publishing to 小窝 is local mock publishing; only mutual accepted local friends on the same device can see published mood posts, and this is not real cross-device social sync.
- Published mood posts keep both
publishedAtand the original moodcreatedAt; 小窝 lists sort bypublishedAtdescending. - Published mood posts store the publisher's 8-digit 小窝 ID and should resolve display names from the account's personal profile nickname when available.
- Published mood comments store the commenter's 8-digit 小窝 ID when a user is logged in and should resolve display names from the account's personal profile nickname when available.
- Unpublished mood records can still open a private comment detail thread; private comments are visible only to the current account.
- Unpublishing a mood archives existing comments into the private thread when comments exist. Republishing the same mood restores archived comments to 小窝.
- Restored comments from a previously unpublished mood must not create unread comment reminders for friends when the mood is republished.
- Friend requests are a local global request pool keyed by from/to 小窝 ID so another local account can receive them after switching accounts.
- Accepted friends, chat messages, and hidden conversations are account-owned local
shared_preferencesdata. - Adding a friend creates a pending request; accepting the request adds each account to the other account's local friend list.
- If the target still has the current account as a friend after one-way deletion, adding that target by 小窝 ID restores friendship directly without a pending verification request.
- Deleting a friend is one-way: it removes the friend only from the current account's list, clears only the current account's local chat with that friend, and leaves existing mood comments/data in place.
- Mutual friendship, not one-sided list membership, gates friend mood visibility, friend-profile mood previews, and successful chat delivery.
- If the current account deleted a friend but the other side did not, the other side can keep the old conversation locally, but new messages to the deleting account are saved as failed local outgoing messages and are not delivered.
- Chat list hide only removes the conversation from the list; clearing chat history deletes that friend's local messages for the current account unless a call explicitly clears both sides.
Mood Summary API Rules
- DeepSeek API keys must never be committed, added to Flutter code, or packaged into APKs.
- The app reads only
XIAOWO_MOOD_SUMMARY_ENDPOINTandXIAOWO_MOOD_SUMMARY_TOKENfrom--dart-define. - The DeepSeek key belongs only in local shell environment variables, ignored
server/.env, or deployment environment variables. - 首页 must not call
RemoteMoodSummaryServiceon initial load; only the user-triggered analysis button may consume API quota. - If
RemoteMoodSummaryServicecannot reach the proxy or receives invalid data, 首页 must keep/fall back to local summary logic. - Keep
server/.env,server/.env.*, and other local secret helper files ignored by Git.
Home And Mood Rules
- 首页 can add mood records through a bottom-sheet flow similar to DailyMoodEntryPage; saving must refresh both today's summary and the latest-record card.
- 首页 latest-record card should show the newest local
MoodEntrybycreatedAt, including emoji, mood, timestamp, and a short note preview when present. - 首页 must not call remote mood analysis merely because a mood was added; only the analysis button may call
RemoteMoodSummaryService.
Auth Rules
- Account is a China mainland mobile number:
^1[3-9]\d{9}$. - Password is 8-20 characters and must contain at least one letter and one digit.
- A mobile number cannot be registered twice.
- Registration requires confirm password to match.
- Registration does not automatically enter the app; user logs in after successful registration.
- Login success calls
LocalAuthStore.markLoggedIn(account). - Switch-account first shows historical local accounts; tapping a different historical account switches without entering a password.
- Tapping the currently logged-in account in switch-account must only show 账号已登录; do not re-login or navigate away.
Profile Rules
- Birthday controls constellation automatically in
PersonalProfile. - Entry greetings should prefer the current account's personal profile nickname; fall back to the registered nickname only when the profile nickname is empty.
- Hometown must use the complete province / city / district picker from
city_picker_china. - Do not replace the hometown picker with handwritten partial area data.
- Gender stays as a styled dropdown, not inline chips.
- Keep the “个人资料” list item on 我的 page as a simple single-line entry; do not show detailed field descriptions there.
- Switch-account list display names come from each account's personal profile nickname; if empty, show the default 小窝用户.
Commands
flutter analyze
flutter test
flutter build apk
Local API development requires the Node proxy to be running separately:
node server/deepseek_mood_summary_proxy.mjs
When adding native plugins, do a full restart/reinstall:
flutter clean
flutter pub get
flutter run