DataTalksClub / DataTalksClub/website
Implement the event lifecycle, public pages, people, and calendar contracts
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Parent epic: #6
Normative authority:
_docs/specs/05-events-registration-email.md, especially Event model, Person relationships, Event changes, Studio/API capabilities, and aggregate-only historical registration overlay;_docs/specs/02-url-link-seo-compatibility.md#canonical-public-event-identity;_docs/specs/06-studio-and-admin-api.md, for capability/service/permission/audit parity;_docs/specs/07-security-privacy-operations.md, for protected join information, denial, redaction, caching, and accessibility;_docs/specs/09-migration-rollout-roadmap.md#historical-registration-aggregate-rollout; and_docs/specs/10-verification-strategy.md.
Accepted inputs: #18 (no capacity/waitlist), #19 (legacy naive timestamps are Europe/Berlin, stored UTC with retained IANA timezone and ordinary zoneinfo fold=0), #31, #35, #136, and #173.
Current disposition
This issue owns the full database Event lifecycle, public Event surfaces, Person relationships, calendar behavior, and Studio/admin-API management. It expands the single existing events.Event identity supplied by #136/#173; it must not create a second Event model or restore a slug-selected public identity.
The complete issue is blocked before engineering on accepted/integrated #289 for the Event lifecycle/calendar core and accepted/integrated #40 for canonical Person short relationships. The prior dependencies on #32/#33 were backwards: closed #86/#87 provide the capability and API foundations used by this domain issue, while #32/#33 later complete production identity/high-risk acceptance for the domain capabilities that #45 registers. #46 and #49 are downstream consumers, not prerequisites, and grant no registration, email, Relay, credential, provider, or production authority to this issue.
#289 is now the separately filed and groomed non-activating Event lifecycle/calendar core. It owns only forward migrations on the existing Event, deterministic checked-source import, lifecycle/revision/registration-availability services, calendar UID/sequence, pure ICS serialization, and synthetic tests. It explicitly excludes public/template work, Person relationships, Studio/admin adapters, registration, delivery, and provider calls. #289 remains on an operational start hold until the release/source base is green; #45 itself does not authorize an untracked partial commit.
The authoritative specs require public calendar builders but do not currently name a new Event ICS endpoint. A child or full handoff that exposes a new route must first record that exact path; engineering must not invent it.
Outcome
Complete one database-owned Event aggregate while preserving the accepted checked public projection and compatibility identities:
- extend the existing immutable UUID/internal identity and stable positive
public_idwith safe content, visibility, type/image, timezone-aware schedule plus retained IANA timezone, registration window, public location and separately protected join information; - add guarded lifecycle transitions, publication timestamps, monotonic revision, stable calendar UID, calendar sequence, and optional recording/recap/course/cohort/external-event relationships;
- import/reconcile the checked legacy Event source deterministically without changing or duplicating accepted UUID/public-ID/source mappings;
- add ordered speaker/host relationships to canonical active #40 Person
shortidentities; - make public hub/detail/calendar presentation, Studio, and admin API consume the same Event services; and
- preserve #112's aggregate-only count and source-to-Event attachment without creating attendee identities or double-counting a later native-row replacement.
Public route and presentation contract
- The hub canonical is
/events. - The sole detail canonical is
/events/<positive-public-id>/<current-title-slug>. The numeric public ID selects the Event; the title slug is cosmetic; UUID remains management-only. - Exact numeric-only, numeric/stale-slug, accepted lowercase UUID/current-slug and UUID-only, and reviewed date/title aliases redirect permanently in one hop to the numeric/current-slug route with the raw query preserved. Resolution never guesses an unrecorded spelling, slash form, source/provider key, nearby title/date, or case variant.
- Canonical numeric
GET/HEADis terminal200and self-canonical. Malformed, unknown, signed, zero-padded, overlong, alternate-case, canonical trailing-slash, and unrecorded alias forms are real404; unsafe methods are405withAllow: GET, HEADand no-store behavior. - Internal links, canonical/OG/JSON-LD, breadcrumbs, registration/calendar builders, feeds, and sitemap emit only the numeric/current-title-slug identity.
/events/<positive-public-id>/<current-title-slug>/registerremains owned by #46 and is not introduced here. - Ordinary public pages use
templates/core/content_page.html; desktop/mobile, JavaScript-on/off, keyboard, focus, zoom/reflow, metadata, and cache classifications follow the shared contracts. Protected join information never enters public HTML, metadata, cache, logs, screenshots, or exports.
Lifecycle and service contract
- Lifecycle is
draft -> published -> completed -> archived, withcancelledreachable before completion. Unsupported transitions fail without partial mutation. - Registration availability is derived only from publication, registration window, event time, and cancellation; there is no capacity field or waitlist.
- Event edits use a revision-guarded application service shared by Studio and the admin API. Title changes retain UUID/public ID and register the accepted old route as a direct alias.
- Rescheduling and cancellation advance calendar sequence exactly once per accepted change. Calendar UID remains stable across title, time, location, and slug changes.
- Once native registrations or messages exist, the Event cannot be physically deleted. Editing title/time/location requires a bounded change summary and explicit notification decision result, but #45 creates no
EmailDelivery, durable email job, Relay call, provider call, or recipient data. - Import and replay preserve the checked UUID/public-ID/source identity and accepted aliases. Missing, duplicate, ambiguous, renumbered, or changed mappings fail before activation.
Person and management contract
- Speakers and hosts reference only resolvable active canonical #40 Person
shortkeys, preserve explicit role/order, and may reuse one Person across roles/domains. - Removing or renaming a referenced Person fails unless #40 supplies an accepted alias/replacement; no public Person becomes a user, staff identity, or permission principal.
- This issue registers Event create/edit/preview/publish/complete/cancel/archive, people-ordering, and calendar-change capabilities through #86/#87. Studio and
/api/v1/admin/call the same services with capability/object/field authorization, revision/If-Match, idempotency where retryable, safe errors, and redacted audit parity. - #32/#33 remain responsible for final production staff/service-principal identity and high-risk lifecycle. #45 does not infer or enable those identities or credentials.
Aggregate-only historical total handoff
- The canonical detail may render only #112's exact complete integer copy
N registered; it never renders or exposes attendee cards, names, initials, avatars, profiles, directories, provider breakdowns, or the wordattendedfor that count. - Missing, incomplete, quarantined, or unreconciled historical coverage is omitted, not guessed as zero.
- The checked source-identity-to-Event UUID attachment and any later native-row replacement use the accepted expand-and-contract pointer contract. Aggregate and native contributions cannot be active for the same coverage slot at once.
- #112's protected-source HUMAN gate remains separate. This issue uses synthetic fixtures and grants no production/protected-source access.
Acceptance criteria
- Existing Event UUID/public-ID/source identity is expanded in place; import/replay preserves every accepted mapping and fails atomically on missing, duplicate, ambiguous, changed, or renumbered identity.
- All Event fields, constraints, lifecycle transitions, registration-availability derivation, revision conflicts, archive/delete protection, calendar UID, and sequence behavior match the normative contract and contain no capacity/waitlist field.
- Legacy naive timestamps use accepted
Europe/Berlin/fold=0interpretation, persist UTC plus IANA timezone, and render correctly across DST and leap-day cases. -
/eventsand/events/<positive-public-id>/<current-title-slug>are the only emitted hub/detail canonicals; exact aliases redirect one hop with raw query preservation, malformed/unrecorded paths fail closed, and metadata/links/feeds/sitemap/builders contain no UUID canonical. - Public content, location, join-information separation, lifecycle visibility, error/empty states, caching, SEO, accessibility, responsive behavior, and calendar output pass.
- Speaker/host relations resolve #40 canonical active
shortidentities, preserve role/order, and block unsafe deletion/rename without an accepted alias/replacement. - Studio/admin API Event capabilities use one service, exact permissions, revision/idempotency policy, safe denials, and redacted audit/OpenAPI parity without production identity or credential inference.
- Registered-event title/time/location edits require an explicit summary/notification-decision result and correct calendar sequence, while this issue creates zero delivery/job/Relay/provider side effects.
- #112 zero/one/many aggregate display, incomplete/source-missing omission, source-to-UUID attachment, replacement/rollback, and no-attendee-identity invariants pass without count drift.
- A current versioned verification plan, focused Django/migration/concurrency/security tests, graph-selected Playwright/container checks, independent desktop/mobile screenshots, tester PASS, and PM acceptance exist before commit.
Required test scenarios
- Create/import/replay; accepted and forbidden lifecycle transitions; stale revision; title rename/alias; archive/delete protection; registration-window boundaries; Europe/Berlin UTC conversion, ambiguous fold, DST changes, and leap day.
- Stable calendar UID, exact sequence increments for reschedule/cancel, cancelled ICS representation, replay/idempotency, and no email/job/network side effect.
- Missing/inactive/renamed Person, duplicate role/order, one Person in multiple roles, protected join information, unsafe content, and cross-domain relationship safety.
- Exhaustive checked Event alias manifest: numeric canonical, numeric-only, stale slug, accepted UUID/date variants, raw query, client-side fragment, malformed/encoded/case/slash variants, missing IDs, no chain/loop, and canonical/OG/JSON-LD/breadcrumb/feed/sitemap finals.
- Exact zero/one/many complete historical totals, incomplete/source-missing/quarantine omission, source attachment, native replacement and rollback, no double count, and zero attendee identity.
- Studio/API allowed and denied roles, object/field denial, stale
If-Match, retry/idempotency, validation, preview/publish/complete/cancel/archive, people ordering, calendar change, audit redaction, and parity.
Playwright
At approximately 1440x900 and 390x844, with JavaScript on/off as selected by the verification graph, navigate the Event hub, canonical detail, checked redirects, calendar action, and Studio Event flows. Inspect published/draft/cancelled/completed, upcoming/past/empty/error states; Person links/order; timezone/location; exact aggregate copy; protected join-information absence; canonical URL/metadata; keyboard/focus/zoom/reflow; safe denials; and screenshots. No screenshot may contain protected join data, attendee identity, token, credential, or registration email.
Dependencies and sequencing
- Accepted/integrated inputs: #18, #19, #31, #35, #86, #87, #136, and #173.
- Full completion depends on accepted/integrated #289 for the Event lifecycle/calendar core and accepted/integrated #40 for canonical Person relationships.
- #112 is an existing aggregate-only integration contract and separate HUMAN protected-source gate; it is not permission to read protected data.
- #32/#33 are later production identity/high-risk acceptance gates, not prerequisites for Event domain source work.
- #46 consumes the finished Event lifecycle/registration-window/revision interface. #49 supplies durable delivery independently. Neither is a #45 prerequisite, and #45 does not own their identity, preference, token, email, Relay, credential, or provider behavior.
- Before any engineer handoff, use a clean current
origin/mainwhose release/source provenance and required baseline CI gates are green; do not build from the dirty redesign checkout or treat an old scheduled run as current evidence.
Explicit non-goals
No capacity/waitlist; native registration/token/attendance/export implementation; email preference; EmailDelivery; Relay/template/provider work; account/profile/social/OIDC behavior; production credential or protected-source access; public attendee identity/list; physical delete after dependent records; guessed calendar endpoint; catch-all/homepage redirect; or route-family redesign outside Events.
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 the normative contracts in _docs/specs/05-events-registration-email.md, _docs/specs/02-url-link-seo-compatibility.md, _docs/specs/06-studio-and-admin-api.md, and _docs/specs/07-security-privacy-operations.md, then review blocked dependencies #289 and #40. Work cannot begin until those dependencies are integrated; done requires the lifecycle, public routes, Person relationships, APIs, calendar behavior, and listed Django, migration, security, accessibility, and verification tests to pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, python
- Domain
- api, backend, database, frontend, full-stack, security, testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100