@se-studio/skills 1.4.1 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @se-studio/skills
|
|
2
2
|
|
|
3
|
+
## 1.4.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Document SSG guardrails (Biome, route-build-policy, validate-build-routes) in se-marketing-sites-smoke-test-setup skill.
|
|
8
|
+
|
|
9
|
+
## 1.4.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Add flat navigation assembly via `getNavigation` in `createAppHelpers` — menus resolve without Contentful include depth. Registry and link-index fetchers stay package-internal so apps cannot call them directly.
|
|
14
|
+
|
|
15
|
+
Flat-nav caches use collection tags (`FLAT_NAV_CACHE_TAGS`, including `tagType` and `link`) for webhook invalidation, with `FLAT_NAV_TIME_REVALIDATE_SECONDS` (3600) as an ISR fallback when webhooks miss.
|
|
16
|
+
|
|
17
|
+
Fix flat-nav Contentful fetches for spaces with differing content models (e.g. OM1): registry and link-wrapper fetches omit `select`; tagType bulk link fetches request golden `fields.slug` and fall back to minimal fields when absent. Unresolved nav targets log under `LOG_CMS`.
|
|
18
|
+
|
|
3
19
|
## 1.4.1
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -270,8 +270,67 @@ Remove legacy `smoke-test:validate-links`, `smoke-test-preload.cjs`, and bespoke
|
|
|
270
270
|
3. Update `@se-studio/site-check` to `^2.6.1` when adopting integrity; otherwise `^2.1.2` minimum.
|
|
271
271
|
4. Follow workflow above to create `smoke.cases.json`.
|
|
272
272
|
|
|
273
|
+
## SSG guardrails (all marketing sites)
|
|
274
|
+
|
|
275
|
+
Prevent `DYNAMIC_SERVER_USAGE` / production 500s on on-demand SSG routes (`●` in `next build`). Three layers — lint, build policy, production smoke.
|
|
276
|
+
|
|
277
|
+
### 1. Biome — ban dynamic request APIs in SSG surfaces
|
|
278
|
+
|
|
279
|
+
Copy the override block from `@se-studio/site-check/templates/biome-ssg-guardrails.override.json` into the app `biome.json` `overrides` array.
|
|
280
|
+
|
|
281
|
+
Restricts request-time Next.js APIs in:
|
|
282
|
+
|
|
283
|
+
- `src/app/layout.tsx`
|
|
284
|
+
- `src/app/(cms-routes)/**`
|
|
285
|
+
- `src/project/**`
|
|
286
|
+
|
|
287
|
+
Banned: `next/headers` (headers, cookies, draftMode), `connection` from `next/server`, `unstable_noStore` from `next/cache`. `unstable_cache` and other `next/cache` exports remain allowed.
|
|
288
|
+
|
|
289
|
+
Dynamic by design (no restriction): `(cms-dev)`, `preview`, `api`, `middleware.ts`.
|
|
290
|
+
|
|
291
|
+
Lint is necessary but not sufficient — route policy + production smoke still required.
|
|
292
|
+
|
|
293
|
+
Runs on every `pnpm check` / `pnpm validate`.
|
|
294
|
+
|
|
295
|
+
### 2. Build route policy — no surprise `ƒ` on CMS segment routes
|
|
296
|
+
|
|
297
|
+
Requires `@se-studio/site-check` **^2.7.0**.
|
|
298
|
+
|
|
299
|
+
Commit `route-build-policy.json` beside `smoke.cases.json`. Start from `@se-studio/site-check/templates/route-build-policy.example.json` and adjust route segments to match the app.
|
|
300
|
+
|
|
301
|
+
```json
|
|
302
|
+
{
|
|
303
|
+
"allowedDynamic": ["/", "/articles", "/tags", "/people", "/_not-found"],
|
|
304
|
+
"mustBeSsgOrStatic": [
|
|
305
|
+
"/[level1]",
|
|
306
|
+
"/[level1]/[...slugs]",
|
|
307
|
+
"/articles/[articleType]",
|
|
308
|
+
"/articles/[articleType]/[...slugs]"
|
|
309
|
+
]
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
- `mustBeSsgOrStatic` — must be `●` or `○` in `next build`, never `ƒ`.
|
|
314
|
+
- `allowedDynamic` — documents known `ƒ` routes; fail if a new `ƒ` appears without updating the policy.
|
|
315
|
+
|
|
316
|
+
**Scripts:**
|
|
317
|
+
|
|
318
|
+
```json
|
|
319
|
+
"validate:routes": "validate-build-routes",
|
|
320
|
+
"validate": "pnpm check && pnpm type-check && pnpm validate:routes"
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
`validate-build-routes` runs `pnpm build` and compares the Route (app) table to the policy. `smoke-test-one` also validates after build when `route-build-policy.json` exists (`SMOKE_TEST_VALIDATE_ROUTES=false` to skip).
|
|
324
|
+
|
|
325
|
+
### 3. Production smoke (runtime safety net)
|
|
326
|
+
|
|
327
|
+
`pnpm smoke-test:cache` / `smoke-test:deploy-check` catches breakage lint/policy miss. Keep mandatory in CI / Vercel build gates.
|
|
328
|
+
|
|
329
|
+
**HubSpot bootstrap:** use `createHubSpotBootstrapScript()` with no args in root layout — not `headers()` + middleware pathname.
|
|
330
|
+
|
|
273
331
|
## Reference
|
|
274
332
|
|
|
275
333
|
- HTTP + integrity example: `apps/example-empty/smoke.cases.json` and `scripts/smoke-test-run.ts` (monorepo).
|
|
276
|
-
-
|
|
334
|
+
- SSG guardrails reference app: `apps/example-empty/route-build-policy.json` and `biome.json` overrides.
|
|
335
|
+
- Package API: `runStaticSmokeTest`, `runStaticSmokeTestWithIntegrity`, `runPreviewStaticSmokeTest`, `auditCacheLogs`, `validateBuildRoutesFromBuildOutput` from `@se-studio/site-check/smoke-test`.
|
|
277
336
|
- CMS integrity types: `@se-studio/site-check/cms-integrity`.
|
|
@@ -75,6 +75,7 @@ The secret is passed as a **request header** (`REVALIDATION_SECRET`), not a quer
|
|
|
75
75
|
* 5. Updates .env.local with the new secret
|
|
76
76
|
*/
|
|
77
77
|
|
|
78
|
+
import { REVALIDATION_WEBHOOK_ENTRY_CONTENT_TYPES } from '@se-studio/contentful-rest-api';
|
|
78
79
|
import { createClient } from 'contentful-management';
|
|
79
80
|
import { randomBytes } from 'node:crypto';
|
|
80
81
|
import { spawnSync } from 'node:child_process';
|
|
@@ -149,13 +150,8 @@ const WEBHOOK_NAME = 'Vercel Revalidation';
|
|
|
149
150
|
const ASSET_WEBHOOK_NAME = 'Vercel Revalidation (Assets)';
|
|
150
151
|
const PREVIEW_WEBHOOK_NAME = 'Vercel Revalidation (Preview)';
|
|
151
152
|
|
|
152
|
-
const ENTRY_CONTENT_TYPES = [
|
|
153
|
-
'article', 'articleType', 'banner', 'customType', 'location',
|
|
154
|
-
'navigation', 'page', 'pageVariant', 'person', 'tag', 'template',
|
|
155
|
-
];
|
|
156
|
-
|
|
157
153
|
const contentTypeFilter = {
|
|
158
|
-
in: [{ doc: 'sys.contentType.sys.id' },
|
|
154
|
+
in: [{ doc: 'sys.contentType.sys.id' }, [...REVALIDATION_WEBHOOK_ENTRY_CONTENT_TYPES]],
|
|
159
155
|
};
|
|
160
156
|
|
|
161
157
|
async function main(): Promise<void> {
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vercel-logs-audit
|
|
3
|
+
description: "Pull and triage Vercel error logs across SE Studio marketing sites (develop + production). Use when checking production errors, monitoring Vercel runtime issues, or running incremental log audits."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Vercel logs audit
|
|
7
|
+
|
|
8
|
+
Cross-project error monitoring for the 7 marketing sites in `docs/vercel-logs/projects.registry.json`.
|
|
9
|
+
|
|
10
|
+
**Requires:** Vercel CLI (`vercel`), authenticated via `vercel login` or `VERCEL_TOKEN` in `.env.local`.
|
|
11
|
+
|
|
12
|
+
**Output:** Generated under `docs/vercel-logs/` — **do not commit** except `projects.registry.json` and `README.md`.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
From repo root:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Full pipeline: pull → filter → analyze
|
|
22
|
+
pnpm vercel-logs
|
|
23
|
+
|
|
24
|
+
# Subset
|
|
25
|
+
pnpm vercel-logs --sites se2026,brightline --envs develop
|
|
26
|
+
|
|
27
|
+
# Re-backfill 7 days (resets checkpoints for selected targets)
|
|
28
|
+
pnpm vercel-logs --full
|
|
29
|
+
|
|
30
|
+
# Plan fetches without calling Vercel
|
|
31
|
+
pnpm vercel-logs:pull --dry-run
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Individual steps:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm vercel-logs:pull
|
|
38
|
+
pnpm vercel-logs:filter
|
|
39
|
+
pnpm vercel-logs:analyze
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Incremental behaviour
|
|
45
|
+
|
|
46
|
+
| Run | Window |
|
|
47
|
+
|-----|--------|
|
|
48
|
+
| First run (no `state.json`) | Last **7 days** per site × environment |
|
|
49
|
+
| Subsequent runs | Since last checkpoint minus 5-minute overlap |
|
|
50
|
+
| `--full` | Clears checkpoints and re-backfills 7 days |
|
|
51
|
+
| `--since 2d` | Override start time for selected pull |
|
|
52
|
+
|
|
53
|
+
Checkpoints live in `docs/vercel-logs/state.json` (gitignored).
|
|
54
|
+
|
|
55
|
+
If a pull hits the Vercel log limit, the checkpoint is set to the **oldest fetched timestamp** (not `now`) so the next run can backfill older entries.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Pipeline steps
|
|
60
|
+
|
|
61
|
+
| Step | Input | Output |
|
|
62
|
+
|------|-------|--------|
|
|
63
|
+
| `pull` | Vercel CLI | `raw/<runId>/.../logs.jsonl` (raw JSON) |
|
|
64
|
+
| `filter` | Raw JSONL + manifests | `errors/<runId>.jsonl` (normalized) |
|
|
65
|
+
| `analyze` | Filtered JSONL | `reports/<runId>-summary.md` |
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Teams and projects
|
|
70
|
+
|
|
71
|
+
The registry maps each site to a Vercel project and team scope:
|
|
72
|
+
|
|
73
|
+
| Team | Sites |
|
|
74
|
+
|------|-------|
|
|
75
|
+
| `se-studio` | se2026, om1, pedestal, headwater |
|
|
76
|
+
| `brightline` | brightline, brightlifekids |
|
|
77
|
+
| `engineeringpointmes-projects` | pointme |
|
|
78
|
+
|
|
79
|
+
Your Vercel account must have access to all three teams. Verify with `vercel whoami`.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Reading results
|
|
84
|
+
|
|
85
|
+
After `pnpm vercel-logs:analyze`, open:
|
|
86
|
+
|
|
87
|
+
`docs/vercel-logs/reports/<runId>-summary.md`
|
|
88
|
+
|
|
89
|
+
Triage in this order:
|
|
90
|
+
|
|
91
|
+
1. **By site × environment** — which deploy surface is failing?
|
|
92
|
+
2. **Top messages** — group identical errors (often one root cause)
|
|
93
|
+
3. **Status codes** — 5xx vs application-level errors
|
|
94
|
+
4. **Sample paths** — affected routes
|
|
95
|
+
5. **Changes since previous run** — new regressions
|
|
96
|
+
|
|
97
|
+
Filtered entries: `docs/vercel-logs/errors/<runId>.jsonl`
|
|
98
|
+
|
|
99
|
+
Exit code **2** from analyze means errors were found (useful for future CI).
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## What counts as an error
|
|
104
|
+
|
|
105
|
+
Pull uses two CLI passes per target:
|
|
106
|
+
|
|
107
|
+
- Log level `error` or `fatal`
|
|
108
|
+
- HTTP status `500`–`508`
|
|
109
|
+
|
|
110
|
+
Filter normalizes raw JSON and keeps entries matching:
|
|
111
|
+
|
|
112
|
+
- Log level `error` or `fatal`
|
|
113
|
+
- HTTP status `5xx`
|
|
114
|
+
|
|
115
|
+
Optional: `pnpm vercel-logs:filter --include-warnings`
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Troubleshooting
|
|
120
|
+
|
|
121
|
+
| Problem | Fix |
|
|
122
|
+
|---------|-----|
|
|
123
|
+
| `vercel logs failed` / auth error | `vercel login` or set `VERCEL_TOKEN` |
|
|
124
|
+
| Wrong team / project not found | Check `team` in `projects.registry.json`; use `vercel projects ls --scope <team>` |
|
|
125
|
+
| No targets matched | Check `--sites` / `--envs` keys match registry `key` fields |
|
|
126
|
+
| Empty report after errors expected | Widen with `--full` or `--since 7d`; confirm develop uses `--branch develop` |
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Maintenance
|
|
131
|
+
|
|
132
|
+
- Registry: `docs/vercel-logs/projects.registry.json`
|
|
133
|
+
- Scripts: `scripts/vercel-logs/`
|
|
134
|
+
- Tests: `pnpm vercel-logs:test`
|