一键导入
mobile-patterns
Use when working in apps/mobileAppYC. Covers React Native architecture, navigation, Redux Toolkit state management, and mobile-specific conventions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when working in apps/mobileAppYC. Covers React Native architecture, navigation, Redux Toolkit state management, and mobile-specific conventions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Use when fixing SonarQube issues in apps/frontend or writing Sonar-clean code. Contains the full enforced rule set with examples and quick fixes.
Use when working in apps/backend — new endpoints, controllers, services, models, queues/workers, or integrations. Covers the Router to Controller to Service to Model architecture, Zod validation, Prisma/PostgreSQL data access, Winston logging, BullMQ jobs, and FHIR/IDEXX/Merck integrations.
Use when reviewing code, auditing a PR, or doing an adversarial review of a change. Runs quality, security, accessibility, and convention checks specific to this codebase.
Use when fixing SonarCloud issues in apps/desktop or writing Sonar-clean Electron and renderer code. Covers the enforced rule categories, the accepted role=dialog deferral, CSP and page-asset rules, and links the live SonarCloud project.
Use when building or changing UI in apps/frontend. Covers the custom design system, component library (Button, Card, Badge, and more), design tokens, and styling conventions so UI stays consistent and on-brand.
Use when fixing SonarQube issues in apps/frontend or writing Sonar-clean code. Contains the full enforced rule set with examples and quick fixes.
| name | mobile-patterns |
| description | Use when working in apps/mobileAppYC. Covers React Native architecture, navigation, Redux Toolkit state management, and mobile-specific conventions. |
Use this skill when working on apps/mobileAppYC. Covers React Native architecture, navigation, Redux state management, and mobile-specific conventions.
TRIGGER: any task in apps/mobileAppYC — screens, components, navigation, state, or native integrations.
apps/mobileAppYC/
src/
screens/ ← Full-screen views
components/ ← Reusable UI components
navigation/ ← React Navigation config
store/ ← Redux Toolkit slices
services/ ← API calls (axios)
hooks/ ← Custom React hooks
utils/ ← Pure utility functions
i18n/ ← Translation files (i18next)
assets/ ← Images, fonts
Redux Toolkit (not Zustand — that's frontend only). Redux Persist is enabled.
// Define a slice
import { createSlice } from '@reduxjs/toolkit';
const appointmentSlice = createSlice({
name: 'appointments',
initialState,
reducers: { ... },
});
Never mix Redux and local useState for the same piece of data. Local state is for ephemeral UI state (modal open, input focus). Shared/persisted state goes in Redux.
React Navigation 7 with bottom tabs + native stack + drawer.
// Type your navigation params
type RootStackParamList = {
Home: undefined;
AppointmentDetail: { appointmentId: string };
};
Never navigate with bare strings — always use typed route names.
react-hook-form + Yup for all forms.
const schema = yup.object({ name: yup.string().required() });
const { control, handleSubmit } = useForm({ resolver: yupResolver(schema) });
All user-visible strings must go through i18next.
import { useTranslation } from 'react-i18next';
const { t } = useTranslation();
<Text>{t('appointments.title')}</Text>;
Never hardcode English strings in components.
PAYMENT_AT_CLINIC, VET).Actor as a user-facing label; prefer contextual labels (Lead, Support) or neutral Updated by.AWS Amplify Auth is the mobile auth provider. Firebase handles push notifications and supplementary auth flows. Never bypass Amplify for core auth.
@stripe/stripe-react-native — use the SDK's pre-built UI sheets where possible. Never build custom card input from scratch.
pnpm --filter mobileAppYC run test -- --testPathPattern="path/to/file"--testPathPattern.Target: ≥ 95% Statements, Branches, Functions, Lines across apps/mobileAppYC. Every change must move coverage upward, never downward.
| Layer | Tool | When required |
|---|---|---|
| Unit | Jest | Every service, Redux slice, hook, utility, helper |
| Component | React Testing Library for RN | Every screen and reusable component — render + interaction + conditional rendering |
| Snapshot | Jest toMatchSnapshot | Stable UI layouts — complement behavioural tests, never replace them |
| E2E | Detox | Auth flows, booking, checkout, payment, any critical user journey |
All four layers must grow together. Do not add unit tests while leaving Detox untouched for critical flows, and vice versa.
# After every change, run coverage for the touched file(s):
pnpm --filter mobileAppYC run test -- --testPathPattern="<YourFile>" --coverage --collectCoverageFrom="src/path/to/YourFile.tsx"
# Check — if Statements/Branches/Functions dropped vs what you started with, add tests before declaring done.
Every new module, screen, service, hook, slice, or utility added to apps/mobileAppYC must ship with tests in the same batch. No exceptions.
| What you add | What you must also add |
|---|---|
| Service function / API call | Jest unit: success + all error branches |
| Redux slice | Jest: every reducer, action creator, selector, and async thunk |
| Custom hook | renderHook covering all return values and state branches |
| Utility function | Jest unit with full branch coverage |
| Screen component | Jest + Testing Library render + key interaction |
| E2E-critical flow (auth, booking, checkout) | Detox test |
Coverage bar for any new file you author: Statements ≥ 90%, Branches ≥ 90%, Functions ≥ 90%.
Never leave an existing file in a worse coverage state than you found it.
npx tsc --noemit # from apps/mobileAppYC/
pnpm --filter mobileAppYC run lint
pnpm --filter mobileAppYC run test -- --testPathPattern="<YourFile>"
react-native-permissions requires explicit permission requests before accessing camera, location, contacts — never assume granted.react-native-fs paths differ between iOS and Android — use RNFS.DocumentDirectoryPath not hardcoded paths.@gorhom/bottom-sheet requires GestureHandlerRootView at app root — it's already there, don't remove it.__DEV__ checks.src/i18n/ — add new keys there before using t().