Release 0.36.0 - #31
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
28 commits since 0.35.0 — the torrent detail page and the catalogue rebuilt
around the questions their readers arrive with, and the review passes that
followed. As with 0.35.0, the findings that mattered came from probing the
running stack, not from static analysis: semgrep and gitleaks were clean or
already arbitrated, while calling the changed routes without a session, then
with another member's session, is what turned up the leaks below.
The torrent detail page
The page used to answer "what is this release?" some 700px below the fold,
repeat every audio and subtitle track twice, and offer no way to say "wrong
film". It now opens on a hero band that names the work, with two columns where
the decision — download, cost, seed obligation — is pinned, swarm health read
from the collector, and a report affordance on the metadata itself. The work's
own colour, extracted from its poster, tints the band; the remaining motion is
limited to what carries meaning (the click, the fold, the numbers).
them; the 24 h shown on every torrent page was a code default. They are now
in the admin panel, bounded, and read from one place.
One network hiccup cost thirty posters until the entry expired. Timeouts,
5xx, 429 and malformed JSON now share a 120 s error cache; only a real 404
is remembered as an absence.
Sec-Fetchheaders, any port,any image type — an SVG served from our own origin would have executed
there. Now: same-origin image requests only, three CDN hosts, raster types,
a 400 KB cap enforced during the stream, no redirects, 60/min per address.
Dkey downloaded on repeat; the shortcut now ignores keyrepeat, composition, open modals and editable targets.
The catalogue
A bar that understands what you type —
s02e04,@member, a TMDb or IMDblink, a resolution, a year — turning each into a removable chip; a rail of
facets that carry their counts; works before releases; and an empty state that
proposes what to drop rather than apologising.
A work card opens on its own header, with a chevron: the scope badge used to be
the only way in. Inside, seasons and episodes fold down to the releases, each
carrying its age with the exact date on hover.
are now indexed and searched, so a file named
Sousou.no.Frieren.S01E10answers to "frieren", and a near miss gets a did-you-mean.
uploader and tag families included — and their links replay exactly what was
stored.
favourites), this browser's recent searches, and the category tree. Opens on
hover with an intention, on the chevron by click or keyboard, never on hover
alone for a touch screen.
record of searches that found nothing, and category merge — all in the admin
panel.
Security and correctness
whole site. Four API calls per page view meant 25 page views in 10 seconds
blacklisted the instance for everyone, for five minutes doubling to twenty-four
hours. Server-side rendering is now recognised by a discriminant an Internet
client cannot forge (private socket peer and no forwarding header), and
only the coarse counter is relaxed — never the agent filter, the path
validation, the address bans, the per-route limits or authentication.
anonymous_uploadswas honoured by the detail page and the feeds but bynone of the new catalogue paths. The listing returned the name,
?uploader=<name>listed an anonymous member's whole history, and a savedsearch on that name notified every one of their uploads.
single token for the text-search parser, and the fuzzy fallback hid the hole
whenever the exact search returned zero.
backdrop-filterwritten before its-webkittwin was dropped by theminifier. Five glass surfaces across the site had no blur in Chrome — a
correct source and a stripped stylesheet.
tagGroupsfanned out to one query per group ona pool of ten connections,
search_missesgrew a row per distinct emptysearch, and neither the listing nor the facets carried a rate limit.
routes answered for a torrent the member cannot see.
carrying an upload pattern), and could make an adult category's torrents
visible to members who opted out.
repeat or drop a row; the year facet counts every year in a name with the
same pattern the filter uses; and the metadata warmer no longer marks a work
done for a week because the upstream was briefly unavailable.
Verified
nuxt typecheckand the APItscclean; 558 API and 948 web unit tests; schemaparity between
schema.tsand the 77 migrations; the end-to-end suite (13scenarios, 543 checks) against images built from this branch; and a browser
pass at 1280 and 390, dark and light, with no horizontal scroll, no truncated
text, no dangling
aria-controlsand no failed asset.🤖 Generated with Claude Code