Skip to content

技術的負債管理完全ガイド

技術的負債の特定、計測、返済戦略を、実務で使える実装例とベストプラクティスとともに詳しく解説します。

技術的負債は、短期的な解決策を選択した結果として発生する、長期的なコストです。

技術的負債の特徴
├─ 短期的な利益
├─ 長期的なコスト
├─ 複利効果
└─ 不可視性
## 技術的負債の分類
### 1. コード品質の負債
- **コードの重複**: 同じロジックが複数箇所にある
- **複雑なコード**: 循環的複雑度が高い
- **長い関数**: 関数が長すぎる
- **マジックナンバー**: 意味のない数値が直接記述されている
### 2. テストの負債
- **テストカバレッジの不足**: テストが不十分
- **テストの重複**: 同じテストが複数ある
- **フレーキーテスト**: 不安定なテスト
- **テストの保守性**: テストが保守しにくい
### 3. ドキュメントの負債
- **ドキュメントの不足**: ドキュメントがない
- **古いドキュメント**: ドキュメントが更新されていない
- **不正確なドキュメント**: ドキュメントと実装が一致していない
### 4. アーキテクチャの負債
- **モノリシックな構造**: 密結合な設計
- **スケーラビリティの問題**: スケールできない設計
- **技術的負債の累積**: 過去の負債が蓄積
### 5. 依存関係の負債
- **古いライブラリ**: 古いバージョンのライブラリ
- **セキュリティ脆弱性**: 脆弱性のあるライブラリ
- **メンテナンスされていないライブラリ**: 更新されていないライブラリ
- **依存関係の複雑さ**: 依存関係が複雑
### 6. インフラの負債
- **古いバージョン**: 古いバージョンの使用
- **適切でない設定**: 最適化されていない設定
- **監視の不足**: 監視が不十分
- **バックアップの不足**: バックアップ戦略が不十分
// 技術的負債の例: 重複コード
function calculateTotal(items: OrderItem[]): number {
let total = 0;
for (let i = 0; i < items.length; i++) {
total += items[i].price * items[i].quantity;
}
return total;
}
function calculateSubtotal(items: OrderItem[]): number {
let total = 0;
for (let i = 0; i < items.length; i++) {
total += items[i].price * items[i].quantity;
}
return total;
}
// 解決策: 共通関数の抽出
function calculateItemTotal(items: OrderItem[]): number {
return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
function calculateTotal(items: OrderItem[]): number {
return calculateItemTotal(items);
}
function calculateSubtotal(items: OrderItem[]): number {
return calculateItemTotal(items);
}
// 技術的負債の例: 複雑なコード
function processOrder(order: Order): void {
if (order.status === 'pending') {
if (order.paymentMethod === 'credit') {
if (order.amount > 1000) {
if (order.customer.vip) {
// 複雑なロジック
} else {
// 複雑なロジック
}
} else {
// 複雑なロジック
}
} else {
// 複雑なロジック
}
} else {
// 複雑なロジック
}
}
// 解決策: 早期リターンと関数の分割
function processOrder(order: Order): void {
if (order.status !== 'pending') {
handleNonPendingOrder(order);
return;
}
if (order.paymentMethod === 'credit') {
processCreditCardOrder(order);
} else {
processOtherPaymentOrder(order);
}
}
function processCreditCardOrder(order: Order): void {
if (order.amount > 1000 && order.customer.vip) {
processVipLargeOrder(order);
} else {
processStandardOrder(order);
}
}
// 技術的負債の例: テストがない
function processPayment(amount: number, paymentMethod: PaymentMethod): PaymentResult {
// 複雑なロジック
// テストがない
if (amount <= 0) {
throw new Error('Invalid amount');
}
if (paymentMethod === 'credit') {
return processCreditCard(amount);
} else if (paymentMethod === 'debit') {
return processDebitCard(amount);
} else {
throw new Error('Invalid payment method');
}
}
// 解決策: テストの追加
describe('processPayment', () => {
it('should process credit card payment correctly', () => {
const result = processPayment(100, 'credit');
expect(result.success).toBe(true);
});
it('should throw error for invalid amount', () => {
expect(() => processPayment(-1, 'credit')).toThrow('Invalid amount');
});
it('should throw error for invalid payment method', () => {
expect(() => processPayment(100, 'invalid')).toThrow('Invalid payment method');
});
});
## アーキテクチャの不整合の例
### 問題のあるアーキテクチャ
- **密結合**: モジュール間の依存関係が複雑
- **責務の混在**: 1つのモジュールが複数の責務を持つ
- **データフローの不明確**: データの流れが不明確
### 解決策
- **依存性注入**: 依存関係を外部から注入
- **責務の分離**: 単一責任の原則に従う
- **明確なデータフロー**: データの流れを明確に
// 技術的負債の計測
interface TechnicalDebtMetrics {
// コード品質メトリクス
codeDuplication: number; // コード重複率(%)
cyclomaticComplexity: number; // 平均循環的複雑度
codeSmells: number; // コードスメルの数
maintainabilityIndex: number; // 保守性インデックス
// テストメトリクス
testCoverage: number; // テストカバレッジ(%)
testCount: number; // テスト数
flakyTests: number; // フレーキーテストの数
// ドキュメントメトリクス
documentationCoverage: number; // ドキュメントカバレッジ(%)
outdatedDocumentation: number; // 古いドキュメントの数
// 依存関係メトリクス
outdatedDependencies: number; // 古い依存関係の数
vulnerableDependencies: number; // 脆弱性のある依存関係の数
unusedDependencies: number; // 未使用の依存関係の数
// 技術的負債の総合評価
technicalDebtRatio: number; // 技術的負債比率
technicalDebtHours: number; // 技術的負債の工数(時間)
}
function calculateTechnicalDebt(metrics: TechnicalDebtMetrics): {
score: number;
hours: number;
priority: 'high' | 'medium' | 'low';
} {
// コード品質スコア
const duplicationScore = metrics.codeDuplication * 0.2;
const complexityScore = (metrics.cyclomaticComplexity / 10) * 0.2;
const smellsScore = (metrics.codeSmells / 100) * 0.2;
// テストスコア
const testCoverageScore = (100 - metrics.testCoverage) * 0.15;
const flakyTestsScore = metrics.flakyTests * 0.1;
// 依存関係スコア
const outdatedDepsScore = metrics.outdatedDependencies * 0.05;
const vulnerableDepsScore = metrics.vulnerableDependencies * 0.1;
const totalScore =
duplicationScore +
complexityScore +
smellsScore +
testCoverageScore +
flakyTestsScore +
outdatedDepsScore +
vulnerableDepsScore;
// 工数の計算(経験値)
const hours =
(metrics.codeDuplication / 10) * 2 +
(metrics.cyclomaticComplexity / 10) * 1 +
(metrics.codeSmells / 10) * 0.5 +
((100 - metrics.testCoverage) / 10) * 1 +
metrics.outdatedDependencies * 2 +
metrics.vulnerableDependencies * 4;
// 優先度の決定
let priority: 'high' | 'medium' | 'low';
if (totalScore > 50 || metrics.vulnerableDependencies > 0) {
priority = 'high';
} else if (totalScore > 20) {
priority = 'medium';
} else {
priority = 'low';
}
return { score: totalScore, hours, priority };
}
Terminal window
# SonarQubeでの技術的負債の計測
sonar-scanner \
-Dsonar.projectKey=my-project \
-Dsonar.sources=src \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.login=your-token
# 技術的負債レポートの確認
# SonarQubeダッシュボードで確認
.codeclimate.yml
version: "2"
plugins:
duplication:
enabled: true
config:
languages:
- javascript
- typescript
eslint:
enabled: true
test-coverage:
enabled: true
config:
coverage: 80
Terminal window
# コード重複の検出
jscpd src/ --min-lines 5 --min-tokens 50
# テストカバレッジの計測
npm run test:coverage
# 循環的複雑度の計測
complexity-report src/
# 依存関係の脆弱性チェック
npm audit
yarn audit
# 未使用の依存関係の検出
depcheck
# コードスメルの検出
eslint src/
## 技術的負債ダッシュボード
### メトリクスの可視化
- **コード品質**: コード重複率、循環的複雑度
- **テスト品質**: テストカバレッジ、フレーキーテスト
- **依存関係**: 古い依存関係、脆弱性
- **技術的負債の総合評価**: スコア、工数、優先度
### トレンドの可視化
- **技術的負債の推移**: 時系列での変化
- **返済率**: 返済された負債の割合
- **増加率**: 新たに追加された負債の割合
## 技術的負債レポートの例
### サマリー
- **総技術的負債**: 120時間
- **高優先度**: 40時間
- **中優先度**: 60時間
- **低優先度**: 20時間
### カテゴリ別
- **コード品質**: 50時間
- **テスト**: 30時間
- **依存関係**: 20時間
- **ドキュメント**: 20時間
### トレンド
- **前月比**: +10時間(8.3%増加)
- **返済率**: 15時間(12.5%)
- **新規負債**: 25時間
## 技術的負債のコスト
### 1. 直接コスト
- **返済コスト**: 負債を返済するための工数
- **修正コスト**: 負債によるバグ修正のコスト
- **学習コスト**: 複雑なコードを理解するコスト
### 2. 間接コスト
- **開発速度の低下**: 新機能開発の遅延
- **品質の低下**: バグの増加
- **チームのモチベーション**: モチベーションの低下
### 3. 機会損失
- **新機能の遅延**: 新機能がリリースできない
- **競争力の低下**: 競合に遅れを取る
- **顧客満足度の低下**: 品質問題による顧客離れ
## 技術的負債のコスト計算例
### 返済コスト
- **高優先度の負債**: 40時間 × 5,000円/時間 = 200,000円
- **中優先度の負債**: 60時間 × 5,000円/時間 = 300,000円
- **低優先度の負債**: 20時間 × 5,000円/時間 = 100,000円
- **合計**: 600,000円
### 機会損失
- **開発速度の低下**: 20%の低下
- **新機能の遅延**: 2週間の遅延
- **機会損失**: 500,000円/週 × 2週 = 1,000,000円
### 総コスト
- **返済コスト**: 600,000円
- **機会損失**: 1,000,000円
- **合計**: 1,600,000円
## 優先順位マトリックス
| 影響度 | 高 | 中 | 低 |
|--------|----|----|----|
| **** | P0 | P1 | P2 |
| **** | P1 | P2 | P3 |
| **** | P2 | P3 | P4 |
### 優先度の定義
- **P0 - Critical**: 即座に対応が必要(セキュリティ、可用性)
- **P1 - High**: できるだけ早く対応(パフォーマンス、開発速度)
- **P2 - Medium**: 通常の対応(コード品質、テスト)
- **P3 - Low**: 時間があるときに対応(ドキュメント、スタイル)
- **P4 - Deferred**: 対応不要または延期
// 影響度の評価
interface TechnicalDebtItem {
id: string;
description: string;
category: 'code' | 'test' | 'documentation' | 'architecture' | 'dependencies' | 'infrastructure';
impact: {
developmentSpeed: number; // 開発速度への影響(0-10)
quality: number; // 品質への影響(0-10)
security: number; // セキュリティへの影響(0-10)
performance: number; // パフォーマンスへの影響(0-10)
maintainability: number; // 保守性への影響(0-10)
};
effort: 'high' | 'medium' | 'low'; // 返済工数
estimatedHours: number; // 見積もり工数(時間)
priority: number; // 優先度スコア
}
function calculatePriority(item: TechnicalDebtItem): number {
// 影響度の合計
const totalImpact =
item.impact.developmentSpeed +
item.impact.quality +
item.impact.security * 2 + // セキュリティは2倍
item.impact.performance +
item.impact.maintainability;
// 工数の逆数(工数が少ないほど優先度が高い)
const effortScore = { high: 1, medium: 2, low: 3 }[item.effort];
// 優先度スコア = 影響度 × 工数スコア
return totalImpact * effortScore;
}
// 例: セキュリティ脆弱性のある依存関係
const securityDebt: TechnicalDebtItem = {
id: 'TD-001',
description: '脆弱性のあるライブラリの更新',
category: 'dependencies',
impact: {
developmentSpeed: 2,
quality: 3,
security: 10, // セキュリティへの影響が高い
performance: 1,
maintainability: 2,
},
effort: 'low',
estimatedHours: 4,
priority: 0, // 計算前
};
securityDebt.priority = calculatePriority(securityDebt);
// 優先度スコア: 36(高優先度)
## ボーイスカウトルール
「コードを触ったら、必ず少しでも改善する」
### 実践例
- **バグ修正時**: 関連するコードをリファクタリング
- **機能追加時**: 既存コードの改善とテストの追加
- **コードレビュー時**: 改善提案を積極的に行う
- **リファクタリング時**: 小さな改善を継続的に実施
### 効果
- 技術的負債の蓄積を防ぐ
- コード品質の継続的な改善
- チームの意識向上
## 負債返済スプリント
定期的に技術的負債の返済に専念するスプリントを設ける
### 実施頻度
- **四半期ごと**: 四半期に1回、負債返済スプリント
- **月次**: 毎月、負債返済日を設ける
- **スプリントの20%**: 各スプリントの20%を負債返済に充てる
### 実施内容
- 高優先度の負債の返済
- コード品質の改善
- テストカバレッジの向上
- 依存関係の更新

戦略3: 新機能開発時の負債返済

Section titled “戦略3: 新機能開発時の負債返済”
// 新機能開発時に負債を返済
function addNewFeature(feature: Feature): void {
// 1. 既存コードのリファクタリング
refactorExistingCode();
// 2. テストの追加
addTests();
// 3. ドキュメントの更新
updateDocumentation();
// 4. 新機能の実装
implementFeature(feature);
}
// 実践例: ユーザー認証機能の追加時に負債を返済
function addUserAuthentication(): void {
// 既存の認証コードをリファクタリング
refactorLegacyAuth();
// テストを追加
addAuthTests();
// セキュリティの改善
improveSecurity();
// 新機能の実装
implementNewAuth();
}
## 段階的な返済戦略
### フェーズ1: 緊急対応(1ヶ月)
- セキュリティ脆弱性の修正
- クリティカルなバグの修正
- 可用性の問題の解決
### フェーズ2: 重要対応(3ヶ月)
- パフォーマンスの問題の解決
- 開発速度に影響する負債の返済
- テストカバレッジの向上
### フェーズ3: 改善対応(6ヶ月)
- コード品質の改善
- アーキテクチャの改善
- ドキュメントの整備
## 技術的負債の記録方法
### 1. Issue管理ツール
- **GitHub Issues**: ラベル「technical-debt」で管理
- **Jira**: エピック「技術的負債」で管理
- **Linear**: プロジェクト「技術的負債」で管理
### 2. ドキュメント
- **技術的負債一覧**: Markdownファイルで管理
- **ADR(Architecture Decision Record)**: 意思決定を記録
### 3. コードコメント
- **TODOコメント**: コード内にTODOコメント
- **FIXMEコメント**: 修正が必要な箇所にFIXME
## 技術的負債記録テンプレート
### 基本情報
- **ID**: TD-001
- **タイトル**: パスワードのハッシュ化が不適切
- **カテゴリ**: セキュリティ
- **発見日**: 2024/03/15
- **発見者**: 田中
### 詳細
- **説明**: 現在MD5を使用しているが、bcryptに変更する必要がある
- **影響範囲**: すべてのユーザー認証
- **リスク**: 高(セキュリティ侵害のリスク)
### 評価
- **影響度**: 高(セキュリティ: 10、品質: 5、保守性: 3)
- **工数**: 低(2日)
- **優先度**: P0(Critical)
### 見積もり
- **返済工数**: 2日(16時間)
- **返済コスト**: 80,000円(5,000円/時間 × 16時間)
### 返済計画
- **返済予定日**: 2024/03/20
- **担当者**: 佐藤
- **関連Issue**: #123
### 進捗
- **ステータス**: 未着手
- **進捗率**: 0%
- **完了日**: -

9. 技術的負債のコミュニケーション

Section titled “9. 技術的負債のコミュニケーション”
## ステークホルダーへの報告
### 報告内容
- **技術的負債の現状**: 総負債、優先度別の内訳
- **コスト**: 返済コスト、機会損失
- **返済計画**: 短期、中期、長期の計画
- **進捗**: 返済の進捗状況
### 報告頻度
- **月次**: 月次で進捗を報告
- **四半期**: 四半期で総合的な報告
- **緊急時**: 高優先度の負債発見時は即座に報告
## ビジネス言語での説明例
### 技術的負債の説明
「技術的負債は、過去の開発で積み重ねられた技術的な問題です。
これらを放置すると、新機能の開発速度が20%低下し、
バグの発生率が30%増加する可能性があります。」
### 返済の必要性
「技術的負債の返済には、現在120時間(約600,000円)かかりますが、
返済しない場合、年間で約2,000,000円の機会損失が発生します。
返済により、開発速度が向上し、品質が改善されます。」
### 返済計画
「四半期ごとに負債返済スプリントを設け、
各スプリントの20%を負債返済に充てることで、
6ヶ月で主要な負債を返済できます。」
## コードレビューのチェックリスト
### コード品質
- [ ] コードの重複がないか
- [ ] 循環的複雑度が適切か(10以下)
- [ ] 関数が適切な長さか(50行以下)
- [ ] マジックナンバーがないか
- [ ] 命名が適切か
### テスト
- [ ] テストが十分か(カバレッジ80%以上)
- [ ] テストが保守しやすいか
- [ ] フレーキーテストがないか
### ドキュメント
- [ ] ドキュメントが十分か
- [ ] コメントが適切か
- [ ] READMEが更新されているか
### アーキテクチャ
- [ ] アーキテクチャに整合性があるか
- [ ] 依存関係が適切か
- [ ] 責務が分離されているか
### パフォーマンス
- [ ] パフォーマンスの問題がないか
- [ ] メモリリークがないか
- [ ] 不要な処理がないか
## 継続的な改善の仕組み
### 1. 定期的なレビュー
- **週次**: コードベースの週次レビュー
- **月次**: 技術的負債の月次レビュー
- **四半期**: アーキテクチャの四半期レビュー
### 2. メトリクスの監視
- **自動監視**: CI/CDでメトリクスを自動監視
- **ダッシュボード**: 技術的負債ダッシュボードで可視化
- **アラート**: 閾値を超えた場合にアラート
### 3. 教育とトレーニング
- **技術的負債の教育**: チームへの教育
- **ベストプラクティス**: ベストプラクティスの共有
- **コードレビューの訓練**: コードレビューの訓練
### 4. ツールの活用
- **自動化**: 自動化ツールの活用
- **統合**: CI/CDへの統合
- **レポート**: 自動レポートの生成

11. 実践的なベストプラクティス

Section titled “11. 実践的なベストプラクティス”
// 技術的負債の追跡システム
interface DebtTracker {
addDebt(debt: TechnicalDebtItem): void;
getDebtsByPriority(): TechnicalDebtItem[];
getDebtsByCategory(category: string): TechnicalDebtItem[];
updateDebt(id: string, updates: Partial<TechnicalDebtItem>): void;
resolveDebt(id: string): void;
getMetrics(): TechnicalDebtMetrics;
}
class TechnicalDebtTracker implements DebtTracker {
private debts: TechnicalDebtItem[] = [];
addDebt(debt: TechnicalDebtItem): void {
debt.priority = calculatePriority(debt);
this.debts.push(debt);
}
getDebtsByPriority(): TechnicalDebtItem[] {
return this.debts
.filter(debt => !debt.resolvedAt)
.sort((a, b) => b.priority - a.priority);
}
getDebtsByCategory(category: string): TechnicalDebtItem[] {
return this.debts
.filter(debt => debt.category === category && !debt.resolvedAt)
.sort((a, b) => b.priority - a.priority);
}
updateDebt(id: string, updates: Partial<TechnicalDebtItem>): void {
const debt = this.debts.find(d => d.id === id);
if (debt) {
Object.assign(debt, updates);
if (updates.impact || updates.effort) {
debt.priority = calculatePriority(debt);
}
}
}
resolveDebt(id: string): void {
const debt = this.debts.find(d => d.id === id);
if (debt) {
debt.resolvedAt = new Date();
debt.status = 'resolved';
}
}
getMetrics(): TechnicalDebtMetrics {
const unresolved = this.debts.filter(d => !d.resolvedAt);
return {
totalDebts: unresolved.length,
highPriority: unresolved.filter(d => d.priority > 30).length,
mediumPriority: unresolved.filter(d => d.priority > 10 && d.priority <= 30).length,
lowPriority: unresolved.filter(d => d.priority <= 10).length,
totalHours: unresolved.reduce((sum, d) => sum + d.estimatedHours, 0),
resolvedThisMonth: this.debts.filter(d =>
d.resolvedAt &&
d.resolvedAt.getMonth() === new Date().getMonth()
).length,
};
}
}
## 負債返済の計画例
### 短期計画(1-3ヶ月)
**目標**: 高優先度の負債の返済
- **セキュリティ脆弱性**: 4時間 × 5件 = 20時間
- **クリティカルなバグ**: 8時間 × 3件 = 24時間
- **可用性の問題**: 16時間 × 2件 = 32時間
- **合計**: 76時間
### 中期計画(3-6ヶ月)
**目標**: 中優先度の負債の返済
- **パフォーマンスの問題**: 40時間
- **開発速度に影響する負債**: 60時間
- **テストカバレッジの向上**: 30時間
- **合計**: 130時間
### 長期計画(6-12ヶ月)
**目標**: 低優先度の負債の返済と改善
- **コード品質の改善**: 80時間
- **アーキテクチャの改善**: 100時間
- **ドキュメントの整備**: 40時間
- **合計**: 220時間
## 解決策
### 1. 定期的なレビュー
- **四半期ごと**: 四半期ごとに負債をレビュー
- **優先順位付け**: 影響度と工数で優先順位を決定
- **返済計画**: 返済計画を立てて実行
### 2. 早期発見
- **コードレビュー**: コードレビューで早期発見
- **自動化ツール**: 自動化ツールで継続的に監視
- **メトリクス監視**: メトリクスで早期に問題を発見
### 3. 予防策の強化
- **ボーイスカウトルール**: 小さな改善を継続
- **コードレビュー基準**: レビュー基準を明確に
- **教育**: チームへの教育を強化
## 解決策
### 1. 時間の確保
- **負債返済スプリント**: 定期的な返済スプリント
- **スプリントの20%**: 各スプリントの20%を負債返済に充てる
- **新機能開発時の返済**: 新機能開発時に負債を返済
### 2. 優先順位の見直し
- **高優先度に集中**: 高優先度の負債に集中
- **低優先度の延期**: 低優先度の負債は延期
- **ROIの評価**: 投資対効果の高い負債から返済
### 3. リソースの調整
- **人員の追加**: 必要に応じて人員を追加
- **外部リソース**: 外部リソースを活用
- **自動化**: 自動化で効率化

問題3: ステークホルダーの理解が得られない

Section titled “問題3: ステークホルダーの理解が得られない”
## 解決策
### 1. ビジネス言語での説明
- **コストの明確化**: 返済コストと機会損失を明確に
- **ROIの提示**: 投資対効果を提示
- **リスクの説明**: 負債を放置するリスクを説明
### 2. データに基づいた説明
- **メトリクス**: メトリクスで現状を可視化
- **トレンド**: 負債の増加トレンドを示す
- **比較**: 他社との比較データ
### 3. 段階的なアプローチ
- **小さな成功**: 小さな成功から始める
- **実績の積み重ね**: 実績を積み重ねる
- **信頼の構築**: 信頼を構築してから大きな投資を提案
## 技術的負債管理ツール
### 1. SonarQube
- **機能**: コード品質の監視、技術的負債の計測
- **特徴**: 包括的なコード品質分析
- **コスト**: オープンソース(Community版)
### 2. CodeClimate
- **機能**: コード品質の監視、技術的負債の計測
- **特徴**: GitHub統合、自動レビュー
- **コスト**: 有料(SaaS)
### 3. Dependabot
- **機能**: 依存関係の脆弱性監視、自動更新
- **特徴**: GitHub統合、自動プルリクエスト
- **コスト**: 無料(GitHub)
### 4. Renovate
- **機能**: 依存関係の自動更新
- **特徴**: 柔軟な設定、複数プラットフォーム対応
- **コスト**: オープンソース
.github/workflows/technical-debt.yml
name: Technical Debt Check
on:
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 0' # 毎週日曜日
jobs:
technical-debt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run SonarQube
uses: sonarsource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Check test coverage
run: |
npm run test:coverage
if [ $(cat coverage/coverage-summary.json | jq '.total.lines.pct') -lt 80 ]; then
echo "Test coverage is below 80%"
exit 1
fi
- name: Check dependencies
run: |
npm audit --audit-level=high
- name: Generate technical debt report
run: |
# 技術的負債レポートの生成
npm run debt:report

技術的負債管理完全ガイドのポイント:

  • 特定: コードの重複、テストの不足、アーキテクチャの不整合、依存関係の古さ
  • 計測: メトリクスの収集、ツールの使用、可視化
  • コスト計算: 返済コスト、機会損失、総コスト
  • 優先順位付け: 影響度と工数による優先順位、優先度マトリックス
  • 返済戦略: ボーイスカウトルール、負債返済スプリント、新機能開発時の返済、段階的な返済
  • 記録と管理: Issue管理、ドキュメント、コードコメント
  • コミュニケーション: ステークホルダーへの報告、ビジネス言語での説明
  • 予防: コードレビュー、継続的な改善、教育とトレーニング
  • ツールと自動化: SonarQube、CodeClimate、CI/CDへの統合
  • 実践例: 負債の記録、返済計画、よくある問題と解決方法

適切な技術的負債管理により、持続可能な開発が可能になります。