1. 開発プロセス

採用する開発プロセスを決定する。

日付: 2024-11-13

ステータス

2024-11-13 提案されました

コンテキスト

mindmap
  root((開発プロセス))
   SCRUM
       原則
            経験プロセスを管理する
            自己組織化する
            コラボレーションする
            価値観に基づいて優先順位を付ける
            時間を区切る
            反復的に開発する
       価値基準
            確約
            勇気
            集中
            公開
            尊敬
       プロセス
            バックログを整理する
            スプリント計画セッションを開く
            スクラムスプリントを開始する
            デイリースクラムを開く
            スプリントレビューを開く
            スプリントレトロスペクティブを開く
       役割
            スクラムマスター
            プロダクトオーナー
            開発チーム
       アーティファクト
            プロダクトバックログ
            スプリントバックログ
            製品インクリメント
   XP
       5つの価値
            シンプルさ
            コミュニケーション
            フィードバック
            勇気
            尊重
       5つのルール
            計画
            管理
            設計
            コーディング
            テスト
      12のプラクティス
            計画ゲーム
            顧客テスト
            小規模リリース
            シンプルな設計
            ペアプログラミング
            テスト駆動開発
            リファクタリング
            集団所有権
            継続的インテグレーション
            持続可能なペース
            メタファー
            コーディング規約

アジャイル開発の中で、SCRUMXPが有名である。SCRUMは経験プロセスを管理することを重視し、XPはプラクティスを重視する。どちらもアジャイル開発の価値観を共有している。 今回は、どちらか一方を採用するか、または両方を組み合わせるかを決定する。

決定

XPを採用する、理由は以下の通り。

開発プロセスは以下の通り。

---
title: XP開発プロセス
---
stateDiagram-v2
    [*] --> リリース計画
    リリース計画 --> イテレーション計画
    イテレーション計画 --> コーディングとテスト
    コーディングとテスト --> イテレーションレビュー

    イテレーションレビュー --> [*]
    イテレーションレビュー --> イテレーション計画

影響

ポジティブ:

ネガティブ:

コプライアンス

各テーマは個別に検討する。

備考

2. シンプルな設計

設計アプローチに関して決定する

日付: 2024-11-14

ステータス

2024-11-14 提案されました

コンテキスト

mindmap
  root((設計))
   ユースケース
   ドメインモデル
   データモデル
   ユーザーインターフェース
        ビュー
        モデル
        インタラクション

アプリケーションを構成する設計要素に以下のものが含まれる。

決定

以下の設計プロセスを採用する。

---
title: 設計プロセス
---
stateDiagram-v2
    [*] --> ユースケース作成
    ユースケース作成 --> データモデル設計
    データモデル設計 --> ドメインモデル設計
    ドメインモデル設計 --> コーディングとテスト
    コーディングとテスト --> リファクタリング
    コーディングとテスト --> ユーザーインターフェース設計
    ユーザーインターフェース設計 --> コーディングとテスト
    コーディングとテスト --> リファクタリング

    リファクタリング --> [*]
    リファクタリング  --> ユースケース作成

影響

ポジティブ

ネガティブ

コプライアンス

開発支援ツールを使用して設計プロセスを実行する

備考

3. テスト駆動開発

テスト駆動開発の進め方についての決定

日付: 2024-11-14

ステータス

2024-11-14 提案されました

コンテキスト

mindmap
  root((テスト駆動開発))
    TODOリスト
    テストファースト
    仮実装
    三角測量
    リファクタリング
    テスト  
     単体テスト
     統合テスト
     受け入れテスト
%%{init: {'theme': 'base', 'themeVariables': { 'pie1': '#ffcc00', 'pie2': '#ff9900', 'pie3': '#ff6600' }}}%%
pie
    title テスティングピラミッド
    "単体テスト" : 70
    "統合テスト" : 20
    "E2Eテスト" : 10

ここで対象となるテストは単体テストである。

決定

コーディングとテストにおいていはテスト駆動開発の採用する。 理由は、設計のスピードアップと高品質なコードが期待できるから。

