* fix(server): deduplicate migration user-state upsert batches
Prevent migration failures when source data contains duplicate user-state rows for the same target keys. Keep the latest row per upsert key and prefer richer reading progress signals on timestamp ties, then cover the behavior with focused unit and e2e tests.
Closes#71
* ci: raise commitlint body line limit to 500 chars
Allow longer commit body lines so convention checks do not fail on detailed but still concise commit explanations in this repository.
* fix(books): switch progress reset to per-file controls
Remove the book-level reset action and endpoint, and keep reset scoped to each file row to avoid accidental bulk clears.
Add tests for per-file reset behavior and progress formatting edge cases while keeping migration import filters aligned with the new progress expectations.
closes#57
* ci: increase commitlint body line limit to 250
Allow longer explanatory commit bodies so CI accepts existing project commit patterns without forcing manual hard wraps at 100 characters.
Series position badge (#N) rendered in the top-right corner of cover
cards, sharing a flex-column container with the existing lock-status
badge. Shown only when seriesIndex is non-null. Whole numbers strip the
decimal (3.0 -> #3); fractional values display as-is (1.5 -> #1.5).
Hovering the badge shows a tooltip with the full series name and position.
Enabled by default in Appearance -> Card Overlays.
Closes#32
Validate BO-<issue>-<slug> branch names and lint PR titles and commit headers in CI and release workflows.
Require GitHub closing-keyword issue references and verify referenced issues exist. Align contributing, release, commit, testing, and policy docs with the enforced behavior and tone.