- ClickHouse migrations in the
packages/shared/clickhouse/migrations/clustereddirectory should includeON CLUSTER defaultand should useReplicatedmerge tree table types.- E.g.
ReplacingMergeTreeis likely an error whileReplicatedReplacingMergeTreewould be correct in most cases.
- E.g.
- ClickHouse migrations in the
packages/shared/clickhouse/migrations/unclustereddirectory must not includeON CLUSTERstatements and must not useReplicatedmerge tree table types. - Migrations in
packages/shared/clickhouse/migrations/clusteredshould match their counterparts inpackages/shared/clickhouse/migrations/unclusteredaside from the restrictions listed above. - When adding new indexes on ClickHouse, ensure that there is a corresponding
MATERIALIZE INDEXstatement in the same migration. The materialization can useSETTINGS mutations_sync = 2if they operate on smaller tables, but may timeout otherwise. - All ClickHouse queries on project-scoped tables (traces, observations, scores, events, sessions, etc.) must include
WHERE project_id = {projectId: String}filter to ensure proper tenant isolation and that queries only access data from the intended project. - For operations on the
eventstable, you must never use theFINALkeyword as it kills performance.eventsis built so thatFINALis never required.
- Most
schema.prismachanges should produce a change inpackages/shared/prisma/migrations. - All Prisma queries on project-scoped tables must include
projectIdin the WHERE clause (e.g.,where: { id: traceId, projectId }) to ensure proper tenant isolation and that queries only access data from the intended project.
- Environment variables should be imported from the
env.mjs/tsfile of the respective package and not fromprocess.env.*to ensure validation and typing.
- Highlight usage of
redis.callinvocations. Those may have suboptimal redis cluster routing and will raise errors. Instead, use the native call patterns. Example:await redis?.call("SET", key, "1", "NX", "EX", TTLSeconds);should useawait redis?.set(key, "1", "EX", TTLSeconds, "NX");instead.
- When attempting to confirm if the current environment is Langfuse Cloud in the frontend, use the
useLangfuseCloudRegionhook and never environment variables directly.
- Use
top-banner-offsetinstead oftop-0for any elements that are positionedsticky,fixed, orabsolutewith a global reference point (e.g.,top-0). This ensures proper spacing when system banners (payment, maintenance, etc.) are displayed. - The banner height is managed through CSS variables (
--banner-heightand--banner-offset) defined inweb/src/styles/globals.css. - Banner components (like PaymentBanner) dynamically update
--banner-heightusing ResizeObserver to track their actual height, ensuring accurate positioning even when banners resize (e.g., on mobile wrapping). - Available Tailwind utilities:
top-banner-offset/pt-banner-offset- For sticky/fixed/absolute positioning and paddingh-screen-with-banner/min-h-screen-with-banner- For full-height containers accounting for banners
- use concat instead of spread to avoid stack overflow with large arrays
- make sure that for new features with data model changes, the database seeder is adjusted.
- Whenever a file in
web/src/features/public-api/typeschanges, thefern/apisdefinition probably needs to be adjusted, too. nullishtypes should map tooptional<nullable<T>>in fern.nullabletypes should map tonullable<T>in fern.optionaltypes should map tooptional<T>in fern.