フルスタックアーキテクチャのブループリント —— 著者:王教成#
Kotlin クロスプラットフォームフルスタックアーキテクチャのブループリント:縦 10 モジュール × 横 12 層の SpringBoot+MySQL + 多プラットフォーム実践#
1. サーバーサイド Database#
L0 ビジネスエコシステム層:データベースがビジネスエコシステム内でのコア機能を特定する(例:e コマースプラットフォームの注文データ中枢)
L1 システム層:MySQL 高可用アーキテクチャを設計する(主従クラスター+読み書き分離+自動フェイルオーバー)
L2 サブシステム層:ビジネスドメインに基づいて物理データベースを分割する(ユーザーデータベース/注文データベース/在庫データベース)およびデータ同期メカニズムを定義する
L3 セキュリティアーキテクチャ層:トランスポート層暗号化を実施する(TLS1.3)および列レベルデータ暗号化(AES-256)
L4 モジュール層:コアモジュール構造を定義する(ユーザー管理モジュールのテーブル集合および関係)
L5 パッケージ構造層:バージョン管理されたマイグレーションスクリプトディレクトリを整理する(/database/migrations/V1.0__core_schema.sql)
L6 クラスとインターフェース層:テーブル構造を設計する(フィールドタイプ/主外キー/インデックス戦略)
L7 メソッド層:ストアドプロシージャを作成してビジネスロジックを実装する(例:ユーザー消費レベルの計算)
L8 コードブロック層:トランザクション制御ブロックを構築する(START TRANSACTION; UPDATE; INSERT; COMMIT;)
L9 ステートメント層:DDL 定義ステートメントを実行する(CREATE TABLE users(id BIGINT AUTO_INCREMENT PRIMARY KEY))
L10 式層:クエリ式を最適化する(WHERE status = 'ACTIVE' AND last_login > NOW() - INTERVAL 30 DAY)
L11 原子操作層:制約条件を設定する(UNIQUE(email), NOT NULL(username))
2. サーバーサイド Entity#
L0 ビジネスエコシステム層:なし
L1 システム層:Hibernate の二次キャッシュおよびバッチ処理パラメータを設定する(hibernate.cache.use_second_level_cache=true)
L2 サブシステム層:ビジネスドメインに基づいてパッケージを分割する(com.ecommerce.user.entityにはUser/Profileエンティティが含まれる)
L3 セキュリティアーキテクチャ層:フィールドレベル暗号化を実施する(@Convert(converter = PasswordEncryptor.class))
L4 モジュール層:ドメインモジュールを構築し、エンティティスキャンパスを含める(@EntityScan(basePackages = "com.ecommerce"))
L5 パッケージ構造層:エンティティの層別パッケージを整理する(.entity/.embeddable/.enums)
L6 クラスとインターフェース層:JPA エンティティクラスを定義する(@Entity @Table(name="users") class User)
L7 メソッド層:監査コールバックメソッドを実装する(@LastModifiedDate private LocalDateTime updatedAt)
L8 コードブロック層:フィールド検証ブロックを構築する(if (email.isEmpty()) throw new InvalidEntityException())
L9 ステートメント層:マッピング関係を宣言する(@OneToMany(mappedBy = "user", cascade = CascadeType.ALL))
L10 式層:遅延読み込み戦略を設定する(@ManyToOne(fetch = FetchType.LAZY))
L11 原子操作層:equals()/hashCode()メソッドを生成する
3. サーバーサイド Repository#
L0 ビジネスエコシステム層:なし
L1 システム層:Spring Data JPA のクエリ戦略を設定する(メソッド名解析/ページング設定)
L2 サブシステム層:集約ルートに基づいてパッケージを分割する(com.ecommerce.order.repositoryにはOrder/LineItemが含まれる)
L3 セキュリティアーキテクチャ層:行レベルのセキュリティフィルタを実装する(@PostFilter("hasPermission(filterObject, 'READ')"))
L4 モジュール層:リポジトリモジュールを作成し、JPA リポジトリスキャンを含める(@EnableJpaRepositories)
L5 パッケージ構造層:リポジトリの層を整理する(.repository/.custom/.projection)
L6 クラスとインターフェース層:リポジトリインターフェースを宣言する(interface OrderRepository extends JpaRepository<Order, Long>)
L7 メソッド層:動的クエリメソッドを定義する(Page<Order> findByUserId(Long userId, Pageable pageable))
L8 コードブロック層:@Query注釈ブロックを構築する(@Query("SELECT o FROM Order o WHERE o.status = :status"))
L9 ステートメント層:派生クエリを宣言する(List<Order> findByCreatedAtBetween(LocalDate start, LocalDate end))
L10 式層:SpEL セキュリティ式を使用する(@Query("SELECT u FROM #{#entityName} u WHERE u.active = true"))
L11 原子操作層:flush操作を実行する(saveAndFlush(entity))
4. サーバーサイド Service#
L0 ビジネスエコシステム層:なし
L1 システム層:分散トランザクションを統合する(Seata ATモード+ロールバックログ)
L2 サブシステム層:ビジネス能力に基づいてサービス境界を分割する(PaymentService/InventoryService)
L3 セキュリティアーキテクチャ層:メソッドレベルの権限制御を実施する(@PreAuthorize("hasRole('ADMIN') or #userId == principal.id"))
L4 モジュール層:サービスモジュールを作成し、トランザクションマネージャを設定する(@EnableTransactionManagement)
L5 パッケージ構造層:サービスの層を整理する(.api/.impl/.event)
L6 クラスとインターフェース層:サービスクラスを実装する(@Service @Transactional(propagation=REQUIRED) class OrderServiceImpl)
L7 メソッド層:コアビジネスロジックを作成する(Order createOrder(Cart cart) 在庫を減らして注文を生成しメッセージを発信する)
L8 コードブロック層:トランザクション制御ブロックを構築する(@Transactional(timeout=30, rollbackFor=BusinessException.class))
L9 ステートメント層:ドメインイベントをトリガーする(applicationEventPublisher.publishEvent(new OrderCreatedEvent(this)))
L10 式層:EL を使用してビジネスルールを表現する(if (user.getLevel() >= VIP_LEVEL) applyDiscount(15%))
L11 原子操作層:空安全呼び出しを実行する(user?.address ?: throw AddressRequiredException())
5. サーバーサイド Controller#
L0 ビジネスエコシステム層:なし
L1 システム層:OpenAPI 3.0 仕様を策定し Swagger を設定する(@OpenAPIDefinition)
L2 サブシステム層:API ゲートウェイのルーティングルールを設定する(/order-serviceを注文クラスターにルーティング)
L3 セキュリティアーキテクチャ層:JWT 認証を実施する(@AuthenticationPrincipal JwtUserDetails)
L4 モジュール層:web モジュールを作成しメッセージコンバータを設定する(HttpMessageConverters)
L5 パッケージ構造層:コントローラーパッケージを整理する(.controller.user/.controller.order)
L6 クラスとインターフェース層:RestController を定義する(@RestController @RequestMapping("/api/orders"))
L7 メソッド層:エンドポイントメソッドを宣言する(@PostMapping @ResponseStatus(CREATED) fun createOrder())
L8 コードブロック層:パラメータ検証ブロックを構築する(@Valid @RequestBody OrderCreateDTO dto, BindingResult result)
L9 ステートメント層:標準化された応答を返す(ResponseEntity.status(CREATED).body(OrderResponse.from(order)))
L10 式層:MapStruct を使用して変換式を使用する(OrderMapper.INSTANCE.toDTO(domainEntity))
L11 原子操作層:レスポンスヘッダーを設定する(headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest()))
6. クライアント データソース (多プラットフォーム)#
L0 ビジネスエコシステム層:なし
L1 システム層:Ktor Client の多プラットフォームネットワークスタックを設定する(HttpClient + 30sタイムアウト + GraphQLサポート)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:統一認証メカニズムを実施する(JWT自動更新 + プラットフォーム特有のセキュリティストレージ)
L4 モジュール層:networkモジュールを構築しクロスプラットフォームネットワークリクエストをカプセル化する
L5 パッケージ構造層:データソースの層を整理する(.graphql/.api/.interceptor)
L6 クラスとインターフェース層:汎用データソースインターフェースを定義する(interface ApiService { suspend fun query<T>(query: String): T })
L7 メソッド層:反応的データストリームを宣言する(fun getProducts(): Flow<ProductDTO>)
L8 コードブロック層:指数バックオフ再試行ロジックを構築する(retryWhen { e, attempt -> if (e is TimeoutCancellationException && attempt < 3) })
L9 ステートメント層:クロスプラットフォームネットワーク呼び出しを実行する(withContext(Dispatchers.Default) { apiService.fetchData() })
L10 式層:kotlinx.serialization を使用して解析する(Json.decodeFromString<T>(response))
L11 原子操作層:プラットフォーム識別ヘッダーを追加する(headers.append("Platform", Platform.platformName))
7. クライアント ストレージ層 (多プラットフォーム)#
L0 ビジネスエコシステム層:なし
L1 システム層:統一キャッシュ戦略を設計する(メモリキャッシュ + SqlDelight永続化 + 自動同期)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:ローカルデータ暗号化を実施する(プラットフォーム特有のセキュリティストレージ)
L4 モジュール層:storageモジュールを作成しデータ調整を実現する
L5 パッケージ構造層:ストレージ実装を整理する(.cache/.database/.preference)
L6 クラスとインターフェース層:スマートキャッシュリポジトリを実装する(class SmartCacheRepository<T>(...))
L7 メソッド層:混合データ取得を作成する(ローカルキャッシュを先に読み取り、なければネットワークリクエストを行いキャッシュを更新する)
L8 コードブロック層:キャッシュの有効期限制御を構築する(if (lastUpdated.isBefore(now - 5.minutes)) refreshRemote())
L9 ステートメント層:クロスプラットフォームデータベースクエリを実行する(db.userQueries.getById(id).executeAsOneOrNull())
L10 式層:拡張関数を使用して変換する(networkDTO.toDomainEntity())
L11 原子操作層:StateFlow にデータを発信する(_dataState.emit(Result.success(data)))
8. クライアント ビジネスロジック (多プラットフォーム)#
L0 ビジネスエコシステム層:なし
L1 システム層:クロスプラットフォームユースケース仕様を策定する(純Kotlin実装 + 単一責任原則)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:統一権限チェックを実施する(if (!sessionManager.hasPermission(required)) throw PermissionDenied())
L4 モジュール層:domainモジュールを定義しビジネスルールを含める
L5 パッケージ構造層:ユースケースパッケージを整理する(.usecase.user/.usecase.order)
L6 クラスとインターフェース層:プラットフォームに依存しないユースケースクラスを作成する(class CheckoutUseCase @Inject constructor(val repo: CartRepo))
L7 メソッド層:コアビジネスロジックを実装する(suspend operator fun invoke():在庫を検証→合計を計算→注文を提出)
L8 コードブロック層:エラー変換ブロックを構築する(catch { e -> when(e) { is NetworkException -> ... } })
L9 ステートメント層:リポジトリメソッドを呼び出す(val cart = cartRepo.getCart().first())
L10 式層:require を使用してパラメータを検証する(require(cart.items.isNotEmpty()))
L11 原子操作層:ドメインオブジェクトを構築する(Order.createFromCart(cart, userId))
9. クライアント 状態管理 (多プラットフォーム)#
L0 ビジネスエコシステム層:なし
L1 システム層:統一状態管理を設定する(StateFlow + MVIモデル)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:セッションの期限切れ処理を実施する(catch (e: UnauthorizedException) { _state.value = SessionExpired })
L4 モジュール層:presentationモジュールを作成し状態コンテナを定義する
L5 パッケージ構造層:ViewModel パッケージを整理する(.viewmodel.user/.viewmodel.product)
L6 クラスとインターフェース層:汎用状態コンテナを定義する(class UserViewModel : KoinComponent { ... })
L7 メソッド層:状態更新メソッドを作成する(fun loadData() { viewModelScope.launch { ... } })
L8 コードブロック層:状態変換ブロックを構築する(private fun mapToUiState(data: T): UiState)
L9 ステートメント層:UI 状態を更新する(_state.update { it.copy(data = data, loading = false) })
L10 式層:密封クラスを使用して状態を変換する(when(result) { is Success -> UiState.Data(...) })
L11 原子操作層:UseCase メソッドを呼び出す(val result = getUserUseCase(userId))
10. クライアント UI 層 (プラットフォーム特定の実装)#
L0 ビジネスエコシステム層:統一ユーザージャーニーパスを設計する(登録→ログイン→ホーム→詳細→支払い)
L1 システム層:プラットフォーム UI フレームワークを採用する(Android: Jetpack Compose/iOS: SwiftUI/Web: Compose for Web)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:インターフェースのハイジャック防止を実施する(Android: onPauseでぼかし/iOS: willResignActiveでぼかし/Web: blurイベント処理)
L4 モジュール層:uiメインモジュールを構築しテーマ設定を含める
L5 パッケージ構造層:UI コンポーネントパッケージを整理する(.screen.login/.screen.cart/.component)
L6 クラスとインターフェース層:プラットフォーム UI コンポーネントを定義する(Android: @Composable fun/iOS: struct View: View/Web: fun Render())
L7 メソッド層:イベント処理関数を作成する(val onLogin = { viewModel.login(credentials) })
L8 コードブロック層:状態応答レンダリングブロックを構築する(when(state) { Loading -> ローディングインジケーターを表示 })
L9 ステートメント層:UI 要素を組み合わせる(Android: Column { }/iOS: VStack { }/Web: Div { })
L10 式層:アニメーション式を使用する(Android: AnimatedVisibility/iOS: withAnimation/Web: animate {})
L11 原子操作層:テキスト属性を設定する(Android: Text(...)/iOS: Text(...)/Web: Span { Text(...) })
Kotlin フルスタックアーキテクチャのブループリント:縦 10 モジュール × 横 12 層の SpringBoot+MySQL+Android 実践#
1. サーバーサイド Database#
L0 ビジネスエコシステム層:データベースがビジネスエコシステム内でのコア機能を特定する(例:e コマースプラットフォームの注文データ中枢)
L1 システム層:MySQL 高可用アーキテクチャを設計する(主従クラスター+読み書き分離+自動フェイルオーバー)
L2 サブシステム層:ビジネスドメインに基づいて物理データベースを分割する(ユーザーデータベース/注文データベース/在庫データベース)およびデータ同期メカニズムを定義する
L3 セキュリティアーキテクチャ層:トランスポート層暗号化を実施する(TLS1.3)および列レベルデータ暗号化(AES-256)
L4 モジュール層:コアモジュール構造を定義する(ユーザー管理モジュールのテーブル集合および関係)
L5 パッケージ構造層:バージョン管理されたマイグレーションスクリプトディレクトリを整理する(/database/migrations/V1.0__core_schema.sql)
L6 クラスとインターフェース層:テーブル構造を設計する(フィールドタイプ/主外キー/インデックス戦略)
L7 メソッド層:ストアドプロシージャを作成してビジネスロジックを実装する(例:ユーザー消費レベルの計算)
L8 コードブロック層:トランザクション制御ブロックを構築する(START TRANSACTION; UPDATE; INSERT; COMMIT;)
L9 ステートメント層:DDL 定義ステートメントを実行する(CREATE TABLE users(id BIGINT AUTO_INCREMENT PRIMARY KEY))
L10 式層:クエリ式を最適化する(WHERE status = 'ACTIVE' AND last_login > NOW() - INTERVAL 30 DAY)
L11 原子操作層:制約条件を設定する(UNIQUE(email), NOT NULL(username))
2. サーバーサイド Entity#
L0 ビジネスエコシステム層:なし
L1 システム層:Hibernate の二次キャッシュおよびバッチ処理パラメータを設定する(hibernate.cache.use_second_level_cache=true)
L2 サブシステム層:ビジネスドメインに基づいてパッケージを分割する(com.ecommerce.user.entityにはUser/Profileエンティティが含まれる)
L3 セキュリティアーキテクチャ層:フィールドレベル暗号化を実施する(@Convert(converter = PasswordEncryptor.class))
L4 モジュール層:ドメインモジュールを構築し、エンティティスキャンパスを含める(@EntityScan(basePackages = "com.ecommerce"))
L5 パッケージ構造層:エンティティの層別パッケージを整理する(.entity/.embeddable/.enums)
L6 クラスとインターフェース層:JPA エンティティクラスを定義する(@Entity @Table(name="users") class User)
L7 メソッド層:監査コールバックメソッドを実装する(@LastModifiedDate private LocalDateTime updatedAt)
L8 コードブロック層:フィールド検証ブロックを構築する(if (email.isEmpty()) throw new InvalidEntityException())
L9 ステートメント層:マッピング関係を宣言する(@OneToMany(mappedBy = "user", cascade = CascadeType.ALL))
L10 式層:遅延読み込み戦略を設定する(@ManyToOne(fetch = FetchType.LAZY))
L11 原子操作層:equals()/hashCode()メソッドを生成する
3. サーバーサイド Repository#
L0 ビジネスエコシステム層:なし
L1 システム層:Spring Data JPA のクエリ戦略を設定する(メソッド名解析/ページング設定)
L2 サブシステム層:集約ルートに基づいてパッケージを分割する(com.ecommerce.order.repositoryにはOrder/LineItemが含まれる)
L3 セキュリティアーキテクチャ層:行レベルのセキュリティフィルタを実装する(@PostFilter("hasPermission(filterObject, 'READ')"))
L4 モジュール層:リポジトリモジュールを作成し、JPA リポジトリスキャンを含める(@EnableJpaRepositories)
L5 パッケージ構造層:リポジトリの層を整理する(.repository/.custom/.projection)
L6 クラスとインターフェース層:リポジトリインターフェースを宣言する(interface OrderRepository extends JpaRepository<Order, Long>)
L7 メソッド層:動的クエリメソッドを定義する(Page<Order> findByUserId(Long userId, Pageable pageable))
L8 コードブロック層:@Query注釈ブロックを構築する(@Query("SELECT o FROM Order o WHERE o.status = :status"))
L9 ステートメント層:派生クエリを宣言する(List<Order> findByCreatedAtBetween(LocalDate start, LocalDate end))
L10 式層:SpEL セキュリティ式を使用する(@Query("SELECT u FROM #{#entityName} u WHERE u.active = true"))
L11 原子操作層:flush操作を実行する(saveAndFlush(entity))
4. サーバーサイド Service#
L0 ビジネスエコシステム層:なし
L1 システム層:分散トランザクションを統合する(Seata ATモード+ロールバックログ)
L2 サブシステム層:ビジネス能力に基づいてサービス境界を分割する(PaymentService/InventoryService)
L3 セキュリティアーキテクチャ層:メソッドレベルの権限制御を実施する(@PreAuthorize("hasRole('ADMIN') or #userId == principal.id"))
L4 モジュール層:サービスモジュールを作成し、トランザクションマネージャを設定する(@EnableTransactionManagement)
L5 パッケージ構造層:サービスの層を整理する(.api/.impl/.event)
L6 クラスとインターフェース層:サービスクラスを実装する(@Service @Transactional(propagation=REQUIRED) class OrderServiceImpl)
L7 メソッド層:コアビジネスロジックを作成する(Order createOrder(Cart cart) 在庫を減らして注文を生成しメッセージを発信する)
L8 コードブロック層:トランザクション制御ブロックを構築する(@Transactional(timeout=30, rollbackFor=BusinessException.class))
L9 ステートメント層:ドメインイベントをトリガーする(applicationEventPublisher.publishEvent(new OrderCreatedEvent(this)))
L10 式層:EL を使用してビジネスルールを表現する(if (user.getLevel() >= VIP_LEVEL) applyDiscount(15%))
L11 原子操作層:空安全呼び出しを実行する(user?.address ?: throw AddressRequiredException())
5. サーバーサイド Controller#
L0 ビジネスエコシステム層:なし
L1 システム層:OpenAPI 3.0 仕様を策定し Swagger を設定する(@OpenAPIDefinition)
L2 サブシステム層:API ゲートウェイのルーティングルールを設定する(/order-serviceを注文クラスターにルーティング)
L3 セキュリティアーキテクチャ層:JWT 認証を実施する(@AuthenticationPrincipal JwtUserDetails)
L4 モジュール層:web モジュールを作成しメッセージコンバータを設定する(HttpMessageConverters)
L5 パッケージ構造層:コントローラーパッケージを整理する(.controller.user/.controller.order)
L6 クラスとインターフェース層:RestController を定義する(@RestController @RequestMapping("/api/orders"))
L7 メソッド層:エンドポイントメソッドを宣言する(@PostMapping @ResponseStatus(CREATED) fun createOrder())
L8 コードブロック層:パラメータ検証ブロックを構築する(@Valid @RequestBody OrderCreateDTO dto, BindingResult result)
L9 ステートメント層:標準化された応答を返す(ResponseEntity.status(CREATED).body(OrderResponse.from(order)))
L10 式層:MapStruct を使用して変換式を使用する(OrderMapper.INSTANCE.toDTO(domainEntity))
L11 原子操作層:レスポンスヘッダーを設定する(headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest()))
6. クライアント データソース(Android)#
L0 ビジネスエコシステム層:なし
L1 システム層:Retrofit を設定する(GsonConverterFactory + 30sタイムアウト + キャッシュ制御)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:証明書ピンニングを実施する(CertificatePinner.Builder())
L4 モジュール層:data-sourceモジュールを構築しネットワークリクエストをカプセル化する
L5 パッケージ構造層:データソースの層を整理する(.api/.retrofit/.local)
L6 クラスとインターフェース層:Retrofit インターフェースを定義する(@GET("users/{id}") suspend fun getUser(@Path("id") id: Long): UserDTO)
L7 メソッド層:ストリーミングデータ取得を宣言する(fun getProducts(): Flow<ProductDTO>)
L8 コードブロック層:再試行ロジックブロックを構築する(retryWhen { e, attempt -> if (e is SocketTimeoutException && attempt < 3) })
L9 ステートメント層:ネットワークリクエストを実行する(withContext(Dispatchers.IO) { apiService.fetchData() })
L10 式層:kotlinx.serialization を使用して解析する(Json.decodeFromString<UserDTO>(response))
L11 原子操作層:認証ヘッダーを追加する(request.addHeader("Authorization", "Bearer ${tokenStorage.accessToken}"))
7. クライアント Repository(Android)#
L0 ビジネスエコシステム層:なし
L1 システム層:スマートキャッシュ戦略を設計する(メモリキャッシュ+Room永続化+自動更新)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:ローカルデータ暗号化を実施する(SQLCipher統合)
L4 モジュール層:リポジトリモジュールを作成しデータ調整を実現する
L5 パッケージ構造層:リポジトリ実装を整理する(.repo_impl.user/.repo_impl.product)
L6 クラスとインターフェース層:リポジトリクラスを実装する(class UserDataRepository @Inject constructor(...))
L7 メソッド層:キャッシュ優先戦略を作成する(CoreData をチェック→ネットワークリクエスト→キャッシュを更新)
L8 コードブロック層:キャッシュ更新制御を構築する(if (lastUpdated.isBefore(now - 5.minutes)) refreshRemote())
L9 ステートメント層:Room クエリを実行する(roomDb.userDao().getById(id).flowOn(Dispatchers.IO))
L10 式層:拡張関数を使用して変換する(networkDTO.toDomainEntity())
L11 原子操作層:StateFlow にデータを発信する(_userState.emit(Result.success(user)))
8. クライアント UseCase(Android)#
L0 ビジネスエコシステム層:なし
L1 システム層:ユースケース仕様を策定する(純Kotlin実装+単一責任原則)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:権限チェックを実施する(if (!sessionManager.isAdmin()) throw PermissionDeniedException())
L4 モジュール層:ドメインモジュールを定義しビジネスルールを含める
L5 パッケージ構造層:ユースケースパッケージを整理する(.usecase.user/.usecase.product)
L6 クラスとインターフェース層:ユースケースの迅速な応答を作成する(class CheckoutUseCase @Inject constructor(val repo: CartRepo))
L7 メソッド層:コアロジックを実装する(func execute(cart: Cart) async throws:在庫検証→合計計算→注文)
L8 コードブロック層:エラー変換を構築する(catch { throw DomainErrorMapper.transform($0) })
L9 ステートメント層:リポジトリメソッドを呼び出す(let stock = try await stockRepo.checkAvailability(productId))
L10 式層:guard を使用してパラメータを検証する(guard cart.items.count > 0 else { throw CartError.empty })
L11 原子操作層:ドメインモデルを構築する(Order.create(from: cart, user: user))
9. クライアント ViewModel(Android)#
L0 ビジネスエコシステム層:なし
L1 システム層:Hilt 依存性注入 ViewModel を設定する(@HiltViewModel)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:セッションの期限切れ処理を実施する(catch (e: UnauthorizedException) { _state.value = SessionExpired })
L4 モジュール層:presentation モジュールを作成し状態コンテナを定義する
L5 パッケージ構造層:ViewModel パッケージを整理する(.viewmodel.home/.viewmodel.cart)
L6 クラスとインターフェース層:ViewModel を継承する(class UserViewModel @Inject constructor(val useCase: GetUserUseCase): ViewModel())
L7 メソッド層:非同期ロードメソッドを作成する(@MainActor func loadProfile() async { ... })
L8 コードブロック層:状態変換器を構築する(private func mapResult(_ result: Result<User, Error>))
L9 ステートメント層:UI 状態を更新する(state = .loaded(user))
L10 式層:列挙型の関連値を使用する(enum ViewState { case idle, loading, loaded(User), failed(Error) })
L11 原子操作層:UseCase を呼び出す(self.user = try await useCase.fetchUser(id))
10. クライアント UI 層(Android)#
L0 ビジネスエコシステム層:ユーザージャーニーパスを設計する(登録ログインホーム詳細支払い)
L1 システム層:Jetpack Compose フレームワークを採用しテーマシステムを設定する(MaterialTheme)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:インターフェースのハイジャック防止を実施する(onPause時にぼかし効果を適用)
L4 モジュール層:app メインモジュールを構築しテーマ設定を含める
L5 パッケージ構造層:UI コンポーネントパッケージを整理する(.screen.login/.screen.cart/.component.button)
L6 クラスとインターフェース層:可組み合わせ関数を定義する(@Composable fun HomeScreen(viewModel: HomeViewModel))
L7 メソッド層:イベント処理関数を作成する(private func handlePurchase() { Task { await viewModel.purchase() } })
L8 コードブロック層:状態応答ブロックを構築する(switch viewModel.state { case .loading: ProgressView() })
L9 ステートメント層:UI 要素を組み合わせる(Column(modifier = Modifier.fillMaxSize()) { Header() })
L10 式層:暗黙のアニメーションを使用する(.animation(.spring, value: viewModel.state))
L11 原子操作層:テキスト表示を設定する(Text(text = stringResource(id = R.string.welcome)))
Kotlin+Swift フルスタックアーキテクチャのブループリント:縦 10 モジュール × 横 12 層の SpringBoot+MySQL+iOS 実践#
1. サーバーサイド Database#
L0 ビジネスエコシステム層:データベースがビジネスエコシステム内でのコア機能を特定する(例:e コマースプラットフォームの注文データ中枢)
L1 システム層:MySQL 高可用アーキテクチャを設計する(主従クラスター+読み書き分離+自動フェイルオーバー)
L2 サブシステム層:ビジネスドメインに基づいて物理データベースを分割する(ユーザーデータベース/注文データベース/在庫データベース)およびデータ同期メカニズムを定義する
L3 セキュリティアーキテクチャ層:トランスポート層暗号化を実施する(TLS1.3)および列レベルデータ暗号化(AES-256)
L4 モジュール層:コアモジュール構造を定義する(ユーザー管理モジュールのテーブル集合および関係)
L5 パッケージ構造層:バージョン管理されたマイグレーションスクリプトディレクトリを整理する(/database/migrations/V1.0__core_schema.sql)
L6 クラスとインターフェース層:テーブル構造を設計する(フィールドタイプ/主外キー/インデックス戦略)
L7 メソッド層:ストアドプロシージャを作成してビジネスロジックを実装する(例:ユーザー消費レベルの計算)
L8 コードブロック層:トランザクション制御ブロックを構築する(START TRANSACTION; UPDATE; INSERT; COMMIT;)
L9 ステートメント層:DDL 定義ステートメントを実行する(CREATE TABLE users(id BIGINT AUTO_INCREMENT PRIMARY KEY))
L10 式層:クエリ式を最適化する(WHERE status = 'ACTIVE' AND last_login > NOW() - INTERVAL 30 DAY)
L11 原子操作層:制約条件を設定する(UNIQUE(email), NOT NULL(username))
2. サーバーサイド Entity#
L0 ビジネスエコシステム層:なし
L1 システム層:Hibernate の二次キャッシュおよびバッチ処理パラメータを設定する(hibernate.cache.use_second_level_cache=true)
L2 サブシステム層:ビジネスドメインに基づいてパッケージを分割する(com.ecommerce.user.entityにはUser/Profileエンティティが含まれる)
L3 セキュリティアーキテクチャ層:フィールドレベル暗号化を実施する(@Convert(converter = PasswordEncryptor.class))
L4 モジュール層:ドメインモジュールを構築し、エンティティスキャンパスを含める(@EntityScan(basePackages = "com.ecommerce"))
L5 パッケージ構造層:エンティティの層別パッケージを整理する(.entity/.embeddable/.enums)
L6 クラスとインターフェース層:JPA エンティティクラスを定義する(@Entity @Table(name="users") class User)
L7 メソッド層:監査コールバックメソッドを実装する(@LastModifiedDate private LocalDateTime updatedAt)
L8 コードブロック層:フィールド検証ブロックを構築する(if (email.isEmpty()) throw new InvalidEntityException())
L9 ステートメント層:マッピング関係を宣言する(@OneToMany(mappedBy = "user", cascade = CascadeType.ALL))
L10 式層:遅延読み込み戦略を設定する(@ManyToOne(fetch = FetchType.LAZY))
L11 原子操作層:equals()/hashCode()メソッドを生成する
3. サーバーサイド Repository#
L0 ビジネスエコシステム層:なし
L1 システム層:Spring Data JPA のクエリ戦略を設定する(メソッド名解析/ページング設定)
L2 サブシステム層:集約ルートに基づいてパッケージを分割する(com.ecommerce.order.repositoryにはOrder/LineItemが含まれる)
L3 セキュリティアーキテクチャ層:行レベルのセキュリティフィルタを実装する(@PostFilter("hasPermission(filterObject, 'READ')"))
L4 モジュール層:リポジトリモジュールを作成し、JPA リポジトリスキャンを含める(@EnableJpaRepositories)
L5 パッケージ構造層:リポジトリの層を整理する(.repository/.custom/.projection)
L6 クラスとインターフェース層:リポジトリインターフェースを宣言する(interface OrderRepository extends JpaRepository<Order, Long>)
L7 メソッド層:動的クエリメソッドを定義する(Page<Order> findByUserId(Long userId, Pageable pageable))
L8 コードブロック層:@Query注釈ブロックを構築する(@Query("SELECT o FROM Order o WHERE o.status = :status"))
L9 ステートメント層:派生クエリを宣言する(List<Order> findByCreatedAtBetween(LocalDate start, LocalDate end))
L10 式層:SpEL セキュリティ式を使用する(@Query("SELECT u FROM #{#entityName} u WHERE u.active = true"))
L11 原子操作層:flush操作を実行する(saveAndFlush(entity))
4. サーバーサイド Service#
L0 ビジネスエコシステム層:なし
L1 システム層:分散トランザクションを統合する(Seata ATモード+ロールバックログ)
L2 サブシステム層:ビジネス能力に基づいてサービス境界を分割する(PaymentService/InventoryService)
L3 セキュリティアーキテクチャ層:メソッドレベルの権限制御を実施する(@PreAuthorize("hasRole('ADMIN') or #userId == principal.id"))
L4 モジュール層:サービスモジュールを作成し、トランザクションマネージャを設定する(@EnableTransactionManagement)
L5 パッケージ構造層:サービスの層を整理する(.api/.impl/.event)
L6 クラスとインターフェース層:サービスクラスを実装する(@Service @Transactional(propagation=REQUIRED) class OrderServiceImpl)
L7 メソッド層:コアビジネスロジックを作成する(Order createOrder(Cart cart) 在庫を減らして注文を生成しメッセージを発信する)
L8 コードブロック層:トランザクション制御ブロックを構築する(@Transactional(timeout=30, rollbackFor=BusinessException.class))
L9 ステートメント層:ドメインイベントをトリガーする(applicationEventPublisher.publishEvent(new OrderCreatedEvent(this)))
L10 式層:EL を使用してビジネスルールを表現する(if (user.getLevel() >= VIP_LEVEL) applyDiscount(15%))
L11 原子操作層:空安全呼び出しを実行する(user?.address ?: throw AddressRequiredException())
5. サーバーサイド Controller#
L0 ビジネスエコシステム層:なし
L1 システム層:OpenAPI 3.0 仕様を策定し Swagger を設定する(@OpenAPIDefinition)
L2 サブシステム層:API ゲートウェイのルーティングルールを設定する(/order-serviceを注文クラスターにルーティング)
L3 セキュリティアーキテクチャ層:JWT 認証を実施する(@AuthenticationPrincipal JwtUserDetails)
L4 モジュール層:web モジュールを作成しメッセージコンバータを設定する(HttpMessageConverters)
L5 パッケージ構造層:コントローラーパッケージを整理する(.controller.user/.controller.order)
L6 クラスとインターフェース層:RestController を定義する(@RestController @RequestMapping("/api/orders"))
L7 メソッド層:エンドポイントメソッドを宣言する(@PostMapping @ResponseStatus(CREATED) fun createOrder())
L8 コードブロック層:パラメータ検証ブロックを構築する(@Valid @RequestBody OrderCreateDTO dto, BindingResult result)
L9 ステートメント層:標準化された応答を返す(ResponseEntity.status(CREATED).body(OrderResponse.from(order)))
L10 式層:MapStruct を使用して変換式を使用する(OrderMapper.INSTANCE.toDTO(domainEntity))
L11 原子操作層:レスポンスヘッダーを設定する(headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest()))
6. クライアント データソース(iOS)#
L0 ビジネスエコシステム層:なし
L1 システム層:URLSession ネットワークスタックを設定する(URLSessionConfiguration.ephemeral+30sタイムアウト+URLCache)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:SSL 証明書ピンニングを実施する(SecTrust証明書チェーン検証)
L4 モジュール層:NetworkServiceモジュールを構築しネットワーク層をカプセル化する
L5 パッケージ構造層:データソースの層を整理する(Networking/API/Networking/Models/Networking/Interceptors)
L6 クラスとインターフェース層:API プロトコルを定義する(protocol UserAPIService { func fetchUser(id: Int) async throws -> UserDTO })
L7 メソッド層:Combine データストリームを宣言する(func productStream() -> AnyPublisher<[ProductDTO], Error>)
L8 コードブロック層:再試行ロジックを構築する(.retry(3) { $0 is URLError })
L9 ステートメント層:ネットワークリクエストを発起する(let (data, _) = try await URLSession.shared.data(for: request))
L10 式層:Codable を使用して解析する(JSONDecoder().decode(UserDTO.self, from: data))
L11 原子操作層:認証ヘッダーを追加する(request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization"))
7. クライアント Repository(iOS)#
L0 ビジネスエコシステム層:なし
L1 システム層:混合キャッシュ戦略を設計する(NSCache+CoreData+自動同期)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:データ暗号化を実施する(NSFileProtectionCompleteファイル保護)
L4 モジュール層:Persistenceデータ調整モジュールを作成する
L5 パッケージ構造層:リポジトリ実装を整理する(Repositories/UserRepository/Repositories/ProductRepository)
L6 クラスとインターフェース層:リポジトリクラスを実装する(struct CoreDataUserRepository: UserRepositoryProtocol)
L7 メソッド層:キャッシュ優先戦略を作成する(CoreData をチェック→ネットワークリクエスト→キャッシュを更新)
L8 コードブロック層:キャッシュ更新制御を構築する(if cacheEntry.lastUpdated.timeIntervalSinceNow < -300 { fetchRemote() })
L9 ステートメント層:CoreData クエリを実行する(try container.viewContext.fetch(NSFetchRequest<UserEntity>(entityName: "User")))
L10 式層:マッピング拡張を使用してモデルを変換する(extension UserDTO { func toManagedObject() })
L11 原子操作層:CoreData コンテキストを保存する(container.viewContext.save())
8. クライアント UseCase(iOS)#
L0 ビジネスエコシステム層:なし
L1 システム層:ユースケース仕様を策定する(純Swift実装+単一責任)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:権限チェックを実施する(guard context.authService.isAdmin else { throw AuthError.unauthorized })
L4 モジュール層:DomainLogicビジネスルールモジュールを定義する
L5 パッケージ構造層:ユースケースパッケージを整理する(UseCases/CheckoutUseCase/UseCases/UserManagement)
L6 クラスとインターフェース層:ユースケース構造体を作成する(struct PurchaseUseCase { let repository: OrderRepository })
L7 メソッド層:コアロジックを実装する(func execute(cart: Cart) async throws:在庫検証→合計計算→注文)
L8 コードブロック層:エラー変換を構築する(catch { throw DomainErrorMapper.transform($0) })
L9 ステートメント層:リポジトリメソッドを呼び出す(let stock = try await stockRepo.checkAvailability(productId))
L10 式層:guard を使用してパラメータを検証する(guard cart.items.count > 0 else { throw CartError.empty })
L11 原子操作層:ドメインモデルを構築する(Order.create(from: cart, user: user))
9. クライアント ViewModel(iOS)#
L0 ビジネスエコシステム層:なし
L1 システム層:依存性注入を設定する(Swinjectコンテナ登録)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:セッションの期限切れ処理を実施する(.onReceive(authService.$sessionState) { if $0 == .expired { handleLogout() } })
L4 モジュール層:PresentationLogic反応型モジュールを作成する
L5 パッケージ構造層:ViewModel を整理する(ViewModels/ProfileViewModel/ViewModels/CartViewModel)
L6 クラスとインターフェース層:ObservableObject を定義する(class UserProfileViewModel: ObservableObject { @Published private(set) var state = ViewState.idle })
L7 メソッド層:非同期ロードメソッドを作成する(@MainActor func loadProfile() async { ... })
L8 コードブロック層:状態変換器を構築する(private func mapResult(_ result: Result<User, Error>))
L9 ステートメント層:UI 状態を更新する(state = .loaded(user))
L10 式層:列挙型の関連値を使用する(enum ViewState { case idle, loading, loaded(User), failed(Error) })
L11 原子操作層:UseCase を呼び出す(self.user = try await useCase.fetchUser(id))
10. クライアント UI 層(iOS)#
L0 ビジネスエコシステム層:ユーザージャーニーパスを設計する(登録ログインホーム詳細支払い)
L1 システム層:SwiftUI フレームワークを採用しテーマを設定する(ViewModifier+Environment)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:インターフェースのハイジャック防止を実施する(.onReceive(UIApplication.willResignActiveNotification) { blurScreen() })
L4 モジュール層:UserInterfaceビューコンポーネントライブラリを構築する
L5 パッケージ構造層:ビューを層別に整理する(Modules/Login/Views/Modules/Checkout/Components)
L6 クラスとインターフェース層:View 構造体を定義する(struct ProductDetailView:View { @StateObject var viewModel: DetailViewModel })
L7 メソッド層:イベント処理を作成する(private func handlePurchase() { Task { await viewModel.purchase() } })
L8 コードブロック層:状態応答ブロックを構築する(switch viewModel.state { case .loading: ProgressView() })
L9 ステートメント層:ビュー要素を組み合わせる(VStack { HeaderView(); ProductGallery() })
L10 式層:暗黙のアニメーションを使用する(.animation(.spring, value: viewModel.state))
L11 原子操作層:テキスト表示を設定する(Text(user.name).font(.system(size: 16, weight: .semibold)))
Kotlin+TypeScript フルスタックアーキテクチャのブループリント:縦 11 層級 × 横 10 モジュールの SpringBoot+MySQL+Web 実践#
1. サーバーサイド Database#
L0 ビジネスエコシステム層:データベースがビジネスエコシステム内でのコア機能を特定する(例:e コマースプラットフォームの注文データ中枢)
L1 システム層:MySQL 高可用アーキテクチャを設計する(主従クラスター+読み書き分離+自動フェイルオーバー)
L2 サブシステム層:ビジネスドメインに基づいて物理データベースを分割する(ユーザーデータベース/注文データベース/在庫データベース)およびデータ同期メカニズムを定義する
L3 セキュリティアーキテクチャ層:トランスポート層暗号化を実施する(TLS1.3)および列レベルデータ暗号化(AES-256)
L4 モジュール層:コアモジュール構造を定義する(ユーザー管理モジュールのテーブル集合および関係)
L5 パッケージ構造層:バージョン管理されたマイグレーションスクリプトディレクトリを整理する(/database/migrations/V1.0__core_schema.sql)
L6 クラスとインターフェース層:テーブル構造を設計する(フィールドタイプ/主外キー/インデックス戦略)
L7 メソッド層:ストアドプロシージャを作成してビジネスロジックを実装する(例:ユーザー消費レベルの計算)
L8 コードブロック層:トランザクション制御ブロックを構築する(START TRANSACTION; UPDATE; INSERT; COMMIT;)
L9 ステートメント層:DDL 定義ステートメントを実行する(CREATE TABLE users(id BIGINT AUTO_INCREMENT PRIMARY KEY))
L10 式層:クエリ式を最適化する(WHERE status = 'ACTIVE' AND last_login > NOW() - INTERVAL 30 DAY)
L11 原子操作層:制約条件を設定する(UNIQUE(email), NOT NULL(username))
2. サーバーサイド Entity#
L0 ビジネスエコシステム層:なし
L1 システム層:Hibernate の二次キャッシュおよびバッチ処理パラメータを設定する(hibernate.cache.use_second_level_cache=true)
L2 サブシステム層:ビジネスドメインに基づいてパッケージを分割する(com.ecommerce.user.entityにはUser/Profileエンティティが含まれる)
L3 セキュリティアーキテクチャ層:フィールドレベル暗号化を実施する(@Convert(converter = PasswordEncryptor.class))
L4 モジュール層:ドメインモジュールを構築し、エンティティスキャンパスを含める(@EntityScan(basePackages = "com.ecommerce"))
L5 パッケージ構造層:エンティティの層別パッケージを整理する(.entity/.embeddable/.enums)
L6 クラスとインターフェース層:JPA エンティティクラスを定義する(@Entity @Table(name="users") class User)
L7 メソッド層:監査コールバックメソッドを実装する(@LastModifiedDate private LocalDateTime updatedAt)
L8 コードブロック層:フィールド検証ブロックを構築する(if (email.isEmpty()) throw new InvalidEntityException())
L9 ステートメント層:マッピング関係を宣言する(@OneToMany(mappedBy = "user", cascade = CascadeType.ALL))
L10 式層:遅延読み込み戦略を設定する(@ManyToOne(fetch = FetchType.LAZY))
L11 原子操作層:equals()/hashCode()メソッドを生成する
3. サーバーサイド Repository#
L0 ビジネスエコシステム層:なし
L1 システム層:Spring Data JPA のクエリ戦略を設定する(メソッド名解析/ページング設定)
L2 サブシステム層:集約ルートに基づいてパッケージを分割する(com.ecommerce.order.repositoryにはOrder/LineItemが含まれる)
L3 セキュリティアーキテクチャ層:行レベルのセキュリティフィルタを実装する(@PostFilter("hasPermission(filterObject, 'READ')"))
L4 モジュール層:リポジトリモジュールを作成し、JPA リポジトリスキャンを含める(@EnableJpaRepositories)
L5 パッケージ構造層:リポジトリの層を整理する(.repository/.custom/.projection)
L6 クラスとインターフェース層:リポジトリインターフェースを宣言する(interface OrderRepository extends JpaRepository<Order, Long>)
L7 メソッド層:動的クエリメソッドを定義する(Page<Order> findByUserId(Long userId, Pageable pageable))
L8 コードブロック層:@Query注釈ブロックを構築する(@Query("SELECT o FROM Order o WHERE o.status = :status"))
L9 ステートメント層:派生クエリを宣言する(List<Order> findByCreatedAtBetween(LocalDate start, LocalDate end))
L10 式層:SpEL セキュリティ式を使用する(@Query("SELECT u FROM #{#entityName} u WHERE u.active = true"))
L11 原子操作層:flush操作を実行する(saveAndFlush(entity))
4. サーバーサイド Service#
L0 ビジネスエコシステム層:なし
L1 システム層:分散トランザクションを統合する(Seata ATモード+ロールバックログ)
L2 サブシステム層:ビジネス能力に基づいてサービス境界を分割する(PaymentService/InventoryService)
L3 セキュリティアーキテクチャ層:メソッドレベルの権限制御を実施する(@PreAuthorize("hasRole('ADMIN') or #userId == principal.id"))
L4 モジュール層:サービスモジュールを作成し、トランザクションマネージャを設定する(@EnableTransactionManagement)
L5 パッケージ構造層:サービスの層を整理する(.api/.impl/.event)
L6 クラスとインターフェース層:サービスクラスを実装する(@Service @Transactional(propagation=REQUIRED) class OrderServiceImpl)
L7 メソッド層:コアビジネスロジックを作成する(Order createOrder(Cart cart) 在庫を減らして注文を生成しメッセージを発信する)
L8 コードブロック層:トランザクション制御ブロックを構築する(@Transactional(timeout=30, rollbackFor=BusinessException.class))
L9 ステートメント層:ドメインイベントをトリガーする(applicationEventPublisher.publishEvent(new OrderCreatedEvent(this)))
L10 式層:EL を使用してビジネスルールを表現する(if (user.getLevel() >= VIP_LEVEL) applyDiscount(15%))
L11 原子操作層:空安全呼び出しを実行する(user?.address ?: throw AddressRequiredException())
5. サーバーサイド Controller#
L0 ビジネスエコシステム層:なし
L1 システム層:OpenAPI 3.0 仕様を策定し Swagger を設定する(@OpenAPIDefinition)
L2 サブシステム層:API ゲートウェイのルーティングルールを設定する(/order-serviceを注文クラスターにルーティング)
L3 セキュリティアーキテクチャ層:JWT 認証を実施する(@AuthenticationPrincipal JwtUserDetails)
L4 モジュール層:web モジュールを作成しメッセージコンバータを設定する(HttpMessageConverters)
L5 パッケージ構造層:コントローラーパッケージを整理する(.controller.user/.controller.order)
L6 クラスとインターフェース層:RestController を定義する(@RestController @RequestMapping("/api/orders"))
L7 メソッド層:エンドポイントメソッドを宣言する(@PostMapping @ResponseStatus(CREATED) fun createOrder())
L8 コードブロック層:パラメータ検証ブロックを構築する(@Valid @RequestBody OrderCreateDTO dto, BindingResult result)
L9 ステートメント層:標準化された応答を返す(ResponseEntity.status(CREATED).body(OrderResponse.from(order)))
L10 式層:MapStruct を使用して変換式を使用する(OrderMapper.INSTANCE.toDTO(domainEntity))
L11 原子操作層:レスポンスヘッダーを設定する(headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest()))
6. クライアント データソース(Web)#
L0 ビジネスエコシステム層:なし
L1 システム層:Axios インスタンスを設定する(baseURL + interceptor + 30sタイムアウト)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:CSRF 保護を実施する(anti-CSRF token)および JWT 自動更新
L4 モジュール層:api-serviceモジュールを構築しネットワークリクエストをカプセル化する
L5 パッケージ構造層:データソースの層を整理する(/services/api/authService.ts,/services/api/productService.ts)
L6 クラスとインターフェース層:API サービスクラスを定義する(class AuthService { async login(credentials: LoginDTO): Promise<AuthResponse> })
L7 メソッド層:反応的データストリームを宣言する(const productObservable = new BehaviorSubject<Product[]>([]))
L8 コードブロック層:指数バックオフ再試行ロジックを構築する(retryWithBackoff(axiosCall, maxRetries = 3))
L9 ステートメント層:API リクエストを実行する(return axios.post<AuthResponse>('/auth/login', credentials))
L10 式層:zod を使用して応答検証を行う(AuthResponseSchema.parse(response.data))
L11 原子操作層:認証ヘッダーを注入する(config.headers.Authorization = 'Bearer ${token}')
7. クライアント 状態管理(Web)#
L0 ビジネスエコシステム層:なし
L1 システム層:Redux 状態アーキテクチャを設計する(redux-toolkit + redux-persist)
L2 サブシステム層:なし
L3 セキュリティアーキテクチャ層:敏感データのクリアを実施する(localStorage.clear())
L4 モジュール層:storeモジュールを作成しアプリケーション状態を管理する
L5 パッケージ構造層:状態スライスを整理する(/store/slices/authSlice.ts,/store/slices/cartSlice.ts)
L6 クラスとインターフェース層:非同期 Thunk を定義する(export const fetchUser = createAsyncThunk('user/fetch'))
L7 メソッド層:状態更新ロジックを作成する(reducers: { addToCart: (state, action) => { ... } })
L8 コードブロック層:データの正規化ブロックを構築する(createEntityAdapter<Product>())
L9 ステートメント層:状態変化を購読する(store.subscribe(() => { ... }))
L10 式層:selector を使用して効率的にデータを選択する(const user = useSelector(selectCurrentUser))
L11 原子操作層:Immer ドラフトを生成する(`produce (state, draft => { draft.cart.items.push (item