Skip to content

feat(ui): Split contest table for tessoku book (#2819)#2820

Merged
KATO-Hiro merged 6 commits intostagingfrom
#2819
Nov 12, 2025
Merged

feat(ui): Split contest table for tessoku book (#2819)#2820
KATO-Hiro merged 6 commits intostagingfrom
#2819

Conversation

@KATO-Hiro
Copy link
Collaborator

@KATO-Hiro KATO-Hiro commented Nov 12, 2025

close #2819

Summary by CodeRabbit

  • New Features

    • Providers now support optional sectioning (examples, practicals, challenges) so multiple sections can exist per contest type.
    • TessokuBook content is split into three sectioned providers for clearer discovery.
  • Documentation

    • Added a plan, testing guidance, and migration notes describing the provider-key and sectioning approach.
  • Tests

    • Expanded tests for provider keys, section-specific providers, group lookups, presets, and backward-compatible retrieval.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 12, 2025

Warning

Rate limit exceeded

@KATO-Hiro has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 14 minutes and 35 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between e5ce308 and 0efc893.

📒 Files selected for processing (1)
  • src/test/lib/utils/contest_table_provider.test.ts (7 hunks)

Walkthrough

Adds a provider-key scheme for contest table providers: introduces ProviderKey and TESSOKU_SECTIONS, makes ContestTableProviderBase section-aware with createProviderKey()/getProviderKey(), changes ContestTableProviderGroup to store providers by providerKey and accept provider instances, and splits TessokuBook into three sectioned providers.

Changes

Cohort / File(s) Summary
Documentation & Plan
docs/dev-notes/2025-11-12/add_provider_key_for_contest_table_provider/plan.md
New design/plan documenting provider key approach, implementation steps, tests, and backward-compatibility notes.
Type Definitions
src/lib/types/contest_table_provider.ts
Added exported ProviderKey template-literal type and exported TESSOKU_SECTIONS constant; imports ContestType as a type.
Provider Base & Group Implementation
src/lib/utils/contest_table_provider.ts
ContestTableProviderBase: added readonly section?, constructor updated, added static createProviderKey(contestType, section?) and getProviderKey(). ContestTableProviderGroup: switched internal Map to use providerKey (Map<string, ContestTableProviderBase>), changed addProvider/addProviders to accept provider instances, updated getProvider(contestType, section?) for key-based and backward-compatible lookups, getStats() now exposes providerKey. Introduced TessokuBookForExamplesProvider, TessokuBookForPracticalsProvider, TessokuBookForChallengesProvider and adjusted presets/registrations to use instances.
Tests
src/test/lib/utils/contest_table_provider.test.ts
Tests updated to import new providers and TESSOKU_SECTIONS, validate createProviderKey and getProviderKey, assert providerKey in stats, verify sectioned TessokuBook registrations and backward-compatible getProvider behavior.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Group as ContestTableProviderGroup
    participant Provider as ContestTableProviderBase

    Client->>Group: addProvider(providerInstance)
    activate Group
    Group->>Provider: providerInstance.getProviderKey()
    activate Provider
    Provider-->>Group: "ContestType" or "ContestType::section"
    deactivate Provider
    Group->>Group: providers.set(providerKey, providerInstance)
    deactivate Group

    Client->>Group: getProvider(contestType, section?)
    activate Group
    Group->>Group: key = ContestTableProviderBase.createProviderKey(contestType, section)
    Group-->>Client: providers.get(key) or fallback lookup (no section)
    deactivate Group
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay attention to createProviderKey() formatting and template-literal ProviderKey usage.
  • Verify all provider registrations/presets were converted to instance-based addProvider/addProviders.
  • Confirm getProvider(contestType, section?) fallback behavior preserves backward compatibility.
  • Check tests and any callers for the getStats() shape change (now exposes providerKey).

Poem

🐇 I stitched a key for every nook and case,
Tessoku wears each section's bright new face,
Providers hop in order, neat and spry,
Old paths still open when the new keys fly,
A little rabbit cheers the tidy race!

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly describes the main change: splitting the contest table for Tessoku Book into sections, which aligns with the PR's core objective.
Linked Issues check ✅ Passed The changes implement provider key mechanism and section-aware providers (Examples, Practicals, Challenges) to enable splitting Tessoku Book contest table by sections.
Out of Scope Changes check ✅ Passed All changes are focused on provider architecture and key management to support splitting Tessoku Book tables; no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 578d31b and 10b49c1.

📒 Files selected for processing (4)
  • docs/dev-notes/2025-11-12/add_provider_key_for_contest_table_provider/plan.md (1 hunks)
  • src/lib/types/contest_table_provider.ts (2 hunks)
  • src/lib/utils/contest_table_provider.ts (12 hunks)
  • src/test/lib/utils/contest_table_provider.test.ts (7 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: preview
🔇 Additional comments (1)
docs/dev-notes/2025-11-12/add_provider_key_for_contest_table_provider/plan.md (1)

1-323: Implementation successfully aligns with plan specifications—all key requirements verified.

The planning document's specifications are correctly implemented:

  • ProviderKey type (src/lib/types/contest_table_provider.ts:76): Defined as template literal union \${ContestType}` | `${ContestType}::${string}`` ✓
  • ContestTableProviderBase: section property marked readonly, static createProviderKey() and protected getProviderKey() methods implemented with correct return type ✓
  • Tessoku Book providers: All three subclasses (Examples, Practicals, Challenges) correctly pass section identifiers ('examples', 'practicals', 'challenges') to parent constructor ✓
  • ContestTableProviderGroup: addProvider() and addProviders() methods correctly use bracket notation (provider['getProviderKey']()) to access protected method ✓
  • Test coverage: "Provider key functionality" describe block verifies simple keys, composite keys, multiple provider registration, and backward compatibility ✓

The implementation maintains backward compatibility, achieves type safety through template literals, and properly separates concerns via protected method abstraction. The plan's completion report appears accurate.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 10b49c1 and 95bb5a5.

📒 Files selected for processing (2)
  • docs/dev-notes/2025-11-12/add_provider_key_for_contest_table_provider/plan.md (1 hunks)
  • src/lib/utils/contest_table_provider.ts (12 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: preview

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/lib/utils/contest_table_provider.ts (1)

307-371: LGTM: Section-specific providers correctly implemented.

The three providers properly extend TessokuBookProvider and implement section-specific filtering. The filtering logic correctly combines the base contest type check with prefix matching on task_table_index.

Optional: Consider extracting section constants for type safety.

The section strings ('examples', 'practicals', 'challenges') are currently hardcoded in constructors. For improved maintainability and type safety, consider defining them as constants:

const TESSOKU_SECTIONS = {
  EXAMPLES: 'examples',
  PRACTICALS: 'practicals',
  CHALLENGES: 'challenges',
} as const;

Then use in constructors:

 export class TessokuBookForExamplesProvider extends TessokuBookProvider {
   constructor(contestType: ContestType) {
-    super(contestType, 'examples');
+    super(contestType, TESSOKU_SECTIONS.EXAMPLES);
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 95bb5a5 and 2c87855.

📒 Files selected for processing (2)
  • docs/dev-notes/2025-11-12/add_provider_key_for_contest_table_provider/plan.md (1 hunks)
  • src/lib/utils/contest_table_provider.ts (13 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/dev-notes/2025-11-12/add_provider_key_for_contest_table_provider/plan.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: preview
🔇 Additional comments (8)
src/lib/utils/contest_table_provider.ts (8)

33-45: LGTM: Clean refactoring to support sectioned providers.

The addition of the optional section field and making contestType readonly are well-designed. The readonly modifier prevents accidental mutations, and the optional section maintains backward compatibility for providers that don't need section-based filtering.


47-66: LGTM: Provider key generation properly implemented.

The static createProviderKey and instance getProviderKey methods are well-designed. Making getProviderKey public resolves the previous TypeScript compilation issue, and the conditional formatting (contestType::section vs plain contestType) is clean and logical.


267-277: LGTM: Excellent documentation of architectural intent.

The JSDoc clearly documents that TessokuBookProvider serves as a base class for section-specific providers and that callers should use section-qualified lookups. This addresses the backward compatibility concern from the previous review and provides valuable context for future maintainers.


544-577: LGTM: Provider registration API correctly refactored.

The changes to use string-based keys and provider-derived keys are well-implemented:

  • Changing the Map to Map<string, ContestTableProviderBase> supports composite provider keys
  • Both addProvider and addProviders correctly use provider.getProviderKey() for keying
  • The variadic signature for addProviders is cleaner than accepting an array

587-590: LGTM: Backward-compatible section-aware lookup.

The updated getProvider method properly supports optional section lookups while maintaining backward compatibility. Using createProviderKey ensures the lookup key format is consistent with registration.


632-636: LGTM: Stats correctly expose provider keys.

Updating getStats to include providerKey from the map entries provides better visibility into the actual keys being used, which is helpful for debugging and introspection of the provider system.


690-694: LGTM: TessokuBook sectioned providers correctly registered.

The TessokuBook preset correctly uses addProviders to register all three section-specific providers (examples, practicals, challenges). This aligns with the documented design where only section-specific providers are registered, not the base TessokuBookProvider.


654-722: LGTM: All preset registrations properly updated.

All provider preset functions have been correctly updated to use the new API:

  • Single-provider groups use addProvider with provider instances
  • Multi-provider groups use addProviders with multiple instances
  • All provider instantiations correctly pass ContestType arguments

The refactoring maintains consistency across all preset definitions.

@KATO-Hiro
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 12, 2025

✅ Actions performed

Review triggered.

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/test/lib/utils/contest_table_provider.test.ts (1)

1111-1125: Simplify method calls by removing unnecessary bracket notation.

Lines 1116, 1119, and 1122 use bracket notation provider['getProviderKey'](), but getProviderKey() is now a public method (see Line 65 in the main file). Call it directly for better readability and consistency.

Apply this diff:

-      expect(examplesProvider['getProviderKey']()).toBe(
+      expect(examplesProvider.getProviderKey()).toBe(
         `TESSOKU_BOOK::${TESSOKU_SECTIONS.EXAMPLES}`,
       );
-      expect(practicalsProvider['getProviderKey']()).toBe(
+      expect(practicalsProvider.getProviderKey()).toBe(
         `TESSOKU_BOOK::${TESSOKU_SECTIONS.PRACTICALS}`,
       );
-      expect(challengesProvider['getProviderKey']()).toBe(
+      expect(challengesProvider.getProviderKey()).toBe(
         `TESSOKU_BOOK::${TESSOKU_SECTIONS.CHALLENGES}`,
       );
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 34513b4 and e5ce308.

📒 Files selected for processing (4)
  • docs/dev-notes/2025-11-12/add_provider_key_for_contest_table_provider/plan.md (1 hunks)
  • src/lib/types/contest_table_provider.ts (2 hunks)
  • src/lib/utils/contest_table_provider.ts (13 hunks)
  • src/test/lib/utils/contest_table_provider.test.ts (7 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/types/contest_table_provider.ts
🔇 Additional comments (9)
src/lib/utils/contest_table_provider.ts (5)

1-9: LGTM! Clean import additions for provider key functionality.

The new imports for ProviderKey and TESSOKU_SECTIONS are properly structured and support the provider key mechanism.


33-67: Excellent design! Provider key mechanism is well-implemented.

The changes properly introduce section-aware provider keys with:

  • Immutable contestType and section fields
  • Static createProviderKey() for centralized key generation
  • Public getProviderKey() for external access (resolves previous protected access issue)

The implementation maintains clean separation of concerns and enables multiple providers per contest type.


306-370: Well-structured sectioned providers!

The three TessokuBook subclasses are properly implemented with:

  • Clear section identifiers passed to the base constructor
  • Appropriate filtering logic based on task_table_index prefixes (A, B, C)
  • Descriptive metadata for each section

The inheritance pattern maintains code reusability while enabling section-specific behavior.


540-638: Solid refactoring to support provider keys!

The ContestTableProviderGroup changes are well-executed:

  • Map storage correctly switched to Map<string, ContestTableProviderBase>
  • Methods properly derive keys from providers via getProviderKey()
  • getProvider(contestType, section?) maintains backward compatibility
  • Stats output updated to reflect providerKey

The implementation cleanly supports multiple providers per contest type while preserving existing API contracts.


687-695: Proper preset configuration with clear documentation!

The TessokuBook group correctly registers three sectioned providers with explanatory comments about the design decision. The comment addresses the backward compatibility concern raised in previous reviews.

src/test/lib/utils/contest_table_provider.test.ts (3)

1-24: LGTM! Test imports properly updated.

The new imports correctly include the sectioned provider classes and TESSOKU_SECTIONS constant needed for comprehensive testing.


1093-1182: Excellent test coverage for provider key functionality!

The new test suite comprehensively validates:

  • Simple and composite key generation
  • Sectioned provider key retrieval
  • Multiple providers stored separately
  • Backward compatibility (section-less lookups)
  • Non-existent section handling

The tests provide strong confidence in the provider key mechanism.


1248-1266: Proper test update for sectioned TessokuBook providers!

The test correctly verifies that the TessokuBook preset now creates three sectioned providers with appropriate type assertions for each section.

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

1-482: Comprehensive and well-structured documentation!

The plan document thoroughly covers the provider key mechanism implementation, including:

  • Clear background and objectives
  • Detailed specification and implementation steps
  • Test strategy and verification approach
  • Lessons learned and backward compatibility considerations
  • TESSOKU_SECTIONS constant usage guidelines

This documentation will be valuable for future maintainers understanding the design decisions.

Copy link
Collaborator Author

@KATO-Hiro KATO-Hiro left a comment

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 f6cdcb9 into staging Nov 12, 2025
3 checks passed
@KATO-Hiro KATO-Hiro deleted the #2819 branch November 12, 2025 11:10
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.

[UI / UX] コンテスト別・鉄則本をA・B・Cで別のテーブルに分けましょう

1 participant