Skip to content

Commit 2c87855

Browse files
committed
chore(docs): Backwards compatibility regression for getProvider (#2819)
1 parent 95bb5a5 commit 2c87855

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

docs/dev-notes/2025-11-12/add_provider_key_for_contest_table_provider/plan.md

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,52 @@ pnpm format src/lib/utils/contest_table_provider.ts
324324
- **段階的実装**: 型定義 → ベースクラス → 子クラス → Group クラス → プリセット の順序で実装することで、依存関係を最小化
325325
- **型安全性と実用性のバランス**: TypeScript のテンプレートリテラル型で型安全性を確保しつつ、runtime では string として柔軟に操作
326326

327+
### 後方互換性に関する重要な知見
328+
329+
**Backwards Compatibility Regression の防止**
330+
331+
セクション化による Provider 実装変更時、後方互換性が壊れる可能性を検出したので記録:
332+
333+
#### 問題状況
334+
335+
従来のコードが `getProvider(ContestType.TESSOKU_BOOK)` を呼び出していた場合、セクション専用 Provider のみを登録すると以下が発生:
336+
337+
```typescript
338+
// 登録: TESSOKU_BOOK::examples, TESSOKU_BOOK::practicals, TESSOKU_BOOK::challenges のみ
339+
// 呼び出し: getProvider(ContestType.TESSOKU_BOOK) ← セクション未指定
340+
// 結果: undefined が返る ❌ (互換性回帰)
341+
```
342+
343+
#### 回避方法(複数の選択肢)
344+
345+
1. **セクション化+従来 Provider の併記**(最も安全)
346+
347+
```typescript
348+
.addProviders(
349+
new TessokuBookProvider(ContestType.TESSOKU_BOOK), // key: "TESSOKU_BOOK"
350+
new TessokuBookForExamplesProvider(ContestType.TESSOKU_BOOK), // key: "TESSOKU_BOOK::examples"
351+
new TessokuBookForPracticalsProvider(ContestType.TESSOKU_BOOK), // key: "TESSOKU_BOOK::practicals"
352+
new TessokuBookForChallengesProvider(ContestType.TESSOKU_BOOK), // key: "TESSOKU_BOOK::challenges"
353+
)
354+
```
355+
356+
2. **セクション専用のみ+事前検証**(リスク低い場合)
357+
- grep で既存コード全体から `getProvider(ContestType.TESSOKU_BOOK)` の セクション未指定呼び出しが **存在しない** ことを確認
358+
- 本プロジェクトではこの検証後、セクション専用のみを採用
359+
360+
#### 実装決定
361+
362+
本プロジェクトでは方法 2 を採用:
363+
364+
```bash
365+
# 検証コマンド例
366+
grep -r "getProvider.*TESSOKU_BOOK" /usr/src/app/src --include="*.ts" --include="*.tsx" --include="*.svelte"
367+
# 結果: すべてが section 付き呼び出し (getProvider(TESSOKU_BOOK, 'examples') など)
368+
```
369+
370+
**結論**: セクション専用 Provider のみの登録は、セクション未指定の呼び出しが存在しないことが確認できればリスクがない。ただしコメント(TSDoc)で明記し、将来のメンテナーに注意喚起することが重要。
371+
327372
---
328373

329-
**状態**: ✅ 完了(ProviderKey 型を活用)
374+
**状態**: ✅ 完了(ProviderKey 型を活用、後方互換性検証済み
330375
````

src/lib/utils/contest_table_provider.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,17 @@ export class Typical90Provider extends ContestTableProviderBase {
264264
}
265265
}
266266

267+
/**
268+
* Base provider for Tessoku Book tasks.
269+
*
270+
* This provider has been refactored to use section-specific subclasses (examples, practicals, challenges)
271+
* instead of a single unified provider. The TessokuBook group registers only the section-specific providers
272+
* (TessokuBookForExamplesProvider, TessokuBookForPracticalsProvider, TessokuBookForChallengesProvider).
273+
* Ensure all callers use section-specific lookups via getProvider(ContestType.TESSOKU_BOOK, section)
274+
* rather than the non-sectioned variant.
275+
*
276+
* @see https://github.com/AtCoder-NoviSteps/AtCoderNoviSteps/pull/2820
277+
*/
267278
export class TessokuBookProvider extends ContestTableProviderBase {
268279
protected setFilterCondition(): (taskResult: TaskResult) => boolean {
269280
return (taskResult: TaskResult) => {

0 commit comments

Comments
 (0)