refactor(settings): remove the preview-feature opt-ins

The per-account preview switch was kept for the topic overview pages,
which were dropped before they shipped. Its one flag was stored, served
and backed up, and read by nothing; the column-reader audit listed it as
a pending consumer that will not come.

Removed completely:

- `/api/settings/preview-features` (GET, PATCH) is retired: it answers
  410 Gone with `meta.errorCode: route.retired` and `removedIn: 1.46.0`,
  and the contract publishes it under Retired. The route, its validation
  schema, the `PreviewFeatures` OpenAPI schemas and the settings module
  are deleted.
- Migration 0485 drops `users.preview_features_json` under a bounded lock
  wait, with the retry marker.
- The backup no longer writes the field. A file from v1.44 or v1.45 that
  carries it still restores: the schema accepts it and no codec reads it,
  so nothing is refused or written for it. The backup-parity goldens
  lose the field and apply one setting fewer.
- The data-wipe plan entry and the sharing-surface actor entry go with
  the route (frozen count 273 -> 272).

No client build reads the route: neither iOS repository nor any local
checkout references it.
This commit is contained in:
Marc-André Bombeck committed 2026-10-25 00:44:15 +02:00
1 parent f3b9329fb2
commit 2ae23f4ca8
26 files changed
+125 -437

No files matched your search

+55 -89
View File
@@ -15428,45 +15428,6 @@ paths:
"403": *a9
"422": *a4
"429": *a5
/api/settings/preview-features:
get:
tags:
- Meta
summary: Get the preview-feature opt-ins
description: Every flag, off unless the caller switched it on.
responses:
"200":
description: The opt-ins.
content:
application/json:
schema:
$ref: "#/components/schemas/PreviewFeaturesEnvelope"
"401": *a1
"403": *a9
"422": *a4
"429": *a5
patch:
tags:
- Meta
summary: Switch preview features on or off
description: Sets the flags the body names and keeps the rest. An unknown flag or an empty body is refused with 422.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PreviewFeaturesPatchBody"
responses:
"200":
description: The opt-ins as stored.
content:
application/json:
schema:
$ref: "#/components/schemas/PreviewFeaturesSavedEnvelope"
"401": *a1
"403": *a9
"422": *a4
"429": *a5
/api/settings/privacy-summary:
get:
tags:
@@ -27212,6 +27173,61 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
/api/settings/preview-features:
get:
security: []
deprecated: true
tags:
- Retired
summary: GET /api/settings/preview-features — removed in v1.46.0
description: >-
Removed in v1.46.0. Every request to this path answers 410 Gone, whatever the method and whatever credential it
carries. There is no replacement; the capability is gone rather than moved.
Stored per-account opt-ins to preview features, of which there was one, the topic overview pages. Those pages
were dropped before they shipped, so the switch governed nothing; the route and its column are gone, and no
preview is gated per account.
Retiring a path is deliberate, so the answer says so rather than leaving a client to read a 404 as a broken
deployment and retry forever. Treat 410 as terminal: drop the call, degrade the surface that depended on it, and
do not offer a retry.
responses:
"410":
description: The path was removed in v1.46.0 and will not answer again. `meta.errorCode` = `route.retired`,
`meta.removedIn` carries the version, and `meta.replacedBy` carries the replacement path or null.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
patch:
security: []
deprecated: true
tags:
- Retired
summary: PATCH /api/settings/preview-features — removed in v1.46.0
description: >-
Removed in v1.46.0. Every request to this path answers 410 Gone, whatever the method and whatever credential it
carries. There is no replacement; the capability is gone rather than moved.
Stored per-account opt-ins to preview features, of which there was one, the topic overview pages. Those pages
were dropped before they shipped, so the switch governed nothing; the route and its column are gone, and no
preview is gated per account.
Retiring a path is deliberate, so the answer says so rather than leaving a client to read a 404 as a broken
deployment and retry forever. Treat 410 as terminal: drop the call, degrade the surface that depended on it, and
do not offer a retry.
responses:
"410":
description: The path was removed in v1.46.0 and will not answer again. `meta.errorCode` = `route.retired`,
`meta.removedIn` carries the version, and `meta.replacedBy` carries the replacement path or null.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
components:
schemas:
CreateCycleCustomSymptomRequest:
@@ -33264,12 +33280,6 @@ components:
- version
- list
additionalProperties: false
PreviewFeaturesPatchBody:
type: object
properties:
topics:
type: boolean
additionalProperties: false
ConsentPostBody:
type: object
properties:
@@ -73560,50 +73570,6 @@ components:
- data
- error
additionalProperties: false
PreviewFeaturesEnvelope:
type: object
properties:
data:
$ref: "#/components/schemas/PreviewFeatures"
error:
type: "null"
meta:
type: object
properties:
requestId:
type: string
additionalProperties: false
required:
- data
- error
additionalProperties: false
PreviewFeatures:
type: object
properties:
topics:
type: boolean
description: Topic overview pages above the single-metric Insights pages. Off by default.
required:
- topics
additionalProperties: false
description: Per-user opt-in to preview features, one boolean per flag, every flag off by default.
PreviewFeaturesSavedEnvelope:
type: object
properties:
data:
$ref: "#/components/schemas/PreviewFeatures"
error:
type: "null"
meta:
type: object
properties:
requestId:
type: string
additionalProperties: false
required:
- data
- error
additionalProperties: false
PrivacySummaryEnvelope:
type: object
properties: