stack/apps/e2e/tests/backend/performance/mock-users.sql
BilalG1 d09a180dfe
Some checks failed
all-good: Did all the other checks pass? / all-good (push) Has been cancelled
Ensure Prisma migrations are in sync with the schema / check_prisma_migrations (22.x) (push) Has been cancelled
DB migrations are backwards-compatible / Check if migrations changed (push) Has been cancelled
Docker Server Build and Push / Docker Build and Push Server (push) Has been cancelled
Docker Server Build and Run / docker (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (mock, 22.x) (push) Has been cancelled
Runs E2E API Tests / E2E Tests (Node ${{ matrix.node-version }}, Freestyle ${{ matrix.freestyle-mode }}) (prod, 22.x) (push) Has been cancelled
Runs E2E API Tests with custom port prefix / build (22.x) (push) Has been cancelled
Lint & build / lint_and_build (latest) (push) Has been cancelled
Dev Environment Test With Custom Base Port / restart-dev-and-test-with-custom-base-port (push) Has been cancelled
Dev Environment Test / restart-dev-and-test (push) Has been cancelled
Run setup tests with custom base port / setup-tests-with-custom-base-port (push) Has been cancelled
Run setup tests / setup-tests (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
DB migrations are backwards-compatible / Test migrations with ${{ needs.check-migrations-changed.outputs.base_branch }} branch code (push) Has been cancelled
DB migrations are backwards-compatible / No migration changes (skipped) (push) Has been cancelled
clickhouse user sync (#1159)
<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Real-time AI search with project-scoped analytics and dynamic query
execution; streaming AI responses replace the placeholder flow.
* External DB sync adds ClickHouse support: users sync, sync metadata
tracking, tenancy-aware status, and per-mapping throttling.
* AI assistant UI shows expandable tool-invocation results and streams
via the real AI pipeline.

* **Chores**
* Dashboard dependencies and workspace exclusions updated; development
OpenAI env var added; editor config flag toggled.

* **Tests**
* E2E coverage extended to validate ClickHouse user sync and analytics
queries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: aadesh18 <110230993+aadesh18@users.noreply.github.com>
Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
2026-02-12 16:52:20 -08:00

144 lines
4.5 KiB
PL/PgSQL

BEGIN;
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
WITH internal_tenancy AS (
SELECT id
FROM "Tenancy"
WHERE "projectId" = 'internal'
AND "branchId" = 'main'
LIMIT 1
),
params AS (
-- How many users to insert per run.
-- Edit the numeric literal below before running the script.
SELECT 50000::bigint AS batch_size
),
existing_max AS (
SELECT
COALESCE(
MAX((regexp_match(cc."value", '^perf-user-([0-9]+)@internal\.stack$'))[1]::bigint),
0
) AS max_idx
FROM internal_tenancy t
LEFT JOIN "ContactChannel" cc
ON cc."tenancyId" = t.id
AND cc."type" = 'EMAIL'
AND cc."usedForAuth" = 'TRUE'::"BooleanTrue"
AND cc."value" ~ '^perf-user-[0-9]+@internal\.stack$'
),
next_range AS (
SELECT
GREATEST(1, max_idx + 1) AS start_idx,
GREATEST(1, max_idx + 1) + p.batch_size - 1 AS end_idx
FROM existing_max
CROSS JOIN params p
),
generated AS (
SELECT
gs AS idx,
t.id AS tenancy_id,
('perf-user-' || gs::text || '@internal.stack') AS email_value,
(
substr(md5(t.id::text || ':project_user:' || gs::text), 1, 8) || '-' ||
substr(md5(t.id::text || ':project_user:' || gs::text), 9, 4) || '-' ||
substr(md5(t.id::text || ':project_user:' || gs::text), 13, 4) || '-' ||
substr(md5(t.id::text || ':project_user:' || gs::text), 17, 4) || '-' ||
substr(md5(t.id::text || ':project_user:' || gs::text), 21, 12)
)::uuid AS project_user_id,
(
substr(md5(t.id::text || ':auth_method:' || gs::text), 1, 8) || '-' ||
substr(md5(t.id::text || ':auth_method:' || gs::text), 9, 4) || '-' ||
substr(md5(t.id::text || ':auth_method:' || gs::text), 13, 4) || '-' ||
substr(md5(t.id::text || ':auth_method:' || gs::text), 17, 4) || '-' ||
substr(md5(t.id::text || ':auth_method:' || gs::text), 21, 12)
)::uuid AS auth_method_id,
(
substr(md5(t.id::text || ':contact:' || gs::text), 1, 8) || '-' ||
substr(md5(t.id::text || ':contact:' || gs::text), 9, 4) || '-' ||
substr(md5(t.id::text || ':contact:' || gs::text), 13, 4) || '-' ||
substr(md5(t.id::text || ':contact:' || gs::text), 17, 4) || '-' ||
substr(md5(t.id::text || ':contact:' || gs::text), 21, 12)
)::uuid AS contact_id,
now() AS ts
FROM internal_tenancy t
CROSS JOIN next_range r
CROSS JOIN generate_series(r.start_idx, r.end_idx) AS gs
-- Ensure re-running this script can't error due to the unique constraint on
-- (tenancyId, type, value, usedForAuth). If a perf-user email already exists
-- and is used for auth, skip generating that row entirely.
WHERE NOT EXISTS (
SELECT 1
FROM "ContactChannel" cc
WHERE cc."tenancyId" = t.id
AND cc."type" = 'EMAIL'
AND cc."value" = ('perf-user-' || gs::text || '@internal.stack')
AND cc."usedForAuth" = 'TRUE'::"BooleanTrue"
)
),
insert_users AS (
INSERT INTO "ProjectUser"
("tenancyId","projectUserId","mirroredProjectId","mirroredBranchId","displayName",
"projectId","createdAt","updatedAt")
SELECT
tenancy_id,
project_user_id,
'internal',
'main',
'Perf Test User ' || idx,
'internal',
ts,
ts
FROM generated
ON CONFLICT ("tenancyId", "projectUserId") DO NOTHING
RETURNING "tenancyId","projectUserId"
),
insert_contacts AS (
INSERT INTO "ContactChannel"
("tenancyId","projectUserId","id","type","isPrimary","usedForAuth",
"isVerified","value","createdAt","updatedAt")
SELECT
g.tenancy_id,
g.project_user_id,
g.contact_id,
'EMAIL',
'TRUE'::"BooleanTrue",
'TRUE'::"BooleanTrue",
false,
g.email_value,
g.ts,
g.ts
FROM generated g
ON CONFLICT DO NOTHING
RETURNING "tenancyId","projectUserId"
),
insert_auth_methods AS (
INSERT INTO "AuthMethod"
("tenancyId","id","projectUserId","createdAt","updatedAt")
SELECT
tenancy_id,
auth_method_id,
project_user_id,
ts,
ts
FROM generated
ON CONFLICT ("tenancyId", "id") DO NOTHING
RETURNING "tenancyId","id","projectUserId"
)
INSERT INTO "PasswordAuthMethod"
("tenancyId","authMethodId","projectUserId","passwordHash","createdAt","updatedAt")
SELECT
g.tenancy_id,
g.auth_method_id,
g.project_user_id,
'$2a$13$TVyY/gpw9Db/w1fBeJkCgeNg2Rae2JfNqrPnSACtj.ufAO5cVF13.', -- swap in your own bcrypt hash if desired
g.ts,
g.ts
FROM generated g
-- A user can only have one password auth method.
-- If this was already inserted by a previous run, skip it.
ON CONFLICT DO NOTHING;
COMMIT;