You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PAGE_PREVIEWS_TOKEN_TTL_SECONDS = 30 # The front end receives a presigned url. This setting defines the token expiry window. It is recommended to keep this as low as possible, and can possibly be set to as low as 30 seconds, the time it takes for the front end to render the page. Default is 30 seconds. It is recommended to set this to a higher threshold in development environments (e.g. 86400, which is 24 hours).
94
94
```
95
95
96
-
## Files Changed (Best viewed in VSCode)
97
-
98
-
| File Name | Purpose of Change | Process (Inputs, Process, Outputs, Example) |
| config.py | Provides the app-level secret source used by preview token salt derivation. |**Input:**`SECRET_KEY` from environment.<br>**Process:** Preview token salt generation depends on this configured secret.<br>**Output:** Stable secret material consumed by preview signing settings.<br>**Example:** Input: `SECRET_KEY=abc`; Output: deterministic salt derivation path enabled. |
101
-
| metrics/api/settings/default.py | Introduces/updates preview settings and deterministic `PAGE_PREVIEWS_TOKEN_SALT`. |**Input:**`PAGE_PREVIEWS_*` env values + `SECRET_KEY`.<br>**Process:** Adds preview flags/TTL defaults and derives the preview salt via HMAC from `SECRET_KEY`.<br>**Output:** Runtime settings for redirect signing and token validation.<br>**Example:** Input: `PAGE_PREVIEWS_TOKEN_TTL_SECONDS=30`; Output: short-lived signed preview tokens. |
102
-
| metrics/api/settings/local.py | Sets local-development overrides for preview behavior. |**Input:** Local settings profile.<br>**Process:** Applies local overrides so preview/time-travel can be exercised in development.<br>**Output:** Dev-ready preview configuration.<br>**Example:** Input: local env boot; Output: preview flow available locally. |
103
-
| metrics/api/settings/public_api.py | Aligns public API settings touched by preview/time-travel integration. |**Input:** Public API settings module.<br>**Process:** Updates public API settings where needed for compatibility with preview token handling.<br>**Output:** Consistent preview-related behavior in public API runtime.<br>**Example:** Input: public API deployment; Output: compatible preview auth/settings behavior. |
104
-
| docs/environment_variables.md | Documents PR-added preview and time-travel settings semantics. |**Input:** Implemented redirect/token behavior.<br>**Process:** Documents `et`, token template behavior, and preview env vars.<br>**Output:** Updated operator/developer setup guidance.<br>**Example:** Input: deployment setup task; Output: correct env var configuration for previews. |
105
-
| cms/dashboard/models.py | Adds dashboard-page participation in preview enablement. |**Input:** Dashboard page model definitions.<br>**Process:** Introduces preview-related model behavior used by admin hooks and preview routes.<br>**Output:** Dashboard page models eligible for preview flow.<br>**Example:** Input: dashboard page edit; Output: preview button eligibility. |
106
-
| cms/common/models.py | Extends common page types for preview support. |**Input:** Common page model definitions.<br>**Process:** Adds preview capability hooks/fields required by the external preview workflow.<br>**Output:** Common page types included in preview rollout.<br>**Example:** Input: common page draft; Output: previewable model state. |
107
-
| cms/composite/models.py | Enables composite pages for the new external preview flow. |**Input:** Composite model definitions.<br>**Process:** Adds preview-specific behavior so composite drafts can be resolved by preview endpoints.<br>**Output:** Composite pages supported by preview API path.<br>**Example:** Input: composite draft revision; Output: returned by draft preview endpoint. |
108
-
| cms/home/models/landing_page.py | Adds landing page preview support for this feature rollout. |**Input:** Landing page model definition.<br>**Process:** Updates preview enablement on landing pages.<br>**Output:** Landing pages can use preview-to-frontend flow.<br>**Example:** Input: LandingPage edit session; Output: preview action available. |
109
-
| cms/topic/models.py | Adds topic page preview support for this feature rollout. |**Input:** Topic page model definition.<br>**Process:** Updates preview enablement on topic pages.<br>**Output:** Topic pages can use preview-to-frontend flow.<br>**Example:** Input: TopicPage edit session; Output: preview action available. |
110
-
| cms/dashboard/serializers.py | Extends serialized output used by draft preview responses. |**Input:** Draft/published page objects.<br>**Process:** Adjusts serialization needed by the frontend preview consumer.<br>**Output:** Preview-compatible page JSON structure.<br>**Example:** Input: page instance; Output: serialized payload used by `/api/drafts/{id}`. |
111
-
| cms/dashboard/wagtail_hooks.py | Registers PR-specific admin actions/routes for external preview. |**Input:** Wagtail hook registry + action menu context.<br>**Process:** Wires preview action(s) to `/admin/preview-to-frontend/{id}/` and related menu behavior.<br>**Output:** Admin UI entry point into preview redirect flow.<br>**Example:** Input: edit page action menu; Output: preview button triggers redirect endpoint. |
112
-
| cms/dashboard/templates/wagtailadmin/base.html | Adds template-level admin integration required by this PR. |**Input:** Wagtail admin base template.<br>**Process:** Includes/extends blocks needed for preview-related UI customizations.<br>**Output:** Base admin template supports preview custom assets/components.<br>**Example:** Input: admin page render; Output: custom preview template blocks loaded. |
113
-
| cms/dashboard/templates/wagtailadmin/pages/action_menu/frontend_viewlive.html | Updates View Live action template alongside preview changes. |**Input:** Action menu rendering context.<br>**Process:** Aligns view-live template behavior with the new preview action menu setup.<br>**Output:** Action menu remains consistent with preview rollout.<br>**Example:** Input: live page menu render; Output: correct action ordering/markup. |
114
-
| cms/dashboard/templates/wagtailadmin/pages/action_menu/frontend_preview.html | Adds the PR Preview + Time Travel modal markup and controls. |**Input:** Preview action template context.<br>**Process:** Renders preview button, modal container, and time-travel control elements used by picker JS/CSS.<br>**Output:** UI surface for selecting embargo time and launching preview.<br>**Example:** Input: edit page action menu; Output: Preview + Time Travel controls visible. |
115
-
| cms/dashboard/templates/icons/preview.svg | Adds/updates icon asset used by preview action introduced here. |**Input:** Wagtail icon lookup by name.<br>**Process:** Provides the preview icon used in action menu templates.<br>**Output:** Icon renders correctly in preview button context.<br>**Example:** Input: `{% icon name="preview" %}`; Output: preview SVG rendered. |
116
-
| cms/dashboard/templates/icons/rocket.svg | Adds/updates icon asset used by Time Travel action introduced here. |**Input:** Wagtail icon lookup by name.<br>**Process:** Provides the rocket icon used beside Time Travel controls.<br>**Output:** Time Travel button/icon renders as designed.<br>**Example:** Input: `{% icon name="rocket" %}`; Output: rocket SVG rendered. |
117
-
| cms/dashboard/static/css/vendor/flatpickr.min.css | Vendors Flatpickr styles required for the PR’s date picker. |**Input:** Flatpickr calendar markup in modal.<br>**Process:** Bundles vendor CSS dependency used by embargo picker UI.<br>**Output:** Baseline styling for calendar widget.<br>**Example:** Input: open Time Travel modal; Output: styled flatpickr calendar. |
118
-
| cms/dashboard/static/js/vendor/flatpickr.min.js | Vendors Flatpickr runtime required for the PR’s date picker. |**Input:** Picker initialization call from embargo JS.<br>**Process:** Bundles vendor JS dependency powering date selection.<br>**Output:** Interactive calendar behavior available in admin modal.<br>**Example:** Input: initialize picker; Output: selectable inline calendar. |
119
-
| cms/dashboard/static/css/embargo_time_picker.css | Adds PR-specific styling for the Time Travel picker/modal. |**Input:** Modal/button/calendar DOM from preview template.<br>**Process:** Styles picker layout, navigation visibility, and control states (including accessibility-focused updates).<br>**Output:** Usable, visible Time Travel UI in admin.<br>**Example:** Input: open picker; Output: month/year controls visible without hover. |
120
-
| cms/dashboard/static/js/embargo_time_picker.js | Implements the PR’s embargo selection and preview URL augmentation. |**Input:** Editor selection (`now` or date) and Preview click.<br>**Process:** Captures selected time and appends `embargo_time` query value before opening preview redirect.<br>**Output:** Redirect request carries embargo context to backend/frontend.<br>**Example:** Input: choose date + click preview; Output: request includes `embargo_time=<epoch>`. |
121
-
| cms/dashboard/views.py | Implements preview redirect endpoint changes for token + `et` propagation. |**Input:** GET `/admin/preview-to-frontend/{id}` + optional `embargo_time`.<br>**Process:** Validates/normalizes embargo input, adds embargo claim to signed payload, and appends `et` to frontend redirect URL.<br>**Output:** Signed redirect URL with consistent preview/time-travel context.<br>**Example:** Input: `embargo_time=now`; Output: redirect contains token + `et=now`. |
122
-
| validation/shared.py | Extends shared token validation/decoding used by preview and middleware paths. |**Input:** Bearer token presented by frontend/API callers.<br>**Process:** Provides shared payload extraction/verification used by draft endpoint and embargo middleware.<br>**Output:** Unified token validation behavior across preview paths.<br>**Example:** Input: preview token; Output: decoded payload consumed by viewset/middleware. |
123
-
| metrics/api/middleware.py | Adds request-scoped embargo-time setup for API requests with valid preview token. |**Input:**`/api/*` requests with `x-cms-auth` header.<br>**Process:** Validates token, sets/clears context embargo time, and returns appropriate 401/501 responses for invalid/time-travel-disabled cases.<br>**Output:** API requests execute with correct virtual clock context.<br>**Example:** Input: token with `embargo_time`; Output: `virtual_clock` set for request duration. |
124
-
| cms/dashboard/virtual_clock.py | Introduces/updates PR-specific virtual clock primitives for embargo time travel. |**Input:** Embargo values from token/query (`now` or epoch).<br>**Process:** Parses values, validates token context when setting, stores request-scoped embargo datetime, and falls back to `timezone.now()` when unset/invalid.<br>**Output:** Single source of truth for embargo-aware “current time”.<br>**Example:** Input: `1711456200`; Output: timezone-aware embargo datetime in contextvar. |
125
-
| cms/dashboard/viewsets.py | Updates draft endpoint to enforce token rules and return embargo metadata. |**Input:** GET `/api/drafts/{id}` + Bearer token payload.<br>**Process:** Validates token/page, applies `set_embargo_time`, handles 401/501 branches, and appends `embargo_time` to response via `_with_embargo_time`.<br>**Output:** Draft response aligned to virtual time and containing embargo metadata.<br>**Example:** Input: valid token with embargo claim; Output: 200 response with `"embargo_time"`. |
126
-
| metrics/data/managers/core_models/time_series.py | Updates embargo filtering to use virtual clock during preview. |**Input:** Time series querysets with embargoed records.<br>**Process:** Switches embargo cutoff checks to `get_embargo_time()` for preview-time consistency.<br>**Output:** Time-series visibility follows selected Time Travel datetime.<br>**Example:** Input: future embargo + simulated future time; Output: record becomes visible. |
127
-
| metrics/data/managers/api_models/time_series.py | Updates API-model embargo filtering to use virtual clock during preview. |**Input:** API-facing time series querysets.<br>**Process:** Replaces runtime cutoff source with `get_embargo_time()` in embargo checks.<br>**Output:** API response filtering matches preview virtual time.<br>**Example:** Input: preview token embargo claim; Output: embargo filtering uses virtual clock. |
128
-
| metrics/data/managers/core_models/headline.py | Updates headline embargo checks to use virtual clock during preview. |**Input:** Headline querysets with embargo fields.<br>**Process:** Changes headline embargo comparisons to `get_embargo_time()`.<br>**Output:** Headline visibility is consistent with Time Travel selection.<br>**Example:** Input: embargoed headline + virtual future time; Output: headline included. |
129
-
| metrics/interfaces/weather_health_alerts/access.py | Updates weather health alerts embargo access to use virtual clock. |**Input:** Weather alert period end timestamps.<br>**Process:** Evaluates release conditions against `get_embargo_time()`.<br>**Output:** Weather alert preview behavior aligned with embargo time travel.<br>**Example:** Input: alert ending after now but before virtual time; Output: alert shown in preview. |
130
-
| scripts/_quality.sh | Includes an unrelated shell ergonomics fix included on this branch. |**Input:** Quality script invocation from sourced shell.<br>**Process:** Changes script flow to return instead of exit where appropriate.<br>**Output:** Shell session remains open after script completion.<br>**Example:** Input: source and run quality script; Output: terminal not terminated. |
131
-
| tests/integration/cms/test_api.py | Adds integration coverage for preview draft retrieval behavior. |**Input:** Requests to `/api/drafts` endpoints in integration tests.<br>**Process:** Verifies draft endpoint returns expected revision/data behavior under preview usage.<br>**Output:** Integration safety net for preview API behavior.<br>**Example:** Input: unpublished revision exists; Output: latest draft returned. |
132
-
| tests/unit/cms/dashboard/test_models.py | Adds unit tests for model preview enablement changes. |**Input:** Updated page model preview logic.<br>**Process:** Asserts page types expose expected preview support behavior.<br>**Output:** Confidence that model-level preview gating works as intended.<br>**Example:** Input: preview-enabled model; Output: expected eligibility result. |
133
-
| tests/unit/cms/dashboard/test_serializers.py | Adds unit tests for serializer changes used by preview responses. |**Input:** Serializer output for previewed pages.<br>**Process:** Validates adjusted serialized fields used by frontend preview payloads.<br>**Output:** Stable serializer contract for preview consumer.<br>**Example:** Input: page object; Output: expected serialized keys/values. |
134
-
| tests/unit/cms/dashboard/test_wagtail_hooks.py | Adds unit tests for new/updated preview hooks. |**Input:** Hook registration and action menu context.<br>**Process:** Verifies preview hook wiring and action rendering logic.<br>**Output:** Regression protection for admin hook integration.<br>**Example:** Input: hook discovery; Output: preview route/action hook present. |
135
-
| tests/unit/cms/dashboard/test_preview_views_and_hooks.py | Adds unit coverage for redirect/token/`et` behavior. |**Input:** Redirect view requests with `embargo_time` variants.<br>**Process:** Asserts token payload content, URL construction, and `et` propagation edge cases.<br>**Output:** Confidence in preview redirect and time-travel query handling.<br>**Example:** Input: `embargo_time=1711456200`; Output: redirect query contains `et=1711456200`. |
136
-
| tests/unit/cms/dashboard/test_viewsets.py | Adds unit coverage for draft endpoint auth + embargo handling. |**Input:** Draft viewset requests with mocked token payloads.<br>**Process:** Tests success/error paths for token validation, time-travel support checks, and `embargo_time` response field inclusion.<br>**Output:** Verified draft endpoint behavior for preview time travel.<br>**Example:** Input: invalid token; Output: 401 response. |
137
-
| tests/unit/cms/dashboard/test_virtual_clock.py | Adds unit coverage for new virtual clock behavior. |**Input:** Parse/set/get/clear operations with valid and invalid values.<br>**Process:** Validates parsing rules, token-gated setting, fallback behavior, and context clearing.<br>**Output:** Confidence in virtual clock correctness and safety.<br>**Example:** Input: invalid embargo value; Output: set rejected / fallback applies. |
138
-
| tests/unit/metrics/api/test_middleware.py | Adds unit coverage for middleware embargo context and auth handling. |**Input:** API requests with/without CMS auth header/token.<br>**Process:** Verifies middleware sets/clears embargo context and returns expected 401/501 paths.<br>**Output:** Reliable middleware behavior for preview-authenticated API calls.<br>**Example:** Input: malformed bearer header; Output: 401 invalid token detail. |
139
-
| tests/unit/metrics/api/test_settings_preview_salt.py | Adds unit tests for deterministic preview salt derivation. |**Input:** Multiple `SECRET_KEY` values in test context.<br>**Process:** Asserts same key => same salt, different keys => different salts.<br>**Output:** Confidence in deterministic and isolated token salt behavior.<br>**Example:** Input: `secret-one` and `secret-two`; Output: two distinct salts. |
140
-
| changelog/2026-02-27/CDD-1379.page-previews.md | Records the PR’s architecture, security, flow, and file-level implementation notes. |**Input:** Finalized implementation and review feedback.<br>**Process:** Updates summary/workflow, adds embargo time-travel architecture notes, and regenerates this file-change matrix.<br>**Output:** PR-focused handover documentation.<br>**Example:** Input: branch diff + design decisions; Output: updated changelog entry. |
0 commit comments