Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions apps/landing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"dev": "next dev --turbopack --port 3100",
"build": "next build",
"start": "next start",
"typecheck": "tsc --noEmit"
"typecheck": "tsc --noEmit",
"test": "vitest run --passWithNoTests"
},
"dependencies": {
"@radix-ui/react-slot": "^1.2.4",
Expand All @@ -25,6 +26,7 @@
"@types/react": "^19.1.6",
"@types/react-dom": "^19.1.6",
"tailwindcss": "^4.1.8",
"typescript": "catalog:"
"typescript": "catalog:",
"vitest": "catalog:"
}
}
28 changes: 28 additions & 0 deletions apps/landing/src/app/api/otel/traces/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { ingestOtelTraces } from "~/lib/otelIngest";

export const runtime = "nodejs";

const CORS_HEADERS = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST, OPTIONS",
"Access-Control-Allow-Headers": "content-type, x-marcode-jira-access-token",
"Access-Control-Max-Age": "600",
} as const;

export function OPTIONS(): Response {
return new Response(null, {
status: 204,
headers: CORS_HEADERS,
});
}

export async function POST(request: Request): Promise<Response> {
const result = await ingestOtelTraces(request);
if (result.status === 204) {
return new Response(null, { status: 204, headers: CORS_HEADERS });
}
return Response.json(result.body ?? { error: "OTEL ingest failed" }, {
status: result.status,
headers: CORS_HEADERS,
});
}
168 changes: 168 additions & 0 deletions apps/landing/src/lib/otelIngest.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import { afterEach, describe, expect, it, vi } from "vitest";

import { __resetOtelIngestForTests, ingestOtelTraces } from "./otelIngest";

const makePayload = () => ({
resourceSpans: [
{
resource: {
attributes: [
{ key: "service.name", value: { stringValue: "marcode-web" } },
{ key: "project.name", value: { stringValue: "MarCode" } },
{ key: "auth.token", value: { stringValue: "secret" } },
],
},
scopeSpans: [
{
scope: { name: "test", attributes: [] },
spans: [
{
traceId: "1".repeat(32),
spanId: "2".repeat(16),
name: "marcode.ui.composer.submit",
kind: 1,
startTimeUnixNano: "1",
endTimeUnixNano: "2",
attributes: [
{ key: "provider", value: { stringValue: "codex" } },
{ key: "prompt.text", value: { stringValue: "do not forward" } },
],
events: [
{
name: "event",
timeUnixNano: "1",
attributes: [{ key: "stdout", value: { stringValue: "nope" } }],
},
],
links: [],
status: { code: "STATUS_CODE_OK" },
},
],
},
],
},
],
});

function request(body: unknown, headers?: Record<string, string>) {
return new Request("https://marcode.dev/api/otel/traces", {
method: "POST",
headers: {
"content-type": "application/json",
...headers,
},
body: typeof body === "string" ? body : JSON.stringify(body),
});
}

afterEach(() => {
__resetOtelIngestForTests();
vi.restoreAllMocks();
});

describe("otel ingest", () => {
it("sanitizes and forwards valid OTLP payloads", async () => {
const forwarded: unknown[] = [];
const fetchMock = vi.fn(async (_url: string | URL | Request, init?: RequestInit) => {
forwarded.push(JSON.parse(String(init?.body)));
return new Response(null, { status: 204 });
}) as unknown as typeof fetch;

const result = await ingestOtelTraces(request(makePayload()), {
collectorUrl: "https://collector.example/v1/traces",
fetch: fetchMock,
});

expect(result.status).toBe(204);
expect(forwarded).toHaveLength(1);
const payload = forwarded[0] as ReturnType<typeof makePayload>;
const attrs = payload.resourceSpans[0]!.resource.attributes;
expect(attrs).toContainEqual({ key: "service.name", value: { stringValue: "marcode" } });
expect(attrs).toContainEqual({
key: "marcode.original_service_name",
value: { stringValue: "marcode-web" },
});
expect(attrs.some((attr) => attr.key === "auth.token")).toBe(false);
const spanAttrs = payload.resourceSpans[0]!.scopeSpans[0]!.spans[0]!.attributes;
expect(spanAttrs).toEqual([{ key: "provider", value: { stringValue: "codex" } }]);
expect(payload.resourceSpans[0]!.scopeSpans[0]!.spans[0]!.events![0]!.attributes).toEqual([]);
});

it("marks Genesis users from verified Jira email and bypasses rate limits", async () => {
const forwarded: unknown[] = [];
const fetchMock = vi.fn(async (url: string | URL | Request, init?: RequestInit) => {
if (String(url) === "https://api.atlassian.com/me") {
return Response.json({ email: "dev@gen.tech", account_id: "jira-account" });
}
forwarded.push(JSON.parse(String(init?.body)));
return new Response(null, { status: 204 });
}) as unknown as typeof fetch;

for (let index = 0; index < 3; index++) {
const result = await ingestOtelTraces(
request(makePayload(), { "x-marcode-jira-access-token": "jira-token" }),
{
collectorUrl: "https://collector.example/v1/traces",
fetch: fetchMock,
rateLimitPerMinute: 1,
clientKey: "same-client",
},
);
expect(result.status).toBe(204);
}

const payload = forwarded[0] as ReturnType<typeof makePayload>;
expect(payload.resourceSpans[0]!.resource.attributes).toContainEqual({
key: "analytics.user.is_genesis",
value: { boolValue: true },
});
});

it("rate limits non-Genesis users", async () => {
const fetchMock = vi.fn(
async () => new Response(null, { status: 204 }),
) as unknown as typeof fetch;

const first = await ingestOtelTraces(request(makePayload()), {
collectorUrl: "https://collector.example/v1/traces",
fetch: fetchMock,
rateLimitPerMinute: 1,
clientKey: "same-client",
});
const second = await ingestOtelTraces(request(makePayload()), {
collectorUrl: "https://collector.example/v1/traces",
fetch: fetchMock,
rateLimitPerMinute: 1,
clientKey: "same-client",
});

expect(first.status).toBe(204);
expect(second.status).toBe(429);
});

it("rejects invalid and oversized payloads", async () => {
const invalid = await ingestOtelTraces(request({ nope: true }), {
collectorUrl: "https://collector.example/v1/traces",
});
const oversized = await ingestOtelTraces(request(makePayload()), {
collectorUrl: "https://collector.example/v1/traces",
maxBodyBytes: 10,
});

expect(invalid.status).toBe(400);
expect(oversized.status).toBe(413);
});

it("returns 502 when collector forwarding fails", async () => {
const fetchMock = vi.fn(
async () => new Response("bad", { status: 500 }),
) as unknown as typeof fetch;

const result = await ingestOtelTraces(request(makePayload()), {
collectorUrl: "https://collector.example/v1/traces",
fetch: fetchMock,
});

expect(result.status).toBe(502);
});
});
Loading
Loading