From 2e36cdd14261baa04a08af1a238684c3945e40b3 Mon Sep 17 00:00:00 2001 From: Charlie Hopkins-Brinicombe Date: Tue, 28 Jul 2026 10:56:45 +0100 Subject: [PATCH 1/4] Update endpoint pages to use remote specs. --- .cursor/rules/localization-workflow.mdc | 2 +- README.md | 4 +- .../create-application-api-keys.mdx | 2 +- .../delete-application-api-keys.mdx | 2 +- .../attributes/create-attributes.mdx | 2 +- .../attributes/delete-attributes.mdx | 2 +- .../endpoints/attributes/get-an-attribute.mdx | 2 +- .../endpoints/attributes/list-attributes.mdx | 2 +- .../attributes/update-attributes.mdx | 2 +- .../leaderboards/create-leaderboards.mdx | 2 +- .../leaderboards/delete-leaderboards.mdx | 2 +- .../leaderboards/get-a-leaderboard.mdx | 2 +- .../leaderboards/list-leaderboards.mdx | 2 +- .../leaderboards/update-leaderboards.mdx | 2 +- .../endpoints/metrics/create-metrics.mdx | 2 +- .../endpoints/metrics/delete-metrics.mdx | 2 +- admin-api/endpoints/metrics/get-a-metric.mdx | 2 +- admin-api/endpoints/metrics/list-metrics.mdx | 2 +- .../endpoints/metrics/update-metrics.mdx | 2 +- admin-api/endpoints/points/create-boosts.mdx | 2 +- admin-api/endpoints/points/create-levels.mdx | 2 +- .../points/create-points-systems.mdx | 2 +- .../points/create-points-triggers.mdx | 2 +- admin-api/endpoints/points/delete-boosts.mdx | 2 +- admin-api/endpoints/points/delete-levels.mdx | 2 +- .../points/delete-points-systems.mdx | 2 +- .../points/delete-points-triggers.mdx | 2 +- admin-api/endpoints/points/get-a-boost.mdx | 2 +- admin-api/endpoints/points/get-a-level.mdx | 2 +- .../endpoints/points/get-a-points-system.mdx | 2 +- .../endpoints/points/get-a-points-trigger.mdx | 2 +- admin-api/endpoints/points/list-boosts.mdx | 2 +- admin-api/endpoints/points/list-levels.mdx | 2 +- .../endpoints/points/list-points-systems.mdx | 2 +- .../endpoints/points/list-points-triggers.mdx | 2 +- admin-api/endpoints/points/update-boosts.mdx | 2 +- admin-api/endpoints/points/update-levels.mdx | 2 +- .../points/update-points-systems.mdx | 2 +- .../points/update-points-triggers.mdx | 2 +- admin-api/endpoints/streaks/grant-freezes.mdx | 2 +- .../endpoints/streaks/restore-streaks.mdx | 2 +- .../endpoints/tenants/create-tenants.mdx | 2 +- .../endpoints/tenants/delete-tenants.mdx | 2 +- admin-api/endpoints/tenants/get-a-tenant.mdx | 2 +- admin-api/endpoints/tenants/list-tenants.mdx | 2 +- .../endpoints/tenants/update-tenants.mdx | 2 +- .../achievements/all-achievements.mdx | 2 +- .../mark-an-achievement-as-completed.mdx | 2 +- .../get-all-active-leaderboards.mdx | 2 +- .../leaderboards/get-leaderboard.mdx | 2 +- .../metrics/send-a-metric-change-event.mdx | 2 +- .../endpoints/points/get-points-boosts.mdx | 2 +- .../points/get-points-level-summary.mdx | 2 +- .../endpoints/points/get-points-levels.mdx | 2 +- .../endpoints/points/get-points-summary.mdx | 2 +- api-reference/endpoints/points/get-points.mdx | 2 +- .../endpoints/streaks/get-streaks.mdx | 2 +- .../endpoints/users/create-a-user.mdx | 2 +- ...single-metric-event-summary-for-a-user.mdx | 2 +- .../users/get-a-single-metric-for-a-user.mdx | 2 +- .../endpoints/users/get-a-single-user.mdx | 2 +- .../get-a-users-completed-achievements.mdx | 2 +- .../users/get-a-users-leaderboard.mdx | 2 +- .../users/get-a-users-points-boosts.mdx | 2 +- .../users/get-a-users-points-summary.mdx | 2 +- .../endpoints/users/get-a-users-points.mdx | 2 +- .../endpoints/users/get-a-users-streak.mdx | 2 +- .../endpoints/users/get-a-users-wrapped.mdx | 2 +- .../users/get-all-metrics-for-a-user.mdx | 2 +- .../endpoints/users/get-user-preferences.mdx | 2 +- .../endpoints/users/identify-a-user.mdx | 2 +- .../endpoints/users/update-a-user.mdx | 2 +- .../users/update-user-preferences.mdx | 2 +- .../create-application-api-keys.mdx | 2 +- .../delete-application-api-keys.mdx | 2 +- .../attributes/create-attributes.mdx | 2 +- .../attributes/delete-attributes.mdx | 2 +- .../endpoints/attributes/get-an-attribute.mdx | 2 +- .../endpoints/attributes/list-attributes.mdx | 2 +- .../attributes/update-attributes.mdx | 2 +- .../leaderboards/create-leaderboards.mdx | 2 +- .../leaderboards/delete-leaderboards.mdx | 2 +- .../leaderboards/get-a-leaderboard.mdx | 2 +- .../leaderboards/list-leaderboards.mdx | 2 +- .../leaderboards/update-leaderboards.mdx | 2 +- .../endpoints/metrics/create-metrics.mdx | 2 +- .../endpoints/metrics/delete-metrics.mdx | 2 +- .../endpoints/metrics/get-a-metric.mdx | 2 +- .../endpoints/metrics/list-metrics.mdx | 2 +- .../endpoints/metrics/update-metrics.mdx | 2 +- .../endpoints/points/create-boosts.mdx | 2 +- .../endpoints/points/create-levels.mdx | 2 +- .../points/create-points-systems.mdx | 2 +- .../points/create-points-triggers.mdx | 2 +- .../endpoints/points/delete-boosts.mdx | 2 +- .../endpoints/points/delete-levels.mdx | 2 +- .../points/delete-points-systems.mdx | 2 +- .../points/delete-points-triggers.mdx | 2 +- es/admin-api/endpoints/points/get-a-boost.mdx | 2 +- es/admin-api/endpoints/points/get-a-level.mdx | 2 +- .../endpoints/points/get-a-points-system.mdx | 2 +- .../endpoints/points/get-a-points-trigger.mdx | 2 +- es/admin-api/endpoints/points/list-boosts.mdx | 2 +- es/admin-api/endpoints/points/list-levels.mdx | 2 +- .../endpoints/points/list-points-systems.mdx | 2 +- .../endpoints/points/list-points-triggers.mdx | 2 +- .../endpoints/points/update-boosts.mdx | 2 +- .../endpoints/points/update-levels.mdx | 2 +- .../points/update-points-systems.mdx | 2 +- .../points/update-points-triggers.mdx | 2 +- .../endpoints/streaks/grant-freezes.mdx | 2 +- .../endpoints/streaks/restore-streaks.mdx | 2 +- .../endpoints/tenants/create-tenants.mdx | 2 +- .../endpoints/tenants/delete-tenants.mdx | 2 +- .../endpoints/tenants/get-a-tenant.mdx | 2 +- .../endpoints/tenants/list-tenants.mdx | 2 +- .../endpoints/tenants/update-tenants.mdx | 2 +- .../achievements/all-achievements.mdx | 2 +- .../mark-an-achievement-as-completed.mdx | 2 +- .../get-all-active-leaderboards.mdx | 2 +- .../leaderboards/get-leaderboard.mdx | 2 +- .../metrics/send-a-metric-change-event.mdx | 2 +- .../endpoints/points/get-points-boosts.mdx | 2 +- .../points/get-points-level-summary.mdx | 2 +- .../endpoints/points/get-points-levels.mdx | 2 +- .../endpoints/points/get-points-summary.mdx | 2 +- .../endpoints/points/get-points.mdx | 2 +- .../endpoints/streaks/get-streaks.mdx | 2 +- .../endpoints/users/create-a-user.mdx | 2 +- ...single-metric-event-summary-for-a-user.mdx | 2 +- .../users/get-a-single-metric-for-a-user.mdx | 2 +- .../endpoints/users/get-a-single-user.mdx | 2 +- .../get-a-users-completed-achievements.mdx | 2 +- .../users/get-a-users-leaderboard.mdx | 2 +- .../users/get-a-users-points-boosts.mdx | 2 +- .../users/get-a-users-points-summary.mdx | 2 +- .../endpoints/users/get-a-users-points.mdx | 2 +- .../endpoints/users/get-a-users-streak.mdx | 2 +- .../endpoints/users/get-a-users-wrapped.mdx | 2 +- .../users/get-all-metrics-for-a-user.mdx | 2 +- .../endpoints/users/get-user-preferences.mdx | 2 +- .../endpoints/users/identify-a-user.mdx | 2 +- .../endpoints/users/update-a-user.mdx | 2 +- .../users/update-user-preferences.mdx | 2 +- .../achievements/achievement-completed.mdx | 2 +- es/webhooks/events/emails/achievement-due.mdx | 2 +- .../events/emails/reactivation-due.mdx | 2 +- es/webhooks/events/emails/recap-due.mdx | 2 +- .../events/emails/streak-reminder-due.mdx | 2 +- .../leaderboards/leaderboard-changed.mdx | 2 +- .../leaderboards/leaderboard-finished.mdx | 2 +- .../leaderboards/leaderboard-rank-changed.mdx | 2 +- .../leaderboards/leaderboard-started.mdx | 2 +- .../events/points/points-boost-finished.mdx | 2 +- .../events/points/points-boost-started.mdx | 2 +- es/webhooks/events/points/points-changed.mdx | 2 +- .../events/points/points-level-changed.mdx | 2 +- .../events/streaks/streak-extended.mdx | 2 +- .../events/streaks/streak-freeze-consumed.mdx | 2 +- .../events/streaks/streak-freeze-earned.mdx | 2 +- es/webhooks/events/streaks/streak-lost.mdx | 2 +- es/webhooks/events/streaks/streak-started.mdx | 2 +- i18n.lock | 178 +- openapi/admin.yml | 7425 ----------------- openapi/application.yml | 6230 -------------- scripts/sync-openapi-titles.mjs | 92 +- .../achievements/achievement-completed.mdx | 2 +- webhooks/events/emails/achievement-due.mdx | 2 +- webhooks/events/emails/reactivation-due.mdx | 2 +- webhooks/events/emails/recap-due.mdx | 2 +- .../events/emails/streak-reminder-due.mdx | 2 +- .../leaderboards/leaderboard-changed.mdx | 2 +- .../leaderboards/leaderboard-finished.mdx | 2 +- .../leaderboards/leaderboard-rank-changed.mdx | 2 +- .../leaderboards/leaderboard-started.mdx | 2 +- .../events/points/points-boost-finished.mdx | 2 +- .../events/points/points-boost-started.mdx | 2 +- webhooks/events/points/points-changed.mdx | 2 +- .../events/points/points-level-changed.mdx | 2 +- webhooks/events/streaks/streak-extended.mdx | 2 +- .../events/streaks/streak-freeze-consumed.mdx | 2 +- .../events/streaks/streak-freeze-earned.mdx | 2 +- webhooks/events/streaks/streak-lost.mdx | 2 +- webhooks/events/streaks/streak-started.mdx | 2 +- 184 files changed, 337 insertions(+), 13950 deletions(-) delete mode 100644 openapi/admin.yml delete mode 100644 openapi/application.yml diff --git a/.cursor/rules/localization-workflow.mdc b/.cursor/rules/localization-workflow.mdc index be3f6642..d056df8c 100644 --- a/.cursor/rules/localization-workflow.mdc +++ b/.cursor/rules/localization-workflow.mdc @@ -14,7 +14,7 @@ alwaysApply: true - `scripts/localize-mdx-paths.mjs` rewrites: `/components/*.jsx` for the active locale; `from ".../snippets/..."`; and JSX `src=".../assets/..."` so `../` depth matches the file’s path. Run after Lingo in `translate:generate` and translate-on-main; CI checks via `translate:localize-mdx-paths:check`. - Shared MDX snippets live under repo-root `snippets/` (not per-locale). Import with relative paths from each page; do not add shared MDX snippets to Lingo `i18n.json` buckets unless you intend to translate them. - Locale-aware React components that can contain text live under `components/*.jsx` for default language and `/components/*.jsx` for targets, and are manually maintained per locale (do not add them to Lingo `i18n.json` buckets; do not keep these in shared `snippets/`). -- Keep OpenAPI specs under repo-root `openapi/` (not under locale folders). Endpoint and webhook MDX must use Mintlify’s form `openapi: openapi/.yml ` or `openapi: openapi/.yml webhook `. Do not translate the `openapi:` line. +- Endpoint and webhook MDX must use hosted OpenAPI sources only: `openapi: "https://api.trophy.so/v1/openapi "` (Application API + webhooks) or `openapi: "https://admin.trophy.so/v1/openapi "` (Admin API). For webhooks use `openapi: "https://api.trophy.so/v1/openapi webhook "`. Do not translate or otherwise alter the `openapi:` line. - English **nav titles** for those pages come from OpenAPI **`summary`** via `scripts/sync-openapi-titles.mjs` (`npm run translate:sync-openapi-titles`). It runs at the start of `translate:generate` and on the translate-on-main workflow. Lingo translates the `title` field for target locales; the script only fills a missing target `title` with English (bootstrap)—it does not overwrite existing translations. - Mintlify custom heading IDs use markdown `## Title {#slug}` (see Mintlify docs). Slugs are aligned from English source root files via `scripts/sync-heading-anchors.mjs`. Never translate or alter `{#…}`; sync runs after Lingo in PIT/CI. Do not merge heading-count drift between source root and target locales without fixing structure first. - For Mintlify `` components that may be deep-linked, always set explicit `id` values (do not rely on title-derived hashes) and keep those `id`s identical across locales. diff --git a/README.md b/README.md index d910e7be..732cc5a5 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ Notes: - **Shared MDX snippets (`snippets/*.mdx`)**: Reusable MDX blocks stay in repo-root `snippets/` (not per-locale). Import them with relative paths from each page (for example `../../snippets/foo.mdx` from `locale/
/.mdx`, or more `../` segments for deeper pages). They are excluded from Lingo buckets in `i18n.json` so they stay English and identical everywhere. - **Localized React components (`components/*.jsx` for default language, `/components/*.jsx` for targets)**: UI components that can contain locale text are stored per locale (for example `components/rate-limit-badge.jsx`, `es/components/rate-limit-badge.jsx`) and manually maintained per locale (not translated by PIT/CI automation). - **Media paths**: Default-language pages live at repo root paths like `
/.mdx` and target locales live under `/
/.mdx`; shared files sit in repo-root `assets/`. Prefer relative `src="../assets/..."` (or more `../`) from English source; `scripts/localize-mdx-paths.mjs` rewrites `assets/` `src` depth for each target locale file. -- **`openapi/`**: Split OpenAPI 3.1 specs at the **repository root** (for example `openapi/application.yml`, `openapi/admin.yml`). API and webhook pages reference a spec explicitly in frontmatter, for example `openapi: openapi/application.yml get /users/{id}` or `openapi: openapi/application.yml webhook points.changed`. Do not duplicate the YAML under locale folders; Lingo must not alter `openapi:` lines. +- **Hosted OpenAPI specs**: API and webhook pages reference hosted specs in frontmatter: `https://api.trophy.so/v1/openapi` for Application API + webhooks, and `https://admin.trophy.so/v1/openapi` for Admin API. Example: `openapi: "https://api.trophy.so/v1/openapi get /users/{id}"` or `openapi: "https://api.trophy.so/v1/openapi webhook points.changed"`. Keep `openapi:` lines unchanged across locales; Lingo must not alter them. - **`scripts/sync-openapi-titles.mjs`**: Copies each operation/webhook **`summary`** from the referenced spec into the English page’s **`title:`** frontmatter (Mintlify’s default when `title` is omitted). Target locales get an English `title` only if missing (bootstrap); run **`npm run translate:generate`** so Lingo translates those titles. Runs automatically at the start of `translate:generate` and in translate-on-main before Lingo. - `scripts/sync-heading-anchors.mjs`: Writes Mintlify [custom heading IDs](https://www.mintlify.com/docs/create/text#custom-heading-ids) as **`## Title {#slug}`** markdown. Slugs match Mintlify’s auto rules from the **English** title so hashes like `#pro-plan` stay stable across locales. Run `npm run translate:sync-anchors` after bulk heading edits; translation pipelines run it automatically (see **Heading anchors and Lingo** below). The script can also migrate one-line **`

`** left from older tooling back to `{#slug}` syntax. - `scripts/validate-glossary-csv.mjs`: Validates glossary schema and duplicate canonical keys. Prefer `npm run lingo:validate-glossary`. @@ -92,7 +92,7 @@ Use `npm run