From 02e4d7cd6cbacda3f648c5279d267b5dbd89db33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jun 2026 03:55:51 +0000 Subject: [PATCH 1/6] Bump flatted from 3.3.3 to 3.4.2 Bumps [flatted](https://github.com/WebReflection/flatted) from 3.3.3 to 3.4.2. - [Commits](https://github.com/WebReflection/flatted/compare/v3.3.3...v3.4.2) --- updated-dependencies: - dependency-name: flatted dependency-version: 3.4.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index ec8fddd..b758e75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5049,12 +5049,6 @@ } } }, - "node_modules/astro/node_modules/@rollup/pluginutils/node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "license": "MIT" - }, "node_modules/astro/node_modules/ci-info": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", @@ -7905,11 +7899,10 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true }, "node_modules/flattie": { "version": "1.1.1", From 24bd3d7c2cc1f45d7863d7915374f395c97f7f80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jun 2026 03:56:11 +0000 Subject: [PATCH 2/6] Bump effect and prisma in /apps/status Bumps [effect](https://github.com/Effect-TS/effect/tree/HEAD/packages/effect) to 3.21.0 and updates ancestor dependency [prisma](https://github.com/prisma/prisma/tree/HEAD/packages/cli). These dependencies need to be updated together. Updates `effect` from 3.18.4 to 3.21.0 - [Release notes](https://github.com/Effect-TS/effect/releases) - [Changelog](https://github.com/Effect-TS/effect/blob/main/packages/effect/CHANGELOG.md) - [Commits](https://github.com/Effect-TS/effect/commits/effect@3.21.0/packages/effect) Updates `prisma` from 6.19.0 to 6.19.3 - [Release notes](https://github.com/prisma/prisma/releases) - [Commits](https://github.com/prisma/prisma/commits/6.19.3/packages/cli) --- updated-dependencies: - dependency-name: effect dependency-version: 3.21.0 dependency-type: indirect - dependency-name: prisma dependency-version: 6.19.3 dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- apps/status/package-lock.json | 121 ++++++++++++++++++---------------- apps/status/package.json | 2 +- 2 files changed, 64 insertions(+), 59 deletions(-) diff --git a/apps/status/package-lock.json b/apps/status/package-lock.json index 8d84c83..5e067b4 100644 --- a/apps/status/package-lock.json +++ b/apps/status/package-lock.json @@ -25,7 +25,7 @@ "eslint": "^9.0.0", "eslint-config-next": "^16.0.1", "postcss": "^8.5.10", - "prisma": "^6.19.0", + "prisma": "^6.19.3", "tailwindcss": "^3.4.13", "typescript": "5.9.3", "vitest": "^4.1.8" @@ -1333,66 +1333,66 @@ } }, "node_modules/@prisma/config": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.0.tgz", - "integrity": "sha512-zwCayme+NzI/WfrvFEtkFhhOaZb/hI+X8TTjzjJ252VbPxAl2hWHK5NMczmnG9sXck2lsXrxIZuK524E25UNmg==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.3.tgz", + "integrity": "sha512-CBPT44BjlQxEt8kiMEauji2WHTDoVBOKl7UlewXmUgBPnr/oPRZC3psci5chJnYmH0ivEIog2OU9PGWoki3DLQ==", "devOptional": true, "license": "Apache-2.0", "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", - "effect": "3.18.4", + "effect": "3.21.0", "empathic": "2.0.0" } }, "node_modules/@prisma/debug": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.19.0.tgz", - "integrity": "sha512-8hAdGG7JmxrzFcTzXZajlQCidX0XNkMJkpqtfbLV54wC6LSSX6Vni25W/G+nAANwLnZ2TmwkfIuWetA7jJxJFA==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.19.3.tgz", + "integrity": "sha512-ljkJ+SgpXNktLG0Q/n4JGYCkKf0f8oYLyjImS2I8e2q2WCfdRRtWER062ZV/ixaNP2M2VKlWXVJiGzZaUgbKZw==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/engines": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.19.0.tgz", - "integrity": "sha512-pMRJ+1S6NVdXoB8QJAPIGpKZevFjxhKt0paCkRDTZiczKb7F4yTgRP8M4JdVkpQwmaD4EoJf6qA+p61godDokw==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.19.3.tgz", + "integrity": "sha512-RSYxtlYFl5pJ8ZePgMv0lZ9IzVCOdTPOegrs2qcbAEFrBI1G33h6wyC9kjQvo0DnYEhEVY0X4LsuFHXLKQk88g==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.19.0", - "@prisma/engines-version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", - "@prisma/fetch-engine": "6.19.0", - "@prisma/get-platform": "6.19.0" + "@prisma/debug": "6.19.3", + "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "@prisma/fetch-engine": "6.19.3", + "@prisma/get-platform": "6.19.3" } }, "node_modules/@prisma/engines-version": { - "version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773.tgz", - "integrity": "sha512-gV7uOBQfAFlWDvPJdQxMT1aSRur3a0EkU/6cfbAC5isV67tKDWUrPauyaHNpB+wN1ebM4A9jn/f4gH+3iHSYSQ==", + "version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7.tgz", + "integrity": "sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA==", "devOptional": true, "license": "Apache-2.0" }, "node_modules/@prisma/fetch-engine": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.0.tgz", - "integrity": "sha512-OOx2Lda0DGrZ1rodADT06ZGqHzr7HY7LNMaFE2Vp8dp146uJld58sRuasdX0OiwpHgl8SqDTUKHNUyzEq7pDdQ==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.3.tgz", + "integrity": "sha512-tKtl/qco9Nt7LU5iKhpultD8O4vMCZcU2CHjNTnRrL1QvSUr5W/GcyFPjNL87GtRrwBc7ubXXD9xy4EvLvt8JA==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.19.0", - "@prisma/engines-version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", - "@prisma/get-platform": "6.19.0" + "@prisma/debug": "6.19.3", + "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "@prisma/get-platform": "6.19.3" } }, "node_modules/@prisma/get-platform": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.19.0.tgz", - "integrity": "sha512-ym85WDO2yDhC3fIXHWYpG3kVMBA49cL1XD2GCsCF8xbwoy2OkDQY44gEbAt2X46IQ4Apq9H6g0Ex1iFfPqEkHA==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.19.3.tgz", + "integrity": "sha512-xFj1VcJ1N3MKooOQAGO0W5tsd0W2QzIvW7DD7c/8H14Zmp4jseeWAITm+w2LLoLrlhoHdPPh0NMZ8mfL6puoHA==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.19.0" + "@prisma/debug": "6.19.3" } }, "node_modules/@rolldown/binding-android-arm64": { @@ -2947,9 +2947,9 @@ } }, "node_modules/c12/node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", "devOptional": true, "license": "MIT", "bin": { @@ -3180,9 +3180,9 @@ "dev": true }, "node_modules/confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", "devOptional": true, "license": "MIT" }, @@ -3465,9 +3465,9 @@ "license": "MIT" }, "node_modules/effect": { - "version": "3.18.4", - "resolved": "https://registry.npmjs.org/effect/-/effect-3.18.4.tgz", - "integrity": "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/effect/-/effect-3.21.0.tgz", + "integrity": "sha512-PPN80qRokCd1f015IANNhrwOnLO7GrrMQfk4/lnZRE/8j7UPWrNNjPV0uBrZutI/nHzernbW+J0hdqQysHiSnQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6019,25 +6019,30 @@ } }, "node_modules/nypm": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.2.tgz", - "integrity": "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==", + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.6.tgz", + "integrity": "sha512-vRyr0r4cbBapw07Xw8xrj9Teq3o7MUD35rSaTcanDbW+aK2XHDgJFiU6ZTj2GBw7Q12ysdsyFss+Vdz4hQ0Y6Q==", "devOptional": true, "license": "MIT", "dependencies": { - "citty": "^0.1.6", - "consola": "^3.4.2", + "citty": "^0.2.2", "pathe": "^2.0.3", - "pkg-types": "^2.3.0", - "tinyexec": "^1.0.1" + "tinyexec": "^1.1.1" }, "bin": { "nypm": "dist/cli.mjs" }, "engines": { - "node": "^14.16.0 || >=16.10.0" + "node": ">=18" } }, + "node_modules/nypm/node_modules/citty": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.2.2.tgz", + "integrity": "sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==", + "devOptional": true, + "license": "MIT" + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -6367,14 +6372,14 @@ } }, "node_modules/pkg-types": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", - "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.1.tgz", + "integrity": "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==", "devOptional": true, "license": "MIT", "dependencies": { - "confbox": "^0.2.2", - "exsolve": "^1.0.7", + "confbox": "^0.2.4", + "exsolve": "^1.0.8", "pathe": "^2.0.3" } }, @@ -6562,15 +6567,15 @@ } }, "node_modules/prisma": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.19.0.tgz", - "integrity": "sha512-F3eX7K+tWpkbhl3l4+VkFtrwJlLXbAM+f9jolgoUZbFcm1DgHZ4cq9AgVEgUym2au5Ad/TDLN8lg83D+M10ycw==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.19.3.tgz", + "integrity": "sha512-++ZJ0ijLrDJF6hNB4t4uxg2br3fC4H9Yc9tcbjr2fcNFP3rh/SBNrAgjhsqBU4Ght8JPrVofG/ZkXfnSfnYsFg==", "devOptional": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@prisma/config": "6.19.0", - "@prisma/engines": "6.19.0" + "@prisma/config": "6.19.3", + "@prisma/engines": "6.19.3" }, "bin": { "prisma": "build/index.js" @@ -7594,9 +7599,9 @@ "license": "MIT" }, "node_modules/tinyexec": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", "devOptional": true, "license": "MIT", "engines": { diff --git a/apps/status/package.json b/apps/status/package.json index 7f44421..ee33428 100644 --- a/apps/status/package.json +++ b/apps/status/package.json @@ -27,7 +27,7 @@ "eslint": "^9.0.0", "eslint-config-next": "^16.0.1", "postcss": "^8.5.10", - "prisma": "^6.19.0", + "prisma": "^6.19.3", "tailwindcss": "^3.4.13", "typescript": "5.9.3", "vitest": "^4.1.8" From bc2c47b73e3bd868cc5aa7cebf848b560612d314 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Jun 2026 04:04:05 +0000 Subject: [PATCH 3/6] Bump effect and prisma Bumps [effect](https://github.com/Effect-TS/effect/tree/HEAD/packages/effect) to 3.21.0 and updates ancestor dependency [prisma](https://github.com/prisma/prisma/tree/HEAD/packages/cli). These dependencies need to be updated together. Updates `effect` from 3.18.4 to 3.21.0 - [Release notes](https://github.com/Effect-TS/effect/releases) - [Changelog](https://github.com/Effect-TS/effect/blob/main/packages/effect/CHANGELOG.md) - [Commits](https://github.com/Effect-TS/effect/commits/effect@3.21.0/packages/effect) Updates `prisma` from 6.19.0 to 6.19.3 - [Release notes](https://github.com/prisma/prisma/releases) - [Commits](https://github.com/prisma/prisma/commits/6.19.3/packages/cli) --- updated-dependencies: - dependency-name: effect dependency-version: 3.21.0 dependency-type: indirect - dependency-name: prisma dependency-version: 6.19.3 dependency-type: direct:development ... Signed-off-by: dependabot[bot] --- package-lock.json | 168 ++++++++++++++++++---------------------------- package.json | 2 +- 2 files changed, 67 insertions(+), 103 deletions(-) diff --git a/package-lock.json b/package-lock.json index b758e75..f997bfe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "dotenv": "^17.2.3" }, "devDependencies": { - "prisma": "^6.19.0", + "prisma": "^6.19.3", "tsx": "^4.19.2", "turbo": "*" }, @@ -57,7 +57,7 @@ "eslint": "^9.0.0", "eslint-config-next": "^16.0.1", "postcss": "^8.5.10", - "prisma": "^6.19.0", + "prisma": "^6.19.3", "tailwindcss": "^3.4.13", "typescript": "5.9.3", "vitest": "^4.1.8" @@ -2557,66 +2557,60 @@ } }, "node_modules/@prisma/config": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.0.tgz", - "integrity": "sha512-zwCayme+NzI/WfrvFEtkFhhOaZb/hI+X8TTjzjJ252VbPxAl2hWHK5NMczmnG9sXck2lsXrxIZuK524E25UNmg==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.19.3.tgz", + "integrity": "sha512-CBPT44BjlQxEt8kiMEauji2WHTDoVBOKl7UlewXmUgBPnr/oPRZC3psci5chJnYmH0ivEIog2OU9PGWoki3DLQ==", "devOptional": true, - "license": "Apache-2.0", "dependencies": { "c12": "3.1.0", "deepmerge-ts": "7.1.5", - "effect": "3.18.4", + "effect": "3.21.0", "empathic": "2.0.0" } }, "node_modules/@prisma/debug": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.19.0.tgz", - "integrity": "sha512-8hAdGG7JmxrzFcTzXZajlQCidX0XNkMJkpqtfbLV54wC6LSSX6Vni25W/G+nAANwLnZ2TmwkfIuWetA7jJxJFA==", - "devOptional": true, - "license": "Apache-2.0" + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.19.3.tgz", + "integrity": "sha512-ljkJ+SgpXNktLG0Q/n4JGYCkKf0f8oYLyjImS2I8e2q2WCfdRRtWER062ZV/ixaNP2M2VKlWXVJiGzZaUgbKZw==", + "devOptional": true }, "node_modules/@prisma/engines": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.19.0.tgz", - "integrity": "sha512-pMRJ+1S6NVdXoB8QJAPIGpKZevFjxhKt0paCkRDTZiczKb7F4yTgRP8M4JdVkpQwmaD4EoJf6qA+p61godDokw==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.19.3.tgz", + "integrity": "sha512-RSYxtlYFl5pJ8ZePgMv0lZ9IzVCOdTPOegrs2qcbAEFrBI1G33h6wyC9kjQvo0DnYEhEVY0X4LsuFHXLKQk88g==", "devOptional": true, "hasInstallScript": true, - "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.19.0", - "@prisma/engines-version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", - "@prisma/fetch-engine": "6.19.0", - "@prisma/get-platform": "6.19.0" + "@prisma/debug": "6.19.3", + "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "@prisma/fetch-engine": "6.19.3", + "@prisma/get-platform": "6.19.3" } }, "node_modules/@prisma/engines-version": { - "version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", - "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773.tgz", - "integrity": "sha512-gV7uOBQfAFlWDvPJdQxMT1aSRur3a0EkU/6cfbAC5isV67tKDWUrPauyaHNpB+wN1ebM4A9jn/f4gH+3iHSYSQ==", - "devOptional": true, - "license": "Apache-2.0" + "version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7.tgz", + "integrity": "sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA==", + "devOptional": true }, "node_modules/@prisma/fetch-engine": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.0.tgz", - "integrity": "sha512-OOx2Lda0DGrZ1rodADT06ZGqHzr7HY7LNMaFE2Vp8dp146uJld58sRuasdX0OiwpHgl8SqDTUKHNUyzEq7pDdQ==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.19.3.tgz", + "integrity": "sha512-tKtl/qco9Nt7LU5iKhpultD8O4vMCZcU2CHjNTnRrL1QvSUr5W/GcyFPjNL87GtRrwBc7ubXXD9xy4EvLvt8JA==", "devOptional": true, - "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.19.0", - "@prisma/engines-version": "6.19.0-26.2ba551f319ab1df4bc874a89965d8b3641056773", - "@prisma/get-platform": "6.19.0" + "@prisma/debug": "6.19.3", + "@prisma/engines-version": "7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7", + "@prisma/get-platform": "6.19.3" } }, "node_modules/@prisma/get-platform": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.19.0.tgz", - "integrity": "sha512-ym85WDO2yDhC3fIXHWYpG3kVMBA49cL1XD2GCsCF8xbwoy2OkDQY44gEbAt2X46IQ4Apq9H6g0Ex1iFfPqEkHA==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.19.3.tgz", + "integrity": "sha512-xFj1VcJ1N3MKooOQAGO0W5tsd0W2QzIvW7DD7c/8H14Zmp4jseeWAITm+w2LLoLrlhoHdPPh0NMZ8mfL6puoHA==", "devOptional": true, - "license": "Apache-2.0", "dependencies": { - "@prisma/debug": "6.19.0" + "@prisma/debug": "6.19.3" } }, "node_modules/@repo/eslint-config": { @@ -5490,7 +5484,6 @@ "resolved": "https://registry.npmjs.org/c12/-/c12-3.1.0.tgz", "integrity": "sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==", "devOptional": true, - "license": "MIT", "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", @@ -5519,7 +5512,6 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "devOptional": true, - "license": "MIT", "dependencies": { "readdirp": "^4.0.1" }, @@ -5535,7 +5527,6 @@ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", "devOptional": true, - "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -5544,11 +5535,10 @@ } }, "node_modules/c12/node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", "devOptional": true, - "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" } @@ -5558,7 +5548,6 @@ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "devOptional": true, - "license": "MIT", "engines": { "node": ">= 14.18.0" }, @@ -5781,7 +5770,6 @@ "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", "devOptional": true, - "license": "MIT", "dependencies": { "consola": "^3.2.3" } @@ -5910,18 +5898,16 @@ "license": "MIT" }, "node_modules/confbox": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", - "devOptional": true, - "license": "MIT" + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.4.tgz", + "integrity": "sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==", + "devOptional": true }, "node_modules/consola": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", "devOptional": true, - "license": "MIT", "engines": { "node": "^14.18.0 || >=16.10.0" } @@ -6170,7 +6156,6 @@ "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.5.tgz", "integrity": "sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==", "devOptional": true, - "license": "BSD-3-Clause", "engines": { "node": ">=16.0.0" } @@ -6447,11 +6432,10 @@ "license": "MIT" }, "node_modules/effect": { - "version": "3.18.4", - "resolved": "https://registry.npmjs.org/effect/-/effect-3.18.4.tgz", - "integrity": "sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/effect/-/effect-3.21.0.tgz", + "integrity": "sha512-PPN80qRokCd1f015IANNhrwOnLO7GrrMQfk4/lnZRE/8j7UPWrNNjPV0uBrZutI/nHzernbW+J0hdqQysHiSnQ==", "devOptional": true, - "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" @@ -6475,7 +6459,6 @@ "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", "devOptional": true, - "license": "MIT", "engines": { "node": ">=14" } @@ -7726,8 +7709,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", - "devOptional": true, - "license": "MIT" + "devOptional": true }, "node_modules/extend": { "version": "3.0.2", @@ -7750,7 +7732,6 @@ "url": "https://opencollective.com/fast-check" } ], - "license": "MIT", "dependencies": { "pure-rand": "^6.1.0" }, @@ -8138,7 +8119,6 @@ "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", "devOptional": true, - "license": "MIT", "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", @@ -9576,20 +9556,6 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/magicast": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", - "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "@babel/parser": "^7.25.4", - "@babel/types": "^7.25.4", - "source-map-js": "^1.2.0" - } - }, "node_modules/markdown-table": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", @@ -11157,25 +11123,28 @@ } }, "node_modules/nypm": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.2.tgz", - "integrity": "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==", + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.6.tgz", + "integrity": "sha512-vRyr0r4cbBapw07Xw8xrj9Teq3o7MUD35rSaTcanDbW+aK2XHDgJFiU6ZTj2GBw7Q12ysdsyFss+Vdz4hQ0Y6Q==", "devOptional": true, - "license": "MIT", "dependencies": { - "citty": "^0.1.6", - "consola": "^3.4.2", + "citty": "^0.2.2", "pathe": "^2.0.3", - "pkg-types": "^2.3.0", - "tinyexec": "^1.0.1" + "tinyexec": "^1.1.1" }, "bin": { "nypm": "dist/cli.mjs" }, "engines": { - "node": "^14.16.0 || >=16.10.0" + "node": ">=18" } }, + "node_modules/nypm/node_modules/citty": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.2.2.tgz", + "integrity": "sha512-+6vJA3L98yv+IdfKGZHBNiGW5KHn22e/JwID0Strsz8h4S/csAu/OuICwxrg44k5MRiZHWIo8XXuJgQTriRP4w==", + "devOptional": true + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -11611,8 +11580,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "devOptional": true, - "license": "MIT" + "devOptional": true }, "node_modules/piccolore": { "version": "0.1.3", @@ -11658,14 +11626,13 @@ } }, "node_modules/pkg-types": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", - "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.1.tgz", + "integrity": "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg==", "devOptional": true, - "license": "MIT", "dependencies": { - "confbox": "^0.2.2", - "exsolve": "^1.0.7", + "confbox": "^0.2.4", + "exsolve": "^1.0.8", "pathe": "^2.0.3" } }, @@ -11885,15 +11852,14 @@ } }, "node_modules/prisma": { - "version": "6.19.0", - "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.19.0.tgz", - "integrity": "sha512-F3eX7K+tWpkbhl3l4+VkFtrwJlLXbAM+f9jolgoUZbFcm1DgHZ4cq9AgVEgUym2au5Ad/TDLN8lg83D+M10ycw==", + "version": "6.19.3", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.19.3.tgz", + "integrity": "sha512-++ZJ0ijLrDJF6hNB4t4uxg2br3fC4H9Yc9tcbjr2fcNFP3rh/SBNrAgjhsqBU4Ght8JPrVofG/ZkXfnSfnYsFg==", "devOptional": true, "hasInstallScript": true, - "license": "Apache-2.0", "dependencies": { - "@prisma/config": "6.19.0", - "@prisma/engines": "6.19.0" + "@prisma/config": "6.19.3", + "@prisma/engines": "6.19.3" }, "bin": { "prisma": "build/index.js" @@ -11964,8 +11930,7 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ], - "license": "MIT" + ] }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -11998,7 +11963,6 @@ "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", "devOptional": true, - "license": "MIT", "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" diff --git a/package.json b/package.json index 93b81c7..dc0dd2c 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "seed": "tsx prisma/seed.ts" }, "devDependencies": { - "prisma": "^6.19.0", + "prisma": "^6.19.3", "turbo": "latest", "tsx": "^4.19.2" }, From e73cda7eadc7d33534083d71f696a08d717f433e Mon Sep 17 00:00:00 2001 From: Tsubasa SEKIGUCHI Date: Tue, 16 Jun 2026 20:04:59 +0900 Subject: [PATCH 4/6] feat(status): add incident report script and AI skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a zero-dependency Node script (apps/status/scripts/report-incident.mjs) to post incidents/service status to POST /api/status/events, reading the API key from env/.env and auto-normalizing dates to UTC (the API rejects +09:00 offsets). Wire it up as `npm run report-incident`. Add a project skill (.claude/skills/report-incident/SKILL.md) that drives the end-to-end flow: collect details, build payload, dry-run, confirm, post, and clean up — with known service IDs, status types, and the resolve flow. Co-Authored-By: Claude Opus 4.8 --- .claude/skills/report-incident/SKILL.md | 123 ++++++++++++++++ apps/status/package.json | 1 + apps/status/scripts/report-incident.mjs | 181 ++++++++++++++++++++++++ 3 files changed, 305 insertions(+) create mode 100644 .claude/skills/report-incident/SKILL.md create mode 100644 apps/status/scripts/report-incident.mjs diff --git a/.claude/skills/report-incident/SKILL.md b/.claude/skills/report-incident/SKILL.md new file mode 100644 index 0000000..46e91da --- /dev/null +++ b/.claude/skills/report-incident/SKILL.md @@ -0,0 +1,123 @@ +--- +name: report-incident +description: TrainLCD のステータスページ(apps/status)に障害情報を登録・更新・復旧するときに使う。インシデント(IncidentHistory)とサービスステータスを POST /api/status/events 経由で投稿する。「障害を登録」「インシデントを追加」「ステータスをoutage/degradedにする」「障害を復旧済みにする」などの依頼で起動する。 +--- + +# 障害情報の登録 (TrainLCD Status) + +`apps/status` のステータスページに障害情報を登録・更新する。データは +`POST /api/status/events` 経由で PostgreSQL に永続化され、Redis キャッシュ更新と +SSE 配信まで自動で行われる。投稿には `apps/status/scripts/report-incident.mjs` を使う。 + +## ワークフロー + +1. **情報を集める**(不足があればユーザーに質問する) + - 影響度 `impact`(下記 StatusType) + - 対象サービス `affectedServiceIds`(下記の既知IDから1つ以上) + - タイトル・概要(日本語)。**英語訳は内容に沿ってこちらで用意する** + - 発生日時 `startedAt` + - 任意: 原因 `cause`、復旧日時 `resolvedAt`、外部リンク `externalLink` + - TTSとフィードバックのように複数サービスが同じ原因・同じタイミングなら **1件のインシデントにまとめる**(`affectedServiceIds` に複数指定)。原因やタイミングが異なるなら別インシデントにする。 +2. **ペイロード JSON を生成**してリポジトリ直下の一時ファイル(例 `.incident-payload.json`)に書く。 +3. **dry-run で検証**: `npm run report-incident -- --file --dry-run` + (日時が UTC に正規化されること・JSON が妥当なことを確認) +4. **本番投稿は外部公開操作**。投稿前にユーザーへ最終確認を取る。 + `cd apps/status && npm run report-incident -- --file ` +5. 成功(HTTP 200)を確認したら**一時ファイルを削除**し、確認URLを案内する。 + - 一覧: https://status.trainlcd.app + - 個別: https://status.trainlcd.app/incidents/ + +## 認証 + +スクリプトは環境変数 `STATUS_UPDATE_API_KEY` を使う(リポジトリルート/`apps/status` の +`.env` からも自動読込)。未設定ならユーザーに設定を促す。**APIキーをチャットに貼らせない** +(履歴に残る)。投稿先を変えるときは `STATUS_API_URL` か `--url`。 + +## 既知のサービスID + +| serviceId | サービス | category | +|---|---|---| +| `mobile-ios` | モバイルアプリ(iOS/iPadOS) | application | +| `mobile-android` | モバイルアプリ(Android) | application | +| `tts` | 自動アナウンス機能(TTS) | platform | +| `feedback` | フィードバックシステム | support | +| `station-api` | StationAPI | api | + +※ 存在しない `serviceId` を `services` に渡すと API は 500 を返す。 + +## StatusType + +`operational`(正常) / `maintenance`(メンテ) / `partiallyMaintenance`(一部メンテ) / +`degraded`(機能低下) / `partiallyDegraded`(一部機能低下) / `outage`(停止) / `unknown`(不明) + +## 制約(重要) + +- **日時**: API は `...Z`(UTC) もしくはオフセット無しのみ受理し、`+09:00` を**弾く**。 + 人間が読みやすい JST(`2026-06-16T09:00:00+09:00`) で書いてよい。スクリプトが + `startedAt`/`resolvedAt`/`statusSince`/`createdAt` を自動で UTC に正規化する。 +- **LocaleText は ja/en 両方必須**(`title`/`description`/`summary`/`cause`/`body`)。 +- `affectedServiceIds` は空配列不可。 +- `id` 省略=新規作成、`slug` 省略=自動生成。日本語タイトルだとslugが無意味になるため + **`slug` は `YYYY-MM-DD-<英語短縮>` 形式で明示する**。 +- `services` を併せて送ると、サービス一覧のステータス表示自体も切り替わる。 + +## ペイロード テンプレート(新規・継続中) + +```json +{ + "services": [ + { "serviceId": "tts", "status": "outage", + "summary": { "ja": "...", "en": "..." } } + ], + "incidents": [ + { + "slug": "2026-06-16-...", + "impact": "outage", + "affectedServiceIds": ["tts"], + "title": { "ja": "...", "en": "..." }, + "description": { "ja": "...", "en": "..." }, + "startedAt": "2026-06-16T09:00:00+09:00", + "cause": { "ja": "...", "en": "..." }, + "updates": [ + { "status": "outage", "body": { "ja": "...", "en": "..." } } + ] + } + ] +} +``` + +## 復旧(既存インシデントのクローズ) + +同じ `slug`(または初回作成時の `id`)で再投稿し、次を変える: +- `services` の該当サービスを `status: "operational"` に戻す +- インシデントに `resolvedAt` を設定し、`impact` を実態(多くは `operational`)に更新 +- `updates` に復旧報を1件追加(`status: "operational"`) + +```json +{ + "services": [ + { "serviceId": "tts", "status": "operational", + "summary": { "ja": "現在正常に稼働しております。", "en": "Operating normally." } } + ], + "incidents": [ + { + "slug": "2026-06-16-...", + "impact": "operational", + "affectedServiceIds": ["tts"], + "title": { "ja": "...", "en": "..." }, + "description": { "ja": "...(復旧済みの記述)", "en": "..." }, + "startedAt": "2026-06-16T09:00:00+09:00", + "resolvedAt": "2026-06-17T12:00:00+09:00", + "updates": [ + { "status": "operational", "body": { "ja": "復旧しました。", "en": "Resolved." } } + ] + } + ] +} +``` + +## 参考 + +- API 実装: `apps/status/app/api/status/events/route.ts` +- API ドキュメント: `apps/status/app/api/status/events/README.md` +- スキーマ: `prisma/schema.prisma` diff --git a/apps/status/package.json b/apps/status/package.json index 7f44421..113ed5d 100644 --- a/apps/status/package.json +++ b/apps/status/package.json @@ -8,6 +8,7 @@ "start": "next start", "lint": "eslint . --max-warnings=0", "test": "vitest run", + "report-incident": "node scripts/report-incident.mjs", "postinstall": "prisma generate --schema=../../prisma/schema.prisma" }, "dependencies": { diff --git a/apps/status/scripts/report-incident.mjs b/apps/status/scripts/report-incident.mjs new file mode 100644 index 0000000..d522001 --- /dev/null +++ b/apps/status/scripts/report-incident.mjs @@ -0,0 +1,181 @@ +#!/usr/bin/env node +// @ts-check +/** + * TrainLCD Status - インシデント/サービスステータス登録スクリプト + * + * POST /api/status/events を叩いて障害情報を登録・更新する。 + * 追加依存なし(Node 18+ の組み込み fetch を使用)。 + * + * 使い方: + * node scripts/report-incident.mjs --file payload.json + * node scripts/report-incident.mjs --file payload.json --dry-run + * cat payload.json | node scripts/report-incident.mjs + * + * 環境変数: + * STATUS_UPDATE_API_KEY APIキー(必須。リポジトリルート/カレントの .env からも自動読込) + * STATUS_API_URL 投稿先(既定: https://status.trainlcd.app/api/status/events) + * + * 注意: + * - API は日時に "Z"(UTC) もしくはオフセット無しのみ許可する。本スクリプトは + * startedAt / resolvedAt / statusSince / createdAt を自動で UTC("...Z") に正規化する。 + * 人間が読みやすい "2026-06-16T09:00:00+09:00"(JST) のまま書いてよい。 + */ + +import { readFileSync, existsSync } from "node:fs"; +import { resolve, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +const DEFAULT_URL = "https://status.trainlcd.app/api/status/events"; +const DATE_KEYS = new Set(["startedAt", "resolvedAt", "statusSince", "createdAt"]); + +/** 簡易 .env パーサ(KEY=VALUE のみ。既存の環境変数は上書きしない) */ +function loadEnv() { + const candidates = [ + resolve(process.cwd(), ".env"), + resolve(__dirname, "../.env"), // apps/status/.env + resolve(__dirname, "../../../.env"), // リポジトリルート/.env + ]; + for (const path of candidates) { + if (!existsSync(path)) continue; + const text = readFileSync(path, "utf8"); + for (const rawLine of text.split(/\r?\n/)) { + const line = rawLine.trim(); + if (!line || line.startsWith("#")) continue; + const eq = line.indexOf("="); + if (eq === -1) continue; + const key = line.slice(0, eq).trim(); + if (key in process.env) continue; + let value = line.slice(eq + 1).trim(); + if ( + (value.startsWith('"') && value.endsWith('"')) || + (value.startsWith("'") && value.endsWith("'")) + ) { + value = value.slice(1, -1); + } + process.env[key] = value; + } + } +} + +/** 引数パース */ +function parseArgs(argv) { + const opts = { file: null, url: null, dryRun: false }; + for (let i = 0; i < argv.length; i++) { + const a = argv[i]; + if (a === "--file" || a === "-f") opts.file = argv[++i]; + else if (a === "--url") opts.url = argv[++i]; + else if (a === "--dry-run") opts.dryRun = true; + else if (a === "--help" || a === "-h") opts.help = true; + else if (!a.startsWith("-") && !opts.file) opts.file = a; + } + return opts; +} + +function readStdin() { + try { + return readFileSync(0, "utf8"); + } catch { + return ""; + } +} + +/** 日時フィールドを再帰的に UTC("...Z") へ正規化する */ +function normalizeDates(node) { + if (Array.isArray(node)) { + node.forEach(normalizeDates); + return; + } + if (node && typeof node === "object") { + for (const [key, value] of Object.entries(node)) { + if (DATE_KEYS.has(key) && typeof value === "string" && value) { + const t = Date.parse(value); + if (Number.isNaN(t)) { + throw new Error(`日時 "${key}": "${value}" を解釈できません`); + } + node[key] = new Date(t).toISOString(); + } else if (value && typeof value === "object") { + normalizeDates(value); + } + } + } +} + +async function main() { + loadEnv(); + const opts = parseArgs(process.argv.slice(2)); + + if (opts.help) { + console.log( + "Usage: node scripts/report-incident.mjs --file [--dry-run] [--url ]" + ); + process.exit(0); + } + + const raw = opts.file ? readFileSync(resolve(opts.file), "utf8") : readStdin(); + if (!raw.trim()) { + console.error("エラー: ペイロードがありません(--file か stdin で渡してください)"); + process.exit(1); + } + + let payload; + try { + payload = JSON.parse(raw); + } catch (e) { + console.error("エラー: JSON のパースに失敗しました:", e.message); + process.exit(1); + } + + normalizeDates(payload); + + if (opts.dryRun) { + console.log("[dry-run] 送信される正規化済みペイロード:\n"); + console.log(JSON.stringify(payload, null, 2)); + process.exit(0); + } + + const apiKey = process.env.STATUS_UPDATE_API_KEY; + if (!apiKey) { + console.error( + "エラー: STATUS_UPDATE_API_KEY が未設定です(環境変数か .env に設定してください)" + ); + process.exit(1); + } + + const url = opts.url || process.env.STATUS_API_URL || DEFAULT_URL; + console.log(`POST ${url}`); + + let res; + try { + res = await fetch(url, { + method: "POST", + headers: { + "Content-Type": "application/json; charset=utf-8", + "x-api-key": apiKey, + }, + body: JSON.stringify(payload), + }); + } catch (e) { + console.error("エラー: リクエストに失敗しました:", e.message); + process.exit(1); + } + + const text = await res.text(); + let body = text; + try { + body = JSON.stringify(JSON.parse(text), null, 2); + } catch { + /* プレーンテキストのまま */ + } + + if (res.ok) { + console.log(`\n✅ 成功 (HTTP ${res.status})\n${body}`); + process.exit(0); + } else { + console.error(`\n❌ 失敗 (HTTP ${res.status})\n${body}`); + process.exit(1); + } +} + +main(); From 212ea33da788f2a065c6422dd94f5cf0d6ea96e2 Mon Sep 17 00:00:00 2001 From: Tsubasa SEKIGUCHI Date: Tue, 16 Jun 2026 20:11:07 +0900 Subject: [PATCH 5/6] =?UTF-8?q?fix(status):=20=E3=82=B5=E3=83=BC=E3=83=93?= =?UTF-8?q?=E3=82=B9=E4=B8=80=E8=A6=A7=E3=81=A7=E7=8F=BE=E5=9C=A8=E3=82=B9?= =?UTF-8?q?=E3=83=86=E3=83=BC=E3=82=BF=E3=82=B9=E3=81=AE=E6=96=87=E8=A8=80?= =?UTF-8?q?(statusSummary)=E3=82=92=E8=A1=A8=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 障害発生中でも静的な description が表示され「正常」の文言が残る問題を修正。 statusSummary を優先表示し、空の場合のみ description にフォールバックする。 あわせて運用面を更新: - report-incident.mjs: services[].summary の ja/en 空を送信前に検証 (API は空を弾かないが、空だと description へフォールバックして誤表示になる) - report-incident スキル: summary が一覧に表示される点・影響サービスは 必ず services を同送する点・空にしない点を明記 Co-Authored-By: Claude Opus 4.8 --- .claude/skills/report-incident/SKILL.md | 10 ++++- .../app/components/client/ServicesTable.tsx | 4 +- apps/status/scripts/report-incident.mjs | 41 +++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/.claude/skills/report-incident/SKILL.md b/.claude/skills/report-incident/SKILL.md index 46e91da..b5e7467 100644 --- a/.claude/skills/report-incident/SKILL.md +++ b/.claude/skills/report-incident/SKILL.md @@ -16,6 +16,8 @@ SSE 配信まで自動で行われる。投稿には `apps/status/scripts/report - 対象サービス `affectedServiceIds`(下記の既知IDから1つ以上) - タイトル・概要(日本語)。**英語訳は内容に沿ってこちらで用意する** - 発生日時 `startedAt` + - 影響サービスごとの `status` と `summary`(一覧の各行に表示される現在状況の文言。 + 例: 障害中なら「現在ご利用いただけません」、復旧時なら「現在正常に稼働しております。」) - 任意: 原因 `cause`、復旧日時 `resolvedAt`、外部リンク `externalLink` - TTSとフィードバックのように複数サービスが同じ原因・同じタイミングなら **1件のインシデントにまとめる**(`affectedServiceIds` に複数指定)。原因やタイミングが異なるなら別インシデントにする。 2. **ペイロード JSON を生成**してリポジトリ直下の一時ファイル(例 `.incident-payload.json`)に書く。 @@ -59,7 +61,13 @@ SSE 配信まで自動で行われる。投稿には `apps/status/scripts/report - `affectedServiceIds` は空配列不可。 - `id` 省略=新規作成、`slug` 省略=自動生成。日本語タイトルだとslugが無意味になるため **`slug` は `YYYY-MM-DD-<英語短縮>` 形式で明示する**。 -- `services` を併せて送ると、サービス一覧のステータス表示自体も切り替わる。 +- **インシデントで影響するサービスは、必ず同じ `services` エントリも一緒に送る** + (`status` を実態に合わせ、`summary` に現在状況の文言を入れる)。送らないと、 + サービス一覧のアイコンと文言が古いまま(多くは「正常」表示)残る。 +- **`services[].summary` はサービス一覧の各行にそのまま表示される文言**。 + ステータスに合わせて書く(障害中は障害を表す文、復旧時は正常を表す文)。 + **空文字にしない**——空だと UI が静的な説明文(古い「正常」表記)に + フォールバックして誤表示になる(API は空を弾かないが `report-incident.mjs` が弾く)。 ## ペイロード テンプレート(新規・継続中) diff --git a/apps/status/app/components/client/ServicesTable.tsx b/apps/status/app/components/client/ServicesTable.tsx index 5d762b6..0490a6c 100644 --- a/apps/status/app/components/client/ServicesTable.tsx +++ b/apps/status/app/components/client/ServicesTable.tsx @@ -24,7 +24,9 @@ export default function ServicesTable({ services, locale }: ServicesTableProps) >

{svc.label[locale]}

-

{svc.description[locale]}

+

+ {svc.statusSummary[locale] || svc.description[locale]} +

diff --git a/apps/status/scripts/report-incident.mjs b/apps/status/scripts/report-incident.mjs index d522001..f5ef5d8 100644 --- a/apps/status/scripts/report-incident.mjs +++ b/apps/status/scripts/report-incident.mjs @@ -81,6 +81,40 @@ function readStdin() { } } +/** + * ペイロードの簡易検証。API が弾かない「表示上の落とし穴」を送信前に止める。 + * - services[].summary は サービス一覧の各行にそのまま表示される文言。 + * ja/en どちらかが空だと UI が静的な description(古い「正常」表記)に + * フォールバックしてしまうため、空を許さない。 + * 検出した問題の配列を返す(空配列なら問題なし)。 + */ +function validatePayload(payload) { + const errors = []; + if (!payload || typeof payload !== "object") { + return ["ペイロードがオブジェクトではありません"]; + } + const services = payload.services; + if (services !== undefined) { + if (!Array.isArray(services)) { + errors.push("services は配列である必要があります"); + } else { + services.forEach((svc, i) => { + const id = svc && svc.serviceId ? `"${svc.serviceId}"` : `#${i}`; + const summary = svc ? svc.summary : undefined; + const ja = summary && typeof summary.ja === "string" ? summary.ja.trim() : ""; + const en = summary && typeof summary.en === "string" ? summary.en.trim() : ""; + if (!ja || !en) { + errors.push( + `services[${i}] (${id}): summary.ja / summary.en は空にできません` + + "(空だとサービス一覧で古い説明文が表示されます)" + ); + } + }); + } + } + return errors; +} + /** 日時フィールドを再帰的に UTC("...Z") へ正規化する */ function normalizeDates(node) { if (Array.isArray(node)) { @@ -129,6 +163,13 @@ async function main() { normalizeDates(payload); + const validationErrors = validatePayload(payload); + if (validationErrors.length > 0) { + console.error("エラー: ペイロードの検証に失敗しました:"); + for (const msg of validationErrors) console.error(` - ${msg}`); + process.exit(1); + } + if (opts.dryRun) { console.log("[dry-run] 送信される正規化済みペイロード:\n"); console.log(JSON.stringify(payload, null, 2)); From 7dc50153ffc8fbf7a6887add75b41316457b2c26 Mon Sep 17 00:00:00 2001 From: Tsubasa SEKIGUCHI Date: Tue, 16 Jun 2026 20:14:01 +0900 Subject: [PATCH 6/6] fix: apply CodeRabbit auto-fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit normalizeDates() を try-catch で囲み、無効な日時時のエラー出力を 他のエラーと同じ「エラー:」形式 + exit(1) に統一する。 Co-Authored-By: Claude Opus 4.8 --- apps/status/scripts/report-incident.mjs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/status/scripts/report-incident.mjs b/apps/status/scripts/report-incident.mjs index f5ef5d8..7a115b1 100644 --- a/apps/status/scripts/report-incident.mjs +++ b/apps/status/scripts/report-incident.mjs @@ -161,7 +161,12 @@ async function main() { process.exit(1); } - normalizeDates(payload); + try { + normalizeDates(payload); + } catch (e) { + console.error("エラー: 日時の正規化に失敗しました:", e.message); + process.exit(1); + } const validationErrors = validatePayload(payload); if (validationErrors.length > 0) {