fix(library): seed-pass flip guard, manga null-sentinel, mangadex resolve

- comic/manga sync(): a note's first-ever observed issue/chapter number
  (no prior latest_issue/latest_chapter) now seeds the baseline without
  flipping read_status or notifying. Previously `prev === null` counted
  as "newer", so a Read note with no stored baseline flipped to Unread
  on its very first real sync. Flips now require a prior value AND a
  strictly greater candidate AND read_status Read, mirroring the
  watchlist build.ts `prevLast &&` guard.
- manga rss/last_chapter_date: quotedOrNull renders an unset value as
  the literal `null` token; on the next parse that string came back
  truthy, so an unset rss field was fetched as the URL "null" and
  isActive treated it as "has rss -> active" forever. Sentinel is now
  stripped back to '' everywhere it's read from frontmatter.
- manga resolve(): best-effort MangaDex id lookup by title (unique-exact
  match against attributes.title + altTitles) runs alongside the
  existing MAL lookup when the note has no mangadex_id yet. Any failure
  (no match, ambiguous, network error) is logged and skipped, leaving
  the mal_id patch intact.
This commit is contained in:
afiqzudinhadi 2026-08-03 22:08:40 +08:00
parent 1d5537742f
commit ea5ddd9454
4 changed files with 254 additions and 11 deletions

View file

@ -222,8 +222,12 @@ export const comicSpec: MediaTypeSpec = {
let flipped = false;
if (Number.isFinite(candidate)) {
const isUpdate = prevLatestIssue === null || candidate > prevLatestIssue;
if (isUpdate) {
if (prevLatestIssue === null) {
// seed pass: first-ever observed issue number, nothing to compare against yet --
// record it as the baseline, never flip/notify (mirrors watchlist build.ts's
// `prevLast &&` guard: there's no "new" issue relative to an unknown starting point)
record.latestIssue = candidate;
} else if (candidate > prevLatestIssue) {
record.latestIssue = candidate;
if (record.readStatus === 'Read') {
record.readStatus = 'Unread';