fix(styles): include feature modules in Tailwind content scan
This commit is contained in:
Generated
+45
-37
@@ -4,9 +4,8 @@
|
|||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="bb7b50a5-be9c-4cd7-a05b-979f0e91b173" name="Changes" comment="refactor(products): organize product showcase into feature module">
|
<list default="true" id="bb7b50a5-be9c-4cd7-a05b-979f0e91b173" name="Changes" comment="fix(styles): include feature modules in Tailwind content scan">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/tailwind.config.ts" beforeDir="false" afterPath="$PROJECT_DIR$/tailwind.config.ts" afterDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -97,39 +96,39 @@
|
|||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
<option name="showLibraryContents" value="true" />
|
<option name="showLibraryContents" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent"><![CDATA[{
|
<component name="PropertiesComponent">{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
"ASKED_MARK_IGNORED_FILES_AS_EXCLUDED": "true",
|
"ASKED_MARK_IGNORED_FILES_AS_EXCLUDED": "true",
|
||||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||||
"codeWithMe.voiceChat.enabledByDefault": "false",
|
"codeWithMe.voiceChat.enabledByDefault": "false",
|
||||||
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
|
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
|
||||||
"git-widget-placeholder": "develop",
|
"git-widget-placeholder": "develop",
|
||||||
"javascript.nodejs.core.library.configured.version": "24.20.0",
|
"javascript.nodejs.core.library.configured.version": "24.20.0",
|
||||||
"javascript.nodejs.core.library.typings.version": "24.13.3",
|
"javascript.nodejs.core.library.typings.version": "24.13.3",
|
||||||
"javascript.preferred.runtime.type.id": "node",
|
"javascript.preferred.runtime.type.id": "node",
|
||||||
"js.debugger.nextJs.config.created.client": "true",
|
"js.debugger.nextJs.config.created.client": "true",
|
||||||
"js.debugger.nextJs.config.created.server": "true",
|
"js.debugger.nextJs.config.created.server": "true",
|
||||||
"junie.onboarding.icon.badge.shown": "true",
|
"junie.onboarding.icon.badge.shown": "true",
|
||||||
"kronk.content.tree.expanded.paths": "",
|
"kronk.content.tree.expanded.paths": "",
|
||||||
"last_opened_file_path": "/home/hamed/Documents/Projects/GItLabRepo/device_web",
|
"last_opened_file_path": "/home/hamed/Documents/Projects/GItLabRepo/device_web",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.jshint": "true",
|
"node.js.detected.package.jshint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.jshint": "",
|
"node.js.selected.package.jshint": "",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"prettierjs.PrettierConfiguration.Package": "/home/hamed/Documents/Projects/GIthubRepo/robot-market-landing/node_modules/prettier",
|
"prettierjs.PrettierConfiguration.Package": "/home/hamed/Documents/Projects/GIthubRepo/robot-market-landing/node_modules/prettier",
|
||||||
"settings.editor.selected.configurable": "settings.javascript.prettier",
|
"settings.editor.selected.configurable": "preferences.lookFeel",
|
||||||
"to.speed.mode.migration.done": "true",
|
"to.speed.mode.migration.done": "true",
|
||||||
"ts.external.directory.path": "/home/hamed/Documents/Projects/GIthubRepo/robot-market-landing/node_modules/typescript/lib",
|
"ts.external.directory.path": "/home/hamed/Documents/Projects/GIthubRepo/robot-market-landing/node_modules/typescript/lib",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
}
|
}
|
||||||
}]]></component>
|
}</component>
|
||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
<recent name="$PROJECT_DIR$" />
|
<recent name="$PROJECT_DIR$" />
|
||||||
@@ -225,7 +224,7 @@
|
|||||||
<workItem from="1790568898974" duration="91000" />
|
<workItem from="1790568898974" duration="91000" />
|
||||||
<workItem from="1790569032481" duration="788000" />
|
<workItem from="1790569032481" duration="788000" />
|
||||||
<workItem from="1790573950198" duration="16000" />
|
<workItem from="1790573950198" duration="16000" />
|
||||||
<workItem from="1790660862579" duration="2098000" />
|
<workItem from="1790660862579" duration="6418000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00001" summary="update">
|
<task id="LOCAL-00001" summary="update">
|
||||||
<option name="closed" value="true" />
|
<option name="closed" value="true" />
|
||||||
@@ -595,7 +594,15 @@
|
|||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1790662596270</updated>
|
<updated>1790662596270</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="47" />
|
<task id="LOCAL-00047" summary="fix(styles): include feature modules in Tailwind content scan">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1790663421347</created>
|
||||||
|
<option name="number" value="00047" />
|
||||||
|
<option name="presentableId" value="LOCAL-00047" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1790663421347</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="48" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
@@ -626,6 +633,7 @@
|
|||||||
<MESSAGE value="Improve featured products layout and add support CTA" />
|
<MESSAGE value="Improve featured products layout and add support CTA" />
|
||||||
<MESSAGE value="Replace desktop showcase video with scroll-driven color backgrounds" />
|
<MESSAGE value="Replace desktop showcase video with scroll-driven color backgrounds" />
|
||||||
<MESSAGE value="refactor(products): organize product showcase into feature module" />
|
<MESSAGE value="refactor(products): organize product showcase into feature module" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="refactor(products): organize product showcase into feature module" />
|
<MESSAGE value="fix(styles): include feature modules in Tailwind content scan" />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="fix(styles): include feature modules in Tailwind content scan" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,992 @@
|
|||||||
|
# Next.js Project Development Rules
|
||||||
|
|
||||||
|
You are working on a production Next.js application using the App Router.
|
||||||
|
|
||||||
|
The codebase must remain:
|
||||||
|
|
||||||
|
- simple
|
||||||
|
- readable
|
||||||
|
- maintainable
|
||||||
|
- testable
|
||||||
|
- scalable
|
||||||
|
- junior-developer friendly
|
||||||
|
|
||||||
|
Always prefer the simplest maintainable solution.
|
||||||
|
|
||||||
|
Do not introduce Clean Architecture, repositories, use-cases, factories, dependency-injection systems, adapters, presenters, interactors, or unnecessary architectural layers unless they solve a real current problem.
|
||||||
|
|
||||||
|
Avoid over-engineering.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Technology Stack
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
- Next.js
|
||||||
|
- App Router
|
||||||
|
- React
|
||||||
|
- JavaScript and TypeScript
|
||||||
|
- Tailwind CSS
|
||||||
|
- Redux Toolkit
|
||||||
|
- Vitest
|
||||||
|
- React Testing Library
|
||||||
|
- Playwright
|
||||||
|
|
||||||
|
Do not introduce additional libraries without a clear reason.
|
||||||
|
|
||||||
|
Before adding a dependency:
|
||||||
|
|
||||||
|
1. Check whether Next.js, React, JavaScript, TypeScript, or the existing stack can solve the problem.
|
||||||
|
2. Prefer existing project dependencies.
|
||||||
|
3. Add a dependency only when it clearly improves maintainability, reliability, or developer experience.
|
||||||
|
4. Briefly explain why it is necessary.
|
||||||
|
|
||||||
|
Do not introduce Zod or another validation library unless explicitly requested.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# App Router Only
|
||||||
|
|
||||||
|
Use the Next.js App Router.
|
||||||
|
|
||||||
|
Do not introduce Pages Router patterns into a new App Router project.
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```text
|
||||||
|
app/
|
||||||
|
layout.tsx
|
||||||
|
page.tsx
|
||||||
|
loading.tsx
|
||||||
|
error.tsx
|
||||||
|
not-found.tsx
|
||||||
|
route.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
when appropriate.
|
||||||
|
|
||||||
|
Use route groups for organization where helpful.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
app/
|
||||||
|
├── (public)/
|
||||||
|
├── (auth)/
|
||||||
|
└── (dashboard)/
|
||||||
|
```
|
||||||
|
|
||||||
|
Remember that route groups should organize the project without changing the URL.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Server Components by Default
|
||||||
|
|
||||||
|
Server Components are the default.
|
||||||
|
|
||||||
|
Do not add:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
"use client";
|
||||||
|
```
|
||||||
|
|
||||||
|
unless the component actually requires client-side functionality.
|
||||||
|
|
||||||
|
Client Components are appropriate when using things such as:
|
||||||
|
|
||||||
|
- useState
|
||||||
|
- useEffect
|
||||||
|
- browser APIs
|
||||||
|
- localStorage
|
||||||
|
- event handlers
|
||||||
|
- interactive client-side libraries
|
||||||
|
- Redux hooks
|
||||||
|
|
||||||
|
Keep Client Component boundaries as small as practical.
|
||||||
|
|
||||||
|
Do not convert an entire page into a Client Component just because one small child component needs interactivity.
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Server Page
|
||||||
|
↓
|
||||||
|
Server Components
|
||||||
|
↓
|
||||||
|
Small Client Component
|
||||||
|
```
|
||||||
|
|
||||||
|
rather than:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Entire Page
|
||||||
|
↓
|
||||||
|
"use client"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# General Project Structure
|
||||||
|
|
||||||
|
Recommended structure:
|
||||||
|
|
||||||
|
```text
|
||||||
|
src/
|
||||||
|
├── app/
|
||||||
|
├── features/
|
||||||
|
├── components/
|
||||||
|
│ ├── ui/
|
||||||
|
│ └── layout/
|
||||||
|
├── hooks/
|
||||||
|
├── lib/
|
||||||
|
├── config/
|
||||||
|
├── constants/
|
||||||
|
├── types/
|
||||||
|
├── utils/
|
||||||
|
└── styles/
|
||||||
|
```
|
||||||
|
|
||||||
|
Keep routing in `app/`.
|
||||||
|
|
||||||
|
Keep business and feature-specific code in `features/`.
|
||||||
|
|
||||||
|
Keep generic reusable UI in `components/ui/`.
|
||||||
|
|
||||||
|
Keep infrastructure and reusable technical utilities in `lib/`.
|
||||||
|
|
||||||
|
Do not force every project to have every directory.
|
||||||
|
|
||||||
|
Create directories only when useful.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Keep Pages Thin
|
||||||
|
|
||||||
|
`page.tsx` should primarily:
|
||||||
|
|
||||||
|
- define the route entry
|
||||||
|
- load route-level data when appropriate
|
||||||
|
- compose feature components
|
||||||
|
- pass necessary data
|
||||||
|
|
||||||
|
Avoid putting hundreds of lines of business logic inside `page.tsx`.
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { ProductList } from "@/features/products/components/ProductList";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the product-management page.
|
||||||
|
*/
|
||||||
|
export default async function ProductsPage() {
|
||||||
|
return <ProductList />;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
over a very large page containing:
|
||||||
|
|
||||||
|
- data fetching
|
||||||
|
- filtering
|
||||||
|
- business rules
|
||||||
|
- forms
|
||||||
|
- modals
|
||||||
|
- API calls
|
||||||
|
- transformations
|
||||||
|
- UI rendering
|
||||||
|
|
||||||
|
all together.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Feature-Based Architecture
|
||||||
|
|
||||||
|
Organize business functionality by feature.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
features/
|
||||||
|
├── auth/
|
||||||
|
├── products/
|
||||||
|
├── users/
|
||||||
|
├── machines/
|
||||||
|
├── sales/
|
||||||
|
└── reports/
|
||||||
|
```
|
||||||
|
|
||||||
|
A feature may contain:
|
||||||
|
|
||||||
|
```text
|
||||||
|
features/products/
|
||||||
|
├── components/
|
||||||
|
├── hooks/
|
||||||
|
├── services/
|
||||||
|
├── store/
|
||||||
|
├── utils/
|
||||||
|
├── types/
|
||||||
|
└── tests/
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not create empty folders.
|
||||||
|
|
||||||
|
Only introduce a folder when there is actual code that belongs there.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Shared UI vs Feature UI
|
||||||
|
|
||||||
|
Generic reusable components belong in:
|
||||||
|
|
||||||
|
```text
|
||||||
|
components/ui/
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Button
|
||||||
|
Input
|
||||||
|
Modal
|
||||||
|
Table
|
||||||
|
Card
|
||||||
|
Badge
|
||||||
|
Spinner
|
||||||
|
```
|
||||||
|
|
||||||
|
Feature-specific components stay inside their feature.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```text
|
||||||
|
features/products/components/ProductCard.tsx
|
||||||
|
features/machines/components/MachineStatus.tsx
|
||||||
|
features/sales/components/SalesTable.tsx
|
||||||
|
```
|
||||||
|
|
||||||
|
Generic UI components must not contain feature-specific business logic.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Components
|
||||||
|
|
||||||
|
Each component should have one clear responsibility.
|
||||||
|
|
||||||
|
Keep components small enough to understand easily.
|
||||||
|
|
||||||
|
Split a component when it:
|
||||||
|
|
||||||
|
- handles unrelated responsibilities
|
||||||
|
- contains large amounts of business logic
|
||||||
|
- contains several independent UI sections
|
||||||
|
- becomes difficult to test
|
||||||
|
- becomes difficult to read
|
||||||
|
|
||||||
|
Do not split components unnecessarily.
|
||||||
|
|
||||||
|
Avoid creating wrappers that provide no meaningful behavior.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
|
||||||
|
Functions should be:
|
||||||
|
|
||||||
|
- focused
|
||||||
|
- descriptive
|
||||||
|
- short enough to understand
|
||||||
|
- easy to test
|
||||||
|
|
||||||
|
Prefer meaningful names:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
calculateSaleTotal()
|
||||||
|
formatMachineStatus()
|
||||||
|
canUserEditProduct()
|
||||||
|
getAvailableProducts()
|
||||||
|
```
|
||||||
|
|
||||||
|
Avoid vague names:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
handleData()
|
||||||
|
processStuff()
|
||||||
|
doWork()
|
||||||
|
helper()
|
||||||
|
func1()
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Function Documentation
|
||||||
|
|
||||||
|
Write English documentation comments for important and non-trivial functions.
|
||||||
|
|
||||||
|
Explain:
|
||||||
|
|
||||||
|
- what the function does
|
||||||
|
- important assumptions
|
||||||
|
- important business behavior
|
||||||
|
- non-obvious side effects
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
/**
|
||||||
|
* Returns true when a product is enabled and still has stock available.
|
||||||
|
*/
|
||||||
|
function canSellProduct(product: Product): boolean {
|
||||||
|
return product.enabled && product.stock > 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not comment obvious syntax or trivial statements.
|
||||||
|
|
||||||
|
Comments should explain intent, not translate code into English.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Business Logic
|
||||||
|
|
||||||
|
Keep important business rules outside JSX when practical.
|
||||||
|
|
||||||
|
Bad:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
{machine.enabled &&
|
||||||
|
machine.status === "online" &&
|
||||||
|
machine.products.length > 0 &&
|
||||||
|
user.permissions.includes("manage_machine") && (
|
||||||
|
<ManageButton />
|
||||||
|
)}
|
||||||
|
```
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
/**
|
||||||
|
* Determines whether the current user can manage the given machine.
|
||||||
|
*/
|
||||||
|
function canManageMachine(
|
||||||
|
machine: Machine,
|
||||||
|
user: User
|
||||||
|
): boolean {
|
||||||
|
return (
|
||||||
|
machine.enabled &&
|
||||||
|
machine.status === "online" &&
|
||||||
|
machine.products.length > 0 &&
|
||||||
|
user.permissions.includes("manage_machine")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
{canManageMachine(machine, user) && <ManageButton />}
|
||||||
|
```
|
||||||
|
|
||||||
|
This improves:
|
||||||
|
|
||||||
|
- readability
|
||||||
|
- testing
|
||||||
|
- reuse
|
||||||
|
- maintainability
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Redux Toolkit
|
||||||
|
|
||||||
|
Use Redux Toolkit as the project's global state-management solution.
|
||||||
|
|
||||||
|
Do not store every value in Redux.
|
||||||
|
|
||||||
|
Use local React state for local UI concerns.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```text
|
||||||
|
modal open/close
|
||||||
|
dropdown state
|
||||||
|
form input
|
||||||
|
selected tab
|
||||||
|
temporary UI state
|
||||||
|
```
|
||||||
|
|
||||||
|
Use Redux for meaningful shared application state.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```text
|
||||||
|
authentication
|
||||||
|
current user
|
||||||
|
shared settings
|
||||||
|
cross-page feature state
|
||||||
|
global workflow state
|
||||||
|
```
|
||||||
|
|
||||||
|
Keep Redux state feature-oriented.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
features/auth/store/authSlice.ts
|
||||||
|
features/machines/store/machineSlice.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Avoid a single giant application slice.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Redux in Next.js
|
||||||
|
|
||||||
|
Redux requires Client Components.
|
||||||
|
|
||||||
|
Keep Redux Provider boundaries explicit.
|
||||||
|
|
||||||
|
Do not turn unrelated Server Components into Client Components just to access Redux.
|
||||||
|
|
||||||
|
Prefer passing server-fetched data into client boundaries when practical.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Server Page
|
||||||
|
↓
|
||||||
|
Server data loading
|
||||||
|
↓
|
||||||
|
Client Feature Component
|
||||||
|
↓
|
||||||
|
Redux / interactive state
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not unnecessarily duplicate server data into Redux.
|
||||||
|
|
||||||
|
Use Redux mainly for client-side shared state.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Data Fetching
|
||||||
|
|
||||||
|
Prefer Server Components for server-side data fetching when appropriate.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
/**
|
||||||
|
* Loads the available products and renders the product list.
|
||||||
|
*/
|
||||||
|
export default async function ProductsPage() {
|
||||||
|
const products = await getProducts();
|
||||||
|
|
||||||
|
return <ProductList products={products} />;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not automatically use `useEffect` for every API request.
|
||||||
|
|
||||||
|
Use client-side fetching only when the feature requires client-side re-fetching, polling, user-triggered requests, or interactive behavior.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Service Layer
|
||||||
|
|
||||||
|
Centralize backend communication.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
features/products/services/productService.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
/**
|
||||||
|
* Loads all products from the backend.
|
||||||
|
*/
|
||||||
|
export async function getProducts(): Promise<Product[]> {
|
||||||
|
const response = await fetch(`${API_URL}/products`);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error("Failed to load products.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not scatter backend URLs throughout pages and components.
|
||||||
|
|
||||||
|
Keep HTTP concerns away from presentation components when possible.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Server and Client Boundaries
|
||||||
|
|
||||||
|
Be deliberate about the boundary between server and client code.
|
||||||
|
|
||||||
|
Server-side code may handle:
|
||||||
|
|
||||||
|
- server-side data loading
|
||||||
|
- secure environment variables
|
||||||
|
- server-only APIs
|
||||||
|
- protected backend communication
|
||||||
|
- route handlers
|
||||||
|
- server actions when appropriate
|
||||||
|
|
||||||
|
Client-side code may handle:
|
||||||
|
|
||||||
|
- interaction
|
||||||
|
- browser APIs
|
||||||
|
- local UI state
|
||||||
|
- Redux
|
||||||
|
- event listeners
|
||||||
|
- client-only libraries
|
||||||
|
|
||||||
|
Never expose secrets to Client Components.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Environment Variables
|
||||||
|
|
||||||
|
Do not access environment variables randomly throughout the project.
|
||||||
|
|
||||||
|
Centralize configuration when useful.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
config/env.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
Never expose secrets using:
|
||||||
|
|
||||||
|
```text
|
||||||
|
NEXT_PUBLIC_*
|
||||||
|
```
|
||||||
|
|
||||||
|
Only values intentionally accessible in the browser should use `NEXT_PUBLIC_`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Error Handling
|
||||||
|
|
||||||
|
Use Next.js error boundaries where appropriate.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```text
|
||||||
|
error.tsx
|
||||||
|
not-found.tsx
|
||||||
|
```
|
||||||
|
|
||||||
|
Handle expected failures explicitly.
|
||||||
|
|
||||||
|
Do not silently swallow errors.
|
||||||
|
|
||||||
|
Provide user-friendly messages for recoverable failures.
|
||||||
|
|
||||||
|
Log technical information where appropriate without exposing sensitive data to end users.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Loading States
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```text
|
||||||
|
loading.tsx
|
||||||
|
```
|
||||||
|
|
||||||
|
when route-level loading UI is appropriate.
|
||||||
|
|
||||||
|
For local interactive operations, use explicit loading state.
|
||||||
|
|
||||||
|
Avoid blocking unrelated parts of the UI unnecessarily.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# State Derived from Existing State
|
||||||
|
|
||||||
|
Do not duplicate values that can be calculated.
|
||||||
|
|
||||||
|
Bad:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const [firstName, setFirstName] = useState("");
|
||||||
|
const [lastName, setLastName] = useState("");
|
||||||
|
const [fullName, setFullName] = useState("");
|
||||||
|
```
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const fullName = `${firstName} ${lastName}`;
|
||||||
|
```
|
||||||
|
|
||||||
|
Keep state minimal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# useEffect
|
||||||
|
|
||||||
|
Do not use `useEffect` to calculate values that can be derived during rendering.
|
||||||
|
|
||||||
|
Use `useEffect` primarily for synchronizing with external systems.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
- WebSocket
|
||||||
|
- browser APIs
|
||||||
|
- subscriptions
|
||||||
|
- external widgets
|
||||||
|
- timers
|
||||||
|
- event listeners
|
||||||
|
|
||||||
|
Always clean up resources when required.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Avoid Deep Nesting
|
||||||
|
|
||||||
|
Prefer guard clauses and early returns.
|
||||||
|
|
||||||
|
Bad:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
if (session) {
|
||||||
|
if (session.user) {
|
||||||
|
if (session.user.active) {
|
||||||
|
// logic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
if (!session?.user) return;
|
||||||
|
if (!session.user.active) return;
|
||||||
|
|
||||||
|
// Main logic
|
||||||
|
```
|
||||||
|
|
||||||
|
Keep the happy path visible.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Avoid Magic Values
|
||||||
|
|
||||||
|
Bad:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
if (status === 4) {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
if (status === MachineStatus.Offline) {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Bad:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
if (retryCount > 3) {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const MAX_RETRY_COUNT = 3;
|
||||||
|
|
||||||
|
if (retryCount > MAX_RETRY_COUNT) {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Use descriptive constants where they improve understanding.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Naming
|
||||||
|
|
||||||
|
Names should explain intent.
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
selectedProduct
|
||||||
|
currentUser
|
||||||
|
isMachineOnline
|
||||||
|
canEditSale
|
||||||
|
hasAdminPermission
|
||||||
|
shouldReloadProducts
|
||||||
|
```
|
||||||
|
|
||||||
|
Avoid vague names such as:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
data
|
||||||
|
info
|
||||||
|
item2
|
||||||
|
temp
|
||||||
|
res2
|
||||||
|
obj
|
||||||
|
value1
|
||||||
|
stuff
|
||||||
|
```
|
||||||
|
|
||||||
|
unless the surrounding context makes the meaning completely obvious.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# TypeScript and JavaScript
|
||||||
|
|
||||||
|
JavaScript and TypeScript may coexist.
|
||||||
|
|
||||||
|
Prefer TypeScript for new important logic where practical.
|
||||||
|
|
||||||
|
Do not perform unnecessary project-wide TypeScript migrations during unrelated work.
|
||||||
|
|
||||||
|
Avoid `any` where useful types can be defined.
|
||||||
|
|
||||||
|
Keep feature-specific types close to their feature.
|
||||||
|
|
||||||
|
Use global/shared types only when genuinely shared.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Tailwind CSS
|
||||||
|
|
||||||
|
Use Tailwind CSS for styling.
|
||||||
|
|
||||||
|
Keep styles close to components.
|
||||||
|
|
||||||
|
Avoid creating excessive abstraction only to hide Tailwind classes.
|
||||||
|
|
||||||
|
If a visual pattern is reused meaningfully, extract a reusable component.
|
||||||
|
|
||||||
|
Maintain readable class structures.
|
||||||
|
|
||||||
|
Avoid unnecessarily complex conditional class expressions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
|
||||||
|
Tests are required for meaningful behavior.
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Vitest
|
||||||
|
React Testing Library
|
||||||
|
Playwright
|
||||||
|
```
|
||||||
|
|
||||||
|
Use Vitest for:
|
||||||
|
|
||||||
|
- utilities
|
||||||
|
- business logic
|
||||||
|
- selectors
|
||||||
|
- reducers
|
||||||
|
- non-UI modules
|
||||||
|
|
||||||
|
Use React Testing Library for:
|
||||||
|
|
||||||
|
- interactive components
|
||||||
|
- forms
|
||||||
|
- user behavior
|
||||||
|
- conditional rendering
|
||||||
|
|
||||||
|
Use Playwright for critical user flows.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
```text
|
||||||
|
login
|
||||||
|
logout
|
||||||
|
create product
|
||||||
|
edit machine
|
||||||
|
view report
|
||||||
|
critical dashboard navigation
|
||||||
|
```
|
||||||
|
|
||||||
|
Test behavior rather than implementation details.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Comments
|
||||||
|
|
||||||
|
All project comments must be written in English.
|
||||||
|
|
||||||
|
Use comments to explain:
|
||||||
|
|
||||||
|
- intent
|
||||||
|
- business rules
|
||||||
|
- important decisions
|
||||||
|
- limitations
|
||||||
|
- unusual behavior
|
||||||
|
- non-obvious workarounds
|
||||||
|
|
||||||
|
Do not use excessive comments for obvious code.
|
||||||
|
|
||||||
|
Important functions should have short English documentation comments.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# File Organization
|
||||||
|
|
||||||
|
Keep related code close together.
|
||||||
|
|
||||||
|
Avoid giant generic folders containing hundreds of unrelated files.
|
||||||
|
|
||||||
|
Bad:
|
||||||
|
|
||||||
|
```text
|
||||||
|
components/
|
||||||
|
ProductCard
|
||||||
|
LoginForm
|
||||||
|
SalesChart
|
||||||
|
MachineStatus
|
||||||
|
UserAvatar
|
||||||
|
ReportFilter
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
```text
|
||||||
|
features/products/components/
|
||||||
|
features/auth/components/
|
||||||
|
features/sales/components/
|
||||||
|
features/machines/components/
|
||||||
|
```
|
||||||
|
|
||||||
|
Use global component directories only for truly shared components.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Refactoring Rules
|
||||||
|
|
||||||
|
When refactoring an existing Next.js project:
|
||||||
|
|
||||||
|
1. First understand the existing behavior.
|
||||||
|
2. Preserve functionality unless a behavior change is requested.
|
||||||
|
3. Identify duplicated logic.
|
||||||
|
4. Identify large pages and components.
|
||||||
|
5. Identify unclear naming.
|
||||||
|
6. Identify unnecessary Client Components.
|
||||||
|
7. Identify unnecessary `useEffect` usage.
|
||||||
|
8. Identify duplicated state.
|
||||||
|
9. Identify business logic buried in JSX.
|
||||||
|
10. Identify API calls scattered across UI code.
|
||||||
|
11. Refactor incrementally.
|
||||||
|
12. Add or update tests.
|
||||||
|
13. Remove dead code when safe.
|
||||||
|
14. Do not rewrite working code only to match a theoretical architecture.
|
||||||
|
15. Do not introduce unnecessary layers.
|
||||||
|
16. Keep the final result understandable to junior developers.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# New Features
|
||||||
|
|
||||||
|
When implementing a feature:
|
||||||
|
|
||||||
|
1. Find or create the correct feature directory.
|
||||||
|
2. Reuse existing shared components.
|
||||||
|
3. Keep the page thin.
|
||||||
|
4. Prefer Server Components by default.
|
||||||
|
5. Create Client Components only where needed.
|
||||||
|
6. Put API communication into a service when it improves separation.
|
||||||
|
7. Keep Redux only for meaningful shared client state.
|
||||||
|
8. Keep business rules testable.
|
||||||
|
9. Add appropriate tests.
|
||||||
|
10. Keep names explicit.
|
||||||
|
11. Avoid introducing abstractions before they are needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# New Projects
|
||||||
|
|
||||||
|
For a new Next.js project:
|
||||||
|
|
||||||
|
- use App Router
|
||||||
|
- use Tailwind CSS
|
||||||
|
- configure Redux Toolkit
|
||||||
|
- configure Vitest
|
||||||
|
- configure React Testing Library
|
||||||
|
- configure Playwright
|
||||||
|
- configure linting
|
||||||
|
- establish useful path aliases
|
||||||
|
- create only necessary directories
|
||||||
|
- keep Server Components as the default
|
||||||
|
- create a clear README
|
||||||
|
- avoid empty architecture folders
|
||||||
|
- avoid unnecessary dependencies
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Junior-Friendly Development Rules
|
||||||
|
|
||||||
|
Always ask:
|
||||||
|
|
||||||
|
"Can a junior developer understand this file without knowing hidden architectural conventions?"
|
||||||
|
|
||||||
|
Prefer explicit code.
|
||||||
|
|
||||||
|
Prefer:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const product = await getProduct(productId);
|
||||||
|
|
||||||
|
if (!product) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return product;
|
||||||
|
```
|
||||||
|
|
||||||
|
over clever compressed expressions.
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
- excessive abstractions
|
||||||
|
- unnecessary generics
|
||||||
|
- complex type tricks
|
||||||
|
- deeply nested callbacks
|
||||||
|
- deeply nested conditions
|
||||||
|
- complicated ternaries
|
||||||
|
- hidden side effects
|
||||||
|
- unnecessary factories
|
||||||
|
- unnecessary inheritance
|
||||||
|
- excessive indirection
|
||||||
|
- premature reusable frameworks
|
||||||
|
|
||||||
|
A small amount of duplication is better than a confusing abstraction.
|
||||||
|
|
||||||
|
Refactor duplication when a clear reusable concept actually emerges.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Final Decision Rule
|
||||||
|
|
||||||
|
When multiple implementations are valid, prefer the one that is:
|
||||||
|
|
||||||
|
1. simplest
|
||||||
|
2. easiest to read
|
||||||
|
3. easiest to test
|
||||||
|
4. easiest to debug
|
||||||
|
5. easiest to extend
|
||||||
|
6. easiest for a junior developer to understand
|
||||||
|
|
||||||
|
Do not optimize for impressive architecture.
|
||||||
|
|
||||||
|
Optimize for clarity, predictability, and maintainability.
|
||||||
@@ -1,599 +0,0 @@
|
|||||||
# Next.js Frontend Architecture Guide
|
|
||||||
|
|
||||||
## Objective
|
|
||||||
|
|
||||||
This document defines the architecture rules for this Next.js project.
|
|
||||||
|
|
||||||
Before implementing new features, refactoring existing code, or creating new modules, read and follow this architecture.
|
|
||||||
|
|
||||||
The goal is to create a scalable, production-ready frontend suitable for a professional development team.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Technology Stack
|
|
||||||
|
|
||||||
The project must use:
|
|
||||||
|
|
||||||
- Next.js (App Router)
|
|
||||||
- React
|
|
||||||
- TypeScript
|
|
||||||
- Redux Toolkit
|
|
||||||
- Axios
|
|
||||||
- Tailwind CSS
|
|
||||||
- Ant Design
|
|
||||||
|
|
||||||
Do not introduce alternative frameworks or libraries unless explicitly requested.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Architecture Pattern
|
|
||||||
|
|
||||||
Use:
|
|
||||||
|
|
||||||
## Feature-Based Architecture
|
|
||||||
|
|
||||||
Organize code around business features, not technical file types.
|
|
||||||
|
|
||||||
Avoid:
|
|
||||||
|
|
||||||
```
|
|
||||||
src/
|
|
||||||
|
|
||||||
components/
|
|
||||||
pages/
|
|
||||||
services/
|
|
||||||
utils/
|
|
||||||
```
|
|
||||||
|
|
||||||
as the main structure.
|
|
||||||
|
|
||||||
Use:
|
|
||||||
|
|
||||||
```
|
|
||||||
src/
|
|
||||||
|
|
||||||
├── app/
|
|
||||||
│ ├── (routes)/
|
|
||||||
│ ├── api/
|
|
||||||
│ ├── providers/
|
|
||||||
│ ├── layout.tsx
|
|
||||||
│ ├── loading.tsx
|
|
||||||
│ ├── error.tsx
|
|
||||||
│ └── globals.css
|
|
||||||
│
|
|
||||||
├── features/
|
|
||||||
│ ├── auth/
|
|
||||||
│ ├── users/
|
|
||||||
│ ├── products/
|
|
||||||
│ ├── companies/
|
|
||||||
│ └── ...
|
|
||||||
│
|
|
||||||
├── components/
|
|
||||||
│ ├── ui/
|
|
||||||
│ ├── common/
|
|
||||||
│ └── layouts/
|
|
||||||
│
|
|
||||||
├── services/
|
|
||||||
│ ├── api/
|
|
||||||
│ ├── storage/
|
|
||||||
│ └── websocket/
|
|
||||||
│
|
|
||||||
├── store/
|
|
||||||
│
|
|
||||||
├── hooks/
|
|
||||||
│
|
|
||||||
├── lib/
|
|
||||||
│
|
|
||||||
├── types/
|
|
||||||
│
|
|
||||||
├── utils/
|
|
||||||
│
|
|
||||||
└── config/
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Next.js App Router Rules
|
|
||||||
|
|
||||||
Use Next.js App Router.
|
|
||||||
|
|
||||||
Routes must be created using:
|
|
||||||
|
|
||||||
```
|
|
||||||
app/
|
|
||||||
```
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
app/dashboard/page.tsx
|
|
||||||
```
|
|
||||||
|
|
||||||
creates:
|
|
||||||
|
|
||||||
```
|
|
||||||
/dashboard
|
|
||||||
```
|
|
||||||
|
|
||||||
Do not use React Router.
|
|
||||||
|
|
||||||
Do not manually create routing logic.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Server Components vs Client Components
|
|
||||||
|
|
||||||
## Default Rule
|
|
||||||
|
|
||||||
All components should be Server Components by default.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
export default function UsersPage() {
|
|
||||||
return <div>Users</div>;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Client Components
|
|
||||||
|
|
||||||
Use Client Components only when required.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
- useState
|
|
||||||
- useEffect
|
|
||||||
- Redux hooks
|
|
||||||
- Browser APIs
|
|
||||||
- Event handlers
|
|
||||||
|
|
||||||
Then add:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
'use client';
|
|
||||||
```
|
|
||||||
|
|
||||||
at the top.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
'use client';
|
|
||||||
|
|
||||||
export default function LoginForm() {}
|
|
||||||
```
|
|
||||||
|
|
||||||
Do not add `"use client"` unnecessarily.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Feature Structure
|
|
||||||
|
|
||||||
Each business feature must be isolated.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
features/auth/
|
|
||||||
|
|
||||||
├── api/
|
|
||||||
│ └── auth.api.ts
|
|
||||||
│
|
|
||||||
├── components/
|
|
||||||
│ └── LoginForm.tsx
|
|
||||||
│
|
|
||||||
├── hooks/
|
|
||||||
│ └── useLogin.ts
|
|
||||||
│
|
|
||||||
├── store/
|
|
||||||
│ └── auth.slice.ts
|
|
||||||
│
|
|
||||||
├── schemas/
|
|
||||||
│ └── auth.schema.ts
|
|
||||||
│
|
|
||||||
├── types.ts
|
|
||||||
│
|
|
||||||
└── index.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Example business features:
|
|
||||||
|
|
||||||
```
|
|
||||||
features/
|
|
||||||
|
|
||||||
auth
|
|
||||||
users
|
|
||||||
companies
|
|
||||||
machines
|
|
||||||
inventory
|
|
||||||
sales
|
|
||||||
payments
|
|
||||||
reports
|
|
||||||
settings
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Component Architecture
|
|
||||||
|
|
||||||
## Shared Components
|
|
||||||
|
|
||||||
Reusable components belong here:
|
|
||||||
|
|
||||||
```
|
|
||||||
components/ui/
|
|
||||||
```
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
```
|
|
||||||
Button
|
|
||||||
Modal
|
|
||||||
Input
|
|
||||||
Table
|
|
||||||
Dropdown
|
|
||||||
Form
|
|
||||||
```
|
|
||||||
|
|
||||||
These components must not contain business logic.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Business components belong inside features:
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
features/products/components/ProductCard.tsx
|
|
||||||
```
|
|
||||||
|
|
||||||
Not:
|
|
||||||
|
|
||||||
```
|
|
||||||
components/ProductCard.tsx
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# API Architecture
|
|
||||||
|
|
||||||
All API communication must go through Axios.
|
|
||||||
|
|
||||||
Never call Axios directly inside components.
|
|
||||||
|
|
||||||
Wrong:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
function Users() {
|
|
||||||
axios.get('/users');
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Correct:
|
|
||||||
|
|
||||||
```
|
|
||||||
Component
|
|
||||||
|
|
||||||
↓
|
|
||||||
|
|
||||||
Hook
|
|
||||||
|
|
||||||
↓
|
|
||||||
|
|
||||||
Feature API
|
|
||||||
|
|
||||||
↓
|
|
||||||
|
|
||||||
Axios Service
|
|
||||||
|
|
||||||
↓
|
|
||||||
|
|
||||||
Backend API
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Axios configuration:
|
|
||||||
|
|
||||||
```
|
|
||||||
services/api/
|
|
||||||
|
|
||||||
axios.ts
|
|
||||||
interceptors.ts
|
|
||||||
endpoints.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
export const api = axios.create({
|
|
||||||
baseURL: process.env.NEXT_PUBLIC_API_URL,
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Redux Toolkit Rules
|
|
||||||
|
|
||||||
Redux Toolkit is used only for global client state.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
- Authentication state
|
|
||||||
- User preferences
|
|
||||||
- Application settings
|
|
||||||
- Global UI state
|
|
||||||
|
|
||||||
Structure:
|
|
||||||
|
|
||||||
```
|
|
||||||
store/
|
|
||||||
|
|
||||||
├── index.ts
|
|
||||||
├── provider.tsx
|
|
||||||
└── slices/
|
|
||||||
```
|
|
||||||
|
|
||||||
Feature state:
|
|
||||||
|
|
||||||
```
|
|
||||||
features/auth/store/
|
|
||||||
|
|
||||||
auth.slice.ts
|
|
||||||
auth.selector.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Do not store everything in Redux.
|
|
||||||
|
|
||||||
Use:
|
|
||||||
|
|
||||||
```
|
|
||||||
useState
|
|
||||||
```
|
|
||||||
|
|
||||||
for local component state.
|
|
||||||
|
|
||||||
Use Redux only for shared application state.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Redux Provider in Next.js
|
|
||||||
|
|
||||||
Redux Provider must be a Client Component.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
store/provider.tsx
|
|
||||||
```
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
'use client';
|
|
||||||
|
|
||||||
import {Provider} from 'react-redux';
|
|
||||||
|
|
||||||
export function ReduxProvider({children}) {
|
|
||||||
return <Provider store={store}>{children}</Provider>;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Register it in:
|
|
||||||
|
|
||||||
```
|
|
||||||
app/layout.tsx
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# TypeScript Rules
|
|
||||||
|
|
||||||
The project must be strongly typed.
|
|
||||||
|
|
||||||
Avoid:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
any;
|
|
||||||
```
|
|
||||||
|
|
||||||
Prefer:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
interface;
|
|
||||||
type;
|
|
||||||
generics;
|
|
||||||
unknown;
|
|
||||||
```
|
|
||||||
|
|
||||||
Each feature owns its types:
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```
|
|
||||||
features/users/types.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Tailwind CSS Rules
|
|
||||||
|
|
||||||
Use Tailwind for:
|
|
||||||
|
|
||||||
- Layout
|
|
||||||
- Spacing
|
|
||||||
- Responsive design
|
|
||||||
- Custom styling
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
```tsx
|
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
```
|
|
||||||
|
|
||||||
Avoid unnecessary CSS files.
|
|
||||||
|
|
||||||
Global CSS should only contain:
|
|
||||||
|
|
||||||
- Variables
|
|
||||||
- Theme
|
|
||||||
- Global styles
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Ant Design Rules
|
|
||||||
|
|
||||||
Use Ant Design for complex UI components:
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
- Tables
|
|
||||||
- Forms
|
|
||||||
- Modal
|
|
||||||
- DatePicker
|
|
||||||
- Dropdown
|
|
||||||
- Pagination
|
|
||||||
- Notification
|
|
||||||
|
|
||||||
Use Tailwind for:
|
|
||||||
|
|
||||||
- Layout
|
|
||||||
- Positioning
|
|
||||||
- Spacing
|
|
||||||
- Responsive behavior
|
|
||||||
|
|
||||||
Do not rewrite Ant Design components unless required.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Data Fetching Rules
|
|
||||||
|
|
||||||
Follow this structure:
|
|
||||||
|
|
||||||
```
|
|
||||||
Page
|
|
||||||
|
|
||||||
↓
|
|
||||||
|
|
||||||
Feature Component
|
|
||||||
|
|
||||||
↓
|
|
||||||
|
|
||||||
Custom Hook
|
|
||||||
|
|
||||||
↓
|
|
||||||
|
|
||||||
API Layer
|
|
||||||
|
|
||||||
↓
|
|
||||||
|
|
||||||
Axios
|
|
||||||
|
|
||||||
↓
|
|
||||||
|
|
||||||
Backend
|
|
||||||
```
|
|
||||||
|
|
||||||
Never put business API logic inside UI components.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Dependency Rules
|
|
||||||
|
|
||||||
Features should remain independent.
|
|
||||||
|
|
||||||
Wrong:
|
|
||||||
|
|
||||||
```
|
|
||||||
features/products
|
|
||||||
|
|
||||||
imports
|
|
||||||
|
|
||||||
features/auth
|
|
||||||
```
|
|
||||||
|
|
||||||
Correct:
|
|
||||||
|
|
||||||
```
|
|
||||||
features/products
|
|
||||||
|
|
||||||
↓
|
|
||||||
|
|
||||||
services
|
|
||||||
components
|
|
||||||
utils
|
|
||||||
```
|
|
||||||
|
|
||||||
Shared logic belongs in:
|
|
||||||
|
|
||||||
```
|
|
||||||
components/
|
|
||||||
services/
|
|
||||||
utils/
|
|
||||||
lib/
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Refactoring Rules
|
|
||||||
|
|
||||||
When refactoring an existing project:
|
|
||||||
|
|
||||||
1. Analyze the current structure first.
|
|
||||||
2. Do not rewrite everything immediately.
|
|
||||||
3. Move code gradually into feature folders.
|
|
||||||
4. Preserve existing functionality.
|
|
||||||
5. Improve:
|
|
||||||
- Type safety
|
|
||||||
- Separation of concerns
|
|
||||||
- API abstraction
|
|
||||||
- Component reuse
|
|
||||||
- State management
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Code Quality Rules
|
|
||||||
|
|
||||||
Every file should have one responsibility.
|
|
||||||
|
|
||||||
Avoid:
|
|
||||||
|
|
||||||
```
|
|
||||||
User.tsx
|
|
||||||
|
|
||||||
- UI
|
|
||||||
- API
|
|
||||||
- Validation
|
|
||||||
- State
|
|
||||||
```
|
|
||||||
|
|
||||||
Prefer:
|
|
||||||
|
|
||||||
```
|
|
||||||
UserCard.tsx
|
|
||||||
|
|
||||||
user.api.ts
|
|
||||||
|
|
||||||
useUser.ts
|
|
||||||
|
|
||||||
user.schema.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Final Architecture Goal
|
|
||||||
|
|
||||||
The final project must be:
|
|
||||||
|
|
||||||
- Scalable
|
|
||||||
- Maintainable
|
|
||||||
- Team-friendly
|
|
||||||
- Type-safe
|
|
||||||
- Easy to test
|
|
||||||
- Ready for future features
|
|
||||||
|
|
||||||
Always prefer clean architecture over fast implementation.
|
|
||||||
|
|
||||||
Before creating code, understand where the code belongs in this architecture.
|
|
||||||
Reference in New Issue
Block a user