stateDiagram-v2
    [*] --> TODO: TDOリストを作成
    TODO --> Red: テストを書く
    Red --> Green: 最小限の実装
    Green --> Refactor: リファクタリング
    Refactor --> Red: 次のテストを書く
    Red: テストに失敗
    Green: テストに通る最小限の実装
    Refactor: コードの重複を除去してリファクタリング
    Refactor --> TODO: リファクタリングが完了したらTODOリストに戻る

影響

ポジティブ

ネガティブ

コプライアンス

CI/CDと組み合わせて実施する。

備考

4. リファクタリング

リファクタリングの方針を決定する。

日付: 2024-11-14

ステータス

2024-11-14 提案されました

コンテキスト

mindmap
  root(リファクタリング)
    抽出
      メソッドの抽出
      変数の抽出
      クラスの抽出
      インターフェースの抽出
    インライン
      メソッドのインライン化
      変数のインライン化
    移動
      メソッドの移動
      フィールドの移動
    リネーム
      メソッド名の変更
      変数名の変更
      クラス名の変更
    メソッドシグネチャの変更
      パラメータの追加
      パラメータの削除
      パラメータの並び替え
    一時変数を問い合わせに置き換え
    パラメータオブジェクトの導入
    継承を委譲に置き換え
    フィールドのカプセル化
    条件文の分解
    メソッド呼び出しの簡素化

決定

リファクタリングはカタログの語彙を使って意図を明確にする。

影響

ポジティブ

ネガティブ

コプライアンス

Gitのコミットメッセージにリファクタリングのカタログの語彙を使う。

備考

5. 継続的インテグレーション

継続的インテグレーションを導入する。

日付: 2024-11-14

ステータス

2024-11-14 提案されました

コンテキスト

graph LR
  subgraph GitHub
    subgraph Repository
      Git
    end

    subgraph Continuous_Integration
      GitHub_Actions
    end
  end

  subgraph Vercel
    subgraph Production_Environment_Vercel
      UI
    end
  end

  subgraph Heroku
    subgraph Production_Environment_Heroku
      API
      DB
    end
  end

  開発者 --> Git
  Git --> API & UI
  API --> DB
  API -->|データのやり取り| UI
  Git --> GitHub_Actions
  利用者 --> UI

決定

継続的インテグレーションを導入する。理由は以下の通り。

影響

ポジティブ:

ネガティブ:

コプライアンス

GitHub Actionsを使用する。

備考

6. アプリケーションアーキーテクチャ

アプリケーションアーキテクチャについての決定を記述します。

日付: 2024-11-14

ステータス

2024-11-14 提案されました

コンテキスト

classDiagram
  class データベース

  class プレゼンテーション層 {
    Controller
  }

  class サービス層 {
    Service
  }

  class インフラストラクチャ層 {
    DataSource
  }

  class ドメイン層 {
    Model 
  }

    プレゼンテーション層 --> サービス層
    サービス層 --> インフラストラクチャ層
    サービス層 --> ドメイン層
    インフラストラクチャ層 --> データベース

決定

アーキテクチャスタイルは、レイヤードアーキテクチャを採用。 ドメイン層のアーキテクチャパターンはドメインモデルパターンを採用。

理由は、ドメインモデルパターンは、ビジネスロジックをドメインモデルに集約することで、ビジネスロジックの再利用性を高めることができるため。

影響

ポジティブ:

ネガティブ:

コプライアンス

ArchUnitを使用して、アーキテクチャのコンプライアンスを確認する。

備考

7. プロジェクト構成

プロジェクトの構成についての決定

日付: 2024-11-25

ステータス

2024-11-25 提案されました

コンテキスト

単一のレポジトリで複数のアプリケーションを開発している。

graph TD
  subgraph プロジェクト
    subgraph バックエンド
        販売管理サービス
    end
    subgraph フロントエンド
        販売管理アプリケーション
    end
  end

