Track HiveGrid Cloud planning reference

This commit is contained in:
david committed 2026-06-26 20:48:01 +02:00
1 parent b3d5ea6764
commit e341c5938a
5784 files changed
+1104929 -3

No files matched your search

+66
View File
@@ -0,0 +1,66 @@
import { mkdir } from "node:fs/promises";
import { builtinModules } from "node:module";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { build } from "esbuild";
const apiDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const entryPoint = path.join(apiDir, "src/server.ts");
const outputFile = path.join(apiDir, "dist/server.js");
const nodeBuiltins = new Set([...builtinModules, ...builtinModules.map((moduleName) => `node:${moduleName}`)]);
const sourcemap = process.env.SOURCEMAP === "true" || process.env.BUILD_SOURCEMAPS === "true";
const externalizeRuntimeDependencies = {
name: "externalize-runtime-dependencies",
setup(buildContext) {
buildContext.onResolve({ filter: /.*/ }, (args) => {
if (nodeBuiltins.has(args.path)) {
return { path: args.path, external: true };
}
if (isExternalRuntimePackage(args.path)) {
return { path: args.path, external: true };
}
return undefined;
});
},
};
await mkdir(path.dirname(outputFile), { recursive: true });
await build({
entryPoints: [entryPoint],
outfile: outputFile,
bundle: true,
platform: "node",
format: "esm",
target: "node20",
sourcemap,
banner: {
js: 'import { createRequire as __toolctrlCreateRequire } from "node:module"; const require = __toolctrlCreateRequire(import.meta.url);',
},
plugins: [externalizeRuntimeDependencies],
logLevel: "warning",
});
function isBarePackageSpecifier(specifier) {
return !specifier.startsWith(".") && !specifier.startsWith("/") && !specifier.startsWith("#");
}
function isExternalRuntimePackage(specifier) {
if (!isBarePackageSpecifier(specifier)) {
return false;
}
return (
specifier === "@prisma/client" ||
specifier.startsWith("@prisma/client/") ||
specifier === "@prisma/adapter-pg" ||
specifier.startsWith("@prisma/adapter-pg/") ||
specifier === "jsonwebtoken" ||
specifier.startsWith("jsonwebtoken/") ||
specifier === "pino" ||
specifier.startsWith("pino/")
);
}
@@ -0,0 +1,80 @@
#!/usr/bin/env tsx
/**
* Sentry smoke test for the API process.
*
* Triggers a fake captureException + a fake `Sentry.startSpan` transaction
* so an operator can verify end-to-end that:
* - the API DSN is wired,
* - `beforeSend` sanitises PII,
* - the matching Sentry project receives both an Issue and a Transaction.
*
* Run from the repo root with one of:
* pnpm --filter @toolctrl/api exec tsx scripts/smoke-sentry.ts
* SENTRY_DSN_API=... pnpm --filter @toolctrl/api exec tsx scripts/smoke-sentry.ts
*
* Exits 0 on a clean run, 1 when the SDK fails to load. A no-DSN run is
* intentionally a successful no-op so CI can call it unconditionally.
*
* @see docs/improvement-plan/02-observability/sentry-wiring-api-worker.md
*/
import { initApiSentry, readApiSentryConfig } from "../src/sentry.js";
async function main(): Promise<void> {
const config = readApiSentryConfig();
if (!config.dsn) {
// eslint-disable-next-line no-console
console.warn("[smoke-sentry] SENTRY_DSN_API is not set; nothing to do.");
return;
}
const reporter = initApiSentry(config);
// 1) Fake captureException — exercises beforeSend + sanitisation.
await reporter.report({
component: "api",
operation: "smoke.exception",
severity: "error",
error: new Error(`smoke-sentry: fake exception at ${new Date().toISOString()}`),
// Include obvious PII fields so the operator can confirm redaction in the
// Sentry UI (`token` / `password` should render as [Redacted]).
token: "fake-token-must-be-redacted",
password: "fake-password-must-be-redacted",
});
// 2) Fake transaction — exercises @sentry/node startSpan.
try {
const moduleName = "@sentry/node";
const sentry = (await import(/* @vite-ignore */ moduleName)) as {
startSpan?: (args: { op: string; name: string }, cb: () => Promise<void> | void) => Promise<void> | void;
default?: {
startSpan?: (args: { op: string; name: string }, cb: () => Promise<void> | void) => Promise<void> | void;
};
};
const startSpan = sentry.startSpan ?? sentry.default?.startSpan;
if (typeof startSpan === "function") {
await startSpan({ op: "test", name: "smoke-sentry/api" }, async () => {
await new Promise((resolve) => setTimeout(resolve, 25));
});
} else {
// eslint-disable-next-line no-console
console.warn("[smoke-sentry] @sentry/node loaded but startSpan is unavailable; transaction skipped.");
}
} catch (cause) {
// eslint-disable-next-line no-console
console.error("[smoke-sentry] failed to load @sentry/node for the transaction smoke:", cause);
process.exitCode = 1;
}
// Give the SDK enough time to flush. Sentry's `close()` would be more
// precise but pulling the type via dynamic import is more trouble than it
// is worth for a manual smoke script.
await new Promise((resolve) => setTimeout(resolve, 1500));
// eslint-disable-next-line no-console
console.log("[smoke-sentry] done — check the Sentry UI (Issues + Performance) for boilerplate-api.");
}
main().catch((cause) => {
// eslint-disable-next-line no-console
console.error("[smoke-sentry] unexpected failure:", cause);
process.exit(1);
});