@the-bearded-bear/claude-craft 8.8.1 → 8.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/Dev/i18n/de/Angular/commands/check-compliance.md +218 -168
  2. package/Dev/i18n/de/Common/agents/refactoring-specialist.md +146 -69
  3. package/Dev/i18n/de/Common/commands/add-technology.md +166 -68
  4. package/Dev/i18n/de/Common/commands/setup-ci.md +216 -33
  5. package/Dev/i18n/de/Laravel/commands/check-compliance.md +223 -115
  6. package/Dev/i18n/de/Python/checklists/new-feature.md +319 -44
  7. package/Dev/i18n/de/React/rules/02-architecture.md +483 -322
  8. package/Dev/i18n/de/React/rules/03-coding-standards.md +584 -368
  9. package/Dev/i18n/de/Symfony/commands/check-compliance.md +186 -114
  10. package/Dev/i18n/de/Symfony/rules/07-testing-symfony.md +679 -10
  11. package/Dev/i18n/de/UIUX/commands/a11y-component.md +284 -26
  12. package/Dev/i18n/de/UIUX/commands/design-tokens.md +199 -35
  13. package/Dev/i18n/de/UIUX/commands/user-flow.md +179 -16
  14. package/Dev/i18n/de/VueJS/commands/check-compliance.md +227 -102
  15. package/Dev/i18n/es/Angular/commands/check-compliance.md +217 -167
  16. package/Dev/i18n/es/Common/commands/add-technology.md +158 -60
  17. package/Dev/i18n/es/Laravel/commands/check-compliance.md +223 -115
  18. package/Dev/i18n/es/React/commands/check-testing.md +263 -169
  19. package/Dev/i18n/es/ReactNative/commands/check-testing.md +256 -198
  20. package/Dev/i18n/es/Symfony/commands/check-compliance.md +189 -117
  21. package/Dev/i18n/es/Symfony/commands/check-testing.md +301 -102
  22. package/Dev/i18n/es/Symfony/commands/migration-plan.md +267 -34
  23. package/Dev/i18n/es/UIUX/commands/a11y-component.md +274 -16
  24. package/Dev/i18n/es/UIUX/commands/design-tokens.md +186 -22
  25. package/Dev/i18n/es/UIUX/commands/user-flow.md +173 -10
  26. package/Dev/i18n/es/VueJS/commands/check-compliance.md +227 -102
  27. package/Dev/i18n/fr/Angular/commands/check-compliance.md +217 -167
  28. package/Dev/i18n/fr/Common/commands/ralph-run.md +138 -60
  29. package/Dev/i18n/fr/Laravel/commands/check-compliance.md +223 -115
  30. package/Dev/i18n/fr/React/commands/check-architecture.md +370 -53
  31. package/Dev/i18n/fr/React/commands/check-code-quality.md +454 -64
  32. package/Dev/i18n/fr/React/commands/check-testing.md +476 -102
  33. package/Dev/i18n/fr/Symfony/commands/check-compliance.md +188 -116
  34. package/Dev/i18n/fr/VueJS/commands/check-compliance.md +227 -102
  35. package/Dev/i18n/pt/Angular/commands/check-compliance.md +225 -175
  36. package/Dev/i18n/pt/Common/agents/ralph-conductor.md +211 -30
  37. package/Dev/i18n/pt/Common/commands/add-technology.md +149 -51
  38. package/Dev/i18n/pt/Common/commands/ralph-run.md +239 -35
  39. package/Dev/i18n/pt/Flutter/commands/analyze-performance.md +331 -46
  40. package/Dev/i18n/pt/Flutter/commands/check-compliance.md +234 -29
  41. package/Dev/i18n/pt/Flutter/commands/generate-feature.md +526 -51
  42. package/Dev/i18n/pt/Flutter/commands/generate-widget.md +515 -27
  43. package/Dev/i18n/pt/Flutter/commands/golden-update.md +322 -46
  44. package/Dev/i18n/pt/Flutter/commands/localization-check.md +278 -37
  45. package/Dev/i18n/pt/Laravel/commands/check-compliance.md +212 -104
  46. package/Dev/i18n/pt/React/commands/accessibility-check.md +151 -42
  47. package/Dev/i18n/pt/React/commands/bundle-analyze.md +300 -25
  48. package/Dev/i18n/pt/React/commands/check-architecture.md +369 -34
  49. package/Dev/i18n/pt/React/commands/check-code-quality.md +440 -34
  50. package/Dev/i18n/pt/React/commands/check-compliance.md +232 -62
  51. package/Dev/i18n/pt/React/commands/check-security.md +370 -31
  52. package/Dev/i18n/pt/React/commands/check-testing.md +473 -43
  53. package/Dev/i18n/pt/React/commands/generate-component.md +454 -19
  54. package/Dev/i18n/pt/React/commands/generate-hook.md +425 -24
  55. package/Dev/i18n/pt/React/commands/storybook-story.md +520 -35
  56. package/Dev/i18n/pt/ReactNative/commands/app-size.md +358 -387
  57. package/Dev/i18n/pt/ReactNative/commands/check-code-quality.md +246 -75
  58. package/Dev/i18n/pt/ReactNative/commands/check-compliance.md +191 -85
  59. package/Dev/i18n/pt/ReactNative/commands/check-security.md +363 -115
  60. package/Dev/i18n/pt/ReactNative/commands/check-testing.md +269 -79
  61. package/Dev/i18n/pt/ReactNative/commands/generate-screen.md +491 -324
  62. package/Dev/i18n/pt/ReactNative/commands/native-module.md +539 -82
  63. package/Dev/i18n/pt/ReactNative/commands/store-prepare.md +429 -185
  64. package/Dev/i18n/pt/ReactNative/rules/02-architecture.md +1084 -31
  65. package/Dev/i18n/pt/Symfony/commands/check-compliance.md +195 -123
  66. package/Dev/i18n/pt/UIUX/commands/a11y-audit.md +208 -24
  67. package/Dev/i18n/pt/UIUX/commands/a11y-component.md +281 -23
  68. package/Dev/i18n/pt/UIUX/commands/design-tokens.md +197 -33
  69. package/Dev/i18n/pt/UIUX/commands/user-flow.md +183 -20
  70. package/Dev/i18n/pt/VueJS/commands/check-compliance.md +228 -103
  71. package/Dev/i18n/pt/Workflow/commands/analyze.md +147 -146
  72. package/Dev/i18n/pt/Workflow/commands/design.md +205 -204
  73. package/Dev/i18n/pt/Workflow/commands/implement.md +184 -184
  74. package/Project/i18n/de/Sprint/commands/dev.md +339 -86
  75. package/Project/i18n/es/Sprint/commands/dev.md +342 -91
  76. package/Project/i18n/pt/Sprint/commands/dev.md +343 -92
  77. package/bundles/cursor/.cursorrules +1 -1
  78. package/bundles/windsurf/.windsurfrules +1 -1
  79. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Introdução
