Skip to content
Merged

Dev #20

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
ae0099f
chore(git): ignore local benchmark commit helper
md-dev970 Sep 9, 2026
2ec4a8c
feat(api): add deterministic benchmark data seeder
md-dev970 Sep 9, 2026
4ee9b72
feat(terraform): establish isolated benchmark configuration
md-dev970 Sep 9, 2026
937f594
feat(terraform): add disposable benchmark networking
md-dev970 Sep 9, 2026
6069835
feat(terraform): add benchmark postgres and secrets
md-dev970 Sep 9, 2026
f33bf0e
feat(terraform): deploy benchmark API on ECS
md-dev970 Sep 9, 2026
423947b
feat(benchmark): add authenticated k6 workloads
md-dev970 Sep 9, 2026
a57beb4
feat(benchmark): add execution and evidence tooling
md-dev970 Sep 9, 2026
c9624a3
docs(benchmark): document isolated AWS benchmark workflow
md-dev970 Sep 9, 2026
b23a4a5
feat(benchmark): add postgres query-plan diagnostics
md-dev970 Sep 9, 2026
30d5c18
perf(api): index workspace cost queries by date
md-dev970 Sep 9, 2026
4dae7ea
fix(benchmark): distribute smoke traffic and expand diagnostics
md-dev970 Sep 10, 2026
57fde35
perf(api): cover cost reporting queries
md-dev970 Sep 10, 2026
0047e78
feat(benchmark): add server-side capacity discovery
md-dev970 Sep 10, 2026
f6c356d
perf(api): add daily cost rollups
md-dev970 Sep 10, 2026
f37ea20
feat(benchmark): automate server-side capacity validation
md-dev970 Sep 11, 2026
4e6f32c
docs(benchmark): preserve sanitized capacity evidence
md-dev970 Sep 11, 2026
c496f8e
docs(benchmark): record sanitized image provenance
md-dev970 Sep 11, 2026
8964efb
docs(benchmark): record verified AWS teardown
md-dev970 Sep 11, 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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@ temp/
UI.html


response.json
response.json

# Local commit orchestration helpers
/commit-benchmark-changes.sh
2 changes: 2 additions & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"jobs": "tsx src/jobs/worker.ts",
"migrate": "tsx src/db/migrate.ts",
"seed:demo": "node src/scripts/seed-demo.js",
"seed:benchmark": "tsx src/scripts/seed-benchmark.ts",
"backfill:cost-rollups": "tsx src/scripts/backfill-cost-rollups.ts",
"build": "tsc -p tsconfig.json && node scripts/copy-build-assets.mjs",
"build:lambda": "npm run build && node scripts/build-lambda-package.mjs",
"start": "node dist/server.js",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- The benchmark summary and reporting queries filter by workspace and date
-- without always filtering by AWS account. The original unique index orders
-- aws_account_id before usage_date, so it cannot efficiently serve that path.
CREATE INDEX IF NOT EXISTS idx_cost_snapshots_workspace_date
ON cost_snapshots (workspace_id, usage_date)
INCLUDE (amount, currency);

ANALYZE cost_snapshots;
12 changes: 12 additions & 0 deletions apps/api/src/db/migrations/004_cover_cost_reporting_queries.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- The by-service report needs service_name in addition to the values covered
-- by the workspace/date index. Including it allows all three cost-reporting
-- queries to avoid fetching the matching rows from the heap.
CREATE INDEX IF NOT EXISTS idx_cost_snapshots_workspace_date_reporting
ON cost_snapshots (workspace_id, usage_date)
INCLUDE (service_name, amount, currency);

-- The reporting index is a strict covering replacement for the narrower index
-- introduced by migration 003.
DROP INDEX IF EXISTS idx_cost_snapshots_workspace_date;

ANALYZE cost_snapshots;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE TABLE IF NOT EXISTS workspace_cost_daily_rollups (
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
usage_date DATE NOT NULL,
service_name VARCHAR(255) NOT NULL,
total_amount DECIMAL(18, 6) NOT NULL,
currency VARCHAR(10) NOT NULL DEFAULT 'USD',
updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
PRIMARY KEY (workspace_id, usage_date, service_name)
);

CREATE INDEX IF NOT EXISTS idx_workspace_cost_daily_rollups_workspace_service_date
ON workspace_cost_daily_rollups (workspace_id, service_name, usage_date)
INCLUDE (total_amount, currency);
171 changes: 127 additions & 44 deletions apps/api/src/repositories/cost.repository.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { PoolClient } from "pg";

