DataTalksClub / DataTalksClub/website
Preserve legacy course HTML/API compatibility and rehearse full data migration
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Parent epics: #5, #10. Coordination epic #54 is not a closable prerequisite.
PM disposition
GROOMED / P0 / REHEARSAL-ONLY / DEPENDENCY-BLOCKED.
This issue owns the final side-effect-disabled, production-like course migration and compatibility rehearsal. It proves that the accepted target model, public/learner/management behavior, compatibility adapters, data tools, and rollback path work together against one authorized pinned production-like snapshot. It does not choose or execute production cutover, activate redirects or email delivery, observe a post-deployment retirement window, or contract legacy schema.
All acceptance criteria remain unchecked until one frozen #60 engineer candidate passes the independent tester and PM gates. Closed decisions/baselines and accepted child issues are inputs only; none is #60 acceptance evidence.
Normative authority
_docs/PROCESS.md_docs/specs/04-courses-and-cohorts.md, especially Registration, Expand-and-contract model migration, APIs, URL consolidation, and high-risk migration checks_docs/specs/07-security-privacy-operations.md, privacy and protected-data controls_docs/specs/09-migration-rollout-roadmap.md, rollback and data-migration controls_docs/specs/10-verification-strategy.md, Course/Cohort, migration, privacy, operations, and browser gates_docs/architecture/app-boundaries.md- Parent/coordination boundaries #54, #64, #74; downstream legacy-contract decision #287
Outcome and scope
- Mount the accepted copied
courses.datatalks.clubHTML, data, calendar, certificate, and authenticated API paths as compatibility adapters in unified Django and compare their exact schema/status/auth/method behavior. - Exercise the accepted canonical public, learner, Studio, and
/api/v1/admin/paths over the same business services. - Run repeatable dry-run/import/final-delta tooling for accounts and aliases, Course/Cohort mapping, registrations and #133 provenance, enrollments, curriculum, submissions, reviews, votes, scores/statistics, complaints, certificates/Wrapped, calendars, and send-disabled email/outbox history.
- Produce redacted count, stable-ID-map cardinality, duplicate/missing-reference, transformation, quarantine/rejected-row, checksum/total, idempotency, and source-drift evidence with no unexplained difference.
- Test the explicit old/new write-freeze, final delta, durable-job/outbox classification, backup/restore, and compatible application-image rollback procedure.
- Generate the final explicit legacy-host path map without activating it.
Accepted baseline inputs — not completion evidence
These closed issues remain bounded inputs and are not rerun or broadened here:
- #15 — reviewed legacy edition-to-family mapping decision;
- #16 — named legacy HTML/API consumer and redirect-disposition decision;
- #30 — copied course-platform characterization/adoption baseline;
- #34 — legacy URL/link/fragment/asset/SEO inventory baseline; and
- #35 — compatibility/redirect/link/SEO parity-gate foundation.
Their accepted evidence does not prove a production-like import, complete target behavior, a deployed cutover, or #60 acceptance.
Exact current dependency DAG
No engineer may start #60 until every hard input below is accepted, integrated on one current base, and identified by exact merge SHA/source pin/migration leaves. Open issues remain blockers even when a local candidate or synthetic test is green.
Course/Cohort and account/profile foundation
#224 -> #51
(#51 + #231 + #234) -> #247 -> #248
Registration source and public/learner flows
#247 -> #242
(#242 + #248 + accepted ordinary-delivery interface from #49) -> #243
(#230 + #242 + #248) -> #244 characterization
accepted #243 conversion interface -> #244 final acceptance
Registration management
(#288 owner decision + #243 + #244 + #32 + #33 + #52) -> re-groom/accept #245
(accepted #245 + its already accepted shared foundations) -> #246
Broader Course/Cohort behavior
accepted #51/#52 foundations -> #53
accepted and integrated #53, #55, #56, #57, #58, and #59 supply the lifecycle,
homework, project/review, leaderboard/privacy, certificate/Wrapped, and remaining
Studio/admin-API compatibility contracts consumed by #60
Full rehearsal
(#53 + #55 + #56 + #57 + #58 + #59
+ #242 + #243 + #244 + #245 + #246
+ exact current #133 schema/source-policy/native-boundary fingerprint
+ accepted baseline inputs #15/#16/#30/#34/#35) -> #60
Later destructive contract
accepted #60 rehearsal + deployed target flows + #287 owner choice
+ #287's selected clean immutable-release observation evidence
-> separately re-groomed #287 contract implementation
#54 is the coordination epic for #242–#248/#286–#288, not a hard dependency that must close before #60. Treating parent closure as a prerequisite would create a cycle because #54 itself requires #287 disposition and #287 requires accepted #60 rehearsal. Any older #55–#59 dependency text that names broad parent #54 must be independently re-groomed to the exact child interfaces before those lanes dispatch; #60 does not infer parent closure or waive their lifecycle gates.
#133 is an aggregate/provenance coordination boundary, never a row-level registration source. #60 must freeze and reconcile its exact accepted source/schema/policy/native-boundary fingerprint and prove the aggregate-to-row replacement/no-double-count boundary; it must not bypass, mutate, or expose #133 protected-source evidence.
#49 is consumed transitively through #243 for the durable logical intent/job interface. #50 owns real purpose/sender cutover and Datamailer retirement. #60 may rehearse freeze, drain, history import, reconciliation, and rollback only with every website/Relay/Datamailer outbound path disabled; it neither activates nor closes #50.
#286 is not a hard prerequisite when the owner explicitly defers pre-Cohort interest and the accepted target graph contains no CourseInterest behavior. If the owner selects an implemented CourseInterest contract before #60 freezes, that accepted schema/data path becomes a #60 input. #287 is always downstream and never an implementation dependency of #60.
Rehearsal and evidence contract
Use only an explicitly authorized anonymized production-like snapshot with an immutable source identity, schema-contract checksum, capture/freeze/cutoff timestamps, and approved handling boundary. Every website, Relay, Datamailer, worker, webhook, and provider outbound path is disabled. No protected row value, source locator, secret, reversible identity digest, or registration/profile content enters source control, logs, issue comments, screenshots, or reports.
Run dry-run, apply, exact replay/apply twice, bounded batch restart, concurrent invocation, changed source/schema/plan, forward migration, compatible application rollback, and forward reapplication. Reconcile source and target counts, stable mappings, reason/quarantine counts, safe checksums and derived totals. Recompute scores/statistics rather than trusting or silently replacing them. Unknown, ambiguous, missing, duplicate, stale, or mismatched state fails closed.
A verified backup is restored into an isolated production-like environment. The recorded compatible pre-contract application image must read the expanded schema and all rehearsed post-cutover registrations/enrollments without data loss or duplicate delivery. Do not reverse a migration by fabricating removed data. #60 removes no compatibility field, constraint, mapping, evidence, reader, writer, or rollback projection.
URL and compatibility contract
Snapshot every accepted legacy compatibility response/schema/auth outcome against canonical behavior. The generated path map preserves suffixes, query strings, case/Unicode policy, approved fragments, and one-hop destinations; unknown paths remain true 404s. Authenticated or non-GET APIs retain direct compatibility unless a named consumer has proved method, body, authentication, and authorization preservation. No redirect, DNS/edge, or Lambda activation occurs here.
Acceptance criteria
- Every accepted current course HTML/data/calendar/certificate/API path and schema passes the frozen compatibility contract or has an owner-approved explicit disposition; no consumer or behavior is unclassified.
- #16 consumers and every public, learner, Studio, admin API, export, job, and email-history path are mapped to an accepted target or direct-compatibility disposition with owner/auth/method/rollback evidence.
- Imports are idempotent, snapshot-pinned, side-effect-disabled, and report bounded counts, stable-ID cardinalities, duplicates, missing relations, transformations, quarantines/rejections, checksums/totals, and drift without protected values.
- One authorized production-like full rehearsal reconciles the reviewed Course/Cohort mapping, accounts/aliases, #133 boundary, registrations, enrollments, curriculum, submissions/reviews/votes, recomputed scores/statistics, complaints, certificates/Wrapped, calendars, compatibility responses, and email/outbox history with no unexplained difference.
- The final explicit path map is complete, one-hop, suffix/query/case/Unicode safe, distinguishes HTML from unsafe authenticated/non-GET API redirect cases, and returns 404 for unknown paths without being activated.
- Write freeze, final delta, outbox drain/classification, backup restore, compatible application rollback, retained post-cutover writes, forward reapplication, and one-sender/no-duplicate-delivery behavior are tested with all real sending disabled.
Required verification
- Compare accepted compatibility fixtures across legacy-host routing and canonical routing for status, content/schema, method, authentication/authorization, cache/privacy headers, calendar UID, certificate, and numeric-ID mapping behavior.
- Inject duplicate/missing/ambiguous mappings, stale campaign pointers, identity collisions, bad consent evidence, quarantine rows, #133 drift, source/schema/plan drift, and batch interruption; prove deterministic fail-closed reports and zero outbound work.
- Recompute representative active and archived Cohort homework/project/review/leaderboard/certificate results and compare totals and stable history.
- Restore the frozen backup, exercise the recorded compatible application rollback with post-cutover synthetic writes, then reapply forward and reconcile exact safe evidence.
- Test the generated redirect map for one hop, suffix/query/fragment/case/Unicode, unknown paths, API methods/bodies/authentication, and rollback target selection without deployment.
Browser
Run the graph-selected full Playwright suite over the frozen combined candidate. Exercise copied course E2E on legacy-host compatibility and canonical routing, including account/profile resume, registration, Enrollment conversion, dashboard, calendar, homework, project/review, leaderboard/privacy, certificate, Studio, and safe denial/error states. The independent tester captures and inspects required desktop/mobile screenshots under .tmp/screenshots/; screenshots contain synthetic data only and must show the intended page rather than debug/error leakage or broken layout.
Explicit non-goals
- No production/protected-data access without separate explicit authorization; no real provider, email, worker, webhook, workflow, infrastructure, DNS/edge, redirect, sender, or deployment mutation.
- No owner choice for #286, #287, #288, privacy/retention, sender/purpose, or cutover policy; no inferred decision from elapsed time or passing tests.
- No public/profile/management product behavior invented by rehearsal; each owning issue must already be accepted.
- No destructive contraction, legacy field/constraint/mapping/evidence removal, final target-only constraint activation, data guessing, silent discrepancy correction, blanket/homepage redirect, or authenticated-API redirect that drops method/body/authentication.
- No closure of #50, #54, #64, #74, #133, #286, or #287 by #60 evidence.
#287 release/observation boundary
Accepted #60 evidence proves only the production-like rehearsal prerequisite. It does not start, backdate, shorten, or satisfy #287's E1/E2 clean window and does not select E1/E2/E3. Under E1/E2, #287's clock begins only from its defined later immutable production-release event after the accepted target flows are deployed. Missing telemetry, an incomplete day, rollback, mismatch, legacy-authoritative write, quarantine, unknown consumer, or #133 drift resets that separate window exactly as #287 specifies. E3 authorizes no contraction.
Lifecycle
After every hard input is accepted/integrated, PM rechecks exact SHAs, source pin, migration leaves, compatibility/OpenAPI/capability/#133 fingerprints, snapshot authorization, and absence of a dependency cycle. An engineer then builds one isolated uncommitted #60 rehearsal candidate and records the graph-selected plan. A separate tester independently verifies all criteria, redacted artifacts, full browser evidence, and inspected screenshots. PM accepts only after a complete tester-final report. Only then may a focused Closes #60 commit be locally merged/pushed and observed by on-call. Production cutover, redirect activation, sender activation, #287 observation/contraction, and legacy retirement remain later separately authorized work.
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/04-courses-and-cohorts.md, _docs/specs/09-migration-rollout-roadmap.md, and _docs/specs/10-verification-strategy.md, then identify the accepted dependency SHAs and authorized snapshot. Run the graph-selected full Playwright suite and the required migration, compatibility, rollback, and fail-closed checks. Done means one side-effect-disabled rehearsal produces reconciled evidence with no unexplained differences and no deployment activation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, playwright, python
- Domain
- api, backend, databases, devops, testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 20/100