DataTalksClub / DataTalksClub/website
Restore .html canonical podcast detail URLs
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Product outcome
Restore the established .html canonical for every podcast detail, including the two current exceptions S24E05 and S24E06, without changing podcast content or season-hub behavior. Current-base route and projection behavior must converge on one source-derived contract; generated projection files may not be hand-edited or hidden behind a runtime rewrite.
Normative authority and regression provenance
_docs/specs/02-url-link-seo-compatibility.mdrequires/podcast/<slug>.htmlfor every podcast detail, with clean and trailing-slash slug aliases redirecting permanently in one hop while preserving the raw query.- #105/#119 establish deterministic public projection and podcast identity; #132 changes only the
/podcastseason-hub representation, not detail identities. - The prior #162 implementation, tester PASS, and PM acceptance remain the historical product contract. Merge
c28d353551ff908498f450b2d03b127c97513febimplemented it. bf82c20b760f97149b81f5745d3ba83211358078later introduced the S24E05 exception.9f0354402a3d75829f99d3f1545a1285281e27b2introduced the equivalent S24E06 exception and generic stable-ID routes. Neither commit amended specification 02 or received an owner decision replacing the.htmlrule.- Exact current base
face8e4808d65afbf0374d1ced7a88079950d663has 205 podcast records: 203.htmlpaths and exactly two non-.htmlpaths:/podcast/s24e05/ai-adoption-in-enterprise-beyond-writing-code/podcast/s24e06/how-to-build-ai-that-actually-ships-in-production
Historical acceptance therefore remains exact. This is a P0 compatibility/SEO regression, not a new route-design decision.
Scope
Canonical runtime and aliases
- Make all 205 projected podcast
public_pathvalues exactly/podcast/<record-slug>.html. In particular:/podcast/s24e05-ai-adoption-in-enterprise-beyond-writing-code.html/podcast/s24e06-how-to-build-ai-that-actually-ships-in-production.html
- Each
.htmlfinal is a terminalGET/HEAD200, has noLocation, and emits one query-free production canonical,og:url, PodcastEpisode JSON-LD URL, and final breadcrumb URL matching that.htmlpath. A query-bearing final remains200, self-identifies with the query-free canonical, and isno-store. - Keep the established clean full-slug and trailing-slash full-slug aliases for every record as direct
301redirects to its.htmlfinal, preserving the raw query byte-for-byte. - Preserve the two exact currently projected nested paths listed above as explicit compatibility aliases: each
GET/HEADredirects once with301to its matching.htmlfinal and preserves the raw query. Record them in the route migration/alias authority. This makes exactly 412 accepted podcast detail aliases: 410 established clean/slash aliases plus these two regression-era nested aliases. - Do not retain the generic
/podcast/s<season>e<episode>,/podcast/s<season>e<episode>/<arbitrary-slug>, nested trailing-slash, or stale-cosmetic-slug resolver. Those unrecorded spellings return bounded404withoutLocationor canonical metadata. - Finals and accepted aliases reject unsafe methods with
405, exactAllow: GET, HEAD, andno-store; malformed, ambiguous, duplicate-ID, and unknown records fail closed.
Source, projection, backlinks, and SEO
- Remove the S24E05/S24E06 canonical exceptions from the shared route helper. The supported projection generator must derive both
.htmlpaths; runtime adapters must validate, not rewrite, generated identity. - Regenerate the complete public projection from the exact immutable pins accepted under #253. Two clean supported regenerations must be byte-identical to each other and to the checked result.
- Update route-bearing generated outputs only from that complete regeneration, including
podcasts.json,editorial_route_migration.json,manifest.json, Wiki records/graph/search, people relationships, review projection, and every derived source/artifact/tree digest that actually changes. No selected-file generation or hand-edited generated byte is accepted. - Every hub card, homepage/related link, Person relationship, Wiki citation/graph/search link, review link, feed, sitemap entry, canonical, Open Graph field, JSON-LD value, and breadcrumb must use the matching
.htmlfinal. Source/editorial prose that merely contains a filename or fragment is not rewritten. - Preserve S24E06 source/artwork provenance and all unrelated generated semantics repaired under #253. This issue changes route identity only; it does not bless any
face8e4generated hash.
Dependency and integration order
This contract is fully groomed, but engineering is blocked while #253 remains in needs grooming and lacks its required green immutable content-source pin. This is a baseline/integration prerequisite, not an owner-decision gap and not permission to add needs grooming here.
After #253 records the repaired source SHA/tree/CI/attestation and a deterministic generator-ready base, the work must use one coordinated integration lane:
- apply this issue's route-helper/runtime/alias/test correction;
- let #253's complete two-pass regeneration consume that correction together with its source and generator repairs;
- freeze and independently verify the combined generated tree; and
- land in an order that never checks a runtime/projection mismatch.
#162 must not be implemented against stale face8e4 generated bytes, and #253 must not declare S24E06 route coherence while retaining the non-.html exception. The two issue reports must identify their exact owned semantic deltas; neither issue silently absorbs the other's acceptance.
Explicit non-goals
- No change to
/podcastseason selection, ordering, pagination, controls, titles, query grammar, 24-season/205-episode inventory, transcripts, audio/player behavior, content, copy, people, or artwork. - No new season/episode canonical family and no generic public stable-ID resolver.
- No change to Blog, Book, Person, Wiki detail, Event, course, or other route families.
- No rollback or selective omission of the 16-commit lane associated with
face8e4. - No hand-edited generated JSON/assets/provenance, partial regeneration, manifest/hash blessing, runtime projection rewriting, redirect chain, homepage fallback, test weakening, or unchanged-red workflow rerun.
- No database model or migration, external content-repository mutation, provider action, Search Console action, production probe, deploy, or copy/visual redesign in this issue.
Acceptance criteria
- The supported generator and runtime expose exactly 205 unique podcast finals, all matching
/podcast/<record-slug>.html; S24E05 and S24E06 use the exact.htmlfinals above. - The route migration contains exactly those 205 finals and exactly 412 explicit one-hop detail aliases: 410 clean/slash full-slug aliases plus the two exact nested compatibility aliases. There are no collisions, chains, guessed slash variants, generic ID aliases, or competing canonical
200s. - Every final passes the all-205
GET/HEAD/unsafe-method matrix and exact canonical/OG/PodcastEpisode JSON-LD/breadcrumb assertions. Every accepted alias passes the all-412 direct301GET/HEAD, raw-query preservation, and unsafe-method matrix. - The two nested compatibility aliases redirect directly to their
.htmlfinals for representative empty and byte-sensitive raw queries; their nested slash, ID-only, stale-slug, malformed, ambiguous, and unknown variants fail closed as specified. -
/podcastand each valid season view retain the accepted season behavior and link only to.htmldetails. The podcast sitemap is exactly clean/podcastplus the 205.htmlfinals and contains no alias, query, or nested detail URL. - A repository/projection census finds no S24E05/S24E06 nested path in a canonical/final/backlink/SEO scalar. The only permitted occurrences are the two explicit alias-source records and focused fixtures/assertions proving their redirects.
- The #253-compliant complete regeneration runs twice from its accepted exact pins, produces identical full trees, matches all checked generated bytes, and accounts for every changed path/leaf and digest. Wiki/search route-field changes caused by this issue are classified as intentional
.htmlbacklink corrections; unrelated Wiki/search semantics and counts remain intact. - Focused route-helper, projection-builder, route-migration, public-data, podcast catalogue/stable-route, SEO, sitemap, review-projection, and Playwright tests cover both S24E05 and S24E06 plus the all-record matrices. Tests that currently endorse the exceptions are corrected rather than weakened.
- A versioned verification plan selects fresh full quality, Django, Playwright, screenshot, and container evidence because shared generated projection, public routes, and rendered links change. All required jobs are terminal green on the exact frozen candidate; no
face8e4failure evidence is reused as success.
Browser and independent tester scenarios
- At 1440px and 390px, with JavaScript enabled and disabled where the harness supports it, open both S24E05 and S24E06
.htmlfinals directly. Verify terminal200, correct address/canonical/OG/JSON-LD/breadcrumb, readable content, working media surface, no debug/error page, and no horizontal overflow. - At both widths, open each exact nested compatibility alias with
?utm_source=oncall%2Btest&x=a%2Fb&blank=. Verify one permanent hop preserves the raw query and lands on the correct.htmlfinal; inspect the final render. - Open
/podcast?season=24, activate the visible S24E05 and S24E06 cards, and verify each link goes directly to its.htmlfinal without a browser redirect. Confirm season controls and episode ordering remain unchanged. - Exercise representative Person and Wiki backlinks for both episodes and confirm direct
.htmldestinations. Verify nested slash, ID-only, stale-slug, malformed, and unknown paths show the safe404rather than a detail, hub, or redirect.
The independent tester captures and inspects desktop/mobile screenshots for the season-24 hub and both final detail pages. Screenshots are applicable because public href/address behavior and shared generated render inputs change, even though visible copy/CSS is unchanged.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with _docs/specs/02-url-link-seo-compatibility.md and confirm the #253 prerequisite before inspecting the shared route helper, supported projection generator, runtime adapters, route migration, and named generated outputs. Verify the all-record route, alias, SEO, backlink, and unsafe-method tests for S24E05 and S24E06. Done means a complete deterministic regeneration produces 205 .html finals and exactly 412 accepted aliases with all required evidence green.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, testing, web-dev
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 28/100