また、ドキュメントや構築・運用コードも同じレポジトリで管理している。

graph TD
  subgraph プロジェクト
      subgraph ドキュメント
          ADR
          セットアップガイド
          業務分析
          アプリケーション仕様
      end
      subgraph 構築運用コード
          Dockerfile
          Gulpfile
          DBSchema
      end
  end

決定

以下のディレクトリ構成を採用する。

影響

ポジティブ:

ネガティブ:

コプライアンス

gulpのdevタスクで一連のビルドを実行する。

備考

8. 排他制御

データベースの排他制御についての方針を決定する。

日付: 2024-12-05

ステータス

2024-12-05 提案されました

コンテキスト

MyBatisを使用した排他制御には、以下の方法がある。

行ロック

悲観ロック

楽観ロック

決定

スケーラビリティを考慮し、楽観ロックを採用する。

楽観ロック対象は、集約ルートエンティティとする。

影響

ポジティブ:

ネガティブ:

コプライアンス

単体テストを実施し、楽観ロックが正しく機能することを確認する。

単体テストには、Testcontainersを使用する。

備考

9. E2Eテスト

E2Eテストを導入する。

日付: 2024-12-20

ステータス

2024-12-20 提案されました

コンテキスト

バックエンド、フロントエンドの変更時の影響範囲を確認するために、E2Eテストを導入する。

決定

E2Eテストには、Cypressを採用する。

影響

ポジティブ:

ネガティブ:

コプライアンス

CI/CDパイプラインにE2Eテストを組み込み、自動化する。

  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          java-version: '21'
          distribution: 'temurin'
      - name: Grant execute permission for Gradle wrapper
        run: chmod +x ./gradlew
        working-directory: app/backend/api
      - name: Build with Gradle in api directory
        run: ./gradlew build -x test
        working-directory: app/backend/api
      - name: Run with Gradle in api directory
        run: ./gradlew bootRun &
        working-directory: app/backend/api

      - name: Use Node.js latest
        uses: actions/setup-node@v3
        with:
          node-version: latest
          cache: 'npm'
      - run: npm ci
        working-directory: app/frontend
      - name: Cypress run
        uses: cypress-io/github-action@v5
        with:
          build: npm run build
          start: npm run dev
          wait-on: "http://localhost:5173"
          working-directory: app/frontend

タブを使うユーザーインターフェース部分は開発環境のみメニュー表示を環境変数で切り替えるなどの対応を行う。

<li className="nav-item">
    マスタ
    <ul className="nav-sub-list">
        <SubNavItem id="side-nav-department-nav" to="/department">部門</SubNavItem>
        <SubNavItem id="side-nav-employee-nav" to="/employee">社員</SubNavItem>
        <SubNavItem id="side-nav-product-nav" to="/product">商品</SubNavItem>
        { !Env.isProduction() && (
            <ul className="nav-sub-list">
                <SubNavItem id="side-nav-product-nav" to="/product-category">分類</SubNavItem>
                <SubNavItem id="side-nav-product-nav" to="/product-detail">詳細</SubNavItem>
            </ul>
        )}
    </ul>
</li>

備考

10. 安全なソフトウェア設計

安全なソフトウェア開発を行うために、以下の方針を採用する。

日付: 2025-02-13

ステータス

2025-02-13 提案されました

コンテキスト

mindmap
  root((安全なソフトウェア設計))
    安全性を確立する実装テクニック
        不変性
        速やかな失敗
          メソッドの引数に対する事前条件の確認
          コンストラクタでの不変条件の確認
          オブジェクトの状態の確認と速やかな失敗
        妥当性確認
          オリジンの確認
        データ・サイズの確認
          字句的内容の確認
          構文の確認
          データに対する意味の確認
    安全性を考えた例外失敗時の対策
        例外
            チェックされる例外
            実行時例外
            エラー
        処理が失敗したときの対応に使われる例外
            例外のスロー
             ビジネス例外
             技術的例外
            例外処理
            例外に含ませる情報の扱い
        例外を使わない処理失敗時の対応
            失敗は例外ではない
            処理の失敗を想定できるものとした設計
    設計をより安全なものにする単体テスト
        ドメインルール
        正常値テスト
        境界値テスト
        異常値テスト
        極端値テスト

