Skip to content

fix: redefine daxue sections - #133

Merged
rindrics merged 3 commits into
mainfrom
issue-90
Feb 13, 2026
Merged

fix: redefine daxue sections#133
rindrics merged 3 commits into
mainfrom
issue-90

Conversation

@rindrics

@rindrics rindrics commented Feb 13, 2026

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features

    • Added customizable section labels for classical texts (篇, 章, 経).
    • Expanded hierarchical organization with more granular chapter breakdowns for select texts.
  • Improvements

    • Navigation labels now dynamically adapt to different section types instead of using fixed terminology.
    • Updated UI headers and descriptions to reflect section-specific naming conventions.

@coderabbitai

coderabbitai Bot commented Feb 13, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR introduces a customizable sectionLabel field to support dynamic section naming across classic texts. The label (e.g., "編", "章", "篇") is added to book metadata in the YAML configuration, propagated through the generation pipeline, type definitions, and UI components that display section navigation and metadata.

Changes

Cohort / File(s) Summary
Type Definitions
src/types/book.ts, scripts/generate-contents.ts
Added optional sectionLabel?: string property to InputBook and OutputBook interfaces to carry section label metadata through the generation pipeline.
Book Metadata & Content
contents/books.yaml
Added sectionLabel fields to multiple book entries (篇, 章, 経) and restructured hierarchies for daxue and zhongyong, expanding from single sections to multi-chapter structures with updated totalSections values.
UI Components - Page Metadata & Headings
src/app/books/[bookId]/page.tsx, src/app/books/[bookId]/[sectionId]/page.tsx, src/app/page.tsx
Updated metadata descriptions and page headings to use dynamic sectionLabel instead of hard-coded "編", affecting section listing headers, navigation labels, and description text across three page components.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

Review effort 3/5

Poem

🐰 A label for each tome, from 編 to 篇,
No more hard-coded names of old—
Dynamic labels dance, section by section,
Through scripts and types, a story told,
The classics now speak in customized voice! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'fix: redefine daxue sections' covers only one aspect of the changeset; the PR also redefines zhongyong sections and introduces a sectionLabel field across multiple files. Consider a more comprehensive title like 'fix: add sectionLabel and restructure daxue and zhongyong sections' to better reflect the full scope of changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch issue-90

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.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Review Summary by Qodo

Add sectionLabel to books and redefine daxue/zhongyong sections

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add sectionLabel field to book schema for flexible section naming
• Redefine daxue sections from 1 to 6 chapters structure
• Redefine zhongyong sections from 1 to 19 chapters structure
• Add section labels to all classical texts (篇, 章, 経)
• Update UI to dynamically display section labels instead of hardcoded text
Diagram
flowchart LR
  A["Book Schema"] -->|"Add sectionLabel field"| B["Updated Book Interface"]
  C["YAML Data"] -->|"Add sectionLabel values"| D["Enhanced Book Definitions"]
  D -->|"Redefine sections"| E["Daxue: 1→6 sections<br/>Zhongyong: 1→19 sections"]
  B -->|"Use dynamic labels"| F["UI Components"]
  F -->|"Display flexible labels"| G["Section Pages & Metadata"]
Loading

Grey Divider

File Changes

1. src/types/book.ts ✨ Enhancement +1/-0

Add sectionLabel field to Book interface

• Add optional sectionLabel field to Book interface with JSDoc comment
• Field stores display label for sections (e.g., "編", "章", "篇")

src/types/book.ts


2. scripts/generate-contents.ts ✨ Enhancement +3/-0

Add sectionLabel to book generation interfaces

• Add sectionLabel field to InputBook interface
• Add sectionLabel field to OutputBook interface
• Map sectionLabel from input books to output books in generation logic

scripts/generate-contents.ts


3. contents/books.yaml ⚙️ Configuration changes +84/-6

Redefine daxue/zhongyong sections and add labels

• Add sectionLabel: 篇 to lunyu and mengzi books
• Add sectionLabel: 章 to daxue and zhongyong books
• Redefine daxue from 1 section (11 chapters) to 6 sections (3,4,1,1,2,4 chapters)
• Redefine zhongyong from 1 section (33 chapters) to 19 sections (1 chapter each)
• Add sectionLabel to yijing (経), shujing (篇), shijing (篇), liji (篇), chunqiu (篇)

contents/books.yaml


View more (3)
4. src/app/books/[bookId]/[sectionId]/page.tsx ✨ Enhancement +10/-4

Use dynamic sectionLabel in section page

• Use dynamic sectionLabel from book data instead of hardcoded "編"
• Update error message from "編が見つかりません" to "セクションが見つかりません"
• Update navigation labels to use dynamic section label in prev/next buttons
• Remove book-specific text from metadata description

src/app/books/[bookId]/[sectionId]/page.tsx


5. src/app/books/[bookId]/page.tsx ✨ Enhancement +3/-2

Use dynamic sectionLabel in book page

• Add dynamic sectionLabel variable with fallback to "編"
• Update metadata description to use dynamic section label
• Update section list heading to display dynamic label instead of hardcoded "編一覧"

src/app/books/[bookId]/page.tsx


6. src/app/page.tsx ✨ Enhancement +3/-2

Use dynamic sectionLabel in home page

• Add sectionLabel variable with fallback to "編"
• Update progress text to use dynamic section label for multi-section books
• Update disabled text to use dynamic section label

src/app/page.tsx


Grey Divider

Qodo Logo

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit fb26a1a):

https://izuminokami-kanesada--pr133-issue-90-6s25qnf3.web.app

(expires Fri, 20 Feb 2026 03:30:34 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: 4c4412227845b968bcb4c8b6996048cdd07fd6de

@rindrics
rindrics merged commit 844a2dc into main Feb 13, 2026
5 of 6 checks passed
@rindrics
rindrics deleted the issue-90 branch February 13, 2026 03:31
@rindrics rindrics mentioned this pull request Feb 13, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@contents/books.yaml`:
- Around line 117-141: The books.yaml defines daxue with six sections and
zhongyong with nineteen, but the input content only exists under
contents/input/daxue/1/1.yaml and contents/input/zhongyong/1/1.yaml; fix by
reorganizing the input directory structure to match those section definitions:
create directories contents/input/daxue/2 through contents/input/daxue/6 and
contents/input/zhongyong/2 through contents/input/zhongyong/19, then move or
split the appropriate chapter YAML files into each section directory so that
each section directory contains its chapter files (e.g.,
contents/input/daxue/3/1.yaml for daxue section id '3'); ensure file names and
IDs match the section ids listed in books.yaml so the content generator can find
files for functions/process that read those paths.

In `@src/app/books/`[bookId]/[sectionId]/page.tsx:
- Line 39: In generateMetadata, the local variable sectionLabel (declared as
const sectionLabel = book.sectionLabel ?? '編') is unused; either remove that
declaration from generateMetadata or use sectionLabel when building the
title/description (e.g., incorporate sectionLabel into the title/description
construction where book.title and sectionTitle are combined). Update the
generateMetadata function to reference sectionLabel (or delete the const) so
there are no unused variables.
🧹 Nitpick comments (2)
src/app/books/[bookId]/page.tsx (1)

120-120: Extract sectionLabel to a local variable for consistency.

The generateMetadata function (Line 30) already extracts this to a const sectionLabel, but the render function repeats the inline fallback book.sectionLabel ?? '編'. For consistency with the other page files (page.tsx, [sectionId]/page.tsx) that use a local variable, consider doing the same here.

♻️ Suggested change

Add a local variable in BookPage (e.g., after Line 57) and use it at Line 120:

   const { prev, next } = getAdjacentBookIds(bookId);
+  const sectionLabel = book.sectionLabel ?? '編';

   const prevBook = prev ? getBookById(prev) : null;
-          {book.sectionLabel ?? '編'}一覧
+          {sectionLabel}一覧
src/app/books/[bookId]/[sectionId]/page.tsx (1)

105-105: Hardcoded '編' in fallback labels is inconsistent with dynamic sectionLabel.

The fallback strings '前の編' (Line 105) and '次の編' (Line 118) still use the hardcoded '編'. While these are effectively unreachable (the parent conditional ensures prevUrl/nextUrl are non-null only when the labels are defined), they'd be incorrect if the code were ever restructured. Consider using the dynamic label for defensive consistency.

♻️ Suggested change
-              <span>{prevLabel ?? '前の編'}</span>
+              <span>{prevLabel ?? `前の${sectionLabel}`}</span>
-              <span>{nextLabel ?? '次の編'}</span>
+              <span>{nextLabel ?? `次の${sectionLabel}`}</span>

Also applies to: 118-118

Comment thread contents/books.yaml
Comment on lines 117 to 141
- id: daxue
name: 大学
compositionYear: -450 # 曾子の作とされる
totalSections: 1
sectionLabel: 章
totalSections: 6
sections:
- id: '1'
name: 大学
totalChapters: 11
name: 第一章
totalChapters: 3
- id: '2'
name: 第二章
totalChapters: 4
- id: '3'
name: 第三章
totalChapters: 1
- id: '4'
name: 第四章
totalChapters: 1
- id: '5'
name: 第五章
totalChapters: 2
- id: '6'
name: 第六章
totalChapters: 4

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the directory structure under contents/input/daxue/
echo "=== daxue directory structure ==="
fd . contents/input/daxue/ --type f 2>/dev/null || echo "No daxue input directory found"
echo ""
echo "=== zhongyong directory structure ==="
fd . contents/input/zhongyong/ --type f 2>/dev/null || echo "No zhongyong input directory found"

Repository: Rindrics/izuminokami-kanesada

Length of output: 209


Input directory structure does not match the new daxue and zhongyong section definitions.

The YAML defines daxue with 6 sections and zhongyong with 19 sections, but the input directories contain only contents/input/daxue/1/1.yaml and contents/input/zhongyong/1/1.yaml. The content generation script will not find files for sections 2-6 (daxue) and 2-19 (zhongyong), leaving these sections empty. Reorganize the input files to match the new section structure: contents/input/daxue/1/, contents/input/daxue/2/, ..., contents/input/daxue/6/ and similarly for zhongyong.

🤖 Prompt for AI Agents
In `@contents/books.yaml` around lines 117 - 141, The books.yaml defines daxue
with six sections and zhongyong with nineteen, but the input content only exists
under contents/input/daxue/1/1.yaml and contents/input/zhongyong/1/1.yaml; fix
by reorganizing the input directory structure to match those section
definitions: create directories contents/input/daxue/2 through
contents/input/daxue/6 and contents/input/zhongyong/2 through
contents/input/zhongyong/19, then move or split the appropriate chapter YAML
files into each section directory so that each section directory contains its
chapter files (e.g., contents/input/daxue/3/1.yaml for daxue section id '3');
ensure file names and IDs match the section ids listed in books.yaml so the
content generator can find files for functions/process that read those paths.

return { title: 'セクションが見つかりません' };
}

const sectionLabel = book.sectionLabel ?? '編';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Unused variable sectionLabel in generateMetadata.

sectionLabel is declared on Line 39 but never referenced in the description or title construction (Lines 40–41). Either remove it or incorporate it into the description if that was the intent.

🔧 Remove unused variable
-  const sectionLabel = book.sectionLabel ?? '編';
   const title = `${section.name} - ${book.name}`;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const sectionLabel = book.sectionLabel ?? '編';
const title = `${section.name} - ${book.name}`;
🤖 Prompt for AI Agents
In `@src/app/books/`[bookId]/[sectionId]/page.tsx at line 39, In generateMetadata,
the local variable sectionLabel (declared as const sectionLabel =
book.sectionLabel ?? '編') is unused; either remove that declaration from
generateMetadata or use sectionLabel when building the title/description (e.g.,
incorporate sectionLabel into the title/description construction where
book.title and sectionTitle are combined). Update the generateMetadata function
to reference sectionLabel (or delete the const) so there are no unused
variables.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (2)

Grey Divider


Action required

1. liji section name redundant 📎 Requirement gap ✓ Correctness
Description
liji is still defined with a single section whose name equals book.name, which can keep the
redundant UI hierarchy (e.g., 礼記 → 礼記 → ...). This does not satisfy the requirement to eliminate
consecutive book.name/section.name duplication for 礼記.
Code

contents/books.yaml[258]

+  sectionLabel: 篇
Evidence
PR Compliance ID 7 requires that for 大学・中庸・礼記, book.name and an identically-named section do not
appear consecutively in the UI. In contents/books.yaml, liji remains name: 礼記 and its only
section also remains name: 礼記, meaning the redundant 礼記 → 礼記 structure can still occur.

単一セクション書籍で「book.name と同名 section」による冗長表示を発生させない
contents/books.yaml[256-263]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`liji`(礼記)が単一セクションかつ `section.name === book.name` のため、UIで `礼記 → 礼記 → ...` の冗長な階層表示が発生し得ます。

## Issue Context
PR Compliance ID 7 では、大学・中庸・礼記において `book.name` と同文言の `section` が連続表示されないことが要件です。

## Fix Focus Areas
- contents/books.yaml[256-263]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Daxue/Zhongyong still sectioned 📎 Requirement gap ✓ Correctness
Description
大学・中庸について、section無し(または空セクション)で章を扱える形(A案/B案)になっておらず、複数の命名セクションを導入しています. This does not meet the
checklist requirement that UI should be able to treat them as having no sections (or an empty
section) without inconsistency.
Code

contents/books.yaml[R120-146]

+  sectionLabel: 章
+  totalSections: 6
  sections:
    - id: '1'
-      name: 大学
-      totalChapters: 11
+      name: 第一章
+      totalChapters: 3
+    - id: '2'
+      name: 第二章
+      totalChapters: 4
+    - id: '3'
+      name: 第三章
+      totalChapters: 1
+    - id: '4'
+      name: 第四章
+      totalChapters: 1
+    - id: '5'
+      name: 第五章
+      totalChapters: 2
+    - id: '6'
+      name: 第六章
+      totalChapters: 4

- id: zhongyong
  name: 中庸
  compositionYear: -430 # 子思の作とされる
-  totalSections: 1
+  sectionLabel: 章
+  totalSections: 19
Evidence
PR Compliance ID 8 requires adopting either (A) a true no-section definition (e.g., `totalSections:
0, sections: []`) or (B) a single empty-named section treated as 'no section' in the UI for 大学・中庸.
The updated definitions instead set sectionLabel: 章 and create multiple named sections (e.g.,
第一章, 第二章...), which is neither A nor B.

セクション無し(または空セクション)でも章を扱えるようにし、UI上はセクション無しとして表示できる
contents/books.yaml[117-146]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
大学・中庸の構造が、要件で提示された A案(section無し)/B案(空セクションをUI上section無し扱い)のどちらにもなっておらず、複数の命名セクションを作っています。

## Issue Context
PR Compliance ID 8 は、大学・中庸を「sectionなしでも章を扱える」か「空セクションでUI上はsection無し表示」にすることを求めています。

## Fix Focus Areas
- contents/books.yaml[117-146]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Unused sectionLabel in metadata 🐞 Bug ⛯ Reliability
Description
generateMetadata in the section page declares sectionLabel but never uses it. With Biome linter
enabled (recommended rules) and CI running biome check src, this will fail lint and block
merges/builds.
Code

src/app/books/[bookId]/[sectionId]/page.tsx[39]

+  const sectionLabel = book.sectionLabel ?? '編';
Evidence
The section page metadata function defines sectionLabel and does not reference it afterwards,
which is flagged by the repo’s Biome lint setup that runs in CI.

src/app/books/[bookId]/[sectionId]/page.tsx[30-42]
biome.json[1-8]
package.json[7-25]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`src/app/books/[bookId]/[sectionId]/page.tsx` defines `sectionLabel` inside `generateMetadata`, but the variable is unused. With Biome recommended lint rules enabled and CI running `biome check src`, this will fail lint.

### Issue Context
`sectionLabel` is used later in the page component for prev/next labels, but not in the `generateMetadata` function scope.

### Fix Focus Areas
- src/app/books/[bookId]/[sectionId]/page.tsx[30-47]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Hardcoded 編 ignores sectionLabel 🐞 Bug ✓ Correctness
Description
This PR introduces sectionLabel values like 篇/章/経 in books.yaml, but other UI surfaces still
hardcode "編" for section labeling. This will produce inconsistent/incorrect labels (e.g., stats and
collection badges) for books whose section label isn’t "編".
Code

contents/books.yaml[4]

+  sectionLabel: 篇
Evidence
contents/books.yaml now defines section labels that differ from "編" (e.g., 論語=篇, 大学=章, 易経=経).
However, multiple UI components still render section labels with hardcoded "編", so they will not
reflect the new per-book label.

contents/books.yaml[1-5]
contents/books.yaml[117-126]
contents/books.yaml[208-212]
src/app/stats/page.tsx[86-104]
src/app/stats/page.tsx[280-289]
src/components/CollectionDetailModal.tsx[108-111]
src/app/char/[char]/CharContentList.tsx[55-69]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
After introducing per-book `sectionLabel` (篇/章/経), several UI areas still hardcode &quot;編&quot; when labeling sections. This creates inconsistent/incorrect labeling for books whose section label differs.

### Issue Context
Main book/section pages and home now use `book.sectionLabel ?? &#x27;編&#x27;`, but stats and collection-related components still display &quot;編&quot;.

### Fix Focus Areas
- src/app/stats/page.tsx[76-104]
- src/app/stats/page.tsx[280-290]
- src/components/CollectionDetailModal.tsx[108-112]
- src/components/PublicCollectionDetailModal.tsx[78-82]
- src/app/char/[char]/CharContentList.tsx[55-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment thread contents/books.yaml

- id: liji
name: 礼記
sectionLabel: 篇

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. liji section name redundant 📎 Requirement gap ✓ Correctness

liji is still defined with a single section whose name equals book.name, which can keep the
redundant UI hierarchy (e.g., 礼記 → 礼記 → ...). This does not satisfy the requirement to eliminate
consecutive book.name/section.name duplication for 礼記.
Agent Prompt
## Issue description
`liji`(礼記)が単一セクションかつ `section.name === book.name` のため、UIで `礼記 → 礼記 → ...` の冗長な階層表示が発生し得ます。

## Issue Context
PR Compliance ID 7 では、大学・中庸・礼記において `book.name` と同文言の `section` が連続表示されないことが要件です。

## Fix Focus Areas
- contents/books.yaml[256-263]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread contents/books.yaml
Comment on lines +120 to +146
sectionLabel: 章
totalSections: 6
sections:
- id: '1'
name: 大学
totalChapters: 11
name: 第一章
totalChapters: 3
- id: '2'
name: 第二章
totalChapters: 4
- id: '3'
name: 第三章
totalChapters: 1
- id: '4'
name: 第四章
totalChapters: 1
- id: '5'
name: 第五章
totalChapters: 2
- id: '6'
name: 第六章
totalChapters: 4

- id: zhongyong
name: 中庸
compositionYear: -430 # 子思の作とされる
totalSections: 1
sectionLabel: 章
totalSections: 19

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. Daxue/zhongyong still sectioned 📎 Requirement gap ✓ Correctness

大学・中庸について、section無し(または空セクション)で章を扱える形(A案/B案)になっておらず、複数の命名セクションを導入しています. This does not meet the
checklist requirement that UI should be able to treat them as having no sections (or an empty
section) without inconsistency.
Agent Prompt
## Issue description
大学・中庸の構造が、要件で提示された A案(section無し)/B案(空セクションをUI上section無し扱い)のどちらにもなっておらず、複数の命名セクションを作っています。

## Issue Context
PR Compliance ID 8 は、大学・中庸を「sectionなしでも章を扱える」か「空セクションでUI上はsection無し表示」にすることを求めています。

## Fix Focus Areas
- contents/books.yaml[117-146]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

return { title: 'セクションが見つかりません' };
}

const sectionLabel = book.sectionLabel ?? '編';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

3. Unused sectionlabel in metadata 🐞 Bug ⛯ Reliability

generateMetadata in the section page declares sectionLabel but never uses it. With Biome linter
enabled (recommended rules) and CI running biome check src, this will fail lint and block
merges/builds.
Agent Prompt
### Issue description
`src/app/books/[bookId]/[sectionId]/page.tsx` defines `sectionLabel` inside `generateMetadata`, but the variable is unused. With Biome recommended lint rules enabled and CI running `biome check src`, this will fail lint.

### Issue Context
`sectionLabel` is used later in the page component for prev/next labels, but not in the `generateMetadata` function scope.

### Fix Focus Areas
- src/app/books/[bookId]/[sectionId]/page.tsx[30-47]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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.

1 participant