import { pool } from "../config/db.js";
import type {
CostQueryInput,
Expand All @@ -8,6 +10,31 @@ import type {
TimeseriesCostPoint,
} from "../types/aws-account.types.js";

const rebuildWorkspaceRollups = async (
client: PoolClient,
workspaceId: string,
from: string,
to: string,
): Promise<void> => {
await client.query(
`DELETE FROM workspace_cost_daily_rollups
WHERE workspace_id = $1
AND usage_date BETWEEN $2 AND $3`,
[workspaceId, from, to],
);
await client.query(
`INSERT INTO workspace_cost_daily_rollups (
workspace_id, usage_date, service_name, total_amount, currency, updated_at
)
SELECT workspace_id, usage_date, service_name, SUM(amount), MAX(currency), NOW()
FROM cost_snapshots
WHERE workspace_id = $1
AND usage_date BETWEEN $2 AND $3
GROUP BY workspace_id, usage_date, service_name`,
[workspaceId, from, to],
);
};

export const costRepository = {
async createSyncRun(awsAccountId: string): Promise<string> {
const result = await pool.query(
Expand Down Expand Up @@ -45,42 +72,78 @@ export const costRepository = {
async replaceSnapshots(input: {
workspaceId: string;
awsAccountId: string;
from: string;
to: string;
entries: Array<{
usageDate: string;
serviceName: string;
amount: number;
currency: string;
}>;
}): Promise<number> {
for (const entry of input.entries) {
await pool.query(
`INSERT INTO cost_snapshots (workspace_id, aws_account_id, usage_date, service_name, amount, currency)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (workspace_id, aws_account_id, usage_date, service_name)
DO UPDATE SET amount = EXCLUDED.amount, currency = EXCLUDED.currency`,
[
input.workspaceId,
input.awsAccountId,
entry.usageDate,
entry.serviceName,
entry.amount,
entry.currency,
],
const client = await pool.connect();

try {
await client.query("BEGIN");
// Account syncs are independently locked, so serialize mutations and
// rollup refreshes for the same workspace.
await client.query(
"SELECT pg_advisory_xact_lock(hashtext('cost-rollup:' || $1::text))",
[input.workspaceId],
);
}
await client.query(
`DELETE FROM cost_snapshots
WHERE workspace_id = $1
AND aws_account_id = $2
AND usage_date BETWEEN $3 AND $4`,
[input.workspaceId, input.awsAccountId, input.from, input.to],
);

for (const entry of input.entries) {
await client.query(
`INSERT INTO cost_snapshots (workspace_id, aws_account_id, usage_date, service_name, amount, currency)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (workspace_id, aws_account_id, usage_date, service_name)
DO UPDATE SET amount = EXCLUDED.amount, currency = EXCLUDED.currency`,
[
input.workspaceId,
input.awsAccountId,
entry.usageDate,
entry.serviceName,
entry.amount,
entry.currency,
],
);
}

return input.entries.length;
await rebuildWorkspaceRollups(client, input.workspaceId, input.from, input.to);
await client.query("COMMIT");
return input.entries.length;
} catch (error) {
await client.query("ROLLBACK");
throw error;
} finally {
client.release();
}
},

async getSummary(workspaceId: string, input: CostQueryInput): Promise<CostSummary> {
const result = await pool.query(
`SELECT COALESCE(SUM(amount), 0) AS total_amount, COALESCE(MAX(currency), 'USD') AS currency
FROM cost_snapshots
WHERE workspace_id = $1
AND usage_date BETWEEN $2 AND $3
AND ($4::uuid IS NULL OR aws_account_id = $4::uuid)`,
[workspaceId, input.from, input.to, input.awsAccountId ?? null],
);
const result = input.awsAccountId
? await pool.query(
`SELECT COALESCE(SUM(amount), 0) AS total_amount, COALESCE(MAX(currency), 'USD') AS currency
FROM cost_snapshots
WHERE workspace_id = $1
AND usage_date BETWEEN $2 AND $3
AND aws_account_id = $4::uuid`,
[workspaceId, input.from, input.to, input.awsAccountId],
)
: await pool.query(
`SELECT COALESCE(SUM(total_amount), 0) AS total_amount, COALESCE(MAX(currency), 'USD') AS currency
FROM workspace_cost_daily_rollups
WHERE workspace_id = $1
AND usage_date BETWEEN $2 AND $3`,
[workspaceId, input.from, input.to],
);

return {
totalAmount: Number(result.rows[0]?.total_amount ?? 0),
Expand All @@ -94,16 +157,26 @@ export const costRepository = {
workspaceId: string,
input: CostQueryInput,
): Promise<ServiceCostBreakdownItem[]> {
const result = await pool.query(
`SELECT service_name, SUM(amount) AS total_amount, COALESCE(MAX(currency), 'USD') AS currency
FROM cost_snapshots
WHERE workspace_id = $1
AND usage_date BETWEEN $2 AND $3
AND ($4::uuid IS NULL OR aws_account_id = $4::uuid)
GROUP BY service_name
ORDER BY total_amount DESC`,
[workspaceId, input.from, input.to, input.awsAccountId ?? null],
);
const result = input.awsAccountId
? await pool.query(
`SELECT service_name, SUM(amount) AS total_amount, COALESCE(MAX(currency), 'USD') AS currency
FROM cost_snapshots
WHERE workspace_id = $1
AND usage_date BETWEEN $2 AND $3
AND aws_account_id = $4::uuid
GROUP BY service_name
ORDER BY total_amount DESC`,
[workspaceId, input.from, input.to, input.awsAccountId],
)
: await pool.query(
`SELECT service_name, SUM(total_amount) AS total_amount, COALESCE(MAX(currency), 'USD') AS currency
FROM workspace_cost_daily_rollups
WHERE workspace_id = $1
AND usage_date BETWEEN $2 AND $3
GROUP BY service_name
ORDER BY total_amount DESC`,
[workspaceId, input.from, input.to],
);

return result.rows.map((row) => ({
serviceName: String(row.service_name),
Expand All @@ -116,16 +189,26 @@ export const costRepository = {
workspaceId: string,
input: CostQueryInput,
): Promise<TimeseriesCostPoint[]> {
const result = await pool.query(
`SELECT usage_date, SUM(amount) AS total_amount, COALESCE(MAX(currency), 'USD') AS currency
FROM cost_snapshots
WHERE workspace_id = $1
AND usage_date BETWEEN $2 AND $3
AND ($4::uuid IS NULL OR aws_account_id = $4::uuid)
GROUP BY usage_date
ORDER BY usage_date ASC`,
[workspaceId, input.from, input.to, input.awsAccountId ?? null],
);
const result = input.awsAccountId
? await pool.query(
`SELECT usage_date, SUM(amount) AS total_amount, COALESCE(MAX(currency), 'USD') AS currency
FROM cost_snapshots
WHERE workspace_id = $1
AND usage_date BETWEEN $2 AND $3
AND aws_account_id = $4::uuid
GROUP BY usage_date
ORDER BY usage_date ASC`,
[workspaceId, input.from, input.to, input.awsAccountId],
)
: await pool.query(
`SELECT usage_date, SUM(total_amount) AS total_amount, COALESCE(MAX(currency), 'USD') AS currency
FROM workspace_cost_daily_rollups
WHERE workspace_id = $1
AND usage_date BETWEEN $2 AND $3
GROUP BY usage_date
ORDER BY usage_date ASC`,
[workspaceId, input.from, input.to],
);

return result.rows.map((row) => ({
usageDate: String(row.usage_date).slice(0, 10),
Expand Down
56 changes: 56 additions & 0 deletions apps/api/src/scripts/backfill-cost-rollups.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
if (process.env.ALLOW_COST_ROLLUP_BACKFILL !== "true") {
throw new Error("Refusing to backfill cost rollups without ALLOW_COST_ROLLUP_BACKFILL=true");
}

const { pool } = await import("../config/db.js");

const run = async (): Promise<void> => {
const client = await pool.connect();

try {
await client.query("BEGIN");
await client.query(
"SELECT pg_advisory_xact_lock(hashtext('cost-rollup-backfill'))",
);
await client.query("LOCK TABLE cost_snapshots IN SHARE MODE");
await client.query("LOCK TABLE workspace_cost_daily_rollups IN EXCLUSIVE MODE");
await client.query("DELETE FROM workspace_cost_daily_rollups");
const result = await client.query<{ count: string }>(
`WITH inserted AS (
INSERT INTO workspace_cost_daily_rollups (
workspace_id, usage_date, service_name, total_amount, currency, updated_at
)
SELECT workspace_id, usage_date, service_name, SUM(amount), MAX(currency), NOW()
FROM cost_snapshots
GROUP BY workspace_id, usage_date, service_name
RETURNING 1
)
SELECT COUNT(*)::text AS count FROM inserted`,
);
await client.query("ANALYZE workspace_cost_daily_rollups");
await client.query("COMMIT");

console.log(
JSON.stringify({
costRollupBackfill: true,
rows: Number(result.rows[0]?.count ?? 0),
}),
);
} catch (error) {
await client.query("ROLLBACK");
throw error;
} finally {
client.release();
await pool.end();
}
};

run().catch((error: unknown) => {
console.error(
JSON.stringify({
message: "Cost rollup backfill failed",
error: error instanceof Error ? error.message : "Unknown error",
}),
);
process.exitCode = 1;
});
Loading
Loading