Skip to content

fix(file): update file type and size retrieval to use primaryFile structure#383

Merged
balazs-szucs merged 1 commit into
grimmory-tools:developfrom
balazs-szucs:fix-filetype-predicate
Apr 4, 2026
Merged

fix(file): update file type and size retrieval to use primaryFile structure#383
balazs-szucs merged 1 commit into
grimmory-tools:developfrom
balazs-szucs:fix-filetype-predicate

Conversation

@balazs-szucs

@balazs-szucs balazs-szucs commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

Description

Linked Issue: Fixes #

Changes

This pull request updates how file-related attributes are accessed for books, moving from top-level fields like bookType and fileSizeKb to retrieving these values from the primaryFile property on the frontend and from the bookFiles relationship on the backend. This change improves consistency with the data model and prepares the codebase for handling books with multiple files. The test suite has also been updated to reflect these changes.

Essentially fixes filetype filters.

Summary by CodeRabbit

  • Bug Fixes
    • File type and file size filtering in book rules now correctly source from associated file data, improving the accuracy of rule-based filtering operations.

@coderabbitai

coderabbitai Bot commented Apr 4, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The changes refactor how file-related rule fields (FILE_TYPE, FILE_SIZE) are evaluated across the backend and frontend. In the backend, SQL expressions now derive these values from an optional bookFiles association using LEFT joins instead of direct BookEntity attributes. In the frontend, rule evaluation and tests have been updated to source fileType from book.primaryFile?.bookType rather than top-level book attributes.

Changes

Cohort / File(s) Summary
Backend SQL Rule Evaluation
booklore-api/src/main/java/org/booklore/service/BookRuleEvaluatorService.java
Updated FILE_SIZE and FILE_TYPE rule-field criteria to derive values from LEFT-joined bookFiles association instead of direct BookEntity attributes; changes SQL join paths and row matching behavior when bookFiles are absent.
Frontend Rule Evaluation
frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.ts
Modified fileType rule evaluation to source from book.primaryFile?.bookType instead of top-level book['bookType'] for both normalized comparison arrays and scalar value extraction.
Frontend Test Fixtures
frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.spec.ts
Updated test fixture createBook and all fileType-based assertions to derive format/type from primaryFile.bookType instead of top-level attributes; test data shape now aligns with primaryFile-centric model.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

frontend, backend, enhancement

Poem

🐰 From attributes to associations we hop,
Where primaryFile and bookFiles now stop,
Left joins and nullable paths intertwine,
Rule fields are fresher, their sources align!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
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
Title check ✅ Passed The PR title follows conventional commit format with scope 'file' and describes the main change of updating file type and size retrieval to use primaryFile structure.
Description check ✅ Passed The PR description is complete with all required template sections filled out, including description of changes and a clear explanation of the purpose and scope of the updates.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

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.

@balazs-szucs

Copy link
Copy Markdown
Contributor Author

I think there may be more to this, though.

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
booklore-api/src/main/java/org/booklore/service/BookRuleEvaluatorService.java (1)

774-817: ⚠️ Potential issue | 🟠 Major

Constrain bookFiles to a single primary row before evaluating file rules.

