Skip to content

Commit 53a7819

Browse files
authored
Merge pull request #47 from bartstc/chore/refactor-feature-slice-architecture
chore: refactor feature slice architecture
2 parents ec2c87d + 5dacf9e commit 53a7819

205 files changed

Lines changed: 395 additions & 367 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude/docs/architecture.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@
4040

4141
Each feature follows feature slice architecture patterns with three layers:
4242

43-
- **presentation/** - UI components, UI-wise hooks
44-
- **application/** - Business logic, state management, logic-wise hooks
45-
- **infrastructure/** - Data fetching, external APIs, contracts, DTOs
46-
- **types/** - Type definitions
43+
- **components/** - UI components, presentational and decoupled from data sources, business logic, and router state
44+
- **application/** - Business logic, state management, custom hooks, stores, and functions
45+
- **providers/** - Data fetching, external APIs, platform/SDK interactions, commands/mutations
46+
- **models/** - Type definitions
4747

4848
## Key Patterns
4949

.claude/docs/code-style.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@
77
- Follow functional programming principles - prefer immutability and pure functions
88
- Treat data as immutable - return new objects/arrays instead of mutating
99

10+
## Naming Conventions
11+
12+
### File naming
13+
14+
| Category | Convention | Example |
15+
| ------------------ | ---------- | ------------------------------------------------- |
16+
| React components | PascalCase | `ProductCard.tsx`, `SignInForm.tsx` |
17+
| Storybook stories | PascalCase | `ProductCard.stories.tsx` |
18+
| Page Objects (E2E) | PascalCase | `ProductListPage.ts`, `HeaderComponent.ts` |
19+
| Everything else | kebab-case | `auth-store.ts`, `use-counter.ts`, `build-url.ts` |
20+
21+
"Everything else" includes: hooks, stores, utils, types, models, HOCs, handlers, fixtures, providers, machines, and tests.
22+
23+
Test files mirror their source: `use-counter.ts``use-counter.test.ts`, `all-or-nothing.ts``all-or-nothing.test.ts`.
24+
1025
## TypeScript
1126

1227
- Avoid `any` type - use `unknown` if necessary

.github/instructions/architecture.instructions.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ React SPA built with Vite using feature slice architecture with clean architectu
4747

4848
Each feature follows feature slice architecture patterns with three layers:
4949

50-
- **presentation/** - UI components, UI-wise hooks
51-
- **application/** - Business logic, state management, logic-wise hooks
52-
- **infrastructure/** - Data fetching, external APIs, contracts, DTOs
53-
- **types/** - Type definitions
50+
- **components/** - UI components, presentational and decoupled from data sources, business logic, and router state
51+
- **application/** - Business logic, state management, custom hooks, stores, and functions
52+
- **providers/** - Data fetching, external APIs, platform/SDK interactions, commands/mutations
53+
- **models/** - Type definitions
5454

5555
### Key Patterns
5656

.github/instructions/development.instructions.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ Add specially formatted comments throughout the codebase, where appropriate, for
3131
- Follow functional programming principles where possible, especially prefer immutability and pure functions.
3232
- Treat data as immutable - return new objects/arrays instead of mutating existing ones.
3333

34+
#### Naming Conventions
35+
36+
| Category | Convention | Example |
37+
| ------------------ | ---------- | ------------------------------------------------- |
38+
| React components | PascalCase | `ProductCard.tsx`, `SignInForm.tsx` |
39+
| Storybook stories | PascalCase | `ProductCard.stories.tsx` |
40+
| Page Objects (E2E) | PascalCase | `ProductListPage.ts`, `HeaderComponent.ts` |
41+
| Everything else | kebab-case | `auth-store.ts`, `use-counter.ts`, `build-url.ts` |
42+
43+
"Everything else" includes: hooks, stores, utils, types, models, HOCs, handlers, fixtures, providers, machines, and tests.
44+
45+
Test files mirror their source: `use-counter.ts``use-counter.test.ts`, `all-or-nothing.ts``all-or-nothing.test.ts`.
46+
3447
#### Typescript
3548

3649
- Avoid using `any` type. If necessary, use `unknown` instead.

.storybook/preview.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { ChakraProvider, theme } from "@chakra-ui/react";
22
import { initialize, mswLoader } from "msw-storybook-addon";
33
import { createElement } from "react";
44

5-
import { getUserHandler } from "@/test-lib/handlers/getUserHandler";
6-
import { withAuth } from "@/test-lib/storybook/withAuth";
7-
import { withI18Next } from "@/test-lib/storybook/withI18Next";
8-
import { withReactQuery } from "@/test-lib/storybook/withReactQuery";
5+
import { getUserHandler } from "@/test-lib/handlers/get-user-handler";
6+
import { withAuth } from "@/test-lib/storybook/with-auth";
7+
import { withI18Next } from "@/test-lib/storybook/with-i18next";
8+
import { withReactQuery } from "@/test-lib/storybook/with-react-query";
99

1010
export const parameters = {
1111
controls: {

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ An opinionated, production-ready starter for **Single Page Application** develop
3636
- Feature slice architecture with clean architecture principles
3737
- Centralized API layer with endpoint-based organization and type consolidation
3838
- Formatting utilities for numbers, monetary values, and dates
39+
- File naming: PascalCase for React components/stories/page objects, kebab-case for everything else
3940
- A demo app with authentication showcasing the project structure and tooling in action (powered by [Fake Store API](https://fakestoreapi.com/docs))
4041

4142
## Getting started

e2e/fixtures/credentials-fixture.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import type { IUser } from "@/features/auth/types/IUser";
2-
import { UserFixture } from "@/test-lib/fixtures/UserFixture";
1+
import type { User } from "@/features/auth/models/user";
2+
import { UserFixture } from "@/test-lib/fixtures/user-fixture";
33

44
// AIDEV-NOTE: Reuses UserFixture from @/test-lib for domain data, adds E2E-specific password field
55
export interface TestCredentials {
6-
user: IUser;
6+
user: User;
77
password: string;
88
}
99

e2e/pages/cart/CartPage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Page, Locator } from "@playwright/test";
22

3-
import type { PaymentMethod } from "@/features/carts/types/PaymentMethod";
3+
import type { PaymentMethod } from "@/features/carts/models/payment-method";
44
import { BasePage } from "@e2e/pages/base/BasePage";
55

66
export class CartPage extends BasePage {

eslint.config.mjs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { config, configs as tsConfigs } from "typescript-eslint";
1+
import { defineConfig } from "eslint/config";
2+
import tseslint from "typescript-eslint";
23
import js from "@eslint/js";
34
import { configs } from "eslint-plugin-react-hooks";
45
import reactPlugin from "eslint-plugin-react";
@@ -18,7 +19,7 @@ const featureToFeatureZones = featureSlices.map((feature) => ({
1819
message: "Avoid importing from other features.",
1920
}));
2021

21-
export default config(
22+
export default defineConfig(
2223
{
2324
ignores: [
2425
"**/dist",
@@ -29,8 +30,8 @@ export default config(
2930
],
3031
},
3132
js.configs.recommended,
32-
tsConfigs.recommendedTypeChecked,
33-
tsConfigs.stylisticTypeChecked,
33+
tseslint.configs.recommendedTypeChecked,
34+
tseslint.configs.stylisticTypeChecked,
3435
configs["recommended-latest"],
3536
reactPlugin.configs.flat.recommended,
3637
reactPlugin.configs.flat["jsx-runtime"],

src/app/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import "@fontsource/inter/400.css";
66
import "@fontsource/inter/700.css";
77
import "@fontsource/inter/900.css";
88

9-
import { useAuthStore } from "@/features/auth/application/authStore";
9+
import { useAuthStore } from "@/features/auth/application/auth-store";
1010
import { router } from "@/pages/router";
1111

1212
function App() {

0 commit comments

Comments
 (0)