feat: establish NekoNest Cloud control and relay
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import test from "node:test";
|
||||
import {
|
||||
AUDIT_PUBLIC_BETA_ACCESS_FULFILLMENT_SQL,
|
||||
FULFILL_ACCESS_REQUESTS_BY_PUBLIC_BETA_SQL,
|
||||
PUBLIC_BETA_ACCESS_RESPONSE,
|
||||
} from "../db/access-requests.ts";
|
||||
import { REQUIRED_PUBLIC_BETA_P0_KEYS } from "../db/launch-gates.ts";
|
||||
|
||||
function createDatabase() {
|
||||
const db = new DatabaseSync(":memory:");
|
||||
db.exec(`
|
||||
CREATE TABLE beta_programs (
|
||||
id TEXT PRIMARY KEY,
|
||||
state TEXT NOT NULL,
|
||||
starts_at TEXT NOT NULL,
|
||||
ends_at TEXT
|
||||
);
|
||||
CREATE TABLE launch_gates (
|
||||
key TEXT PRIMARY KEY,
|
||||
priority TEXT NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
owner TEXT,
|
||||
notes TEXT NOT NULL,
|
||||
evidence_url TEXT
|
||||
);
|
||||
CREATE TABLE beta_access_requests (
|
||||
id TEXT PRIMARY KEY,
|
||||
status TEXT NOT NULL,
|
||||
admin_response TEXT,
|
||||
resolved_by TEXT,
|
||||
invitation_grant_id TEXT,
|
||||
resolved_at TEXT,
|
||||
updated_at TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE audit_events (
|
||||
id TEXT PRIMARY KEY,
|
||||
actor_id TEXT NOT NULL,
|
||||
action TEXT NOT NULL,
|
||||
target_type TEXT NOT NULL,
|
||||
target_id TEXT NOT NULL,
|
||||
reason TEXT NOT NULL,
|
||||
before_json TEXT,
|
||||
after_json TEXT,
|
||||
correlation_id TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
INSERT INTO beta_access_requests VALUES
|
||||
('access_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'requested', NULL, NULL, NULL, NULL, '2026-08-12T00:00:00.000Z'),
|
||||
('access_bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb', 'declined', '此前已拒绝', 'admin-old', NULL, '2026-08-11T00:00:00.000Z', '2026-08-11T00:00:00.000Z');
|
||||
INSERT INTO beta_programs VALUES
|
||||
('beta_open', 'active', '2026-08-12T00:00:00.000Z', NULL);
|
||||
`);
|
||||
return db;
|
||||
}
|
||||
|
||||
function reconcile(db, now = "2026-08-12T12:00:00.000Z") {
|
||||
const actor = "admin-public-beta";
|
||||
const correlation = "corr-public-beta";
|
||||
return [
|
||||
Number(db.prepare(FULFILL_ACCESS_REQUESTS_BY_PUBLIC_BETA_SQL).run(
|
||||
PUBLIC_BETA_ACCESS_RESPONSE, actor, now,
|
||||
).changes),
|
||||
Number(db.prepare(AUDIT_PUBLIC_BETA_ACCESS_FULFILLMENT_SQL).run(
|
||||
actor, PUBLIC_BETA_ACCESS_RESPONSE, correlation, now,
|
||||
).changes),
|
||||
];
|
||||
}
|
||||
|
||||
test("fulfills pending requests only after active public beta has complete P0 evidence", () => {
|
||||
const db = createDatabase();
|
||||
for (const key of REQUIRED_PUBLIC_BETA_P0_KEYS.slice(0, -1)) {
|
||||
db.prepare("INSERT INTO launch_gates VALUES (?, 'P0', 'passed', 'owner', 'verified', ?)")
|
||||
.run(key, `https://evidence.example.test/${key}`);
|
||||
}
|
||||
assert.deepEqual(reconcile(db), [0, 0]);
|
||||
assert.equal(db.prepare("SELECT status FROM beta_access_requests WHERE id LIKE 'access_a%'").get().status, "requested");
|
||||
|
||||
const lastKey = REQUIRED_PUBLIC_BETA_P0_KEYS.at(-1);
|
||||
db.prepare("INSERT INTO launch_gates VALUES (?, 'P0', 'passed', 'owner', 'verified', ?)")
|
||||
.run(lastKey, `https://evidence.example.test/${lastKey}`);
|
||||
assert.deepEqual(reconcile(db), [1, 1]);
|
||||
assert.deepEqual(
|
||||
{ ...db.prepare("SELECT status, admin_response, resolved_by, invitation_grant_id FROM beta_access_requests WHERE id LIKE 'access_a%'").get() },
|
||||
{
|
||||
status: "approved",
|
||||
admin_response: PUBLIC_BETA_ACCESS_RESPONSE,
|
||||
resolved_by: "admin-public-beta",
|
||||
invitation_grant_id: null,
|
||||
},
|
||||
);
|
||||
assert.equal(db.prepare("SELECT status FROM beta_access_requests WHERE id LIKE 'access_b%'").get().status, "declined");
|
||||
const audit = db.prepare("SELECT action, target_id, after_json FROM audit_events").get();
|
||||
assert.equal(audit.action, "beta_access.fulfilled_by_public_beta");
|
||||
assert.equal(audit.target_id, "access_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
assert.equal(JSON.parse(audit.after_json).adminResponse, PUBLIC_BETA_ACCESS_RESPONSE);
|
||||
assert.deepEqual(reconcile(db, "2026-08-12T12:01:00.000Z"), [0, 0]);
|
||||
db.close();
|
||||
});
|
||||
|
||||
test("wires reconciliation into both ways public beta can become open", async () => {
|
||||
const [repository, billingPage, adminPage] = await Promise.all([
|
||||
readFile(new URL("../db/repository.ts", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/dashboard/billing/page.tsx", import.meta.url), "utf8"),
|
||||
readFile(new URL("../app/admin/page.tsx", import.meta.url), "utf8"),
|
||||
]);
|
||||
const fulfillmentUses = repository.match(/FULFILL_ACCESS_REQUESTS_BY_PUBLIC_BETA_SQL/g) ?? [];
|
||||
const auditUses = repository.match(/AUDIT_PUBLIC_BETA_ACCESS_FULFILLMENT_SQL/g) ?? [];
|
||||
assert.equal(fulfillmentUses.length, 3); // one import plus setPublicBeta and updateLaunchGate
|
||||
assert.equal(auditUses.length, 3);
|
||||
assert.match(billingPage, /request\.admin_response/);
|
||||
assert.match(adminPage, /request\.admin_response/);
|
||||
});
|
||||
Reference in New Issue
Block a user