4
4
 
5
- Este documento define a arquitetura recomendada para aplicações React Native com TypeScript e Expo, baseada nas melhores práticas da indústria.
5
+ Este documento define a arquitetura recomendada para aplicações React Native com TypeScript e Expo, baseada nas melhores práticas do setor.
6
6
 
7
7
  ---
8
8
 
@@ -10,7 +10,7 @@ Este documento define a arquitetura recomendada para aplicações React Native c
10
10
 
11
11
  ### 1. Clean Architecture
12
12
 
13
- A aplicação é organizada em **camadas** com responsabilidades claras:
13
+ A aplicação é organizada em **camadas** com responsabilidades bem definidas:
14
14
 
15
15
  ```
16
16
  ┌─────────────────────────────────────┐
@@ -20,21 +20,21 @@ A aplicação é organizada em **camadas** com responsabilidades claras:
20
20
  ├─────────────────────────────────────┤
21
21
  │ CAMADA DE DOMÍNIO │ <- Lógica de Negócio, Tipos
22
22
  ├─────────────────────────────────────┤
23
- │ CAMADA DE DADOS │ <- API, Storage, Serviços
23
+ │ CAMADA DE DADOS │ <- API, Armazenamento, Serviços
24
24
  └─────────────────────────────────────┘
25
25
  ```
26
26
 
27
27
  **Regras de dependência**:
28
28
  - Camadas superiores podem depender de camadas inferiores
29
29
  - Camadas inferiores NÃO DEVEM depender de camadas superiores
30
- - Cada camada tem uma responsabilidade única e bem definida
30
+ - Cada camada tem uma única responsabilidade bem definida
31
31
 
32
- ### 2. Organização Baseada em Features
32
+ ### 2. Organização Baseada em Funcionalidades
33
33
 
34
- Organização por **feature de negócio** ao invés de tipo técnico:
34
+ Organização por **funcionalidade de negócio** em vez de tipo técnico:
35
35
 
36
36
  ```typescript
37
- // ✅ BOM: Baseado em features
37
+ // ✅ BOM: Baseado em funcionalidade
38
38
  features/
39
39
  ├── auth/
40
40
  │ ├── screens/
@@ -56,7 +56,7 @@ types/
56
56
 
57
57
  ### 3. Separação de Responsabilidades
58
58
 
59
- Cada arquivo, função, componente tem **UMA responsabilidade**:
59
+ Cada arquivo, função e componente tem **UMA responsabilidade**:
60
60
 
61
61
  ```typescript
62
62
  // ✅ BOM: Separação clara
@@ -77,7 +77,7 @@ export const LoginButton = () => {
77
77
  const handleLogin = async () => {
78
78
  setLoading(true);
79
79
  const response = await fetch('/api/login');
80
- // Lógica + UI misturados
80
+ // Lógica + UI misturadas
81
81
  };
82
82
  return <Pressable onPress={handleLogin}>Login</Pressable>;
83
83
  };