Line 774 and Line 817 join the full one-to-many bookFiles collection, so rule evaluation can match a non-primary file when a book has multiple files. That can make backend filtering diverge from frontend behavior (primaryFile) and return incorrect fileType/fileSize matches.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@booklore-api/src/main/java/org/booklore/service/BookRuleEvaluatorService.java`
around lines 774 - 817, The switch is joining the whole one-to-many bookFiles
collection (root.join("bookFiles", JoinType.LEFT)) so file-based rules can match
non-primary files; change to join only the primary file by creating a single
Join<?,?> primaryBookFileJoin = root.join("bookFiles", JoinType.LEFT) and apply
an ON predicate for the primary flag (e.g.,
primaryBookFileJoin.on(cb.isTrue(primaryBookFileJoin.get("primaryFile"))) or
equivalent CriteriaBuilder predicate/subquery), then replace all occurrences
that reference root.join("bookFiles", JoinType.LEFT) (used for FILE_SIZE,
AUDIOBOOK_DURATION, AUDIOBOOK_CODEC, AUDIOBOOK_CHAPTER_COUNT, AUDIOBOOK_BITRATE,
FILE_TYPE, etc.) to use primaryBookFileJoin so fileType/fileSize/duration/codec
lookups use the constrained primary file; keep READING_PROGRESS and other
non-file joins unchanged.
🧹 Nitpick comments (1)
frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.spec.ts (1)

17-17: Consider removing default primaryFile.fileSizeKb from fixture to avoid masked assertions.

A default size of 1024 can let file-size tests pass even when a test accidentally sets deprecated top-level fileSizeKb instead of primaryFile.fileSizeKb. Prefer setting fileSizeKb explicitly per file-size test.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.spec.ts`
at line 17, The fixture currently sets primaryFile.fileSizeKb = 1024 which can
mask bugs; remove the default fileSizeKb from the primaryFile object in the test
fixture (the object with key primaryFile) and update any tests that rely on a
size to set primaryFile.fileSizeKb explicitly inside those test cases; also
audit assertions to ensure they reference primaryFile.fileSizeKb (not any
deprecated top-level fileSizeKb) in BookRuleEvaluatorService specs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In
`@booklore-api/src/main/java/org/booklore/service/BookRuleEvaluatorService.java`:
- Around line 774-817: The switch is joining the whole one-to-many bookFiles
collection (root.join("bookFiles", JoinType.LEFT)) so file-based rules can match
non-primary files; change to join only the primary file by creating a single
Join<?,?> primaryBookFileJoin = root.join("bookFiles", JoinType.LEFT) and apply
an ON predicate for the primary flag (e.g.,
primaryBookFileJoin.on(cb.isTrue(primaryBookFileJoin.get("primaryFile"))) or
equivalent CriteriaBuilder predicate/subquery), then replace all occurrences
that reference root.join("bookFiles", JoinType.LEFT) (used for FILE_SIZE,
AUDIOBOOK_DURATION, AUDIOBOOK_CODEC, AUDIOBOOK_CHAPTER_COUNT, AUDIOBOOK_BITRATE,
FILE_TYPE, etc.) to use primaryBookFileJoin so fileType/fileSize/duration/codec
lookups use the constrained primary file; keep READING_PROGRESS and other
non-file joins unchanged.

---

Nitpick comments:
In
`@frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.spec.ts`:
- Line 17: The fixture currently sets primaryFile.fileSizeKb = 1024 which can
mask bugs; remove the default fileSizeKb from the primaryFile object in the test
fixture (the object with key primaryFile) and update any tests that rely on a
size to set primaryFile.fileSizeKb explicitly inside those test cases; also
audit assertions to ensure they reference primaryFile.fileSizeKb (not any
deprecated top-level fileSizeKb) in BookRuleEvaluatorService specs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 36fc821b-5a6a-458e-a5c1-3cb3016b2ac8

📥 Commits

Reviewing files that changed from the base of the PR and between be36d50 and bed3be3.

📒 Files selected for processing (3)
  • booklore-api/src/main/java/org/booklore/service/BookRuleEvaluatorService.java
  • frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.spec.ts
  • frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.ts
📜 Review details
⏰ 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). (3)
  • GitHub Check: Test Suite / Frontend Tests
  • GitHub Check: Test Suite / Backend Tests
  • GitHub Check: Analyze (java-kotlin)
