Skip to content

feat(contest): add getTaskLabels for positional labels and fix prefix accumulation#3639

Merged
KATO-Hiro merged 5 commits into
stagingfrom
#3636
Jun 11, 2026
Merged

feat(contest): add getTaskLabels for positional labels and fix prefix accumulation#3639
KATO-Hiro merged 5 commits into
stagingfrom
#3636

Conversation

@KATO-Hiro

@KATO-Hiro KATO-Hiro commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

close #3636

Summary by CodeRabbit

  • Documentation

    • Svelte の派生値挙動と楽観的更新による蓄積トラップ防止策、表示ラベル生成の指針を追記・整理
  • Refactor

    • コンテスト表の表示ラベル設計を見直し、タイトル整形を表示側へ移譲して元データの不変性を保持
  • Tests

    • 表示ラベル整形とラベル生成ロジックの振る舞いを検証するテストを追加・更新

KATO-Hiro and others added 2 commits June 11, 2026 11:38
… accumulation

Introduce getTaskLabels(filtered) on ContestTableProviderBase to support
display-only positional labels (e.g. "A. Problem Title"). The previous
approach of mutating title inside generateTable caused prefix accumulation
on optimistic-update re-runs because transformed objects were written back
to the source $state array.

AojIcpcPrelimProvider now overrides getTaskLabels instead of generateTable,
and TaskTableBodyCell derives displayTitle via $derived to apply the label.
Also add svelte-runes rule documenting the $derived accumulation trap.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…f/else

Two-level nested ternary is hard to read. $derived.by with early returns
makes the three cases (taskLabel / isShownTaskIndex / default) explicit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4b6c2b99-ec41-47f8-923d-998b17b81224

📥 Commits

Reviewing files that changed from the base of the PR and between 5a1a121 and a311a2f.

📒 Files selected for processing (3)
  • src/features/tasks/types/contest-table/contest_table_provider.ts
  • src/features/tasks/utils/contest-table/aoj_icpc_providers.test.ts
  • src/features/tasks/utils/contest-table/contest_table_provider_base.test.ts

📝 Walkthrough

Walkthrough

ICPC のタスク位置ラベル生成を、データ配列を mutate してタイトルを直接変更する方式から、provider.getTaskLabels が返すラベルマップとビュー側の派生(formatAojIcpcTitle)で表示整形する方式へ移行し、派生内ミューテーションによる「蓄積トラップ」を回避します。

Changes

ICPC Task Label Architecture Refactor

Layer / File(s) Summary
ドキュメントと運用ルール
.claude/rules/svelte-runes.md, .claude/skills/add-contest-table-provider/instructions.md, docs/guides/how-to-add-contest-table-provider.md
派生内でのデータ書き戻しによる累積トラップを明記。タイトル mutate を避け、getTaskLabels とビュー側派生へ移す運用を指示。
Provider contract and helper
src/features/tasks/types/contest-table/contest_table_provider.ts, src/features/tasks/utils/contest-table/aoj_icpc_labels.ts, src/features/tasks/utils/contest-table/aoj_icpc_labels.test.ts
ContestTableProvidergetTaskLabels(filteredTaskResults) を追加。formatAojIcpcTitle(title, letter) を導入しフォーマットを提供、テストを追加。
Base provider & ABS tests
src/features/tasks/utils/contest-table/contest_table_provider_base.ts, src/features/tasks/utils/contest-table/contest_table_provider_base.test.ts
基底クラスに getTaskLabels の既定実装(空オブジェクト)を追加。ABSProvider の挙動テストを追加。
ICPC provider implementation & tests
src/features/tasks/utils/contest-table/aoj_icpc_providers.ts, src/features/tasks/utils/contest-table/aoj_icpc_providers.test.ts
AojIcpcPrelimProvider から generateTable のタイトル接頭辞付与を削除。代わりに getTaskLabels を override してラベルマップを返すように変更。関連テストを生タイトル前提へ更新し、getTaskLabels の挙動を検証。
TaskTable integration
src/features/tasks/components/contest-table/TaskTable.svelte
ProviderData に taskLabels を追加し、prepareContestTable() で provider.getTaskLabels を呼んで格納。描画ループで taskLabel を取得してセルへ渡す。
TaskTableBodyCell の表示ロジック
src/features/tasks/components/contest-table/TaskTableBodyCell.svelte
PropstaskLabel?: string を追加。displayTitle を派生で計算し、taskLabel がある場合は formatAojIcpcTitle を使って表示用タイトルを生成するよう変更。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

