Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
bd201c3
feat(project): Added projects
SteakFisher Jun 16, 2026
bfdfe30
fix(datetime): Slight changes
SteakFisher Jun 16, 2026
4cbc1ed
fix(webhooks): potential leak)
SteakFisher Jun 16, 2026
4b9f81e
fix(user): Cache invalidation
SteakFisher Jun 16, 2026
2b54ffb
fix: composite PK for usersTable, token validation, ensureUserExists …
SteakFisher Jun 17, 2026
287a146
fix: add model.min(1), provider default, token count .min(0) in creat…
SteakFisher Jun 17, 2026
3821899
fix: scope row lock, deleteWebhookEndpoint, and remove metadata from …
SteakFisher Jun 17, 2026
c0755c7
fix: resolve all greptile findings — billing, auth, tests, schema, va…
SteakFisher Jun 18, 2026
7b6179f
fix: prevent dashboard self-revoke, remove unsafe cast in query.ts
SteakFisher Jun 19, 2026
91b3696
fix(schema.ts): added project_id to clickhouse db schema
0xanshu Jun 21, 2026
b6410a7
fix(generateInitialAPIKey): now API key gets inserted into the db
0xanshu Jun 23, 2026
d998a50
fix(generateInitialAPIKey): idempotency gaurd added
0xanshu Jun 24, 2026
97cb89e
fix(project): schema fixes
0xanshu Jun 24, 2026
4788da8
feat(createDashboardKey): made a new route to handle creation of dash…
0xanshu Jun 26, 2026
94184ac
fix(resgisterApiRoutes.ts): fixed params
0xanshu Jun 26, 2026
e9348f1
fix(apiKeys.ts): fixed linting errors
0xanshu Jun 26, 2026
06e61d9
fix(apiKeys): fixed greptile issues
0xanshu Jun 27, 2026
1f4553b
fix(queryEvents): fixed greptile issues
0xanshu Jun 27, 2026
e3fee51
fix(db): constrain config keys
0xanshu Jun 27, 2026
1550d8d
feat(projects): added project create, update, delete routes and func
0xanshu Jun 28, 2026
4ca65cb
fix(projects): fixed projects checking
0xanshu Jun 28, 2026
8b2fa2b
fix(project.ts): fixed multiple grep issues
0xanshu Jun 28, 2026
8441040
fix(projcets.ts): handling failure in updating dodo webhooks
0xanshu Jun 28, 2026
3a45993
fix(projcets.ts): now accepting a dashboard-only target apiKeyId
0xanshu Jun 28, 2026
f076f9f
fix(projcets.ts): fixed greptile issues
0xanshu Jun 28, 2026
0f6fae9
fix(projcets.ts): using left join to insert data for projects
0xanshu Jun 29, 2026
a63ee9b
fix(projcets.ts): currency mismatch fixed
0xanshu Jun 29, 2026
609ab4c
fix(projcets.ts): added API key expiry handling to various files
0xanshu Jun 29, 2026
ffef9a8
fix(projcets.ts): several auth issues are fixed
0xanshu Jun 29, 2026
0b62aaf
fix(projects.ts): checking for existing checkout links THEN making th…
0xanshu Jun 29, 2026
6f309e7
fix(projects.ts): clickhouse startup cleanup
0xanshu Jun 29, 2026
aa3ea44
fix(projects): handling partial metadata insertion failure
0xanshu Jun 29, 2026
4951286
fix(projects): fixed multiple greptile issues
0xanshu Jun 29, 2026
3380597
Merge pull request #93 from 0xanshu/0xanshu/project
SteakFisher Jun 30, 2026
5184332
chore: rename SCRAWN_KEY to MASTER_API_KEY, add MASTER_API_KEY_HASH, …
SteakFisher Jul 1, 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 .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ DATABASE_URL=postgres://postgres:postgres@localhost:5432/scrawn
CLICKHOUSE_URL=http://default:clickhouse@localhost:8123/scrawn

HMAC_SECRET=
MASTER_API_KEY_HASH= # hex(HMAC-SHA256(HMAC_SECRET, <raw master key>)) — computed with HMAC_SECRET as the signing key (used for project creation during onboarding)
APP_URL=http://localhost:8060 # URL the Scrawn backend is hosted on

# SENTRY_DSN=
Expand Down
3 changes: 2 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ services:
NODE_ENV: production
HMAC_SECRET: ${HMAC_SECRET}
APP_URL: ${APP_URL}
MASTER_API_KEY_HASH: ${MASTER_API_KEY_HASH}

dashboard:
profiles:
Expand All @@ -77,6 +78,6 @@ services:
BETTER_AUTH_URL: http://localhost:3000
SCRAWN_BASE_URL: http://server:8060
SCRAWN_HTTP_URL: http://server:8060
SCRAWN_KEY: ${SCRAWN_KEY}
MASTER_API_KEY: ${MASTER_API_KEY}


