rbin-task-flow 1.6.0 → 1.7.0
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.
|
@@ -21,12 +21,42 @@ src/
|
|
|
21
21
|
└── shared/ # Global reusable code
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
+
### Allowed folders in shared/ and features/ (Front web & Mobile only)
|
|
25
|
+
|
|
26
|
+
In **front web** (Next.js, React, or other React-based web) or **mobile** (Expo, React Native) projects, only the following folder names may exist directly under `shared/` or under each feature in `features/`:
|
|
27
|
+
|
|
28
|
+
| Folder | Use |
|
|
29
|
+
|---------------|------------------------|
|
|
30
|
+
| `pages/` | Web only — page components |
|
|
31
|
+
| `screens/` | Mobile only — screen components |
|
|
32
|
+
| `components/` | UI components |
|
|
33
|
+
| `constants/` | Constants |
|
|
34
|
+
| `utils/` | Utilities |
|
|
35
|
+
| `validations/` | Validation helpers (e.g. `.validation.ts` for Zod) |
|
|
36
|
+
| `hooks/` | Custom hooks |
|
|
37
|
+
| `providers/` | Context providers |
|
|
38
|
+
| `styles/` | Styles |
|
|
39
|
+
| `types/` | TypeScript types |
|
|
40
|
+
| `libs/` | Library wrappers |
|
|
41
|
+
| `services/` | React Query / API wrappers |
|
|
42
|
+
| `use-cases/` | Pure API / business logic |
|
|
43
|
+
| `schemas/` | Zod (or similar) schemas |
|
|
44
|
+
|
|
45
|
+
**No other folder names** are allowed under `shared/` or under `features/[feature-name]/`. Use only `pages/` for web and `screens/` for mobile; do not mix both in the same project type.
|
|
46
|
+
|
|
47
|
+
### No subfolders in shared/ (Front web & Mobile only)
|
|
48
|
+
|
|
49
|
+
In **front web** (Next.js, React) or **mobile** (Expo, React Native) projects, each folder under `shared/` must be **flat**: no subfolders. Files assume the responsibility through clear naming.
|
|
50
|
+
|
|
51
|
+
- **shared/components/**: One file per component, directly in `shared/components/`. No nested folders (e.g. no `form/`, `inputs/`). Name files so the purpose is clear (e.g. `button.tsx`, `input-text.tsx`, `input-container.tsx`, `input-error.tsx`, `input-label.tsx`).
|
|
52
|
+
- **shared/hooks/**, **shared/utils/**, **shared/validations/**, **shared/constants/**, etc.: Same rule — only files, no subfolders. Use the file name to carry the responsibility. Validation helpers (e.g. `required-email.validation.ts`) live in `shared/validations/`.
|
|
53
|
+
|
|
24
54
|
---
|
|
25
55
|
|
|
26
56
|
## Tech Stack
|
|
27
57
|
|
|
28
|
-
### Front-end (Next.js)
|
|
29
|
-
- **Framework**: Next.js 15+ with App Router
|
|
58
|
+
### Front-end (Next.js / React)
|
|
59
|
+
- **Framework**: Next.js 15+ with App Router, or React (Vite, CRA, or similar). These rules apply to any React-based web project.
|
|
30
60
|
- **Language**: TypeScript (strict mode)
|
|
31
61
|
- **Styling**: Tailwind CSS v4 + `clsx` + `tailwind-merge` via `cn()` helper
|
|
32
62
|
- **UI Components**: shadcn/ui + `lucide-react` icons
|
|
@@ -37,7 +67,7 @@ src/
|
|
|
37
67
|
- **E2E Testing**: Playwright and/or Cypress
|
|
38
68
|
|
|
39
69
|
### Mobile (Expo / React Native)
|
|
40
|
-
- **Framework**: Expo with Expo Router
|
|
70
|
+
- **Framework**: Expo with Expo Router, or React Native (bare or managed). These rules apply to both Expo and React Native.
|
|
41
71
|
- **Language**: TypeScript (strict mode)
|
|
42
72
|
- **Styling**: NativeWind + `clsx` + `tailwind-merge` via `cn()` helper
|
|
43
73
|
- **Data Fetching**: `@tanstack/react-query`
|
|
@@ -61,7 +91,7 @@ src/
|
|
|
61
91
|
|
|
62
92
|
The `app/` directory contains ONLY route definitions. Each file is a thin wrapper that imports and renders the feature page/screen.
|
|
63
93
|
|
|
64
|
-
**Front-end (Next.js App Router):**
|
|
94
|
+
**Front-end (Next.js App Router or React):**
|
|
65
95
|
```typescript
|
|
66
96
|
// src/app/(private)/dashboard/page.tsx
|
|
67
97
|
import { DashboardPage } from '@/features/dashboard/pages/dashboard.page'
|
|
@@ -71,7 +101,7 @@ export default function Dashboard() {
|
|
|
71
101
|
}
|
|
72
102
|
```
|
|
73
103
|
|
|
74
|
-
**Mobile (Expo Router):**
|
|
104
|
+
**Mobile (Expo Router or React Native):**
|
|
75
105
|
```typescript
|
|
76
106
|
// src/app/(private)/dashboard.tsx
|
|
77
107
|
import { DashboardScreen } from '@/features/dashboard/screens/dashboard.screen'
|
|
@@ -283,6 +313,8 @@ export function DashboardActiveCard({ data, isLoading, isError }: DashboardActiv
|
|
|
283
313
|
|
|
284
314
|
## shared/ — Global Reusable Code
|
|
285
315
|
|
|
316
|
+
In front web (Next.js, React) and mobile (Expo, React Native), `shared/` is flat per folder (no subfolders). One file per concern; naming carries the responsibility.
|
|
317
|
+
|
|
286
318
|
```
|
|
287
319
|
shared/
|
|
288
320
|
├── components/
|
|
@@ -291,14 +323,11 @@ shared/
|
|
|
291
323
|
│ ├── data-handler.tsx
|
|
292
324
|
│ ├── skeleton.tsx
|
|
293
325
|
│ ├── dialog.tsx
|
|
294
|
-
│
|
|
295
|
-
│
|
|
296
|
-
│
|
|
297
|
-
│
|
|
298
|
-
│
|
|
299
|
-
│ ├── input-container.tsx
|
|
300
|
-
│ ├── input-error.tsx
|
|
301
|
-
│ └── input-label.tsx
|
|
326
|
+
│ ├── input-text.tsx
|
|
327
|
+
│ ├── input-select.tsx
|
|
328
|
+
│ ├── input-container.tsx
|
|
329
|
+
│ ├── input-error.tsx
|
|
330
|
+
│ └── input-label.tsx
|
|
302
331
|
├── hooks/
|
|
303
332
|
│ ├── dialog.hook.tsx
|
|
304
333
|
│ └── drawer.hook.tsx
|
|
@@ -312,11 +341,11 @@ shared/
|
|
|
312
341
|
│ └── shared.ui.type.ts
|
|
313
342
|
├── constants/
|
|
314
343
|
│ └── server-routes.constants.ts
|
|
344
|
+
├── validations/
|
|
345
|
+
│ ├── required-email.validation.ts
|
|
346
|
+
│ ├── required-string.validation.ts
|
|
347
|
+
│ └── required-phone.validation.ts
|
|
315
348
|
└── utils/
|
|
316
|
-
├── validation/
|
|
317
|
-
│ ├── required-email.validation.ts
|
|
318
|
-
│ ├── required-string.validation.ts
|
|
319
|
-
│ └── required-phone.validation.ts
|
|
320
349
|
└── error.util.ts
|
|
321
350
|
```
|
|
322
351
|
|
|
@@ -516,8 +545,8 @@ export type ServiceInput<TData = unknown> = {
|
|
|
516
545
|
```typescript
|
|
517
546
|
// src/features/auth/schemas/login.schema.ts
|
|
518
547
|
import { z } from 'zod'
|
|
519
|
-
import { requiredEmail } from '@/shared/
|
|
520
|
-
import { requiredString } from '@/shared/
|
|
548
|
+
import { requiredEmail } from '@/shared/validations/required-email.validation'
|
|
549
|
+
import { requiredString } from '@/shared/validations/required-string.validation'
|
|
521
550
|
|
|
522
551
|
export const loginSchema = z.object({
|
|
523
552
|
email: requiredEmail(),
|
|
@@ -529,7 +558,7 @@ export type LoginSchema = z.infer<typeof loginSchema>
|
|
|
529
558
|
|
|
530
559
|
**Reusable validators in shared/:**
|
|
531
560
|
```typescript
|
|
532
|
-
// src/shared/
|
|
561
|
+
// src/shared/validations/required-string.validation.ts
|
|
533
562
|
import { z } from 'zod'
|
|
534
563
|
|
|
535
564
|
export const requiredString = ({ field, min = 1 }: { field: string; min?: number }) =>
|
|
@@ -547,7 +576,7 @@ import { zodResolver } from '@hookform/resolvers/zod'
|
|
|
547
576
|
import { useForm } from 'react-hook-form'
|
|
548
577
|
import { LoginSchema, loginSchema } from '@/features/auth/schemas/login.schema'
|
|
549
578
|
import { SessionCreateService } from '@/features/auth/services/session-create.service'
|
|
550
|
-
import { InputText } from '@/shared/components/
|
|
579
|
+
import { InputText } from '@/shared/components/input-text'
|
|
551
580
|
import { Button } from '@/shared/components/button'
|
|
552
581
|
|
|
553
582
|
export function LoginForm() {
|
|
@@ -572,7 +601,7 @@ export function LoginForm() {
|
|
|
572
601
|
|
|
573
602
|
**Input uses `Controller` from RHF and is generic:**
|
|
574
603
|
```typescript
|
|
575
|
-
// src/shared/components/
|
|
604
|
+
// src/shared/components/input-text.tsx
|
|
576
605
|
import { Control, Controller, FieldValues, Path, PathValue } from 'react-hook-form'
|
|
577
606
|
import { cn } from '@/shared/libs/tw-merge'
|
|
578
607
|
|
|
@@ -616,13 +645,24 @@ export function InputText<T extends FieldValues>({
|
|
|
616
645
|
|
|
617
646
|
## File Naming Conventions
|
|
618
647
|
|
|
619
|
-
|
|
648
|
+
### Rule for front (web & mobile): outside `app/` only
|
|
649
|
+
|
|
650
|
+
Every file outside the `app/` folder must follow:
|
|
651
|
+
|
|
652
|
+
- **Format**: lowercase, words separated by `-`, then `.tipo.ext` (suffix by role).
|
|
653
|
+
- **Examples**: `pagina-exemplo.page.tsx`, `login.schema.ts`, `session-create.use-case.ts`, `dashboard-active.type.ts`.
|
|
654
|
+
|
|
655
|
+
**Components are the exception**: do **not** use a `.component` suffix. Use only kebab-case + extension, e.g. `pagina-exemplo.tsx`, `dashboard-revenue-card.tsx`, `input-text.tsx`.
|
|
656
|
+
|
|
657
|
+
**Another exception**: files inside any `styles/` folder do not need to follow this pattern (e.g. CSS/SCSS modules may use their own convention).
|
|
658
|
+
|
|
659
|
+
### Suffix by role
|
|
620
660
|
|
|
621
661
|
| Role | Suffix | Example |
|
|
622
662
|
|------|--------|---------|
|
|
623
|
-
| Page component | `.page.tsx` | `
|
|
663
|
+
| Page component | `.page.tsx` | `pagina-exemplo.page.tsx` |
|
|
624
664
|
| Screen component (mobile) | `.screen.tsx` | `login.screen.tsx` |
|
|
625
|
-
| UI component | `.tsx` | `dashboard-revenue-card.tsx` |
|
|
665
|
+
| UI component | (no suffix) `.tsx` | `dashboard-revenue-card.tsx`, `input-text.tsx` |
|
|
626
666
|
| React Query service | `.service.tsx` | `session-create.service.tsx` |
|
|
627
667
|
| API call (pure) | `.use-case.ts` | `session-create.use-case.ts` |
|
|
628
668
|
| Zod schema | `.schema.ts` | `login.schema.ts` |
|
|
@@ -630,7 +670,7 @@ Use kebab-case for all filenames. Suffix reflects the file's role:
|
|
|
630
670
|
| API response type | `.api.type.ts` | `session.api.type.ts` |
|
|
631
671
|
| Domain type | `.type.ts` | `dashboard-active.type.ts` |
|
|
632
672
|
| Utility | `.util.ts` | `error.util.ts` |
|
|
633
|
-
| Validation helper | `.validation.ts` | `required-email.validation.ts` |
|
|
673
|
+
| Validation helper | `.validation.ts` | `required-email.validation.ts` (in `validations/`) |
|
|
634
674
|
| Constants | `.constants.ts` | `server-routes.constants.ts` |
|
|
635
675
|
|
|
636
676
|
---
|
|
@@ -684,7 +724,7 @@ export const useAuth = () => useContext(AuthContext)
|
|
|
684
724
|
|
|
685
725
|
## Testing
|
|
686
726
|
|
|
687
|
-
### Front-end (Next.js)
|
|
727
|
+
### Front-end (Next.js / React)
|
|
688
728
|
- **E2E**: Playwright and/or Cypress
|
|
689
729
|
- Tests live in `e2e/` or `cypress/` at project root
|
|
690
730
|
- Test files: `[feature].spec.ts` (Playwright) or `[feature].cy.ts` (Cypress)
|
|
@@ -710,3 +750,4 @@ export const useAuth = () => useContext(AuthContext)
|
|
|
710
750
|
8. **Type everything**: No `any`. All props, params, and return values must be typed.
|
|
711
751
|
9. **Shared is truly shared**: Only put in `shared/` what is used by 2+ features.
|
|
712
752
|
10. **Naming reflects role**: File name + suffix must make the file's purpose immediately obvious.
|
|
753
|
+
11. **No barrel files for re-exports**: Do not use `index.ts` (or `index.tsx`) only to re-export other modules. Import directly from the source file (e.g. `from '@/shared/components/button'` not `from '@/shared/components'`). An `index.ts` is only allowed when it contains real logic or composition, not mere re-exports.
|