11 KiB
11 KiB
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.,
useInvoicesfrom@/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 callsstores/: State management (Zustand stores)components/: UI components specific to the featurehooks/: React hooks for state and operationsviews/: Page-level view componentsutils/: Utility functionsindex.ts: Feature public API (barrel exports)
4. Centralized Shared Resources
core/: App-wide infrastructure (API client, logging, providers)shared/: Cross-feature utilities, hooks, and constantscomponents/: 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
// 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 sharedapiClienthooks/: React Query hooks that wrap API servicesstores/: Zustand stores for complex state managementcomponents/: Feature UI composed from shared atoms/molecules/organismsviews/: Page-level view components
This ensures pages remain declarative and the feature layer encapsulates logic.
Route Layering
(public): Marketing landing and authentication flowsaccount/: 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