mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-13 21:01:21 +08:00
<img width="567" height="249" alt="Screenshot 2025-10-20 at 11 23 10 AM" src="https://github.com/user-attachments/assets/340df844-f619-489f-8d41-cc26bc165018" /> <img width="595" height="255" alt="Screenshot 2025-10-20 at 11 24 00 AM" src="https://github.com/user-attachments/assets/9321bda1-e6f0-4f53-8c6b-e29d0fc16038" /> <!-- Make sure you've read the CONTRIBUTING.md guidelines: https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md --> <!-- RECURSEML_SUMMARY:START --> ## High-level PR Summary This PR optimizes the performance of user list and metrics endpoints by refactoring SQL queries to use more efficient patterns. The changes include rewriting queries to use `LATERAL` joins and CTEs with proper filtering, extracting common user mapping logic into reusable functions, and adding performance tests with SQL scripts to generate realistic test data (10,000 mock users and activity events across 100 countries). ⏱️ Estimated Review Time: 30-90 minutes <details> <summary>💡 Review Order Suggestion</summary> | Order | File Path | |-------|-----------| | 1 | `apps/e2e/tests/backend/performance/mock-users.sql` | | 2 | `apps/e2e/tests/backend/performance/mock-metric-events.sql` | | 3 | `apps/e2e/tests/backend/performance/users-list.test.ts` | | 4 | `apps/backend/src/app/api/latest/users/crud.tsx` | | 5 | `apps/backend/src/app/api/latest/internal/metrics/route.tsx` | </details> [](https://discord.gg/n3SsVDAW6U) [ <!-- RECURSEML_SUMMARY:END --> <!-- ELLIPSIS_HIDDEN --> ---- > [!IMPORTANT] > Optimize metrics and user list endpoints with SQL refactoring, caching, and performance tests, adding a `CacheEntry` model and mock data scripts. > > - **Performance Optimization**: > - Refactor SQL queries in `route.tsx` to use `LATERAL` joins and CTEs for efficient data retrieval. > - Implement caching in `route.tsx` using `getOrSetCacheValue()` to reduce database load. > - **Database Changes**: > - Add `CacheEntry` model to `schema.prisma` and create corresponding table and index in `migration.sql`. > - Remove auto-migration metadata step from `check-prisma-migrations.yaml`. > - **Testing**: > - Add performance tests in `metrics.test.ts` to benchmark metrics and user endpoints. > - Create mock data scripts `mock-users.sql` and `mock-metric-events.sql` for testing with 10,000 users and events across 100 countries. > - **Miscellaneous**: > - Update `db-migrations.ts` to include new migration file generation logic. > - Add `cache.tsx` for caching logic implementation. > > <sup>This description was created by </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup> for4d9be71063. You can [customize](https://app.ellipsis.dev/stack-auth/settings/summaries) this summary. It will automatically update as commits are pushed.</sup> ---- <!-- ELLIPSIS_HIDDEN --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Metrics now use a cache layer with per-entry TTL and tenancy-aware loaders. * **Bug Fixes** * Improved accuracy of daily active and related metrics with tenancy-aware counting and more robust last-active computation. * **Performance** * Faster metrics responses via batched reads and cache-backed endpoints. * **Tests** * Added end-to-end performance benchmarks and SQL seed scripts for metrics/user load testing. * **Chores** * DB migration added support for cached entries; CI migration check flow adjusted; migration tooling improved. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
82 lines
2.0 KiB
PL/PgSQL
82 lines
2.0 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
|
|
),
|
|
generated AS (
|
|
SELECT
|
|
t.id AS tenancy_id,
|
|
gen_random_uuid() AS project_user_id,
|
|
gen_random_uuid() AS auth_method_id,
|
|
gen_random_uuid() AS contact_id,
|
|
gs AS idx,
|
|
lpad(gs::text, 5, '0') AS padded_idx,
|
|
now() AS ts
|
|
FROM internal_tenancy t
|
|
CROSS JOIN generate_series(10001, 20000) AS gs
|
|
),
|
|
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
|
|
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,
|
|
'perf-user-' || g.padded_idx || '@internal.stack',
|
|
g.ts,
|
|
g.ts
|
|
FROM generated g
|
|
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
|
|
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;
|
|
|
|
COMMIT;
|