@@ -87,21 +87,21 @@ export const LoginButton = () => {
87
87
 
88
88
  ## Estrutura de Pastas
89
89
 
90
- ### Visão Completa
90
+ ### Visão Geral Completa
91
91
 
92
92
  ```
93
93
  my-app/
94
94
  ├── src/
95
95
  │ ├── app/ # Expo Router (App Router)
96
- │ │ ├── (auth)/ # Grupo Auth (layout compartilhado)
96
+ │ │ ├── (auth)/ # Grupo auth (layout compartilhado)
97
97
  │ │ │ ├── login.tsx
98
98
  │ │ │ ├── register.tsx
99
99
  │ │ │ └── _layout.tsx
100
- │ │ ├── (tabs)/ # Grupo Tabs (navegação em tabs)
101
- │ │ │ ├── index.tsx # Tab Home
102
- │ │ │ ├── profile.tsx # Tab Profile
103
- │ │ │ ├── settings.tsx # Tab Settings
104
- │ │ │ └── _layout.tsx # Layout de Tabs
100
+ │ │ ├── (tabs)/ # Grupo tabs (abas de navegação)
101
+ │ │ │ ├── index.tsx # Aba inicial
102
+ │ │ │ ├── profile.tsx # Aba de perfil
103
+ │ │ │ ├── settings.tsx # Aba de configurações
104
+ │ │ │ └── _layout.tsx # Layout das abas
105
105
  │ │ ├── article/
106
106
  │ │ │ └── [id].tsx # Rota dinâmica
107
107
  │ │ ├── modal.tsx # Tela modal
@@ -110,35 +110,145 @@ my-app/
110
110
  │ │
111
111
  │ ├── components/ # Componentes reutilizáveis
112
112
  │ │ ├── ui/ # Componentes UI base
113
+ │ │ │ ├── Button/
114
+ │ │ │ │ ├── Button.tsx
115
+ │ │ │ │ ├── Button.styles.ts
116
+ │ │ │ │ ├── Button.test.tsx
117
+ │ │ │ │ └── index.ts
118
+ │ │ │ ├── Input/
119
+ │ │ │ ├── Card/
120
+ │ │ │ └── index.ts
113
121
  │ │ ├── forms/ # Componentes de formulário
122
+ │ │ │ ├── LoginForm/
123
+ │ │ │ ├── ProfileForm/
124
+ │ │ │ └── index.ts
114
125
  │ │ ├── layout/ # Componentes de layout
126
+ │ │ │ ├── Container/
127
+ │ │ │ ├── SafeArea/
128
+ │ │ │ └── index.ts
115
129
  │ │ └── shared/ # Componentes compartilhados
130
+ │ │ ├── Header/
131
+ │ │ ├── Footer/
132
+ │ │ └── index.ts
116
133
  │ │
117
- │ ├── features/ # Features por domínio de negócio
134
+ │ ├── features/ # Funcionalidades por domínio de negócio
118
135
  │ │ ├── auth/
119
136
  │ │ │ ├── components/ # Componentes específicos de auth
137
+ │ │ │ │ ├── SocialLoginButtons/
138
+ │ │ │ │ └── PasswordStrength/
120
139
  │ │ │ ├── hooks/ # Hooks de auth
140
+ │ │ │ │ ├── useAuth.ts
141
+ │ │ │ │ ├── useLogin.ts
142
+ │ │ │ │ └── useRegister.ts
121
143
  │ │ │ ├── services/ # Serviços de auth
122
- │ │ │ ├── stores/ # Gerenciamento de estado auth
123
- │ │ │ ├── types/ # Tipos auth
124
- │ │ │ └── utils/ # Utils auth
144
+ │ │ │ ├── auth.service.ts
145
+ │ │ │ │ └── token.service.ts
146
+ │ │ │ ├── stores/ # Gerenciamento de estado de auth
147
+ │ │ │ │ └── auth.store.ts
148
+ │ │ │ ├── types/ # Tipos de auth
149
+ │ │ │ │ └── Auth.types.ts
150
+ │ │ │ └── utils/ # Utilitários de auth
151
+ │ │ │ └── validation.ts
125
152
  │ │ ├── profile/
153
+ │ │ │ ├── components/
154
+ │ │ │ ├── hooks/
155
+ │ │ │ ├── services/
156
+ │ │ │ └── types/
126
157
  │ │ └── articles/
158
+ │ │ ├── components/
159
+ │ │ ├── hooks/
160
+ │ │ ├── services/
161
+ │ │ └── types/
127
162
  │ │
128
163
  │ ├── hooks/ # Hooks globais/compartilhados
164
+ │ │ ├── useAppState.ts # Estado do app (foreground/background)
165
+ │ │ ├── useKeyboard.ts # Estado do teclado
166
+ │ │ ├── useOrientation.ts # Orientação do dispositivo
167
+ │ │ ├── useNetworkStatus.ts # Conectividade de rede
168
+ │ │ └── index.ts
169
+ │ │
129
170
  │ ├── services/ # Serviços globais
171
+ │ │ ├── api/ # Serviços de API
172
+ │ │ │ ├── client.ts # Cliente da API (Axios)
173
+ │ │ │ ├── interceptors.ts # Interceptadores de requisição/resposta
174
+ │ │ │ ├── endpoints.ts # Constantes de endpoints da API
175
+ │ │ │ └── index.ts
176
+ │ │ ├── storage/ # Serviços de armazenamento
177
+ │ │ │ ├── mmkv.storage.ts # Armazenamento MMKV
178
+ │ │ │ ├── secure.storage.ts # Armazenamento seguro
179
+ │ │ │ └── index.ts
180
+ │ │ ├── analytics/ # Serviço de analytics
181
+ │ │ │ ├── analytics.service.ts
182
+ │ │ │ └── events.ts
183
+ │ │ ├── notifications/ # Serviço de notificações
184
+ │ │ │ └── push.service.ts
185
+ │ │ └── location/ # Serviço de localização
186
+ │ │ └── location.service.ts
187
+ │ │
130
188
  │ ├── stores/ # Gerenciamento de estado global
189
+ │ │ ├── app.store.ts # Estado global do app
190
+ │ │ ├── theme.store.ts # Estado do tema
191
+ │ │ └── index.ts
192
+ │ │
193
+ │ ├── navigation/ # Configuração de navegação
194
+ │ │ ├── types.ts # Tipos de navegação
195
+ │ │ ├── linking.ts # Configuração de deep linking
196
+ │ │ └── index.ts
197
+ │ │
131
198
  │ ├── utils/ # Utilitários
199
+ │ │ ├── date.utils.ts
200
+ │ │ ├── string.utils.ts
201
+ │ │ ├── number.utils.ts
202
+ │ │ ├── validation.utils.ts
203
+ │ │ └── index.ts
204
+ │ │
132
205
  │ ├── constants/ # Constantes
206
+ │ │ ├── app.constants.ts
207
+ │ │ ├── api.constants.ts
208
+ │ │ ├── storage.constants.ts
209
+ │ │ └── index.ts
210
+ │ │
133
211
  │ ├── types/ # Tipos globais
212
+ │ │ ├── global.types.ts
213
+ │ │ ├── api.types.ts
214
+ │ │ ├── navigation.types.ts
215
+ │ │ └── index.ts
216
+ │ │
134
217
  │ ├── config/ # Configuração
218
+ │ │ ├── env.ts # Variáveis de ambiente
219
+ │ │ ├── app.config.ts # Configuração do app
220
+ │ │ └── index.ts
221
+ │ │
135
222
  │ ├── theme/ # Tema
223
+ │ │ ├── colors.ts
224
+ │ │ ├── spacing.ts
225
+ │ │ ├── typography.ts
226
+ │ │ ├── shadows.ts
227
+ │ │ └── index.ts
228
+ │ │
136
229
  │ └── assets/ # Assets
230
+ │ ├── images/
231
+ │ ├── fonts/
232
+ │ ├── icons/
233
+ │ └── animations/
137
234
 
138
235
  ├── __tests__/ # Testes
139
236
  │ ├── unit/
140
237
  │ ├── integration/
141
238
  │ └── e2e/
239
+
240
+ ├── .expo/ # Gerado pelo Expo
241
+ ├── .husky/ # Git hooks
242
+ ├── node_modules/
243
+ ├── app.json # Configuração do app Expo
244
+ ├── babel.config.js
245
+ ├── tsconfig.json
246
+ ├── package.json
247
+ ├── .eslintrc.js
248
+ ├── .prettierrc.js
249
+ ├── .env.development
250
+ ├── .env.production
251
+ └── README.md
142
252
  ```
143
253
 
144
254
  ---
@@ -149,7 +259,7 @@ my-app/
149
259
 
150
260
  #### A. App Router (Expo Router)
151
261
 
152
- **Nova arquitetura de roteamento baseada em arquivos**:
262
+ **Nova arquitetura de roteamento baseado em arquivos**:
153
263
 
154
264
  ```typescript
155
265
  // src/app/_layout.tsx - Layout raiz
@@ -167,34 +277,977 @@ export default function RootLayout() {
167
277
  </QueryClientProvider>
168
278
  );
169
279
  }
280
+
281
+ // src/app/(tabs)/_layout.tsx - Layout das abas
282
+ import { Tabs } from 'expo-router';
283
+
284
+ export default function TabsLayout() {
285
+ return (
286
+ <Tabs>
287
+ <Tabs.Screen
288
+ name="index"
289
+ options={{
290
+ title: 'Home',
291
+ tabBarIcon: ({ color }) => <HomeIcon color={color} />,
292
+ }}
293
+ />
294
+ <Tabs.Screen
295
+ name="profile"
296
+ options={{
297
+ title: 'Profile',
298
+ tabBarIcon: ({ color }) => <ProfileIcon color={color} />,
299
+ }}
300
+ />
301
+ </Tabs>
302
+ );
303
+ }
304
+
305
+ // src/app/(tabs)/index.tsx - Tela inicial
306
+ export default function HomeScreen() {
307
+ return <HomeView />;
308
+ }
309
+
310
+ // src/app/article/[id].tsx - Rota dinâmica
311
+ import { useLocalSearchParams } from 'expo-router';
312
+
313
+ export default function ArticleScreen() {
314
+ const { id } = useLocalSearchParams();
315
+ return <ArticleDetail id={id} />;
316
+ }
170
317
  ```
171
318
 
172
319
  **Vantagens do Expo Router**:
173
320
  - Roteamento baseado em arquivos (como Next.js)
174
- - Navegação type-safe
321
+ - Navegação com tipagem segura
175
322
  - Deep linking automático
176
- - SEO-friendly (Expo Web)
323
+ - Amigável para SEO (Expo Web)
177
324
  - Layouts compartilhados
178
325
  - Navegação aninhada simplificada
179
326
 
327
+ #### B. Componentes
328
+
329
+ **Organização hierárquica**:
330
+
331
+ ```typescript
332
+ // components/ui/Button/Button.tsx
333
+ import { Pressable, Text } from 'react-native';
334
+ import { styles } from './Button.styles';
335
+ import type { ButtonProps } from './Button.types';
336
+
337
+ export const Button = ({
338
+ children,
339
+ variant = 'primary',
340
+ onPress,
341
+ disabled,
342
+ }: ButtonProps) => {
343
+ return (
344
+ <Pressable
345
+ style={[styles.button, styles[variant], disabled && styles.disabled]}
346
+ onPress={onPress}
347
+ disabled={disabled}
348
+ >
349
+ <Text style={styles.text}>{children}</Text>
350
+ </Pressable>
351
+ );
352
+ };
353
+
354
+ // components/ui/Button/Button.styles.ts
355
+ import { StyleSheet } from 'react-native';
356
+ import { theme } from '@/theme';
357
+
358
+ export const styles = StyleSheet.create({
359
+ button: {
360
+ paddingHorizontal: theme.spacing.md,
361
+ paddingVertical: theme.spacing.sm,
362
+ borderRadius: theme.borderRadius.md,
363
+ alignItems: 'center',
364
+ },
365
+ primary: {
366
+ backgroundColor: theme.colors.primary,
367
+ },
368
+ secondary: {
369
+ backgroundColor: theme.colors.secondary,
370
+ },
371
+ disabled: {
372
+ opacity: 0.5,
373
+ },
374
+ text: {
375
+ color: theme.colors.white,
376
+ fontSize: theme.typography.fontSize.md,
377
+ fontWeight: '600',
378
+ },
379
+ });
380
+
381
+ // components/ui/Button/Button.types.ts
382
+ import type { PressableProps } from 'react-native';
383
+
384
+ export interface ButtonProps extends Omit<PressableProps, 'style'> {
385
+ children: React.ReactNode;
386
+ variant?: 'primary' | 'secondary' | 'outline';
387
+ disabled?: boolean;
388
+ }
389
+
390
+ // components/ui/Button/index.ts
391
+ export { Button } from './Button';
392
+ export type { ButtonProps } from './Button.types';
393
+ ```
394
+
395
+ **Tipos de componentes**:
396
+
397
+ 1. **Componentes UI** (burros/apresentacionais):
398
+ - Sem lógica de negócio
399
+ - Orientados por props
400
+ - Altamente reutilizáveis
401
+ - Facilmente testáveis
402
+
403
+ ```typescript
404
+ // components/ui/Card/Card.tsx
405
+ interface CardProps {
406
+ children: React.ReactNode;
407
+ onPress?: () => void;
408
+ }
409
+
410
+ export const Card = ({ children, onPress }: CardProps) => (
411
+ <Pressable onPress={onPress} style={styles.card}>
412
+ {children}
413
+ </Pressable>
414
+ );
415
+ ```
416
+
417
+ 2. **Componentes Inteligentes** (containers):
418
+ - Conectados ao estado
419
+ - Lidam com lógica de negócio
420
+ - Utilizam hooks
421
+
422
+ ```typescript
423
+ // features/articles/components/ArticleList/ArticleList.tsx
424
+ export const ArticleList = () => {
425
+ const { data: articles, isLoading } = useArticles();
426
+
427
+ if (isLoading) return <LoadingSpinner />;
428
+
429
+ return (
430
+ <FlatList
431
+ data={articles}
432
+ renderItem={({ item }) => <ArticleCard article={item} />}
433
+ keyExtractor={(item) => item.id}
434
+ />
435
+ );
436
+ };
437
+ ```
438
+
439
+ 3. **Componentes Compostos**:
440
+ - Componentes composicionais
441
+ - API intuitiva
442
+
443
+ ```typescript
444
+ // components/ui/Form/Form.tsx
445
+ export const Form = ({ children, onSubmit }: FormProps) => (
446
+ <View style={styles.form}>{children}</View>
447
+ );
448
+
449
+ Form.Field = ({ label, children }: FieldProps) => (
450
+ <View style={styles.field}>
451
+ <Text style={styles.label}>{label}</Text>
452
+ {children}
453
+ </View>
454
+ );
455
+
456
+ Form.Submit = ({ children, ...props }: SubmitProps) => (
457
+ <Button {...props}>{children}</Button>
458
+ );
459
+
460
+ // Uso:
461
+ <Form onSubmit={handleSubmit}>
462
+ <Form.Field label="Email">
463
+ <Input name="email" />
464
+ </Form.Field>
465
+ <Form.Submit>Enviar</Form.Submit>
466
+ </Form>
467
+ ```
468
+
469
+ ---
470
+
471
+ ### 2. Camada de Aplicação (Lógica)
472
+
473
+ #### A. Custom Hooks
474
+
475
+ **Encapsulam lógica reutilizável**:
476
+
477
+ ```typescript
478
+ // hooks/useAuth.ts
479
+ import { useAuthStore } from '@/features/auth/stores/auth.store';
480
+ import { authService } from '@/features/auth/services/auth.service';
481
+
482
+ export const useAuth = () => {
483
+ const { user, setUser, clearUser } = useAuthStore();
484
+
485
+ const login = async (credentials: Credentials) => {
486
+ const response = await authService.login(credentials);
487
+ setUser(response.user);
488
+ return response;
489
+ };
490
+
491
+ const logout = async () => {
492
+ await authService.logout();
493
+ clearUser();
494
+ };
495
+
496
+ const isAuthenticated = !!user;
497
+
498
+ return {
499
+ user,
500
+ login,
501
+ logout,
502
+ isAuthenticated,
503
+ };
504
+ };
505
+
506
+ // Uso no componente:
507
+ const LoginScreen = () => {
508
+ const { login, isAuthenticated } = useAuth();
509
+ const { mutate, isLoading } = useMutation({
510
+ mutationFn: login,
511
+ });
512
+
513
+ if (isAuthenticated) {
514
+ return <Redirect href="/(tabs)" />;
515
+ }
516
+
517
+ return <LoginForm onSubmit={mutate} isLoading={isLoading} />;
518
+ };
519
+ ```
520
+
521
+ **Padrões comuns de hooks**:
522
+
523
+ ```typescript
524
+ // 1. Hook de busca de dados
525
+ export const useArticles = (filters?: ArticleFilters) => {
526
+ return useQuery({
527
+ queryKey: ['articles', filters],
528
+ queryFn: () => articlesService.getAll(filters),
529
+ });
530
+ };
531
+
532
+ // 2. Hook de mutação
533
+ export const useCreateArticle = () => {
534
+ const queryClient = useQueryClient();
535
+
536
+ return useMutation({
537
+ mutationFn: articlesService.create,
538
+ onSuccess: () => {
539
+ queryClient.invalidateQueries({ queryKey: ['articles'] });
540
+ },
541
+ });
542
+ };
543
+
544
+ // 3. Hook específico de plataforma
545
+ export const usePlatform = () => {
546
+ const isIOS = Platform.OS === 'ios';
547
+ const isAndroid = Platform.OS === 'android';
548
+ const isWeb = Platform.OS === 'web';
549
+
550
+ return { isIOS, isAndroid, isWeb };
551
+ };
552
+
553
+ // 4. Hook de informações do dispositivo
554
+ export const useDeviceInfo = () => {
555
+ const { width, height } = useWindowDimensions();
556
+ const isTablet = width > 768;
557
+ const isLandscape = width > height;
558
+
559
+ return { width, height, isTablet, isLandscape };
560
+ };
561
+
562
+ // 5. Hook de teclado
563
+ export const useKeyboard = () => {
564
+ const [isVisible, setIsVisible] = useState(false);
565
+ const [keyboardHeight, setKeyboardHeight] = useState(0);
566
+
567
+ useEffect(() => {
568
+ const showListener = Keyboard.addListener('keyboardDidShow', (e) => {
569
+ setIsVisible(true);
570
+ setKeyboardHeight(e.endCoordinates.height);
571
+ });
572
+
573
+ const hideListener = Keyboard.addListener('keyboardDidHide', () => {
574
+ setIsVisible(false);
575
+ setKeyboardHeight(0);
576
+ });
577
+
578
+ return () => {
579
+ showListener.remove();
580
+ hideListener.remove();
581
+ };
582
+ }, []);
583
+
584
+ return { isVisible, keyboardHeight };
585
+ };
586
+ ```
587
+
588
+ #### B. Gerenciamento de Estado
589
+
590
+ **Arquitetura em múltiplos níveis**:
591
+
592
+ ```typescript
593
+ // 1. Estado Local (useState, useReducer)
594
+ // Para estado isolado em um componente
595
+ const [count, setCount] = useState(0);
596
+
597
+ // 2. Estado de URL (Expo Router)
598
+ // Para estado sincronizado com a URL
599
+ const { id, filter } = useLocalSearchParams<{ id: string; filter: string }>();
600
+
601
+ // 3. Estado do Servidor (React Query)
602
+ // Para dados do servidor com cache
603
+ const { data } = useQuery({
604
+ queryKey: ['user', userId],
605
+ queryFn: () => fetchUser(userId),
606
+ });
607
+
608
+ // 4. Estado Global (Zustand)
609
+ // Para estado global do lado do cliente
610
+ // stores/theme.store.ts
611
+ import { create } from 'zustand';
612
+ import { persist } from 'zustand/middleware';
613
+ import { createMMKVStorage } from '@/services/storage/mmkv.storage';
614
+
615
+ interface ThemeState {
616
+ isDark: boolean;
617
+ toggleTheme: () => void;
618
+ }
619
+
620
+ export const useThemeStore = create<ThemeState>()(
621
+ persist(
622
+ (set) => ({
623
+ isDark: false,
624
+ toggleTheme: () => set((state) => ({ isDark: !state.isDark })),
625
+ }),
626
+ {
627
+ name: 'theme',
628
+ storage: createMMKVStorage(),
629
+ }
630
+ )
631
+ );
632
+
633
+ // 5. Estado Persistido (MMKV)
634
+ // Para armazenamento de alto desempenho
635
+ // services/storage/mmkv.storage.ts
636
+ import { MMKV } from 'react-native-mmkv';
637
+
638
+ const storage = new MMKV();
639
+
640
+ export const mmkvStorage = {
641
+ setItem: (key: string, value: string) => {
642
+ storage.set(key, value);
643
+ },
644
+ getItem: (key: string) => {
645
+ return storage.getString(key) ?? null;
646
+ },
647
+ removeItem: (key: string) => {
648
+ storage.delete(key);
649
+ },
650
+ };
651
+
652
+ export const createMMKVStorage = () => ({
653
+ getItem: (name: string) => {
654
+ const value = storage.getString(name);
655
+ return value ?? null;
656
+ },
657
+ setItem: (name: string, value: string) => {
658
+ storage.set(name, value);
659
+ },
660
+ removeItem: (name: string) => {
661
+ storage.delete(name);
662
+ },
663
+ });
664
+ ```
665
+
666
+ ---
667
+
668
+ ### 3. Camada de Domínio (Lógica de Negócio)
669
+
670
+ #### Tipos e Interfaces
671
+
672
+ **Organização de tipos**:
673
+
674
+ ```typescript
675
+ // types/User.types.ts
676
+ export interface User {
677
+ id: string;
678
+ email: string;
679
+ firstName: string;
680
+ lastName: string;
681
+ avatar?: string;
682
+ createdAt: Date;
683
+ updatedAt: Date;
684
+ }
685
+
686
+ export interface CreateUserDTO {
687
+ email: string;
688
+ password: string;
689
+ firstName: string;
690
+ lastName: string;
691
+ }
692
+
693
+ export interface UpdateUserDTO extends Partial<CreateUserDTO> {
694
+ avatar?: string;
695
+ }
696
+
697
+ // types/Article.types.ts
698
+ export interface Article {
699
+ id: string;
700
+ title: string;
701
+ content: string;
702
+ author: User;
703
+ tags: string[];
704
+ publishedAt: Date;
705
+ updatedAt: Date;
706
+ }
707
+
708
+ export interface ArticleFilters {
709
+ tag?: string;
710
+ authorId?: string;
711
+ search?: string;
712
+ page?: number;
713
+ limit?: number;
714
+ }
715
+
716
+ // types/api.types.ts
717
+ export interface ApiResponse<T> {
718
+ data: T;
719
+ message?: string;
720
+ status: number;
721
+ }
722
+
723
+ export interface PaginatedResponse<T> {
724
+ data: T[];
725
+ total: number;
726
+ page: number;
727
+ limit: number;
728
+ hasMore: boolean;
729
+ }
730
+
731
+ export interface ApiError {
732
+ message: string;
733
+ code: string;
734
+ status: number;
735
+ errors?: Record<string, string[]>;
736
+ }
737
+ ```
738
+
739
+ ---
740
+
741
+ ### 4. Camada de Dados
742
+
743
+ #### A. Serviços de API
744
+
745
+ **Organização do serviço de API**:
746
+
747
+ ```typescript
748
+ // services/api/client.ts
749
+ import axios from 'axios';
750
+ import { setupInterceptors } from './interceptors';
751
+ import { ENV } from '@/config/env';
752
+
753
+ export const apiClient = axios.create({
754
+ baseURL: ENV.API_URL,
755
+ timeout: 10000,
756
+ headers: {
757
+ 'Content-Type': 'application/json',
758
+ },
759
+ });
760
+
761
+ setupInterceptors(apiClient);
762
+
763
+ export default apiClient;
764
+
765
+ // services/api/interceptors.ts
766
+ import type { AxiosInstance } from 'axios';
767
+ import { router } from 'expo-router';
768
+ import { tokenService } from '@/features/auth/services/token.service';
769
+
770
+ export const setupInterceptors = (instance: AxiosInstance) => {
771
+ // Interceptador de requisição
772
+ instance.interceptors.request.use(
773
+ async (config) => {
774
+ const token = await tokenService.getAccessToken();
775
+ if (token) {
776
+ config.headers.Authorization = `Bearer ${token}`;
777
+ }
778
+ return config;
779
+ },
780
+ (error) => Promise.reject(error)
781
+ );
782
+
783
+ // Interceptador de resposta
784
+ instance.interceptors.response.use(
785
+ (response) => response,
786
+ async (error) => {
787
+ const originalRequest = error.config;
788
+
789
+ // Lógica de renovação de token
790
+ if (error.response?.status === 401 && !originalRequest._retry) {
791
+ originalRequest._retry = true;
792
+
793
+ try {
794
+ const newToken = await tokenService.refreshToken();
795
+ originalRequest.headers.Authorization = `Bearer ${newToken}`;
796
+ return instance(originalRequest);
797
+ } catch (refreshError) {
798
+ // Redirecionar para login
799
+ router.replace('/(auth)/login');
800
+ return Promise.reject(refreshError);
801
+ }
802
+ }
803
+
804
+ return Promise.reject(error);
805
+ }
806
+ );
807
+ };
808
+
809
+ // features/articles/services/articles.service.ts
810
+ import { apiClient } from '@/services/api/client';
811
+ import type { Article, ArticleFilters, CreateArticleDTO } from '../types/Article.types';
812
+ import type { PaginatedResponse } from '@/types/api.types';
813
+
814
+ class ArticlesService {
815
+ private readonly endpoint = '/articles';
816
+
817
+ async getAll(filters?: ArticleFilters): Promise<PaginatedResponse<Article>> {
818
+ const { data } = await apiClient.get(this.endpoint, { params: filters });
819
+ return data;
820
+ }
821
+
822
+ async getById(id: string): Promise<Article> {
823
+ const { data } = await apiClient.get(`${this.endpoint}/${id}`);
824
+ return data;
825
+ }
826
+
827
+ async create(dto: CreateArticleDTO): Promise<Article> {
828
+ const { data } = await apiClient.post(this.endpoint, dto);
829
+ return data;
830
+ }
831
+
832
+ async update(id: string, dto: Partial<CreateArticleDTO>): Promise<Article> {
833
+ const { data } = await apiClient.patch(`${this.endpoint}/${id}`, dto);
834
+ return data;
835
+ }
836
+
837
+ async delete(id: string): Promise<void> {
838
+ await apiClient.delete(`${this.endpoint}/${id}`);
839
+ }
840
+ }
841
+
842
+ export const articlesService = new ArticlesService();
843
+ ```
844
+
845
+ #### B. Serviços de Armazenamento
846
+
847
+ ```typescript
848
+ // services/storage/secure.storage.ts
849
+ import * as SecureStore from 'expo-secure-store';
850
+ import { Platform } from 'react-native';
851
+
852
+ class SecureStorage {
853
+ async setItem(key: string, value: string): Promise<void> {
854
+ if (Platform.OS === 'web') {
855
+ // Fallback para web
856
+ localStorage.setItem(key, value);
857
+ return;
858
+ }
859
+ await SecureStore.setItemAsync(key, value);
860
+ }
861
+
862
+ async getItem(key: string): Promise<string | null> {
863
+ if (Platform.OS === 'web') {
864
+ return localStorage.getItem(key);
865
+ }
866
+ return await SecureStore.getItemAsync(key);
867
+ }
868
+
869
+ async removeItem(key: string): Promise<void> {
870
+ if (Platform.OS === 'web') {
871
+ localStorage.removeItem(key);
872
+ return;
873
+ }
874
+ await SecureStore.deleteItemAsync(key);
875
+ }
876
+ }
877
+
878
+ export const secureStorage = new SecureStorage();
879
+ ```
880
+
881
+ ---
882
+
883
+ ## Arquitetura de Navegação
884
+
885
+ ### Padrões do Expo Router
886
+
887
+ ```typescript
888
+ // 1. Rotas de Grupo (Layouts Compartilhados)
889
+ app/
890
+ ├── (auth)/
891
+ │ ├── _layout.tsx # Layout de auth
892
+ │ ├── login.tsx
893
+ │ └── register.tsx
894
+ └── (tabs)/
895
+ ├── _layout.tsx # Layout de abas
896
+ ├── index.tsx
897
+ └── profile.tsx
898
+
899
+ // 2. Rotas Dinâmicas
900
+ app/
901
+ └── article/
902
+ └── [id].tsx # /article/123
903
+
904
+ // 3. Rotas Catch-all
905
+ app/
906
+ └── blog/
907
+ └── [...slug].tsx # /blog/2024/01/article
908
+
909
+ // 4. Rotas de Modal
910
+ app/
911
+ ├── _layout.tsx
912
+ └── modal.tsx # Apresentado como modal
913
+
914
+ // Tipos de navegação
915
+ import type { NativeStackScreenProps } from '@react-navigation/native-stack';
916
+
917
+ type RootStackParamList = {
918
+ '(tabs)': undefined;
919
+ '(auth)': undefined;
920
+ 'article/[id]': { id: string };
921
+ modal: { title: string };
922
+ };
923
+
924
+ type ArticleScreenProps = NativeStackScreenProps<RootStackParamList, 'article/[id]'>;
925
+
926
+ // Navegação com tipagem segura
927
+ import { router } from 'expo-router';
928
+
929
+ router.push({ pathname: '/article/[id]', params: { id: '123' } });
930
+ router.back();
931
+ router.replace('/login');
932
+ ```
933
+
934
+ ---
935
+
936
+ ## Código Específico por Plataforma
937
+
938
+ ### Organização de Código Específico por Plataforma
939
+
940
+ ```typescript
941
+ // Método 1: Platform.select
942
+ import { Platform, StyleSheet } from 'react-native';
943
+
944
+ const styles = StyleSheet.create({
945
+ container: {
946
+ ...Platform.select({
947
+ ios: {
948
+ paddingTop: 20,
949
+ },
950
+ android: {
951
+ paddingTop: 0,
952
+ },
953
+ default: {
954
+ paddingTop: 10,
955
+ },
956
+ }),
957
+ },
958
+ });
959
+
960
+ // Método 2: Extensões de arquivo
961
+ // Button.ios.tsx
962
+ export const Button = () => <IOSButton />;
963
+
964
+ // Button.android.tsx
965
+ export const Button = () => <AndroidButton />;
966
+
967
+ // Button.tsx (fallback)
968
+ export const Button = () => <DefaultButton />;
969
+
970
+ // Método 3: Verificação de plataforma
971
+ if (Platform.OS === 'ios') {
972
+ // Específico para iOS
973
+ } else if (Platform.OS === 'android') {
974
+ // Específico para Android
975
+ }
976
+
977
+ // Método 4: Versão da plataforma
978
+ if (Platform.Version >= 23) {
979
+ // Android API 23+
980
+ }
981
+ ```
982
+
983
+ ---
984
+
985
+ ## Organização de Módulos Nativos
986
+
987
+ ```typescript
988
+ // src/modules/
989
+ ├── camera/
990
+ │ ├── CameraModule.ts # Wrapper TypeScript
991
+ │ ├── CameraModule.ios.ts # Implementação iOS
992
+ │ └── CameraModule.android.ts # Implementação Android
993
+ └── biometrics/
994
+ ├── BiometricsModule.ts
995
+ ├── BiometricsModule.ios.ts
996
+ └── BiometricsModule.android.ts
997
+
998
+ // Exemplo de wrapper
999
+ // modules/camera/CameraModule.ts
1000
+ import { NativeModules } from 'react-native';
1001
+
1002
+ interface CameraInterface {
1003
+ takePicture(): Promise<string>;
1004
+ hasPermission(): Promise<boolean>;
1005
+ requestPermission(): Promise<boolean>;
1006
+ }
1007
+
1008
+ const { CameraModule } = NativeModules;
1009
+
1010
+ export default CameraModule as CameraInterface;
1011
+
1012
+ // Uso
1013
+ import CameraModule from '@/modules/camera/CameraModule';
1014
+
1015
+ const takePicture = async () => {
1016
+ const hasPermission = await CameraModule.hasPermission();
1017
+ if (!hasPermission) {
1018
+ const granted = await CameraModule.requestPermission();
1019
+ if (!granted) return;
1020
+ }
1021
+ const photoUri = await CameraModule.takePicture();
1022
+ return photoUri;
1023
+ };
1024
+ ```
1025
+
1026
+ ---
1027
+
1028
+ ## Boas Práticas de Arquitetura
1029
+
1030
+ ### 1. Injeção de Dependência
1031
+
1032
+ ```typescript
1033
+ // ✅ BOM: Injeção de dependência
1034
+ interface StorageService {
1035
+ get(key: string): Promise<string | null>;
1036
+ set(key: string, value: string): Promise<void>;
1037
+ }
1038
+
1039
+ class UserRepository {
1040
+ constructor(private storage: StorageService) {}
1041
+
1042
+ async getUser(): Promise<User | null> {
1043
+ const data = await this.storage.get('user');
1044
+ return data ? JSON.parse(data) : null;
1045
+ }
1046
+ }
1047
+
1048
+ // Uso
1049
+ const repository = new UserRepository(mmkvStorage);
1050
+
1051
+ // ❌ RUIM: Dependência hard-coded
1052
+ class UserRepository {
1053
+ async getUser() {
1054
+ const data = await mmkvStorage.get('user'); // Acoplamento forte
1055
+ return data ? JSON.parse(data) : null;
1056
+ }
1057
+ }
1058
+ ```
1059
+
1060
+ ### 2. Padrão Repository
1061
+
1062
+ ```typescript
1063
+ // features/articles/repositories/articles.repository.ts
1064
+ import { articlesService } from '../services/articles.service';
1065
+ import { articlesStorage } from '../services/articles.storage';
1066
+
1067
+ class ArticlesRepository {
1068
+ async getArticles(filters?: ArticleFilters): Promise<Article[]> {
1069
+ try {
1070
+ // Tenta a API primeiro
1071
+ const articles = await articlesService.getAll(filters);
1072
+ // Salva em cache local
1073
+ await articlesStorage.saveArticles(articles.data);
1074
+ return articles.data;
1075
+ } catch (error) {
1076
+ // Fallback para armazenamento local
1077
+ return await articlesStorage.getArticles();
1078
+ }
1079
+ }
1080
+
1081
+ async getArticleById(id: string): Promise<Article | null> {
1082
+ // Tenta o cache primeiro
1083
+ const cached = await articlesStorage.getArticleById(id);
1084
+ if (cached) return cached;
1085
+
1086
+ // Busca da API
1087
+ const article = await articlesService.getById(id);
1088
+ await articlesStorage.saveArticle(article);
1089
+ return article;
1090
+ }
1091
+ }
1092
+
1093
+ export const articlesRepository = new ArticlesRepository();
1094
+ ```
1095
+
1096
+ ### 3. Padrão Adapter
1097
+
1098
+ ```typescript
1099
+ // Para adaptar APIs externas
1100
+ interface ArticleDTO {
1101
+ id: number;
1102
+ post_title: string;
1103
+ post_content: string;
1104
+ author_name: string;
1105
+ }
1106
+
1107
+ interface Article {
1108
+ id: string;
1109
+ title: string;
1110
+ content: string;
1111
+ author: string;
1112
+ }
1113
+
1114
+ class ArticleAdapter {
1115
+ static toArticle(dto: ArticleDTO): Article {
1116
+ return {
1117
+ id: String(dto.id),
1118
+ title: dto.post_title,
1119
+ content: dto.post_content,
1120
+ author: dto.author_name,
1121
+ };
1122
+ }
1123
+
1124
+ static toDTO(article: Article): ArticleDTO {
1125
+ return {
1126
+ id: Number(article.id),
1127
+ post_title: article.title,
1128
+ post_content: article.content,
1129
+ author_name: article.author,
1130
+ };
1131
+ }
1132
+ }
1133
+ ```
1134
+
1135
+ ---
1136
+
1137
+ ## Exemplos Completos
1138
+
1139
+ ### Exemplo Completo de Funcionalidade: Artigos
1140
+
1141
+ ```typescript
1142
+ // 1. Tipos
1143
+ // features/articles/types/Article.types.ts
1144
+ export interface Article {
1145
+ id: string;
1146
+ title: string;
1147
+ content: string;
1148
+ authorId: string;
1149
+ tags: string[];
1150
+ publishedAt: Date;
1151
+ }
1152
+
1153
+ // 2. Serviço de API
1154
+ // features/articles/services/articles.service.ts
1155
+ class ArticlesService {
1156
+ async getAll(): Promise<Article[]> {
1157
+ const { data } = await apiClient.get('/articles');
1158
+ return data;
1159
+ }
1160
+ }
1161
+ export const articlesService = new ArticlesService();
1162
+
1163
+ // 3. Serviço de Armazenamento
1164
+ // features/articles/services/articles.storage.ts
1165
+ class ArticlesStorage {
1166
+ async saveArticles(articles: Article[]): Promise<void> {
1167
+ await mmkvStorage.setItem('articles', JSON.stringify(articles));
1168
+ }
1169
+
1170
+ async getArticles(): Promise<Article[]> {
1171
+ const data = await mmkvStorage.getItem('articles');
1172
+ return data ? JSON.parse(data) : [];
1173
+ }
1174
+ }
1175
+ export const articlesStorage = new ArticlesStorage();
1176
+
1177
+ // 4. Repository
1178
+ // features/articles/repositories/articles.repository.ts
1179
+ class ArticlesRepository {
1180
+ async getArticles(): Promise<Article[]> {
1181
+ try {
1182
+ const articles = await articlesService.getAll();
1183
+ await articlesStorage.saveArticles(articles);
1184
+ return articles;
1185
+ } catch {
1186
+ return await articlesStorage.getArticles();
1187
+ }
1188
+ }
1189
+ }
1190
+ export const articlesRepository = new ArticlesRepository();
1191
+
1192
+ // 5. Hook
1193
+ // features/articles/hooks/useArticles.ts
1194
+ export const useArticles = () => {
1195
+ return useQuery({
1196
+ queryKey: ['articles'],
1197
+ queryFn: () => articlesRepository.getArticles(),
1198
+ });
1199
+ };
1200
+
1201
+ // 6. Componente
1202
+ // features/articles/components/ArticleCard/ArticleCard.tsx
1203
+ interface ArticleCardProps {
1204
+ article: Article;
1205
+ }
1206
+
1207
+ export const ArticleCard = ({ article }: ArticleCardProps) => {
1208
+ return (
1209
+ <Card onPress={() => router.push(`/article/${article.id}`)}>
1210
+ <Text style={styles.title}>{article.title}</Text>
1211
+ <Text style={styles.content}>{article.content}</Text>
1212
+ </Card>
1213
+ );
1214
+ };
1215
+
1216
+ // 7. Tela
1217
+ // app/(tabs)/articles.tsx
1218
+ export default function ArticlesScreen() {
1219
+ const { data: articles, isLoading } = useArticles();
1220
+
1221
+ if (isLoading) return <LoadingSpinner />;
1222
+
1223
+ return (
1224
+ <FlatList
1225
+ data={articles}
1226
+ renderItem={({ item }) => <ArticleCard article={item} />}
1227
+ keyExtractor={(item) => item.id}
1228
+ />
1229
+ );
1230
+ }
1231
+ ```
1232
+
180
1233
  ---
181
1234
 
182
1235
  ## Checklist de Arquitetura
183
1236
 
184
- **Antes de implementar uma feature**:
1237
+ **Antes de implementar uma funcionalidade**:
185
1238
 
186
- - [ ] Pasta de feature criada em features/
1239
+ - [ ] Pasta da funcionalidade criada em features/
187
1240
  - [ ] Tipos definidos em types/
188
- - [ ] Serviço API criado em services/
189
- - [ ] Serviço de storage se necessário
190
- - [ ] Repository se lógica complexa
191
- - [ ] Hook customizado criado em hooks/
1241
+ - [ ] Serviço de API criado em services/
1242
+ - [ ] Serviço de armazenamento se necessário
1243
+ - [ ] Repository se houver lógica complexa
1244
+ - [ ] Custom hook criado em hooks/
192
1245
  - [ ] Componentes UI em components/
193
- - [ ] Screen em app/
1246
+ - [ ] Tela em app/
194
1247
  - [ ] Navegação configurada
195
1248
  - [ ] Testes unitários
196
1249
  - [ ] Documentação
197
1250
 
198
1251
  ---
199
1252
 
200
- **Arquitetura é a fundação da manutenibilidade. Invista tempo desde o início.**
1253
+ **A arquitetura é a base da manutenibilidade. Invista tempo desde o início.**