決定

影響

ポジティブ:

ネガティブ:

コプライアンス

CIでの自動化により、コードの品質を保つ。

備考

11. プレゼントテーション層DTO

プレゼントテーションとフロントエンドの間でデータのやり取りを行うためのDTOを定義する。

日付: 2025-03-10

ステータス

2025-03-10 提案されました

コンテキスト

現在、フロントエンドとのやりとりで取得時と登録時で異なるデータ定義をしている。

例:部門マスタ

取得用データ定義

export type DepartmentIdType = {
    deptCode: { value: string };
    departmentStartDate: { value: string };
}

export type DepartmentType = {
    departmentId: DepartmentIdType;
    endDate: { value: string }
    departmentName: string;
    layer: number;
    path: { value: string };
    lowerType: LowerType;
    slitYn: SlitYnType;
    employees: EmployeeType[];
    checked: boolean;
}

APIのドメインモデルをそのままDTOとして使用している

public class Department {
    public static final String TERMINAL_CODE = "99999";

    DepartmentId departmentId; // 部門ID
    DepartmentEndDate endDate; // 終了日
    String departmentName; // 部門名
    Integer layer; // 組織階層
    DepartmentPath path; // 部門パス
    DepartmentLowerType lowerType; // 最下層区分
    SlitYnType slitYn; // 伝票入力可否
    List<Employee> employees; // 社員
    ...

登録用データ定義

export type DepartmentResourceType = {
    departmentCode: string;
    startDate: string;
    endDate: string;
    departmentName: string;
    layer: string;
    path: string;
    lowerType: string;
    slitYn: string;
    employees: EmployeeResourceType[];
}

APIのリソースと関連付けたDTOを定義している

@Setter
@Getter
@Schema(description = "部門")
public class DepartmentResource implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    @NotNull
    private String departmentCode;
    @NotNull
    private String startDate;
    @NotNull
    private String endDate;
    private String departmentName;
    private String layer;
    private String path;
    private DepartmentLowerType lowerType;
    private SlitYnType slitYn;
    private List<EmployeeResource> employees;
}

このような構成のため、フロントエンドとバックエンドの間でデータのやり取りが複雑になっている。

決定

両方ともAPIリソース定義に合わせたDTOを定義する。

影響

ポジティブ

1. フロントエンドとバックエンド間の統一性の向上

2. モデリングとバリデーションが簡素化

3. コードの保守性が向上

4. テストの効率化


ネガティブ

1. 移行の手間が発生

2. 一部の柔軟性の喪失

3. バックエンドにおける影響範囲増加

4. 性能面の影響


コプライアンス

1. 段階的移行

2. テストの拡充

3. バックエンドに変換ヘルパーを導入

備考

12. フィーチャートグル

アプリケーションのフィーチャーを有効化/無効化するための機能を提供する。

日付: 2025-03-15

ステータス

2025-03-15 提案されました

コンテキスト

現在のアプリケーションは、リリース単位でプルリクエストをマージすることで新しい機能を追加しています。

graph TD
    開発(開発中の新機能) --> PR1[プルリクエスト]
    開発 --> PR2[プルリクエスト]
    PR1 --> マージ[マスターブランチ]
    PR2 --> マージ
    マージ --> 本番リリース[本番環境リリース]

決定

フィーチャートグルを導入し、新しい機能を有効化/無効化するための機能を提供する。

graph TD
    開発(開発中の新機能) --> フィーチャートグル
    フィーチャートグル --> 開発ブランチ
    開発ブランチ --> マージ[マスターブランチ]
    マージ --> 本番リリース[本番環境リリース]

影響

ポジティブ

  1. 柔軟な機能管理

    • フィーチャートグルを使用することで、リリース後に特定の機能をオン/オフに切り替えられるため、問題が発生した際には迅速に無効化が可能。
    • 大規模な変更を段階的に展開することができ、リスクを分散させる。
  2. テスト戦略の改善

    • 開発中の機能を本番環境で特定のユーザーにのみ提供することが可能になり、早期のフィードバックを得られる。
  3. リリースプロセスの効率化

    • PR(プルリクエスト)をマスターブランチにマージしつつ、機能有効化のタイミングを調整可能。
  4. デプロイとリリースの分離

    • コードのデプロイと機能の提供を分離することで、デプロイ時の影響を軽減しやすい。
  5. ビジネスのアジリティ向上

    • 新しい機能の市場投入までの時間を短縮できる。ビジネス要件に応じてオンデマンドで機能を展開可能。

ネガティブ

  1. コードベースの複雑化

    • フィーチャートグルにより、コード内に分岐や条件式が増え、メンテナンスの負担が増加。
  2. 技術的負債のリスク

    • 長期間無効化された機能がコードベースに残った場合、技術的負債として作用し、後のトラブルにつながる可能性がある。
  3. 監視と管理のコスト増

    • フィーチャートグル状態の監視や管理に追加のリソースやコストが必要。
  4. テストの複雑化

    • 機能の組み合わせごとにテストが必要になり、テストケースの増加を招く。
  5. スケーリングに伴う課題

    • 多数のフィーチャートグルを導入した場合、状態管理や整合性の維持が難しくなる。

コプライアンス

備考

12. フィーチャートグル

アプリケーションのフィーチャーを有効化/無効化するための機能を提供する。

日付: 2025-03-15

ステータス

2025-03-15 提案されました

コンテキスト

現在のアプリケーションは、リリース単位でプルリクエストをマージすることで新しい機能を追加しています。

graph TD
    開発(開発中の新機能) --> PR1[プルリクエスト]
    開発 --> PR2[プルリクエスト]
    PR1 --> マージ[マスターブランチ]
    PR2 --> マージ
    マージ --> 本番リリース[本番環境リリース]

決定

フィーチャートグルを導入し、新しい機能を有効化/無効化するための機能を提供する。

graph TD
    開発(開発中の新機能) --> フィーチャートグル
    フィーチャートグル --> 開発ブランチ
    開発ブランチ --> マージ[マスターブランチ]
    マージ --> 本番リリース[本番環境リリース]

影響

ポジティブ

  1. 柔軟な機能管理

    • フィーチャートグルを使用することで、リリース後に特定の機能をオン/オフに切り替えられるため、問題が発生した際には迅速に無効化が可能。
    • 大規模な変更を段階的に展開することができ、リスクを分散させる。
  2. テスト戦略の改善

    • 開発中の機能を本番環境で特定のユーザーにのみ提供することが可能になり、早期のフィードバックを得られる。
  3. リリースプロセスの効率化

    • PR(プルリクエスト)をマスターブランチにマージしつつ、機能有効化のタイミングを調整可能。
  4. デプロイとリリースの分離

    • コードのデプロイと機能の提供を分離することで、デプロイ時の影響を軽減しやすい。
  5. ビジネスのアジリティ向上

    • 新しい機能の市場投入までの時間を短縮できる。ビジネス要件に応じてオンデマンドで機能を展開可能。

ネガティブ

  1. コードベースの複雑化

    • フィーチャートグルにより、コード内に分岐や条件式が増え、メンテナンスの負担が増加。
  2. 技術的負債のリスク

    • 長期間無効化された機能がコードベースに残った場合、技術的負債として作用し、後のトラブルにつながる可能性がある。
  3. 監視と管理のコスト増

    • フィーチャートグル状態の監視や管理に追加のリソースやコストが必要。
  4. テストの複雑化

    • 機能の組み合わせごとにテストが必要になり、テストケースの増加を招く。
  5. スケーリングに伴う課題

    • 多数のフィーチャートグルを導入した場合、状態管理や整合性の維持が難しくなる。

コプライアンス

備考