Repository source: docs/plans/qdb_classic_urls_checklist.md
QDB Classic URLs Checklist
Working checklist, not a committed FDP artifact. One item at a time, commit
update this file after each, same pattern as
qdb_theme_fidelity_checklist.md.
All of this is scoped to the qdb site profile only (SiteConfig::siteName()
=== 'qdb') — no routing changes for zenmemes/chouse.
Both forms of each classic URL should resolve the same way: the qdb.us-style
bare path (/latest) and the bash.org-style query flag on / (/?latest).
Decided out of scope for this pass: Queue (would need a real pre-publish moderation concept this app doesn't have — skipped per your call).
Checklist
Done
All items checked. Everything here is additive and scoped to
SiteConfig::siteName() === 'qdb' — no routing/behavior change for
zenmemes/chouse anywhere in this checklist.
Post-checklist follow-up
Nav links: this checklist made the classic routes work, but nothing pointed at them — the top nav still showed the generic Board/About/Users/ Tools/Account for the qdb profile too. Replaced it (qdb profile only) with Latest/Top/Random/Add Quote/Search/Account in
TemplateRenderer::navItems().Bug found while verifying: Latest, Top, and Random all shared the same
boardnav section, so all three lit upis-activetogether on any board-rendered page. Fixed by givingBoardPageController::board()an explicit$activeSectionparameter and distinct section values per nav item, so exactly one highlights at a time. Verified on/latest,/top,/add,/search.Reload-loop bug, reported by the operator:
/latest,/top,/leetness,/add,/random,/searchwere never added toApplication::isApplicationRoute()'s allowlist. That allowlist gatesshouldResumeViewerSession()— without it, the PHP session never resumes on these pages even when the browser already has one, so the viewer's identity never resolves there. Combined with a pre-existing, unrelated client-side quirk (private_site_auth.js's "already authenticated" short-circuit reads adata-authenticated-identity-idbody attribute thatlayout.phpalways renders empty, so it never short-circuits), every load on one of these pages re-ran the browser's auto re-authentication flow, which — once the identity resolved as approved — calledlocation.replace()back to the same page, reloading it, re-running the same sequence, forever. Fixed by adding the six paths toisApplicationRoute()'s allowlist, so the session resumes there like it does on every other real route. Verified with a simulated two-request session (setauthenticated_identity_id, then request each affected path reusing that session): thedata-private-site-auth-statemarker (the thing that triggers the client-side auto-re-auth flow) is now absent on all six, matching/threads/<id>and every other pre-existing route. A fresh visitor with no session still gets a normal 200 render. Thedata-authenticated-identity-id=""client-side quirk itself is pre-existing (not touched by this feature, not fixed here) — it just happened to be harmless before because no pre-existing route was ever missing from the allowlist in the way these six were.Random, redefined at the operator's request:
/randomoriginally 302-redirected to one random thread, matching the classic behavior. The operator asked for a page of random items instead. ChangedBoardPageController::random()to shuffleThreadRepository::fetchThreads()and render the first 10 via a newqdb_random.phptemplate (reusingquote_card.php, same pattern assearch()), with a "Shuffle again" link. Verified both URL forms render a multi-item page (200, not a redirect) and the Random nav item highlights correctly.Welcome page, added at the operator's request: the qdb profile's bare
/used to fall through to the generic board's default "liked" view (confusingly empty). Added a dedicatedqdb_welcome.phppage (short intro, real quote count, links to Latest/Random/Add Quote/Search) via a newBoardPageController::welcome(), and made it the first nav item./?format=rssis explicitly excluded from the welcome-page takeover so the RSS feed at/keeps working. Verified: 200 + the welcome heading on/, RSS still XML, zenmemes' own/and nav untouched.Account/Invite dropped from the qdb nav, at the operator's request: both routes (
/account/key/,/invites/) remain fully reachable by direct URL — only the nav links are gone for the qdb profile, same "hide from nav, don't remove the feature" pattern already used for Tools/Users. Verified/account/key/still returns 200 and the zenmemes profile's Invite link is unaffected.Welcome page layout, matched more closely to a 2009 qdb.us reference (archived snapshot reviewed for structure/style only; all page copy here is original). Adopted the two-column pattern: an intro + a voting-instructions callout box on the left (light-gray background, matching the original's
.instructionstreatment) separated by a thin orange vertical divider from a right column — but instead of copying static site-news text we don't have, the right column shows real "Recent activity" (the 5 most recently active threads), so nothing on the page is fabricated. Verified: renders correctly, zenmemes unaffected, full suite clean.Random page header removed, at the operator's request: dropped the "Random" heading + "Shuffle again" link card from
qdb_random.php— the page now goes straight into the quote list, no intro chrome.Add Quote page compacted, at the operator's request:
/addnow renders a new dedicatedqdb_add.php(via a newComposeAndAccountKeyController::composeThreadCompact()) instead of the sharedcompose_thread.php— no heading, no "Posts are stored..." text, and — by passingcompact: trueto the existingthread_compose_form.phppartial (the same mode the inline board composer already uses) — no visible Subject/Board tags fields, just the body textarea. The shared/compose/threadroute and its template are untouched; verified zenmemes still shows the full form there.Follow-up fix:
compact: true's action-button row (.compact-thread-compose-actions) only goes horizontal above a 640px CSS media-query breakpoint elsewhere (by design, for the small inline composer embedded in the board page). On this full-page context the operator saw it stacked. Added a scoped override (.qdb-add-page .compact-thread-compose-actions) so the buttons are reliably horizontal on this page specifically, without touching the responsive behavior of the inline composer elsewhere.
Search page heading removed, at the operator's request: dropped the
<h1>Search</h1>fromqdb_search.php; the search box is now the first thing on the page.