500f441807
## Summary Partner profile pages (`/partners/profile/[slug]`) returned **404 on every slug** on OpenNext/Cloudflare while `/partners/list` showed live partners from the same API. PR #21963 fixed the list with `export const dynamic = 'force-dynamic'` but only added `dynamicParams = true` on profiles. That is not sufficient on OpenNext — the Worker kept serving **cached prerendered 404s** even when `TWENTY_PARTNERS_API_KEY` was present at runtime. This PR mirrors the list page: **`force-dynamic` on the profile route**, plus a small lint guard so both marketplace routes stay dynamic. ## Root cause Partner data is fetched server-side from `https://partners.twenty.com/s/partners` using `TWENTY_PARTNERS_API_KEY`. That key is a **Wrangler runtime secret** (not in `dev.env` / `prod.env`, not available during CI build — by repo convention). | Route | Before | Behavior | |-------|--------|----------| | `/partners/list` | `force-dynamic` (#21963) | Fetches at request time on Worker → works | | `/partners/profile/[slug]` | static + `dynamicParams = true` | Build prewarm often empty; OpenNext served cached 404 | ## Fix - Add `export const dynamic = 'force-dynamic'` to `profile/[slug]/page.tsx` (keep `dynamicParams = true`). - Add `scripts/check-partners-marketplace-routes.mjs` — fails lint if list or profile drop `force-dynamic`. - Wire guard into `project.json` `lint` target (runs before existing `check-conventions.mjs`). **No infra changes.** We intentionally did not add a GitHub Actions secret for the API key — that would contradict the documented pattern (`wrangler secret put` only). ## Verification - [x] `node scripts/check-partners-marketplace-routes.mjs` → OK - [x] `npx jest src/partners-marketplace` → 36/36 pass - [x] Deployed to **dev** (`deploy-website`, env `dev`, ref `rk-partner-profile-404`) - [x] `curl -sI https://twenty-main.com/partners/profile/atlasprods-technologies-llp` → **HTTP 200** - [x] Browser: list → profile link loads ## Test plan - [ ] CI lint + tests green - [ ] After merge: deploy prod when ready (`environment: prod`, confirm `website`) - [ ] Spot-check `https://twenty.com/partners/profile/<slug>` → 200 ## Out of scope - Build-time `generateStaticParams` prewarm (would need a separate infra discussion; not required once profiles are `force-dynamic`) - Per-slug `/s/partner-by-slug` endpoint (optional perf follow-up) <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/22120?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
72 lines
1.8 KiB
JSON
72 lines
1.8 KiB
JSON
{
|
|
"name": "twenty-website",
|
|
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
"sourceRoot": "packages/twenty-website/src",
|
|
"projectType": "application",
|
|
"tags": ["scope:website"],
|
|
"targets": {
|
|
"dev": {
|
|
"executor": "nx:run-commands",
|
|
"options": {
|
|
"cwd": "{projectRoot}",
|
|
"command": "npx next dev --port 3002"
|
|
}
|
|
},
|
|
"build": {
|
|
"executor": "nx:run-commands",
|
|
"options": {
|
|
"cwd": "{projectRoot}",
|
|
"command": "npx next build"
|
|
}
|
|
},
|
|
"typecheck": {
|
|
"executor": "nx:run-commands",
|
|
"dependsOn": ["^build"],
|
|
"options": {
|
|
"cwd": "{projectRoot}",
|
|
"command": "npx tsc -p tsconfig.json --noEmit"
|
|
}
|
|
},
|
|
"test": {
|
|
"executor": "nx:run-commands",
|
|
"dependsOn": ["^build"],
|
|
"options": {
|
|
"cwd": "{projectRoot}",
|
|
"command": "npx jest --config=jest.config.mjs"
|
|
}
|
|
},
|
|
"lint": {
|
|
"executor": "nx:run-commands",
|
|
"options": {
|
|
"cwd": "{projectRoot}",
|
|
"command": "node scripts/check-partners-marketplace-routes.mjs && node scripts/check-conventions.mjs && npx oxlint -c .oxlintrc.json . && npx oxfmt --check ."
|
|
},
|
|
"configurations": {
|
|
"fix": {
|
|
"command": "npx oxfmt ."
|
|
}
|
|
},
|
|
"dependsOn": [
|
|
{
|
|
"projects": ["twenty-ui"],
|
|
"target": "build"
|
|
}
|
|
]
|
|
},
|
|
"lingui:extract": {
|
|
"executor": "nx:run-commands",
|
|
"options": {
|
|
"cwd": "{projectRoot}",
|
|
"command": "lingui extract --overwrite --clean"
|
|
}
|
|
},
|
|
"lingui:compile": {
|
|
"executor": "nx:run-commands",
|
|
"options": {
|
|
"cwd": "{projectRoot}",
|
|
"command": "lingui compile --typescript"
|
|
}
|
|
}
|
|
}
|
|
}
|