ラベルは離れ、表示は葉で咲く
mutate は後に残さずに去る
派生は見るためだけに在り
無限の接頭辞はもう来ない 🌿
小さな分離、大きな安心

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR タイトルはリンク済みの issue #3636「問題番号が無限に追加される」という主要な問題と、その解決方法である getTaskLabels 新規追加を明確に表現しており、変更内容と十分に合致しています。
Linked Issues check ✅ Passed 本 PR は issue #3636 の「回答更新時の問題番号無限追加」バグを、タイトル整形ロジックを generateTable から getTaskLabels へ分離し、TaskTableBodyCell の派生計算で表示用に処理する設計に変更することで修正しており、要件を満たしています。
Out of Scope Changes check ✅ Passed すべての変更は issue #3636 の修正または関連する実装・テスト・ドキュメント更新に関連しており、スコープ外の変更は認められません。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch #3636

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

…tation complete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@KATO-Hiro

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/features/tasks/types/contest-table/contest_table_provider.ts`:
- Around line 70-74: Update the TSDoc for the getTaskLabels(filteredTaskResults:
TaskResults) method to explicitly describe the return structure: a nested record
where the top-level keys are contestId (string), each maps to a second-level
record keyed by task_table_index (string) whose values are the display label
string (e.g., "A", "B" or empty). Mention that entries may be missing for
providers that render indexes in column headers and clarify any invariants
(e.g., no nulls, empty string when absent). Reference getTaskLabels in the
comment so implementers can find and understand expected shapes.

In `@src/features/tasks/utils/contest-table/aoj_icpc_providers.test.ts`:
- Around line 397-426: Add a test that verifies getTaskLabels respects the
ICPC_PRELIM_LABEL_OVERRIDES by setting a mock override map and asserting
provider2023.getTaskLabels(tasks2023) returns the custom labels (e.g. 'X','Y')
for the affected numeric task IDs; specifically reference getTaskLabels,
ICPC_PRELIM_LABEL_OVERRIDES and buildAojIcpcLetterMap to locate logic and add a
new describe/it under the existing getTaskLabels tests that injects the override
(or stubs buildAojIcpcLetterMap) and checks the returned labels object contains
the overridden values for the contestId key.

In `@src/features/tasks/utils/contest-table/contest_table_provider_base.test.ts`:
- Around line 27-31: Add a second test that calls ABSProvider.getTaskLabels with
a non-empty array (e.g., one or more task identifiers) and asserts it still
returns an empty object; specifically locate the ABSProvider instantiation (new
ABSProvider(ContestType.ABS)) and add an additional
expect(provider.getTaskLabels([...nonEmpty...])).toEqual({}) test to confirm the
base implementation consistently returns {} for non-empty input as well.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: fcf38611-17b8-45b5-8c3a-fc094693926b

📥 Commits

Reviewing files that changed from the base of the PR and between 33fca9f and 5a1a121.

📒 Files selected for processing (12)
  • .claude/rules/svelte-runes.md
  • .claude/skills/add-contest-table-provider/instructions.md
  • docs/guides/how-to-add-contest-table-provider.md
  • src/features/tasks/components/contest-table/TaskTable.svelte
  • src/features/tasks/components/contest-table/TaskTableBodyCell.svelte
  • src/features/tasks/types/contest-table/contest_table_provider.ts
  • src/features/tasks/utils/contest-table/aoj_icpc_labels.test.ts
  • src/features/tasks/utils/contest-table/aoj_icpc_labels.ts
  • src/features/tasks/utils/contest-table/aoj_icpc_providers.test.ts
  • src/features/tasks/utils/contest-table/aoj_icpc_providers.ts
  • src/features/tasks/utils/contest-table/contest_table_provider_base.test.ts
  • src/features/tasks/utils/contest-table/contest_table_provider_base.ts

Comment thread src/features/tasks/types/contest-table/contest_table_provider.ts
Comment thread src/features/tasks/utils/contest-table/aoj_icpc_providers.test.ts
KATO-Hiro and others added 2 commits June 11, 2026 13:13
…paths

ContestTableProviderBase.getTaskLabels was untested (always returns {}).
AojIcpcPrelimProvider override map path was also missing coverage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…t.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@KATO-Hiro KATO-Hiro left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@KATO-Hiro KATO-Hiro merged commit fcae579 into staging Jun 11, 2026
3 checks passed
@KATO-Hiro KATO-Hiro deleted the #3636 branch June 11, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug] テーブル「ICPC・国内予選」で回答を更新すると、問題番号が無限に追加されるので修正しましょう

1 participant