2 changes: 1 addition & 1 deletion proto
Submodule proto updated from d9ceee to e4b723
3 changes: 2 additions & 1 deletion src/__tests__/auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import { getPostgresDB } from "../storage/db/postgres/db";
import { webhookEndpointsTable } from "../storage/db/postgres/schema";
import { DateTime } from "luxon";
import { clearDatabase } from "./db";
import { insertKey } from "./fixtures/apiKey";
import { insertKey, TEST_PROJECT_ID } from "./fixtures/apiKey";

async function insertWebhookEndpoint(apiKeyId: string): Promise<void> {
const db = getPostgresDB();
await db.insert(webhookEndpointsTable).values({
projectId: TEST_PROJECT_ID,
apiKeyId,
url: "https://example.com/webhook",
privateKey: "test-private-key",
Expand Down
4 changes: 3 additions & 1 deletion src/__tests__/createAPIKey.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
registerEvent,
} from "./fixtures/grpc";
import { verifyApiKeyCreated } from "./assertions/events";
import { createTestApiKey } from "./fixtures/apiKey";
import { createTestApiKey, TEST_PROJECT_ID } from "./fixtures/apiKey";
import { getPostgresDB } from "../storage/db/postgres/db";
import { hashAPIKey } from "../utils/hashAPIKey";
import {
Expand Down Expand Up @@ -44,6 +44,7 @@ async function createDashboardApiKey(): Promise<{
key: hashAPIKey(rawKey),
role: "dashboard",
expiresAt: DateTime.utc().plus({ years: 1 }).toISO(),
projectId: TEST_PROJECT_ID,
})
.returning({ id: apiKeysTable.id });
return { rawKey, id: key!.id };
Expand Down Expand Up @@ -149,6 +150,7 @@ describe("AuthService", () => {

const db = getPostgresDB();
await db.insert(webhookEndpointsTable).values({
projectId: TEST_PROJECT_ID,
apiKeyId: res.apiKeyId,
url: "https://example.com/webhook",
privateKey: "test-private-key",
Expand Down
3 changes: 2 additions & 1 deletion src/__tests__/db/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export async function clearDatabase() {
users,
tags,
metadata,
expressions
expressions,
projects
RESTART IDENTITY CASCADE
`);

Expand Down
23 changes: 23 additions & 0 deletions src/__tests__/fixtures/apiKey.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
import { getPostgresDB } from "../../storage/db/postgres/db";
import {
projectsTable,
apiKeysTable,
webhookEndpointsTable,
} from "../../storage/db/postgres/schema";
import { eq } from "drizzle-orm";
import { hashAPIKey } from "../../utils/hashAPIKey";
import { DateTime } from "luxon";

export const TEST_PROJECT_ID = "00000000-0000-0000-0000-000000000001";

async function ensureTestProject(): Promise<void> {
const db = getPostgresDB();
const [existing] = await db
.select({ id: projectsTable.id })
.from(projectsTable)
.where(eq(projectsTable.id, TEST_PROJECT_ID))
.limit(1);
if (existing) return;
await db.insert(projectsTable).values({
id: TEST_PROJECT_ID,
name: "test-project",
});
}

export async function createTestApiKey(): Promise<{
rawKey: string;
id: string;
}> {
const db = getPostgresDB();
await ensureTestProject();
const rawKey = `scrn_test_${crypto.randomUUID().replace(/-/g, "").slice(0, 32)}`;
const [key] = await db
.insert(apiKeysTable)
Expand All @@ -19,10 +38,12 @@ export async function createTestApiKey(): Promise<{
key: hashAPIKey(rawKey),
role: "test",
expiresAt: DateTime.utc().plus({ years: 1 }).toISO(),
projectId: TEST_PROJECT_ID,
})
.returning({ id: apiKeysTable.id });

await db.insert(webhookEndpointsTable).values({
projectId: TEST_PROJECT_ID,
apiKeyId: key!.id,
url: "https://example.com/webhook",
privateKey: "test-private-key",
Expand All @@ -38,6 +59,7 @@ export async function insertKey(
overrides: Partial<{ revoked: boolean; expiresAt: string }> = {}
): Promise<string> {
const db = getPostgresDB();
await ensureTestProject();
const [key] = await db
.insert(apiKeysTable)
.values({
Expand All @@ -47,6 +69,7 @@ export async function insertKey(
expiresAt:
overrides.expiresAt ?? DateTime.utc().plus({ years: 1 }).toISO(),
revoked: overrides.revoked ?? false,
projectId: TEST_PROJECT_ID,
})
.returning({ id: apiKeysTable.id });
return key!.id;
Expand Down
1 change: 1 addition & 0 deletions src/context/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export interface AuthContext {
apiKeyId: string;
role: ApiKeyRole;
mode: "production" | "test" | null;
projectId: string;
}
8 changes: 1 addition & 7 deletions src/gen/auth/v1/auth.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

128 changes: 1 addition & 127 deletions src/gen/data/v1/data.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 1 addition & 7 deletions src/gen/event/v1/event.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 1 addition & 7 deletions src/gen/payment/v1/payment.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading