一般的な不合格事例
TQS認証審査で頻繁に発生する不合格事由とその解決方法を整理します。本章は頻出不合格事由、事例別原因分析、よくある質問(FAQ)を含みます。プロジェクトチームは審査申請前に本章の内容を参考にし、同じ過ちを繰り返さないよう事前に備えなければなりません。
33.3.1. 頻出不合格事由 Top 10
以下はTQS認証審査で最も頻繁に発見される不合格事由を頻度順に整理したものです。
| 順位 | 不合格事由 | 頻度 | 影響領域 |
|---|---|---|---|
| 1 | テストカバレッジ未達(ライン80%またはブランチ70%未満) | 非常に高い | テスト |
| 2 | System.out.printlnの使用 | 高い | コードコンベンション |
| 3 | TypeScript any型の使用 | 高い | フロントエンド |
| 4 | CI/CDパイプライン未構成または不完全 | 高い | 運用 |
| 5 | シークレットのハードコーディング(APIキー、パスワード、トークン) | 高い | セキュリティ |
| 6 | JPA/Hibernateの使用(jOOQ未使用) | 中程度 | データ |
| 7 | Vue Options APIの使用 | 中程度 | フロントエンド |
| 8 | Flywayマイグレーション未適用 | 中程度 | データ |
| 9 | .gitignoreの欠落または不完全 | 中程度 | 構成管理 |
| 10 | グローバル例外処理の未実装 | 中程度 | バックエンド |
上記の項目はすべてTQS必須項目に該当します。1つでも未充足の場合、認証を取得することはできません。
33.3.2. 事例別原因分析
各不合格事由について原因、解決方法、予防方法を詳細に説明します。
33.3.2.1. テストカバレッジ未達
原因: テストコード作成の文化が定着していない、またはテスト作成時間を確保できなかった場合に発生します。複雑なビジネスロジックに対するテスト作成が困難で後回しになるケースが多いです。
解決方法:
- コアビジネスロジック(サービスレイヤー)から優先的にテストを作成します。
- テストが不要なコード(設定クラス、DTO、jOOQ自動生成コード)はカバレッジ測定から除外します。
- JaCoCoの
<exclude>設定で除外対象を明示します。
予防方法:
- 新機能開発時にテストコードを併せて作成する慣行を確立します。
- CIパイプラインにカバレッジ閾値検証を追加し、カバレッジが低下するとビルドが失敗するよう設定します。
33.3.2.2. System.out.printlnの使用
原因: デバッグ目的で挿入したSystem.out.printlnが除去されずに残っている場合です。ロギングフレームワークに対する認識が不足している場合にも発生します。
解決方法:
- すべての
System.out.printlnをSLF4J + Logbackベースのロギングに置き換えます。 - デバッグ用出力は
log.debug()を使用し、本番環境ではDEBUGレベルを無効化します。
予防方法:
- ESLintまたは静的解析ツールで
System.out.printlnの使用をエラーとして検出するようルールを設定します。 - コードレビュー時にコンソール出力の使用有無を必須点検項目に含めます。
33.3.2.3. TypeScript any型の使用
原因: 型定義が複雑であったり外部ライブラリの型が不明確な場合に、利便性のためにanyを使用するケースです。
解決方法:
- 外部ライブラリの型が提供されていない場合、
declare moduleで型を宣言します。 - ジェネリクスを活用して柔軟かつ型安全なコードを作成します。
- やむを得ない場合は
unknownを使用し、型ガードで型を絞り込みます。
予防方法:
- ESLintで
@typescript-eslint/no-explicit-anyルールをerrorに設定します。 - 型定義ファイル(
.d.ts)をプロジェクトに含めて管理します。
33.3.2.4. CI/CDパイプライン未構成
原因: CI/CDの必要性を認識していない、または設定の複雑さにより先延ばしにしている場合です。ローカル環境でのみビルドとテストを実行する慣行が固着しているプロジェクトで頻発します。
解決方法:
- CircleCIベースのパイプラインを構成します。
.circleci/config.ymlファイルを作成し、リント → テスト → ビルド → セキュリティスキャンの順序でステージを定義します。 - TQSが要求するすべての検証ツール(Spotless、ESLint、Prettier、JaCoCo、Vitest、OWASP)をパイプラインに統合します。
予防方法:
- プロジェクト初期段階でCI/CDパイプラインを優先的に構成します。
- パイプライン設定ファイルをバージョン管理に含めます。
33.3.2.5. シークレットのハードコーディング
原因: 開発の利便性のためにAPIキー、データベースパスワード、外部サービストークンをソースコードに直接記述する場合です。ローカル環境用に作成したシークレットがコミットに含まれる事故が頻発しています。
解決方法:
- すべてのシークレットを環境変数に分離します。Spring Bootの場合、
application.ymlで${ENV_VAR}形式で参照します。 .envファイルを.gitignoreに追加してバージョン管理から除外します。- Gitの履歴にすでにコミットされたシークレットがある場合、シークレットを直ちに変更(ローテーション)します。
予防方法:
- Pre-commitフックにシークレット検出ツールを追加します。
- コードレビュー時にシークレットの含有有無を必須点検項目に含めます。
33.3.2.6. JPA/Hibernateの使用
原因: TQS規格でデータアクセス層の標準技術としてjOOQを指定していますが、既存のJPA/Hibernateを使用していたプロジェクトが移行していない場合です。
解決方法:
- 新規プロジェクトは最初からjOOQを使用して開発します。
- 既存プロジェクトは新機能からjOOQを適用し、既存のJPAコードは段階的に移行します。
- jOOQコードジェネレーターを設定し、データベーススキーマベースの型安全なクエリを作成します。
予防方法:
- プロジェクト初期設定時にjOOQの依存関係とコードジェネレーターを構成します。
- TQS規格のデータアクセス層標準をチームに共有します。
33.3.2.7. Vue Options APIの使用
原因: Vue 2時代から開発されたプロジェクトでOptions APIをそのまま使用している場合です。Composition APIの学習コストを理由に移行を先延ばしにしているケースもあります。
解決方法:
- すべてのVueコンポーネントを
<script setup>ベースのComposition APIに移行します。 - 共通ロジックはComposable関数として抽出します。
- PiniaストアはSetup Store方式で定義します。
予防方法:
- 新しいコンポーネント作成時に必ずComposition APIを使用するようチーム内ルールを確立します。
- ESLintでOptions APIの使用を検出するルールを有効化します。
33.3.2.8. Flywayマイグレーション未適用
原因: データベーススキーマの変更を手動で管理している、またはマイグレーションツールの必要性を認識していない場合です。
解決方法:
- Flywayをプロジェクトに統合し、すべてのスキーマ変更をマイグレーションスクリプトで管理します。
- マイグレーションファイルは
V{バージョン}__{説明}.sqlの命名規則に従います。 - 既存スキーマを基準に初期マイグレーションファイル(Baseline)を作成します。
予防方法:
- プロジェクト初期にFlywayを設定し、最初のマイグレーションファイルを作成します。
- 手動DDL実行を禁止し、すべてのスキーマ変更をマイグレーションファイルのみで実行するようにします。
33.3.2.9. .gitignoreの欠落
原因: .gitignoreファイルを作成していない、またはIDE設定ファイル、ビルド成果物、環境変数ファイルなどが適切に除外されていない場合です。
解決方法:
- プロジェクトルートに
.gitignoreファイルを作成します。 - 以下の項目が必ず含まれていなければなりません:IDE設定(
.idea/、.vscode/の個人設定)、ビルド成果物(target/、dist/、node_modules/)、環境変数ファイル(.env、.env.local)、OSファイル(.DS_Store、Thumbs.db)。 - すでにコミットされたファイルは
git rm --cachedコマンドで追跡を解除します。
予防方法:
- プロジェクト作成直後に
.gitignoreを設定します。 - チーム共通の
.gitignoreテンプレートを維持します。
33.3.2.10. グローバル例外処理の未実装
原因: 例外処理を各コントローラーで個別に実行している、または例外発生時にスタックトレースがクライアントにそのまま露出している場合です。
解決方法:
- Spring Bootの
@RestControllerAdviceを使用してグローバル例外処理を実装します。 - 標準エラーレスポンス形式を定義し、すべての例外に一貫して適用します。
- 例外種別ごとに適切なHTTPステータスコードを返すよう設定します。
予防方法:
- プロジェクト初期にグローバル例外処理クラスを作成します。
- 標準エラーレスポンス形式をチーム内で共有し、遵守します。
33.3.3. FAQ
TQS認証準備過程でよくある質問と回答を整理します。
Q1. 既存のJPAプロジェクトをjOOQにマイグレーションする必要がありますか?
新規プロジェクトは最初からjOOQを使用しなければなりません。既存のJPAプロジェクトの場合、即時全面移行ではなく段階的移行を推奨します。新機能開発時にjOOQを適用し、既存のJPAコードはメンテナンス過程で順次移行します。ただし、初回審査時に新規プロジェクトでJPAを使用している場合は不合格となります。
Q2. テストカバレッジ80%の達成が困難です。
カバレッジ達成が困難な場合、以下の戦略を適用します。第一に、コアビジネスロジック(サービスレイヤー)を優先的にテストします。第二に、テストが不要なコード(設定クラス、DTO、自動生成コード)をカバレッジ測定から除外します。第三に、単に数値を上げるための意味のないテストは避けます。TQS技術審査ではカバレッジ数値だけでなく、テストの品質も併せて検証します。
Q3. Options APIで作成された大規模プロジェクトの移行に時間が不足しています。
全コンポーネントを一度に移行する必要はありません。ただし、TQS認証時点で全コンポーネントがComposition APIを使用していなければなりません。大規模プロジェクトの場合、認証スケジュールを十分に確保し、段階的に移行することを推奨します。移行作業は単純なコンポーネントから始めて、複雑なコンポーネントへ拡張する方式が効果的です。
Q4. CI/CDパイプラインにすべての検証ツールを含める必要がありますか?
TQSが要求する必須検証ツール(Spotless、ESLint、Prettier、JaCoCo、Vitest、OWASP Dependency-Check)は必ずCIパイプラインに含めなければなりません。Lighthouseはデプロイ後に別途実行することもできますが、CIに統合することを推奨します。パイプラインに含まれていないツールの検証結果は、審査時に認められない場合があります。
Q5. OWASPスキャンで誤検知(False Positive)が発生した場合はどうすればよいですか?
誤検知と確認された脆弱性は抑制(Suppression)ファイルに登録して、以降のスキャンから除外することができます。ただし、抑制登録時に当該脆弱性が誤検知であることを証明する根拠を併せて記録しなければなりません。審査時に抑制ファイルの妥当性も検証対象に含まれます。
Q6. 認証準備期間中に機能開発を並行できますか?
並行は可能ですが、認証準備作業の優先順位を高くすることを推奨します。新機能開発時にTQS規格を遵守して開発すれば、認証準備と機能開発を同時に進めることができます。ただし、認証準備スケジュールが遅延しないよう、プロジェクトリードがスケジュールを管理しなければなりません。
Q7. 基本認証と優秀認証の実質的な違いは何ですか?
基本認証は必須項目の100%充足のみで取得できます。優秀認証は必須項目100%に加えて、推奨項目の80%以上を充足しなければなりません。優秀認証を取得するとTQSマークに「優秀」等級を表記でき、社内技術優秀事例として登録される場合があります。初めて認証を準備するプロジェクトは、基本認証の取得を優先目標とすることを推奨します。
Q8. 審査で条件付き合格を受けた場合はどうなりますか?
条件付き合格は軽微な補完が必要な場合に付与されます。補完期間は最大2週間であり、補完完了後に再確認審査を経て最終判定を受けます。再確認審査は未充足項目についてのみ実施するため、全体再審査より負担が少ないです。
Q9. Flywayマイグレーションを適用すると既存データに影響がありますか?
FlywayのBaseline機能を使用すれば、既存のデータベーススキーマを維持しながらマイグレーション管理を開始することができます。Baseline以降のスキーマ変更のみマイグレーションファイルで管理すればよいため、既存データに影響を与えません。
Q10. HikariCPコネクションプール設定も審査対象ですか?
HikariCPはTQSで必須として指定されたコネクションプールライブラリです。コネクションプール設定(最大プールサイズ、タイムアウトなど)の適切性も審査項目に含まれます。Spring Boot 3.xではHikariCPがデフォルトのコネクションプールであるため、別途のライブラリ入れ替えは必要ありませんが、設定値が本番環境に適切であるか確認しなければなりません。
Q11. フロントエンドのみのプロジェクトでもTQS認証を受けられますか?
フロントエンドのみを含むプロジェクトでもTQS-S/W認証を受けることができます。この場合、フロントエンド関連のチェックリスト項目のみが適用されます。バックエンド関連項目(Spotless、JaCoCo、jOOQ、Flywayなど)は審査から除外されます。
Q12. 認証審査中にコードを修正できますか?
正式な技術審査が進行中は、審査対象ブランチのコードを修正してはなりません。審査申請時に提出したコミットハッシュ基準で検証が行われるため、審査中のコード変更は審査結果の一貫性を損なう可能性があります。コード修正は審査結果の通知後に行わなければなりません。
Q13. セキュリティ事故が発生した履歴があると認証に不利ですか?
セキュリティ事故の履歴自体が不合格事由ではありません。ただし、事故発生後に適切な対応措置(原因分析、再発防止対策、セキュリティ設定の強化)が行われたかを審査します。対応措置がTQS規格を満たしていれば、認証を取得することができます。