Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b382316
feat: add TokMetric activation panel
support371 Jul 17, 2026
ff58d7b
feat: add TokMetric command gateway runtime config
support371 Jul 17, 2026
c9c7f8e
feat: add controlled TokMetric activation gateway
support371 Jul 17, 2026
cbb8bb9
build: retain TokMetric command gateway source
support371 Jul 17, 2026
3a7abc4
feat: add TokMetric command gateway client
support371 Jul 17, 2026
65943b2
feat: expose authenticated TokMetric command API
support371 Jul 17, 2026
db40f28
feat: build live TokMetric activation console
support371 Jul 17, 2026
563a791
feat: add TokMetric production activation console
support371 Jul 17, 2026
d8e6add
test: protect TokMetric activation workflow boundaries
support371 Jul 17, 2026
247ccf4
fix: clean TokMetric command route payload handling
support371 Jul 17, 2026
b52362a
test: align TokMetric no-store boundary assertions
support371 Jul 17, 2026
dd993f3
security: require explicit TokMetric POST operations
support371 Jul 17, 2026
84024db
security: require Supabase JWT for TokMetric command gateway
support371 Jul 17, 2026
f3f2b7d
security: harden TokMetric activation approval boundaries
support371 Jul 17, 2026
057d869
test: enforce TokMetric approval separation and posting scopes
support371 Jul 17, 2026
cc5bff0
feat: modularize governed TokMetric activation commands
support371 Jul 17, 2026
ef218ee
feat: route TokMetric activation through approved admin gateway
support371 Jul 17, 2026
31c7d64
refactor: use approved admin gateway for TokMetric commands
support371 Jul 17, 2026
8867157
build: retain TokMetric admin gateway module
support371 Jul 17, 2026
74e9aa5
test: align activation console with approved admin gateway
support371 Jul 17, 2026
096f16e
test: verify approval safety in approved gateway module
support371 Jul 17, 2026
330ba57
refactor: remove standalone TokMetric command function
support371 Jul 17, 2026
8e700f8
refactor: remove standalone TokMetric command runtime
support371 Jul 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vercelignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ supabase/functions/gem-auth-gateway/*

supabase/functions/gem-admin-write/*
!supabase/functions/gem-admin-write/index.ts
!supabase/functions/gem-admin-write/tokmetric-command.ts

supabase/functions/gem-tokmetric-gpt-gateway/*
!supabase/functions/gem-tokmetric-gpt-gateway/index.ts
Expand Down
66 changes: 66 additions & 0 deletions src/__tests__/tokmetric-activation-approval-safety.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";

function source(path: string) {
return readFileSync(join(process.cwd(), path), "utf8");
}

describe("TokMetric activation approval safety", () => {
const command = source(
"supabase/functions/gem-admin-write/tokmetric-command.ts",
);
const gateway = source("supabase/functions/gem-admin-write/index.ts");

it("requires an explicit operation at application and gateway layers", () => {
const route = source("src/app/api/tokmetric/command/route.ts");
expect(route).toContain("TokMetric command operation is required.");
expect(command).toContain(
'requiredText(input.body.operation, "operation", 3, 100)',
);
expect(command).toContain('"INVALID_OPERATION"');
expect(gateway).toContain('action === "tokmetric_command"');
});

it("requires compliance evidence before approval", () => {
expect(command).toContain('"COMPLIANCE_REVIEW_REQUIRED"');
expect(command).toContain('["PASS", "HUMAN_REVIEW_REQUIRED"]');
expect(command).toContain('"COMPLIANCE_BLOCKED"');
});

it("prevents self-approval and enforces the requested role", () => {
expect(command).toContain("approval.requestedById === actor.id");
expect(command).toContain('"APPROVAL_SEPARATION_REQUIRED"');
expect(command).toContain("roleCanDecide(actor.role, approval.requiredRole)");
expect(command).toContain('"APPROVER_ROLE_REQUIRED"');
});

it("binds approval to the current exact version and object hash", () => {
expect(command).toContain(
"content.currentVersionId !== approval.contentVersionId",
);
expect(command).toContain("version.objectHash !== approval.objectHash");
expect(command).toContain('"APPROVAL_VERSION_MISMATCH"');
expect(command).toContain('"APPROVAL_HASH_MISMATCH"');
});

it("requires a connected posting connector and authorized publishing scope", () => {
expect(command).toContain('"TIKTOK_CONTENT_POSTING_API"');
expect(command).toContain('scopes.has("video.publish")');
expect(command).toContain('scopes.has("video.upload")');
expect(command).toContain('"CONTENT_POSTING_SCOPE_NOT_AUTHORIZED"');
expect(command).toContain('"LIVE_PUBLISHING_GATE_DISABLED"');
});

it("enforces session revocation for every administrator command", () => {
expect(gateway).toContain("validSessionVersion(sessionVersion)");
expect(gateway).toContain("user.sessionVersion !== sessionVersion");
expect(gateway).toContain('"SESSION_REVOKED"');
});

it("never performs an external TikTok write", () => {
expect(command).toContain("externalActionTaken: false");
expect(command).not.toContain("open.tiktokapis.com");
expect(gateway).not.toContain("open.tiktokapis.com");
});
});
104 changes: 104 additions & 0 deletions src/__tests__/tokmetric-activation-command-center.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";

function source(path: string) {
return readFileSync(join(process.cwd(), path), "utf8");
}

describe("TokMetric activation command center", () => {
it("retains the approved administrator gateway and TokMetric module", () => {
const ignore = source(".vercelignore");
expect(ignore).toContain("!supabase/functions/gem-admin-write/");
expect(ignore).toContain("!supabase/functions/gem-admin-write/index.ts");
expect(ignore).toContain(
"!supabase/functions/gem-admin-write/tokmetric-command.ts",
);
});

it("requires a versioned GEM administrator session", () => {
const gateway = source("supabase/functions/gem-admin-write/index.ts");
expect(gateway).toContain("sessionVersion");
expect(gateway).toContain('"SESSION_REVOKED"');
expect(gateway).toContain('payload.iss !== "gem-auth-gateway"');
expect(gateway).toContain('payload.aud !== "gem-enterprise"');
expect(gateway).toContain("ADMIN_ROLES.includes");
});

it("keeps activation operations internal and fail closed", () => {
const command = source(
"supabase/functions/gem-admin-write/tokmetric-command.ts",
);
expect(command).toContain('controlledWriteMode: "COMMAND_CENTER_ONLY"');
expect(command).toContain("externalActionTaken: false");
expect(command).toContain('"LIVE_PUBLISHING_GATE_DISABLED"');
expect(command).not.toContain("PUBLISHED_CONFIRMED");
expect(command).not.toContain("open.tiktokapis.com");
});

it("supports the complete controlled activation sequence", () => {
const command = source(
"supabase/functions/gem-admin-write/tokmetric-command.ts",
);
for (const operation of [
"snapshot",
"create_draft",
"create_version",
"run_review",
"request_approval",
"decide_approval",
"publish_preflight",
]) {
expect(command).toContain(`operation === "${operation}"`);
}
const gateway = source("supabase/functions/gem-admin-write/index.ts");
expect(gateway).toContain('action === "tokmetric_command"');
expect(gateway).toContain("dispatchTokMetricCommand");
});

it("proxies commands only through the HttpOnly GEM session", () => {
const route = source("src/app/api/tokmetric/command/route.ts");
const client = source("src/lib/tokmetric/command-gateway.ts");
expect(route).toContain("getGatewaySessionToken");
expect(route).toContain("GEM_SESSION_REQUIRED");
expect(route).toContain("invokeTokMetricCommandGateway");
expect(route).toContain('"Cache-Control": "no-store, max-age=0"');
expect(client).toContain("adminWriteGateway");
expect(client).toContain('"tokmetric_command"');
expect(client).not.toContain("DEFAULT_COMMAND_GATEWAY_URL");
expect(client).not.toContain("GEM_SUPABASE_GATEWAY_ANON_KEY");
expect(route).not.toContain("POSTGRES_PRISMA_URL");
expect(route).not.toContain("SUPABASE_SERVICE_ROLE_KEY");
});

it("preserves existing administrator, retention, and credential actions", () => {
const gateway = source("supabase/functions/gem-admin-write/index.ts");
for (const action of [
"update_user",
"retention_policy_list",
"retention_policy_create",
"retention_policy_action",
"tokmetric_credential_list",
"tokmetric_credential_issue_hash",
"tokmetric_credential_revoke",
]) {
expect(gateway).toContain(`action === "${action}"`);
}
});

it("exposes real operator controls in the protected command center", () => {
const panel = source(
"src/components/tokmetric/TokMetricActivationPanel.tsx",
);
const page = source("src/app/app/command-center/tokmetric/page.tsx");
expect(panel).toContain('fetch("/api/tokmetric/command"');
expect(panel).toContain("Connect Login Kit");
expect(panel).toContain("Connect Posting API");
expect(panel).toContain("Create internal content draft");
expect(panel).toContain("Run review");
expect(panel).toContain("Request approval");
expect(panel).toContain("Preflight");
expect(panel).toContain("External actions taken: none");
expect(page).toContain("<TokMetricActivationPanel />");
});
});
121 changes: 121 additions & 0 deletions src/app/api/tokmetric/command/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import { NextRequest, NextResponse } from "next/server";
import { getGatewaySessionToken } from "@/lib/auth";
import { GatewayRequestError } from "@/lib/supabase-gateway";
import {
invokeTokMetricCommandGateway,
type TokMetricCommandOperation,
} from "@/lib/tokmetric/command-gateway";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

const OPERATIONS = new Set<TokMetricCommandOperation>([
"snapshot",
"create_draft",
"create_version",
"run_review",
"request_approval",
"decide_approval",
"publish_preflight",
]);

function json(body: unknown, status = 200) {
return NextResponse.json(body, {
status,
headers: {
"Cache-Control": "no-store, max-age=0",
"X-Content-Type-Options": "nosniff",
"Referrer-Policy": "no-referrer",
},
});
}

async function requireToken() {
const token = await getGatewaySessionToken();
if (!token) {
throw new GatewayRequestError(
401,
"GEM_SESSION_REQUIRED",
"Authentication required.",
);
}
return token;
}

async function run(
operation: TokMetricCommandOperation,
payload: Record<string, unknown> = {},
) {
try {
const token = await requireToken();
const result = await invokeTokMetricCommandGateway(
token,
operation,
payload,
);
const created = operation === "create_draft" || operation === "request_approval";
return json(result, created ? 201 : 200);
} catch (error) {
if (error instanceof GatewayRequestError) {
return json(
{ error: error.message, code: error.code },
error.statusCode,
);
}
console.error("[tokmetric command route] internal error", {
name: error instanceof Error ? error.name : "unknown",
});
return json(
{
error: "TokMetric command service is unavailable.",
code: "TOKMETRIC_COMMAND_UNAVAILABLE",
},
503,
);
}
}

export async function GET() {
return run("snapshot");
}

export async function POST(request: NextRequest) {
let body: unknown;
try {
body = await request.json();
} catch {
return json(
{ error: "Request body must be valid JSON.", code: "INVALID_JSON" },
400,
);
}
if (!body || typeof body !== "object" || Array.isArray(body)) {
return json(
{ error: "TokMetric request is invalid.", code: "INVALID_REQUEST" },
400,
);
}
const payload = body as Record<string, unknown>;
if (typeof payload.operation !== "string") {
return json(
{
error: "TokMetric command operation is required.",
code: "INVALID_OPERATION",
},
400,
);
}
const operation = payload.operation as TokMetricCommandOperation;
if (!OPERATIONS.has(operation)) {
return json(
{
error: "TokMetric command operation is invalid.",
code: "INVALID_OPERATION",
},
400,
);
}
const commandPayload = { ...payload };
delete commandPayload.operation;
return run(operation, commandPayload);
}
4 changes: 4 additions & 0 deletions src/app/app/command-center/tokmetric/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
UsersRound,
Video,
} from "lucide-react";
import { TokMetricActivationPanel } from "@/components/tokmetric/TokMetricActivationPanel";
import { TokMetricConnectorPanel } from "@/components/tokmetric/TokMetricConnectorPanel";
import { TokMetricGptCredentialManager } from "@/components/tokmetric/TokMetricGptCredentialManager";

Expand Down Expand Up @@ -86,6 +87,7 @@ const controlState = [
["Native GEM Enterprise module", "READY"],
["Custom GPT Action contracts", "READY"],
["Bearer credential management", "READY"],
["Command Center workflow gateway", "READY"],
["TikTok OAuth authorization", "AUTHORIZATION_REQUIRED"],
["Human approval enforcement", "ENABLED"],
["Live publishing", "LOCKED"],
Expand Down Expand Up @@ -160,6 +162,8 @@ export default function TokMetricCommandCenterPage() {
))}
</section>

<TokMetricActivationPanel />

<section className="grid gap-6 xl:grid-cols-[1.15fr_0.85fr]">
<TokMetricConnectorPanel />

Expand Down
Loading
Loading