rename(phase 3): compose/DB/infra + stray code refs capakraken → nexus (#62)
CI / Lint (push) Successful in 3m4s
CI / Typecheck (push) Successful in 3m6s
CI / Architecture Guardrails (push) Successful in 3m8s
CI / Assistant Split Regression (push) Successful in 3m48s
CI / Build (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Fresh-Linux Docker Deploy (push) Has been cancelled
CI / Release Images (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Lint (push) Successful in 3m4s
CI / Typecheck (push) Successful in 3m6s
CI / Architecture Guardrails (push) Successful in 3m8s
CI / Assistant Split Regression (push) Successful in 3m48s
CI / Build (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Fresh-Linux Docker Deploy (push) Has been cancelled
CI / Release Images (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
rename(phase 3): compose/DB/infra + stray code refs capakraken → nexus (#62) Co-authored-by: Hartmut Nörenberg <hn@hartmut-noerenberg.com> Co-committed-by: Hartmut Nörenberg <hn@hartmut-noerenberg.com>
This commit was merged in pull request #62.
This commit is contained in:
@@ -105,10 +105,10 @@ describe("RBAC cache Redis pub/sub (#57)", () => {
|
||||
|
||||
// Simulate a peer instance publishing an invalidation: grab any
|
||||
// subscriber on the channel and fire the event as if Redis delivered it.
|
||||
const subs = channelSubscribers.get("capakraken:rbac-invalidate");
|
||||
const subs = channelSubscribers.get("nexus:rbac-invalidate");
|
||||
expect(subs).toBeDefined();
|
||||
expect(subs!.size).toBeGreaterThanOrEqual(1);
|
||||
for (const sub of subs!) sub.emit("message", "capakraken:rbac-invalidate", "1");
|
||||
for (const sub of subs!) sub.emit("message", "nexus:rbac-invalidate", "1");
|
||||
|
||||
// Next load must hit the DB again.
|
||||
await loadRoleDefaults();
|
||||
@@ -126,6 +126,6 @@ describe("RBAC cache Redis pub/sub (#57)", () => {
|
||||
|
||||
const newPublishes = publishCalls.slice(countBefore);
|
||||
expect(newPublishes.length).toBe(1);
|
||||
expect(newPublishes[0]!.channel).toBe("capakraken:rbac-invalidate");
|
||||
expect(newPublishes[0]!.channel).toBe("nexus:rbac-invalidate");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,7 +24,7 @@ describe("assertWebhookUrlAllowed — SSRF guard", () => {
|
||||
|
||||
it("allows an HTTPS URL with a path and query string", async () => {
|
||||
await expect(
|
||||
assertWebhookUrlAllowed("https://hooks.external.io/events?source=capakraken"),
|
||||
assertWebhookUrlAllowed("https://hooks.external.io/events?source=nexus"),
|
||||
).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
|
||||
@@ -22,15 +22,15 @@ export function getAppBaseUrl(): string {
|
||||
if (process.env["NODE_ENV"] === "production") {
|
||||
throw new Error(
|
||||
"NEXTAUTH_URL must be set in production — email links will contain localhost otherwise. " +
|
||||
"Set it to the public URL of this app (e.g. https://capakraken.example.com).",
|
||||
"Set it to the public URL of this app (e.g. https://nexus.example.com).",
|
||||
);
|
||||
}
|
||||
|
||||
if (!warned) {
|
||||
warned = true;
|
||||
console.warn(
|
||||
"[capakraken] NEXTAUTH_URL is not set — falling back to http://localhost:3100 for email links. " +
|
||||
"Set NEXTAUTH_URL in your .env to suppress this warning.",
|
||||
"[nexus] NEXTAUTH_URL is not set — falling back to http://localhost:3100 for email links. " +
|
||||
"Set NEXTAUTH_URL in your .env to suppress this warning.",
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,13 +44,13 @@ const redactConfig = { paths: REDACT_PATHS, censor: "[REDACTED]" };
|
||||
export const logger = isProduction
|
||||
? pino({
|
||||
level: LOG_LEVEL,
|
||||
base: { service: "capakraken-api" },
|
||||
base: { service: "nexus-api" },
|
||||
redact: redactConfig,
|
||||
})
|
||||
: pino(
|
||||
{
|
||||
level: LOG_LEVEL,
|
||||
base: { service: "capakraken-api" },
|
||||
base: { service: "nexus-api" },
|
||||
redact: redactConfig,
|
||||
formatters: {
|
||||
level(label: string) {
|
||||
|
||||
@@ -31,7 +31,7 @@ type RateLimiterBackend = {
|
||||
reset: () => Promise<void>;
|
||||
};
|
||||
|
||||
const DEFAULT_REDIS_KEY_PREFIX = "capakraken:ratelimit";
|
||||
const DEFAULT_REDIS_KEY_PREFIX = "nexus:ratelimit";
|
||||
const DEFAULT_REDIS_BACKEND = process.env["RATE_LIMIT_BACKEND"] as RateLimitBackendMode | undefined;
|
||||
const DEFAULT_REDIS_URL = process.env["REDIS_URL"]?.trim();
|
||||
const warnedRedisFailures = new Set<string>();
|
||||
|
||||
@@ -201,7 +201,7 @@ const REDIS_URL =
|
||||
: (() => {
|
||||
throw new Error("REDIS_URL required in production");
|
||||
})());
|
||||
const CHANNEL = "capakraken:sse";
|
||||
const CHANNEL = "nexus:sse";
|
||||
|
||||
let publisher: Redis | null = null;
|
||||
let subscriber: Redis | null = null;
|
||||
|
||||
@@ -42,7 +42,7 @@ const ROLE_DEFAULTS_TTL = 10_000;
|
||||
// We publish a single invalidate message per change; every node subscribes and
|
||||
// clears its local cache on receipt. Failure to publish/subscribe is logged
|
||||
// but never thrown — the TTL above is the fall-back.
|
||||
const RBAC_INVALIDATE_CHANNEL = "capakraken:rbac-invalidate";
|
||||
const RBAC_INVALIDATE_CHANNEL = "nexus:rbac-invalidate";
|
||||
|
||||
let _rbacPublisher: Redis | null = null;
|
||||
let _rbacSubscriber: Redis | null = null;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"./client": "./src/client.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"db:doctor": "node ../../scripts/db-doctor.mjs capakraken",
|
||||
"db:doctor": "node ../../scripts/db-doctor.mjs nexus",
|
||||
"db:push": "node ../../scripts/prisma-with-env.mjs db push --schema ./prisma/schema.prisma",
|
||||
"db:migrate": "node ../../scripts/prisma-with-env.mjs migrate dev --schema ./prisma/schema.prisma",
|
||||
"db:migrate:deploy": "node ../../scripts/prisma-with-env.mjs migrate deploy --schema ./prisma/schema.prisma",
|
||||
|
||||
@@ -22,34 +22,34 @@ test.afterEach(() => {
|
||||
process.env = { ...ORIGINAL_ENV };
|
||||
});
|
||||
|
||||
test("assertDestructiveDbAllowed allows an explicitly confirmed disposable capakraken test database", () => {
|
||||
test("assertDestructiveDbAllowed allows an explicitly confirmed disposable nexus test database", () => {
|
||||
setEnv({
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/capakraken_test",
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/nexus_test",
|
||||
ALLOW_DESTRUCTIVE_DB_TOOLS: "true",
|
||||
CONFIRM_DESTRUCTIVE_DB_NAME: "capakraken_test",
|
||||
CONFIRM_DESTRUCTIVE_DB_NAME: "nexus_test",
|
||||
});
|
||||
|
||||
const target = assertDestructiveDbAllowed({
|
||||
commandName: "db:test",
|
||||
allowedDatabaseNames: ["capakraken_test"],
|
||||
allowedDatabaseNames: ["nexus_test"],
|
||||
});
|
||||
|
||||
assert.equal(target.databaseName, "capakraken_test");
|
||||
assert.equal(target.databaseName, "nexus_test");
|
||||
assert.equal(target.hostname, "localhost");
|
||||
});
|
||||
|
||||
test("assertDestructiveDbAllowed rejects protected live database names even if allowlisted", () => {
|
||||
setEnv({
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/capakraken",
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/nexus",
|
||||
ALLOW_DESTRUCTIVE_DB_TOOLS: "true",
|
||||
CONFIRM_DESTRUCTIVE_DB_NAME: "capakraken",
|
||||
CONFIRM_DESTRUCTIVE_DB_NAME: "nexus",
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() =>
|
||||
assertDestructiveDbAllowed({
|
||||
commandName: "db:test",
|
||||
allowedDatabaseNames: ["capakraken"],
|
||||
allowedDatabaseNames: ["nexus"],
|
||||
}),
|
||||
/explicitly protected/u,
|
||||
);
|
||||
@@ -57,7 +57,7 @@ test("assertDestructiveDbAllowed rejects protected live database names even if a
|
||||
|
||||
test("assertDestructiveDbAllowed rejects missing confirmation", () => {
|
||||
setEnv({
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/capakraken_e2e",
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/nexus_e2e",
|
||||
ALLOW_DESTRUCTIVE_DB_TOOLS: "true",
|
||||
CONFIRM_DESTRUCTIVE_DB_NAME: "wrong_db",
|
||||
});
|
||||
@@ -66,24 +66,24 @@ test("assertDestructiveDbAllowed rejects missing confirmation", () => {
|
||||
() =>
|
||||
assertDestructiveDbAllowed({
|
||||
commandName: "db:test",
|
||||
allowedDatabaseNames: ["capakraken_e2e"],
|
||||
allowedDatabaseNames: ["nexus_e2e"],
|
||||
}),
|
||||
/CONFIRM_DESTRUCTIVE_DB_NAME=capakraken_e2e/u,
|
||||
/CONFIRM_DESTRUCTIVE_DB_NAME=nexus_e2e/u,
|
||||
);
|
||||
});
|
||||
|
||||
test("assertDestructiveDbAllowed rejects missing destructive allow flag", () => {
|
||||
setEnv({
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/capakraken_ci",
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/nexus_ci",
|
||||
ALLOW_DESTRUCTIVE_DB_TOOLS: undefined,
|
||||
CONFIRM_DESTRUCTIVE_DB_NAME: "capakraken_ci",
|
||||
CONFIRM_DESTRUCTIVE_DB_NAME: "nexus_ci",
|
||||
});
|
||||
|
||||
assert.throws(
|
||||
() =>
|
||||
assertDestructiveDbAllowed({
|
||||
commandName: "db:test",
|
||||
allowedDatabaseNames: ["capakraken_ci"],
|
||||
allowedDatabaseNames: ["nexus_ci"],
|
||||
}),
|
||||
/ALLOW_DESTRUCTIVE_DB_TOOLS=true/u,
|
||||
);
|
||||
@@ -99,19 +99,19 @@ test("assertSafeSeedTarget rejects unexpected legacy disposable databases", () =
|
||||
assert.throws(() => assertSafeSeedTarget("db:seed"), /not in the destructive-tool allowlist/u);
|
||||
});
|
||||
|
||||
test("assertNexusDbTarget accepts non-destructive capakraken targets", () => {
|
||||
test("assertNexusDbTarget accepts non-destructive nexus targets", () => {
|
||||
setEnv({
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/capakraken_dev",
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/nexus_dev",
|
||||
});
|
||||
|
||||
const target = assertNexusDbTarget("db:seed:holidays");
|
||||
|
||||
assert.equal(target.databaseName, "capakraken_dev");
|
||||
assert.equal(target.databaseName, "nexus_dev");
|
||||
});
|
||||
|
||||
test("assertNexusDbTarget rejects legacy non-capakraken targets", () => {
|
||||
test("assertNexusDbTarget rejects legacy non-nexus targets", () => {
|
||||
setEnv({
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/legacy_non_capakraken",
|
||||
DATABASE_URL: "postgresql://tester:secret@localhost:5432/legacy_non_nexus",
|
||||
});
|
||||
|
||||
assert.throws(() => assertNexusDbTarget("db:seed:holidays"), /not a valid Nexus target/u);
|
||||
|
||||
@@ -6,7 +6,7 @@ interface DestructiveGuardOptions {
|
||||
requireConfirmation?: boolean;
|
||||
}
|
||||
|
||||
const PROTECTED_DATABASE_NAMES = new Set(["capakraken"]);
|
||||
const PROTECTED_DATABASE_NAMES = new Set(["nexus"]);
|
||||
|
||||
export function parseDatabaseUrl(rawUrl: string) {
|
||||
const parsed = new URL(rawUrl);
|
||||
|
||||
@@ -157,7 +157,7 @@ async function main() {
|
||||
const options = parseArgs(process.argv.slice(2));
|
||||
const target = assertDestructiveDbAllowed({
|
||||
commandName: "db:reset:dispo",
|
||||
allowedDatabaseNames: ["capakraken_test", "capakraken_e2e", "capakraken_ci"],
|
||||
allowedDatabaseNames: ["nexus_test", "nexus_e2e", "nexus_ci"],
|
||||
});
|
||||
const databaseUrl = process.env.DATABASE_URL;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
parseDatabaseUrl,
|
||||
} from "./destructive-db-guard.js";
|
||||
|
||||
const TEST_DATABASE_NAMES = ["capakraken_test", "capakraken_e2e", "capakraken_ci"];
|
||||
const TEST_DATABASE_NAMES = ["nexus_test", "nexus_e2e", "nexus_ci"];
|
||||
|
||||
export function assertSafeSeedTarget(commandName: string) {
|
||||
return assertDestructiveDbAllowed({
|
||||
@@ -24,7 +24,7 @@ export function assertNexusDbTarget(commandName: string) {
|
||||
|
||||
const target = parseDatabaseUrl(rawUrl);
|
||||
|
||||
if (!target.databaseName.startsWith("capakraken")) {
|
||||
if (!target.databaseName.startsWith("nexus")) {
|
||||
throw new Error(
|
||||
`${commandName} aborted: database '${target.databaseName}' is not a valid Nexus target. Target=${formatTarget(target)}`,
|
||||
);
|
||||
|
||||
@@ -2372,7 +2372,7 @@ async function main() {
|
||||
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
||||
.join(" ");
|
||||
|
||||
const email = `${eid}@capakraken.example`;
|
||||
const email = `${eid}@nexus.example`;
|
||||
const lcrCents = Math.round(lcr * 100);
|
||||
const ucrCents = Math.round(ucr * 100);
|
||||
const availability = computeAvailability(fraction, availDays);
|
||||
|
||||
@@ -23,7 +23,7 @@ function toDisplayName(eid) {
|
||||
}
|
||||
|
||||
function toEmail(eid) {
|
||||
return `${eid}@capakraken.example`;
|
||||
return `${eid}@nexus.example`;
|
||||
}
|
||||
|
||||
function computeSkillLabel(chapter, typeOfWork) {
|
||||
@@ -150,7 +150,7 @@ async function main() {
|
||||
{
|
||||
col: 15, // O
|
||||
header: "Email\n(generated)",
|
||||
doc: "Generated email: firstname.lastname@capakraken.example. Required unique field in Nexus. Replace with real email in production.",
|
||||
doc: "Generated email: firstname.lastname@nexus.example. Required unique field in Nexus. Replace with real email in production.",
|
||||
},
|
||||
{
|
||||
col: 16, // P
|
||||
|
||||
Reference in New Issue
Block a user