Commit Graph

713 Commits

Author SHA1 Message Date
neon b08002000f build(docker): upgrade pgvector image to pg18
Upgrades all references of pgvector/pgvector from pg16 to pg18,
including docker-compose files and e2e testing environments.
Updates the development docker-compose to mount the postgres volume
at /var/lib/postgresql to align with pg18+ directory requirements.

Also adds `shrink-0` to WhatsNewDialog header and footer to resolve
a layout overflow glitch.
2026-07-04 21:21:08 +00:00
neon 7f28b40d1f feat(library): use configurable max upload size limit
Replace the hardcoded 500MB limit with a dynamic value from the application
settings to allow uploading files larger than 500MB.

Closes #550
2026-07-04 18:43:18 +00:00
neon 0c7817621b feat(kobo): clarify collection sync requirement in settings
Add a next steps checklist to the pairing success card and a permanent help card to the sync settings tab. Explain that books will only sync to the Kobo device if they are placed in a collection with Kobo sync enabled.

Closes #522
2026-07-04 18:16:29 +00:00
neon 68c8ab2f49 fix(reader): report frame index in fixed-layout contents
Ensure that fixed-layout EPUB content structures expose their frame index and overlayer attributes during retrieval. This prevents the navigation subsystem from falling back to the final page of the document due to unverified page position indexes.

Closes #541
2026-07-04 17:54:24 +00:00
neon 784d390671 fix(reader): update existing annotation instead of duplicating
Prevent duplicate annotations from being created when a user modifies the style or color of an existing highlight. Route the popover actions through a PATCH request on the existing annotation ID instead of invoking the creation flow.

Closes #543
2026-07-04 17:32:57 +00:00
neon 7ae98d3000 fix(metadata): fail hardcover progress sync when page count is missing
When a matched Hardcover edition was missing page counts, progress sync
would silently skip sending updates and save a null progress value to the
local DB. This caused the book to be perpetually stuck in a "Pending sync"
state and triggered endless redundant sync attempts.

We now throw a clear missing pages error during progress calculation to
correctly register the sync error state, log the failure, and trigger background
sync immediately when sync is first enabled for a book.

Closes #544
2026-07-04 17:12:18 +00:00
neon 4df0ed7423 fix(series): preserve book navigation context when navigating away
When transitioning from the series detail view to another view (like edit
metadata), route params update before the component unmounts. This causes
the seriesId computed property to change to null, triggering the seriesId
watcher to reload/reset the books state, which in turn calls setBookContext
with empty values.

Prevent this reset by ignoring null series IDs in both the seriesId watcher
and the books/total watcher, keeping the navigation context intact for the
next view.

Closes #540
2026-07-04 17:03:23 +00:00
neon 66f85cf6af fix(books): skip rename if metadata write fails
When saving metadata synchronously, if the file write operation fails, the rename operation is now skipped to avoid renaming a file that could be left in an inconsistent state.

Closes #532
2026-07-04 05:10:04 +00:00
neon 3db72ced64 fix(dashboard): exclude finished books from continue reading
The dashboard query now joins user book statuses to exclude books marked as 'read', 'skimmed', or 'abandoned' from the continue reading list.

Closes #528
2026-07-04 04:50:14 +00:00
dependabot[bot] 8cf88fb547 chore(deps): bump the production-dependencies group with 13 updates (#515)
Bumps the production-dependencies group with 13 updates:

| Package | From | To |
| --- | --- | --- |
| [@lucide/vue](https://github.com/lucide-icons/lucide/tree/HEAD/packages/vue) | `1.21.0` | `1.23.0` |
| [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) | `4.3.1` | `4.3.2` |
| [@tanstack/vue-virtual](https://github.com/TanStack/virtual/tree/HEAD/packages/vue-virtual) | `3.13.29` | `3.13.31` |
| [cronstrue](https://github.com/bradymholt/cRonstrue) | `3.20.0` | `3.24.0` |
| [driver.js](https://github.com/nilbuild/driver.js) | `1.4.0` | `1.6.0` |
| [reka-ui](https://github.com/unovue/reka-ui) | `2.10.0` | `2.10.1` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.3.1` | `4.3.2` |
| [vue](https://github.com/vuejs/core) | `3.5.38` | `3.5.39` |
| [@nestjs/swagger](https://github.com/nestjs/swagger) | `11.4.4` | `11.4.5` |
| [fastify](https://github.com/fastify/fastify) | `5.8.5` | `5.9.0` |
| [nodemailer](https://github.com/nodemailer/nodemailer) | `9.0.1` | `9.0.3` |
| [sharp](https://github.com/lovell/sharp) | `0.35.2` | `0.35.3` |
| [unzipper](https://github.com/ZJONSSON/node-unzipper) | `0.12.3` | `0.12.5` |


Updates `@lucide/vue` from 1.21.0 to 1.23.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.23.0/packages/vue)

Updates `@tailwindcss/vite` from 4.3.1 to 4.3.2
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.2/packages/@tailwindcss-vite)

Updates `@tanstack/vue-virtual` from 3.13.29 to 3.13.31
- [Release notes](https://github.com/TanStack/virtual/releases)
- [Changelog](https://github.com/TanStack/virtual/blob/main/packages/vue-virtual/CHANGELOG.md)
- [Commits](https://github.com/TanStack/virtual/commits/@tanstack/vue-virtual@3.13.31/packages/vue-virtual)

Updates `cronstrue` from 3.20.0 to 3.24.0
- [Release notes](https://github.com/bradymholt/cRonstrue/releases)
- [Changelog](https://github.com/bradymholt/cRonstrue/blob/main/CHANGELOG.md)
- [Commits](https://github.com/bradymholt/cRonstrue/compare/v3.20.0...v3.24.0)

Updates `driver.js` from 1.4.0 to 1.6.0
- [Release notes](https://github.com/nilbuild/driver.js/releases)
- [Commits](https://github.com/nilbuild/driver.js/compare/1.4.0...1.6.0)

Updates `reka-ui` from 2.10.0 to 2.10.1
- [Release notes](https://github.com/unovue/reka-ui/releases)
- [Commits](https://github.com/unovue/reka-ui/compare/v2.10.0...v2.10.1)

Updates `tailwindcss` from 4.3.1 to 4.3.2
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.2/packages/tailwindcss)

Updates `vue` from 3.5.38 to 3.5.39
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/compare/v3.5.38...v3.5.39)

Updates `@nestjs/swagger` from 11.4.4 to 11.4.5
- [Release notes](https://github.com/nestjs/swagger/releases)
- [Commits](https://github.com/nestjs/swagger/compare/11.4.4...11.4.5)

Updates `fastify` from 5.8.5 to 5.9.0
- [Release notes](https://github.com/fastify/fastify/releases)
- [Commits](https://github.com/fastify/fastify/compare/v5.8.5...v5.9.0)

Updates `nodemailer` from 9.0.1 to 9.0.3
- [Release notes](https://github.com/nodemailer/nodemailer/releases)
- [Changelog](https://github.com/nodemailer/nodemailer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodemailer/nodemailer/compare/v9.0.1...v9.0.3)

Updates `sharp` from 0.35.2 to 0.35.3
- [Release notes](https://github.com/lovell/sharp/releases)
- [Commits](https://github.com/lovell/sharp/compare/v0.35.2...v0.35.3)

Updates `unzipper` from 0.12.3 to 0.12.5
- [Release notes](https://github.com/ZJONSSON/node-unzipper/releases)
- [Commits](https://github.com/ZJONSSON/node-unzipper/commits)

---
updated-dependencies:
- dependency-name: "@lucide/vue"
  dependency-version: 1.23.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: "@tailwindcss/vite"
  dependency-version: 4.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: "@tanstack/vue-virtual"
  dependency-version: 3.13.31
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: cronstrue
  dependency-version: 3.24.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: driver.js
  dependency-version: 1.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: reka-ui
  dependency-version: 2.10.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: tailwindcss
  dependency-version: 4.3.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: vue
  dependency-version: 3.5.39
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: "@nestjs/swagger"
  dependency-version: 11.4.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: fastify
  dependency-version: 5.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: production-dependencies
- dependency-name: nodemailer
  dependency-version: 9.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: sharp
  dependency-version: 0.35.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
- dependency-name: unzipper
  dependency-version: 0.12.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: production-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-03 10:05:31 -06:00
dependabot[bot] fb3e5b96da chore(deps): bump the github-actions group with 5 updates (#514)
Bumps the github-actions group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [dorny/paths-filter](https://github.com/dorny/paths-filter) | `4.0.1` | `4.0.2` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `4.1.0` | `4.2.0` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `7.2.0` | `7.3.0` |
| [docker/login-action](https://github.com/docker/login-action) | `4.2.0` | `4.3.0` |
| [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) | `4.1.0` | `4.2.0` |


Updates `dorny/paths-filter` from 4.0.1 to 4.0.2
- [Release notes](https://github.com/dorny/paths-filter/releases)
- [Changelog](https://github.com/dorny/paths-filter/blob/master/CHANGELOG.md)
- [Commits](https://github.com/dorny/paths-filter/compare/fbd0ab8f3e69293af611ebaee6363fc25e6d187d...7b450fff21473bca461d4b92ce414b9d0420d706)

Updates `docker/setup-buildx-action` from 4.1.0 to 4.2.0
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5...bb05f3f5519dd87d3ba754cc423b652a5edd6d2c)

Updates `docker/build-push-action` from 7.2.0 to 7.3.0
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/f9f3042f7e2789586610d6e8b85c8f03e5195baf...53b7df96c91f9c12dcc8a07bcb9ccacbed38856a)

Updates `docker/login-action` from 4.2.0 to 4.3.0
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/650006c6eb7dba73a995cc03b0b2d7f5ca915bee...c99871dec2022cc055c062a10cc1a1310835ceb4)

Updates `docker/setup-qemu-action` from 4.1.0 to 4.2.0
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/06116385d9baf250c9f4dcb4858b16962ea869c3...96fe6ef7f33517b61c61be40b68a1882f3264fb8)

---
updated-dependencies:
- dependency-name: dorny/paths-filter
  dependency-version: 4.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: docker/build-push-action
  dependency-version: 7.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: docker/login-action
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
- dependency-name: docker/setup-qemu-action
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-03 10:05:09 -06:00
neon 1b46c7f3a0 feat(library): allow renaming books into existing folders
Previously, attempting to rename a book into a folder that already existed on disk was blocked. This change allows users to move books into existing folders, enabling scenarios where different formats (like ebooks and audiobooks) can coexist in the same directory. If a book is already tracked at the target path, the files are merged.

Closes #523
2026-07-03 15:29:51 +00:00
neon 8a36f62b59 fix(library): rename all audio tracks of multi-file audiobooks
When renaming/organizing a book with multiple audio content files (such as
a multi-track audiobook), only the primary file was renamed to the new
destination path, leaving the other track files to collide or remain
unprocessed.

Retrieve the `sortOrder` for all files in the file-rename repository. When
renaming, detect if a book has multiple audio content tracks and resolve any
target path collisions among them by appending `-PartXX` suffixes, ordered by
their sort position.

Closes #521
2026-07-03 14:55:25 +00:00
neon 0f6656a303 feat(users): allow setting default library access for new users
Add configuration settings and backend support to define default library access permissions for newly created users. Newly registered users automatically receive these default library access permissions upon creation. Also align current users page controls and magic link options in the admin tab settings UI, adding styled callout cards for empty states.

Closes #486
2026-07-03 06:28:57 +00:00
neon e97d54953b fix(reader): reconcile remote progress before manual KOReader book sync
When manually syncing a book, the plugin uploaded progress without checking if another device had written a newer progress state to the server first, causing reading progress to be overwritten and lost.

Fetch the remote progress from the server before starting a manual sync. If a newer progress state is found on the server, prompt the user to apply the remote progress locally first. If the prompt is rejected, proceed with the sync of annotations and reading history while bypassing the progress upload.

Closes #461
2026-07-03 05:52:22 +00:00
neon 68134a9f85 fix(stats): use local timezone for peak reading hours
Pass the user's timezone settings to the database query to ensure the
Reading Clock widget groups peak reading hours correctly, instead of
defaulting to UTC.

Also includes a minor UI update to the KOReader plugin to expose a
download options button when multiple formats are available.

Closes #513
2026-07-03 05:11:14 +00:00
neon 6fdd2569e1 feat(kobo): add device sync history tracking
Records success and failure events for Kobo device syncs in the database, including operation duration, event types, and error details. Surfaces the recent sync history in the Kobo Settings UI for users to monitor their device activity.
2026-07-03 00:54:01 +00:00
neon 13be42792d fix(client): prevent cached state leaking across user sessions
Use request generation counters in composables to ignore in-flight fetches that resolve after a state reset. This ensures that user-scoped data like smart scopes, libraries, and collections do not persist across user switches.

Closes #510
2026-07-02 23:10:15 +00:00
neon 283d9ba6d9 fix(books): cast date offset to int to fix smart scope crash
When using date operators in smart scopes or book queries, PostgreSQL
threw an "operator does not exist: date >= integer" error. This explicitly
casts the days offset to an integer in the SQL generated by the book query
builder to prevent the crash.

Closes #508
2026-07-02 18:29:02 +00:00
neon c63ac6cc6c fix(metadata): add poppler pdfinfo fallback for pdf metadata parsing
Some PDF files contain malformed metadata that pdf-lib cannot correctly
decode, despite being readable by external tools. This introduces a
fallback to extract metadata using Poppler's pdfinfo utility, and improves
XMP keyword parsing as a fallback for missing tags.

Closes #491
2026-07-02 18:15:55 +00:00
neon f0374f01c3 fix(server): batch migration queries to prevent parameter limit errors
Processes database queries in chunks of 500 within the migration
repository. This prevents exceeding PostgreSQL maximum bind parameter
limits when importing or querying large datasets.

Closes #504
2026-07-02 17:50:56 +00:00
neon fb35e232ed feat(reader): add KOReader device removal and unmatched book tracking
Introduces the koreader_unmatched_book_devices schema to track unmatched
books per device. Adds API endpoints and UI in settings for dismissing
unmatched books and completely removing a KOReader device.

Closes #504
2026-07-02 17:36:55 +00:00
neon 52bb16c8b8 feat(reader): add persistent sidebar pin
Keep reader sidebar navigation open for repeated jumps when users pin the panel. Use session-scoped state so each book file can remember the preference.

Closes #497
2026-07-02 01:57:22 +00:00
neon a0dad23087 feat(kobo): add manual KOReader book hash linking and unmatched tracking
When KOReader syncs progress or annotations, it identifies books by a document
hash. BookOrbit normally resolves this automatically, but some books cannot be
matched. This adds a tracking table for unmatched hashes and a UI to manually
link them to existing library books.

Closes #458
2026-07-02 00:34:16 +00:00
neon c48c4a0dad fix(metadata): persist Hardcover edition ID during automatic refresh
During an automatic metadata refresh, the fetched Hardcover edition ID was not being copied to the update payload. This ensures the value is persisted to the database alongside the other metadata fields.

Closes #440
2026-07-01 15:44:10 +00:00
neon e7aa6f1efe fix(authors): wire author book delete action
Open the existing delete confirmation from author book cards and keep the author detail counts in sync after deletion.

Closes #211
2026-07-01 15:27:45 +00:00
neon 219815941b feat(reader): support single-page mode for fixed-layout epubs
Adds a fixedLayoutSpread preference to EPUB reader settings to allow forcing single-page display. This is particularly useful for image-based EPUBs like comics and manga.

Closes #487
2026-07-01 15:16:17 +00:00
neon 68a395095a feat(kobo): add catalog bulk download and selection to KOReader plugin
Add support for selecting multiple books and downloading entire lists, pages, or selections in bulk. This includes long-press actions, a dedicated bulk download queue with retry and cancel support, and format preset configurations.

The commit also simplifies the OPDS random book query using ORDER BY random() and adjusts the Nest dev CLI config to disable the Swagger plugin for faster restarts.

Closes #478
2026-07-01 00:21:40 +00:00
neon 6f2fe8612e feat(books): add rich text description formatting bar
Replace the plain textarea for book descriptions with a Tiptap-based rich text editor in the metadata edit tab. Include HTML sanitization utilities to ensure safe rendering of user-provided descriptions.

Closes #460
2026-06-30 20:21:25 +00:00
neon cfc48b6218 feat(stats): demote reading source in default charts and breakdowns
Reading source is often less relevant for day-to-day analytics than
book format or reading pace. Shift the source distribution chart to the
end of the user dashboard and change the default breakdown dimension
from source to format to prioritize more useful metrics. Include a
migration to update existing users who have not customized their chart
order.
2026-06-30 19:56:48 +00:00
neon 117bc82de6 fix(reader): prevent tracking progress out of bounds or non-finite
Progress values computed during reader events could occasionally result in NaN, Infinity, or out-of-bounds numbers, which caused API validation failures or corrupted state. Progress values are now clamped to valid ranges and sanitized to omit non-finite numbers before tracking.

Closes #479
2026-06-30 19:51:06 +00:00
neon e6c24bc608 fix: exclude active and read books from discover something new
The "Discover Something New" dashboard section previously only excluded
books based on reading progress. It now joins the userBookStatus table
to correctly exclude books that are actively being read, finished, or
abandoned.

Closes #484
2026-06-30 19:19:00 +00:00
neon 14b262fa35 feat(server): import Booklore reading state
Import Booklore and Grimmory reading sessions, personal ratings, and progress state through the migration pipeline.

Preserve book-level progress as primary-file progress when source file progress rows are absent.

Closes #482

Closes #483
2026-06-30 18:54:06 +00:00
neon 2dad3eea0b feat(client): expand global search to display all matching books
The search dropdown previously limited results to a fixed number. This change implements virtual scrolling and lazy loading in the AppHeader search bar to allow users to scroll through an unlimited number of matching books efficiently.

Closes #480
2026-06-30 05:56:12 +00:00
neon 47f16fc678 feat(smart-scope): support provider filtering for community ratings
The group rule validator now accepts an optional `provider` field for
`communityRating` rules. This enables smart scopes to filter books based
on community ratings from specific providers (e.g., Goodreads, Amazon)
rather than just the aggregate rating.

The validator ensures that the provider field is only applied to community
rating rules and rejects unsupported providers.

Closes #477
2026-06-29 23:46:33 +00:00
Jadehawk de388392e7 feat(metadata): parse Calibre #extra_tags custom column into book tags (#476)
* feat(metadata): parse Calibre #extra_tags custom column into book tags

Extract #extra_tags from Calibre user metadata and populate ParsedOpf.tags when
the custom column is present.

Support JSON array, pipe-delimited, and comma-delimited string values. Merge
tags from #extra_tags with bookorbit:tags and deduplicate them.

* fix(opf-parser): prefer pipe over comma when splitting extra tags string

Previously, coerceExtraTags used the regex /[|,]/ which splits on both
delimiters simultaneously. A value like "History, Modern|Fantasy" was
parsed into three tags instead of two because every comma and pipe was
treated as a separator regardless of which was the primary delimiter.

Fix: check if the string contains a pipe first; if so, split only on "|",
otherwise fall back to splitting on ",". This preserves commas embedded
within pipe-delimited tags (e.g. "History, Modern" stays intact).

Also adds a regression test covering the mixed-delimiter case.
2026-06-29 17:18:05 -06:00
neon 9e40a3c86a feat(books): surface custom metadata fields in table view
Adds support for displaying custom metadata as columns in the book
table view. The frontend now fetches active fields and dynamically
renders the corresponding cells, backed by book card API updates.

Closes #465
2026-06-29 22:46:22 +00:00
neon a4b39542a0 feat(koreader): add option to skip auto-sync when offline
When enabled, automatic sync on book open will be skipped if the
device is not online, preventing stalls from Wi-Fi connection attempts.

Closes #471
2026-06-29 13:47:11 -06:00
Kyungwook Park b0c6ffb8f7 fix(aladin): use ItemLookUp for ISBN search instead of keyword lookup (#470)
ISBN queries were sent to ItemSearch.aspx as keywords, missing ~24%
of valid Korean ISBNs. Route ISBN searches through ItemLookUp.aspx
with ItemIdType=ISBN13 (13-digit) or ISBN (10-digit), falling back
to keyword search for unrecognised formats.

Closes #437

Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
2026-06-29 13:43:17 -06:00
neon d8e8765518 feat(koreader): add system action to open dashboard in koreader plugin
Closes #449
2026-06-29 19:17:31 +00:00
neon f46824211e feat(metadata): allow manual search with providers outside field rules
Previously, the explicit metadata search modal for a book was restricted
to only the providers configured in the library's field rules. This
prevented users from manually searching a specific provider if it
was not part of their default automated fetch pipeline.

This change allows all globally enabled providers to be used during
a manual metadata search, while still defaulting the selected UI
checkboxes to the providers specified in the field rules.
2026-06-29 19:03:07 +00:00
neon 82c77c72b9 fix(metadata): avoid search reruns on provider filters
Keep provider tabs as local result filters so switching providers does not restart metadata streams.
2026-06-29 18:23:50 +00:00
neon db3d1a07af fix(series): resolve missing series in koreader catalog by id
The KOReader plugin previously matched series by name, which caused
issues for series with identical names or special characters. This
updates the plugin and backend to use the exact series ID for
navigation and filtering, ensuring all series load reliably. Also
bumps the KOReader plugin version to 1.0.1.

Closes #466
2026-06-29 18:08:58 +00:00
neon a88d27a0d5 chore: add funding link 2026-06-29 04:22:13 +00:00
neon 965dcca21e fix(reader): support loading cbz files larger than 2gb
Extracts the ZIP index parser into a dedicated utility that avoids
loading the entire file into a single memory buffer. This fixes an
issue where CBZ files larger than 2GB would fail to load due to
Node.js buffer limits. Also extracts CBR error handling into helper
functions for readability.

Closes #457
2026-06-29 03:30:09 +00:00
neon 2065af41f9 feat(server): add swagger setup for public api documentation
Introduces Swagger and OpenAPI documentation generation for the
backend API. Configures bearer authentication globally while
allowing explicit bypasses for public endpoints. Exports nested
DTO classes across several modules so the NestJS Swagger plugin
can correctly reflect their schema definitions.

Closes #399
2026-06-29 01:52:30 +00:00
neon 246389b050 fix(books): restore metadata editing for multiple selected books
Routes multiple book selection to the edit tab instead of details.
Fixes a bug where deactivated kept-alive sources would passively
clobber the active navigation context by tracking component
activation state. Converts route param computed refs to shallow
refs to prevent reactivity issues during navigation.

Closes #455
2026-06-29 00:49:09 +00:00
neon e0a2c94854 fix(authors): chunk inserts to prevent call stack overflow on backfill
The drizzle-orm query builder hits a RangeError when generating a single
bulk INSERT for tens of thousands of authors during backfill. Chunking
the insertions into smaller batches resolves the issue.

Closes #452
2026-06-28 17:40:47 +00:00
neon e453618463 feat(scanner): add work queue for book dock pipeline and auto-size node heap
Introduce BookDockWorkQueue to serialize metadata extraction and auto-finalize
jobs. Files process newest-first with a 250 ms drain window and 500-1000 ms
inter-job spacing to avoid hammering metadata providers. Watched-folder rescans
now requeue files stuck in extracting or fetching status after a server restart
rather than silently dropping them.

Replace the global ThrottlerGuard with SensitiveEndpointThrottlerGuard, which
only activates on endpoints that carry explicit @Throttle() metadata. This
eliminates all @SkipThrottle() decorators from non-auth controllers and adds
missing throttle coverage for oidcGenerateLinkState and oidcGeneratePreviewState.
Update the login page to match the simplified 429 error message.

Fix countsByStatus to aggregate extracting and fetching rows into the pending
bucket so the UI counter stays accurate mid-pipeline. Add a secondary id sort
to findAll for deterministic pagination ordering.

Auto-detect the container memory limit via cgroup v1/v2 in entrypoint.sh and
compute --max-old-space-size proportionally (50-75 % of limit) instead of
defaulting to a fixed 2048 MB that OOMs small containers.

Closes #441
2026-06-28 17:01:55 +00:00
neon 9951a107af fix(reader): refresh access token when loading epub chapters
Pass the authenticated API fetcher to the streaming book loader instead of a static token. This ensures the token is automatically refreshed if it expires while reading, preventing 401 Unauthorized errors when navigating between chapters.

Closes #446
2026-06-28 05:53:35 +00:00