🧰 Additional context used
📓 Path-based instructions (4)
frontend/src/**/*.{ts,tsx,html,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Use 2-space indentation in TypeScript, HTML, and SCSS files

Files:

  • frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.ts
  • frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.spec.ts
frontend/src/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

frontend/src/app/**/*.{ts,tsx}: Prefer inject() over constructor injection
Follow frontend/eslint.config.js: component selectors use app-*, directive selectors use app*, and any is disallowed

Files:

  • frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.ts
  • frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.spec.ts
booklore-api/src/**/*.java

📄 CodeRabbit inference engine (AGENTS.md)

booklore-api/src/**/*.java: Use 4-space indentation in Java files and match surrounding Java style
Prefer constructor injection via Lombok patterns already used in the codebase. Do not introduce @Autowired field injection
Use MapStruct for entity/DTO mapping

Files:

  • booklore-api/src/main/java/org/booklore/service/BookRuleEvaluatorService.java
frontend/src/**/*.{test,spec}.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use Vitest for tests in the frontend

Files:

  • frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.spec.ts
🧠 Learnings (1)
📚 Learning: 2026-04-04T14:03:24.311Z
Learnt from: balazs-szucs
Repo: grimmory-tools/grimmory PR: 372
File: frontend/src/app/features/book/service/app-books-api.service.ts:150-178
Timestamp: 2026-04-04T14:03:24.311Z
Learning: In `frontend/src/app/features/book/service/app-books-api.service.ts`, the `summaryToBook` function intentionally uses `as unknown as Book` to cast a partial object to the `Book` type. The returned object omits some required `Book` fields (e.g. `metadata.bookId`, `pdfProgress.page`) and includes an extra `bookFiles: []` property not in the `Book` interface. This is by design — consumers of `AppBooksApiService.books()` (e.g. `BookCardComponent`) only access the subset of properties that are populated from `AppBookSummary`, so no runtime issues occur. Do not flag this as a type safety error.

Applied to files:

  • frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.ts
  • frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.spec.ts
🔀 Multi-repo context grimmory-tools/grimmory-docs

Linked repositories findings

grimmory-tools/grimmory-docs

  • docs/magic-shelf.md — Field reference documents File Type (fileType) and File Size (fileSize) as first-class Magic Shelf fields and includes example rules that rely on them (e.g. EPUB filter, includes_any for comic formats, oversized-files > 102400 KB). These docs describe evaluation happening in the browser and show JSON rule examples using fileType/fileSize. [::grimmory-tools/grimmory-docs::docs/magic-shelf.md: "File & Identifiers" table, examples around lines ~120–140 and ~1290–1335]

  • docs/magic-shelf.md — Several example Magic Shelf JSON snippets (EPUB filter, comics filter, oversized files) explicitly use fileType and fileSize keys; these will depend on the frontend evaluator reading those fields from book.primaryFile rather than top-level book properties after this PR. [::grimmory-tools/grimmory-docs::docs/magic-shelf.md: examples at lines ~1298, ~1310, ~1320]

Relevance summary:

  • The documentation confirms the frontend/browser-side rule evaluator is expected to expose fileType and fileSize fields for rules. The PR’s change (frontend: source fileType/fileSize from book.primaryFile; backend: join bookFiles) aligns code with the documented rule keys but changes which books match when primaryFile/bookFiles are absent. Reviewers should ensure docs and example rules remain accurate and that consumers/readers of these docs/test fixtures reflect the primaryFile-centric model. [::grimmory-tools/grimmory-docs::docs/magic-shelf.md]
🔇 Additional comments (1)
frontend/src/app/features/magic-shelf/service/book-rule-evaluator.service.ts (1)

74-75: Primary-file field extraction looks correct and consistent.

These updates consistently source fileType/fileSize from book.primaryFile with null-safe access, matching the updated data model.

Also applies to: 278-280

@balazs-szucs balazs-szucs merged commit 4e9cf79 into grimmory-tools:develop Apr 4, 2026
14 checks passed
zachyale pushed a commit to zachyale/grimmory that referenced this pull request Apr 17, 2026
zachyale pushed a commit to zachyale/grimmory that referenced this pull request Apr 17, 2026
dsmouse pushed a commit to dsmouse/grimmory that referenced this pull request May 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants