254 lines
11 KiB
Markdown
254 lines
11 KiB
Markdown
# Portal Architecture
|
|
|
|
This document outlines the feature-driven architecture implemented for the customer portal.
|
|
|
|
---
|
|
|
|
## Quick Reference
|
|
|
|
| Aspect | Location |
|
|
| --------------------- | ----------------------------------------------------------- |
|
|
| **Feature modules** | `apps/portal/src/features/` |
|
|
| **Shared components** | `apps/portal/src/components/` (atomic design) |
|
|
| **API client** | `apps/portal/src/core/api/index.ts` |
|
|
| **Query keys** | `apps/portal/src/core/api/index.ts` → `queryKeys` |
|
|
| **Domain types** | `import type { X } from "@customer-portal/domain/<module>"` |
|
|
|
|
**Key patterns**:
|
|
|
|
- Pages are thin wrappers → import views from features
|
|
- Features contain: `api/`, `hooks/`, `stores/`, `components/`, `views/`
|
|
- Use React Query hooks from features (e.g., `useInvoices` from `@/features/billing`)
|
|
|
|
---
|
|
|
|
## Folder Structure
|
|
|
|
```
|
|
apps/portal/src/
|
|
├── app/ # Next.js App Router entry points (route groups only)
|
|
│ ├── (public)/ # Marketing + auth routes, pages import feature views
|
|
│ ├── account/ # Authenticated portal routes, thin wrappers around features
|
|
│ ├── api/ # App Router API routes
|
|
│ ├── favicon.ico / globals.css # Global assets
|
|
│ └── layout.tsx # Root layout/providers
|
|
├── components/ # Shared UI components (design system)
|
|
│ ├── atoms/ # Basic building blocks (Button, Input, Badge, etc.)
|
|
│ ├── molecules/ # Combinations of atoms (DataTable, FormField, etc.)
|
|
│ ├── organisms/ # Complex UI sections (AppShell, SiteFooter, etc.)
|
|
│ └── templates/ # Page-level layouts (AuthLayout, PageLayout, etc.)
|
|
├── core/ # App-wide infrastructure
|
|
│ ├── api/ # HTTP client, query keys, error handling
|
|
│ ├── logger/ # Application logging
|
|
│ └── providers/ # React context providers (QueryProvider)
|
|
├── features/ # Feature-specific modules composed by routes
|
|
│ ├── account/
|
|
│ ├── address/ # Address management and Japan Post lookup
|
|
│ ├── auth/
|
|
│ ├── billing/
|
|
│ ├── checkout/
|
|
│ ├── dashboard/
|
|
│ ├── get-started/ # Unified signup and eligibility flow
|
|
│ ├── landing-page/
|
|
│ ├── marketing/
|
|
│ ├── notifications/
|
|
│ ├── orders/
|
|
│ ├── realtime/
|
|
│ ├── services/ # Service browsing and ordering (pre-purchase)
|
|
│ ├── subscriptions/ # Subscription management
|
|
│ ├── support/
|
|
│ └── verification/
|
|
├── shared/ # Cross-feature helpers
|
|
│ ├── api/ # Shared API services (currency, etc.)
|
|
│ ├── constants/ # Data constants (countries, prefectures)
|
|
│ ├── hooks/ # Generic React hooks
|
|
│ └── utils/ # General utilities (cn, date, error-handling)
|
|
├── styles/ # Global styles and design tokens
|
|
└── config/ # Environment configuration
|
|
```
|
|
|
|
## Design Principles
|
|
|
|
### 1. Feature-First Organization
|
|
|
|
Related functionality is grouped together in feature modules, making it easier to understand and maintain code.
|
|
|
|
### 2. Atomic Design
|
|
|
|
UI components follow atomic design principles:
|
|
|
|
- **Atoms**: Basic building blocks (Button, Input, Badge, Spinner, etc.)
|
|
- **Molecules**: Combinations of atoms (DataTable, FormField, AlertBanner, etc.)
|
|
- **Organisms**: Complex UI sections (AppShell, SiteFooter, AgentforceWidget)
|
|
- **Templates**: Page-level layouts (AuthLayout, PageLayout, PublicShell)
|
|
|
|
### 3. Separation of Concerns
|
|
|
|
Each feature module contains:
|
|
|
|
- `api/`: Data fetching and API calls
|
|
- `stores/`: State management (Zustand stores)
|
|
- `components/`: UI components specific to the feature
|
|
- `hooks/`: React hooks for state and operations
|
|
- `views/`: Page-level view components
|
|
- `utils/`: Utility functions
|
|
- `index.ts`: Feature public API (barrel exports)
|
|
|
|
### 4. Centralized Shared Resources
|
|
|
|
- `core/`: App-wide infrastructure (API client, logging, providers)
|
|
- `shared/`: Cross-feature utilities, hooks, and constants
|
|
- `components/`: Reusable UI components following atomic design
|
|
|
|
## Feature Module Structure
|
|
|
|
Each feature follows a consistent internal structure:
|
|
|
|
```
|
|
features/[feature-name]/
|
|
├── api/ # Data fetching layer
|
|
│ ├── [feature].api.ts
|
|
│ └── index.ts
|
|
├── stores/ # State management (if needed)
|
|
│ ├── [feature].store.ts
|
|
│ └── index.ts
|
|
├── components/ # Feature-specific components
|
|
│ ├── [Component].tsx
|
|
│ └── index.ts
|
|
├── hooks/ # Feature-specific hooks
|
|
│ ├── use[Feature].ts
|
|
│ └── index.ts
|
|
├── views/ # Page-level views
|
|
│ └── [Feature]View.tsx
|
|
├── utils/ # Feature utilities
|
|
└── index.ts # Feature public API
|
|
```
|
|
|
|
## Core vs Shared
|
|
|
|
### Core (`@/core/`)
|
|
|
|
App-wide infrastructure that features depend on:
|
|
|
|
- **api/**: HTTP client, query keys, response helpers, error handling
|
|
- **logger/**: Application logging utilities
|
|
- **providers/**: React context providers (QueryProvider)
|
|
|
|
### Shared (`@/shared/`)
|
|
|
|
Cross-feature utilities that aren't infrastructure:
|
|
|
|
- **api/**: Shared API services (currency)
|
|
- **constants/**: Data constants (countries, prefectures)
|
|
- **hooks/**: Generic React hooks (useLocalStorage, useDebounce, useMediaQuery)
|
|
- **utils/**: General utilities (cn, date formatting, error handling)
|
|
|
|
## Import Patterns
|
|
|
|
### Recommended Import Patterns
|
|
|
|
```typescript
|
|
// Feature imports (prefer barrel exports)
|
|
import { LoginForm, useAuthStore } from "@/features/auth";
|
|
import { billingService, useInvoices } from "@/features/billing";
|
|
|
|
// Component imports (atomic design)
|
|
import { Button, Badge, Spinner } from "@/components/atoms";
|
|
import { DataTable, FormField } from "@/components/molecules";
|
|
import { AppShell } from "@/components/organisms";
|
|
|
|
// Core infrastructure
|
|
import { apiClient, queryKeys } from "@/core/api";
|
|
import { logger } from "@/core/logger";
|
|
import { QueryProvider } from "@/core/providers";
|
|
|
|
// Shared utilities
|
|
import { cn, formatIsoDate } from "@/shared/utils";
|
|
import { useDebounce, useMediaQuery } from "@/shared/hooks";
|
|
import { countries, japanPrefectures } from "@/shared/constants";
|
|
|
|
// Domain types (from shared package)
|
|
import type { Invoice } from "@customer-portal/domain/billing";
|
|
```
|
|
|
|
### Path Mappings
|
|
|
|
- `@/*` - Root src directory
|
|
- `@/components/*` - Component library (atomic design)
|
|
- `@/core/*` - App-wide infrastructure
|
|
- `@/features/*` - Feature modules
|
|
- `@/shared/*` - Cross-feature utilities
|
|
- `@/styles/*` - Style files
|
|
- `@/config/*` - Environment configuration
|
|
|
|
## Pages vs Features
|
|
|
|
- Route pages under `src/app/**` are thin shells and do not call APIs directly.
|
|
- Data fetching and business logic live in `src/features/**`:
|
|
- `api/`: Feature API services built on the shared `apiClient`
|
|
- `hooks/`: React Query hooks that wrap API services
|
|
- `stores/`: Zustand stores for complex state management
|
|
- `components/`: Feature UI composed from shared atoms/molecules/organisms
|
|
- `views/`: Page-level view components
|
|
|
|
This ensures pages remain declarative and the feature layer encapsulates logic.
|
|
|
|
### Route Layering
|
|
|
|
- `(public)`: Marketing landing and authentication flows
|
|
- `account/`: Authenticated portal experience (dashboard, billing, subscriptions, etc.)
|
|
- `api/`: App Router API endpoints
|
|
|
|
Only `layout.tsx`, `page.tsx`, and `loading.tsx` files live inside the route groups.
|
|
|
|
## Feature Module Inventory
|
|
|
|
| Feature | API Service | Key Hooks | Purpose |
|
|
| --------------- | --------------------------------------------- | ------------------------------------------------------- | ------------------------------ |
|
|
| `account` | `accountService` | `useProfileEdit`, `useAddressEdit` | Profile and address management |
|
|
| `address` | `addressService` | `useAddressLookup` | Japan Post address lookup |
|
|
| `auth` | (via store) | `useAuthStore`, `useAuthSession` | Authentication state |
|
|
| `billing` | `billingService` | `useInvoices`, `usePaymentMethods`, `usePaymentRefresh` | Invoices and payments |
|
|
| `checkout` | `checkoutService` | `useCheckoutStore` | Checkout flow |
|
|
| `dashboard` | `getMeStatus` | `useMeStatus` | Dashboard data |
|
|
| `get-started` | `getStartedService` | `useGetStartedFlow` | Unified signup flow |
|
|
| `landing-page` | — | — | Marketing landing page |
|
|
| `marketing` | — | — | Marketing components |
|
|
| `notifications` | `notificationService` | `useNotifications` | User notifications |
|
|
| `orders` | `ordersService` | `useOrdersList`, `useOrderDetail` | Order management |
|
|
| `realtime` | — | `useRealtimeEvents` | SSE/WebSocket events |
|
|
| `services` | `servicesService` | `useInternetCatalog`, `useSimCatalog`, `useVpnCatalog` | Product catalog |
|
|
| `subscriptions` | `simActionsService`, `internetActionsService` | `useSubscriptions` | Active service management |
|
|
| `support` | `supportService` | `useCases`, `useCreateCase` | Support tickets |
|
|
| `verification` | `verificationService` | `useResidenceCardVerification` | ID verification |
|
|
|
|
## Benefits
|
|
|
|
### Developer Experience
|
|
|
|
- Predictable code organization
|
|
- Easy to find and modify code
|
|
- Consistent patterns across features
|
|
- Better IntelliSense and type safety
|
|
|
|
### Maintainability
|
|
|
|
- Clear separation of concerns
|
|
- Reusable components and utilities
|
|
- Centralized design system
|
|
- Easier testing and debugging
|
|
|
|
### Performance
|
|
|
|
- Tree-shakeable exports
|
|
- Code splitting by feature
|
|
- Optimized bundle size
|
|
- Better caching strategies
|
|
|
|
### Scalability
|
|
|
|
- Easy to add new features
|
|
- Consistent architecture patterns
|
|
- Modular and composable design
|
|
- Clear boundaries between features
|