mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-04 21:04:37 +08:00
Merge branch 'clickhouse-sync-session-replays' into clickhouse-sync-project-api-keys
This commit is contained in:
commit
52f2f28bbf
@ -358,14 +358,19 @@ CREATE TABLE IF NOT EXISTS analytics_internal.email_outboxes (
|
||||
created_with LowCardinality(String),
|
||||
email_draft_id Nullable(String),
|
||||
email_programmatic_call_template_id Nullable(String),
|
||||
theme_id Nullable(String),
|
||||
is_high_priority UInt8,
|
||||
rendered_is_transactional Nullable(UInt8),
|
||||
rendered_subject Nullable(String),
|
||||
rendered_notification_category_id Nullable(String),
|
||||
started_rendering_at Nullable(DateTime64(3, 'UTC')),
|
||||
finished_rendering_at Nullable(DateTime64(3, 'UTC')),
|
||||
render_error Nullable(String),
|
||||
scheduled_at DateTime64(3, 'UTC'),
|
||||
created_at DateTime64(3, 'UTC'),
|
||||
started_sending_at Nullable(DateTime64(3, 'UTC')),
|
||||
finished_sending_at Nullable(DateTime64(3, 'UTC')),
|
||||
server_error Nullable(String),
|
||||
sent_at Nullable(DateTime64(3, 'UTC')),
|
||||
delivered_at Nullable(DateTime64(3, 'UTC')),
|
||||
opened_at Nullable(DateTime64(3, 'UTC')),
|
||||
@ -373,8 +378,10 @@ CREATE TABLE IF NOT EXISTS analytics_internal.email_outboxes (
|
||||
unsubscribed_at Nullable(DateTime64(3, 'UTC')),
|
||||
marked_as_spam_at Nullable(DateTime64(3, 'UTC')),
|
||||
bounced_at Nullable(DateTime64(3, 'UTC')),
|
||||
delivery_delayed_at Nullable(DateTime64(3, 'UTC')),
|
||||
can_have_delivery_info Nullable(UInt8),
|
||||
skipped_reason LowCardinality(Nullable(String)),
|
||||
skipped_details Nullable(String),
|
||||
send_retries Int32,
|
||||
is_paused UInt8,
|
||||
sync_sequence_id Int64,
|
||||
@ -399,14 +406,19 @@ SELECT
|
||||
created_with,
|
||||
email_draft_id,
|
||||
email_programmatic_call_template_id,
|
||||
theme_id,
|
||||
is_high_priority,
|
||||
rendered_is_transactional,
|
||||
rendered_subject,
|
||||
rendered_notification_category_id,
|
||||
started_rendering_at,
|
||||
finished_rendering_at,
|
||||
render_error,
|
||||
scheduled_at,
|
||||
created_at,
|
||||
started_sending_at,
|
||||
finished_sending_at,
|
||||
server_error,
|
||||
sent_at,
|
||||
delivered_at,
|
||||
opened_at,
|
||||
@ -414,8 +426,10 @@ SELECT
|
||||
unsubscribed_at,
|
||||
marked_as_spam_at,
|
||||
bounced_at,
|
||||
delivery_delayed_at,
|
||||
can_have_delivery_info,
|
||||
skipped_reason,
|
||||
skipped_details,
|
||||
send_retries,
|
||||
is_paused
|
||||
FROM analytics_internal.email_outboxes
|
||||
|
||||
@ -566,6 +566,7 @@ const CLICKHOUSE_COLUMN_NORMALIZERS: Record<string, Record<string, 'json' | 'boo
|
||||
is_high_priority: 'boolean',
|
||||
rendered_is_transactional: 'nullable_boolean',
|
||||
can_have_delivery_info: 'nullable_boolean',
|
||||
skipped_details: 'json',
|
||||
is_paused: 'boolean',
|
||||
sync_is_deleted: 'boolean',
|
||||
},
|
||||
|
||||
@ -114,6 +114,8 @@ describe("AI Query Endpoint - Validation", () => {
|
||||
});
|
||||
|
||||
it("rejects invalid tool names", async ({ expect }) => {
|
||||
// Deterministic non-AI check: this payload is schema-valid, then rejected by
|
||||
// route-level tool-name validation before any model/provider call.
|
||||
const response = await niceBackendFetch("/api/v1/ai/query/generate", {
|
||||
method: "POST",
|
||||
accessType: "admin",
|
||||
@ -196,23 +198,6 @@ describe("AI Query Endpoint - Validation", () => {
|
||||
expect(response.body).toMatchObject({ code: "SCHEMA_ERROR", error: expect.stringContaining("messages") });
|
||||
});
|
||||
|
||||
it("accepts valid request body with all required fields", async ({ expect }) => {
|
||||
// This will forward to production, so we just verify it doesn't fail validation
|
||||
const response = await niceBackendFetch("/api/v1/ai/query/generate", {
|
||||
method: "POST",
|
||||
accessType: "admin",
|
||||
body: {
|
||||
quality: "dumb",
|
||||
speed: "fast",
|
||||
tools: [],
|
||||
systemPrompt: "command-center-ask-ai",
|
||||
messages: [{ role: "user", content: "test" }],
|
||||
},
|
||||
});
|
||||
|
||||
expect(response.body).not.toMatchObject({ code: "SCHEMA_ERROR" });
|
||||
|
||||
}, 10000); // 60 seconds for AI API call
|
||||
});
|
||||
|
||||
describeWithAi("AI Query Endpoint - Authentication", () => {
|
||||
|
||||
@ -348,7 +348,9 @@ describe("Stack CLI", () => {
|
||||
|
||||
// --- init command tests ---
|
||||
|
||||
it("init create writes stack.config.ts with selected apps", async ({ expect }) => {
|
||||
// TODO: Re-enable these create-mode tests once init mode handling is finalized.
|
||||
// We keep these skipped (instead of todo) so the test logic remains visible and easy to re-enable.
|
||||
it.skip("init create writes stack.config.ts with selected apps", async ({ expect }) => {
|
||||
const initDir = path.join(tmpDir, "init-create");
|
||||
fs.mkdirSync(initDir, { recursive: true });
|
||||
|
||||
@ -367,7 +369,7 @@ describe("Stack CLI", () => {
|
||||
expect(parsed.apps.installed.teams).toEqual({ enabled: true });
|
||||
});
|
||||
|
||||
it("init create with single app", async ({ expect }) => {
|
||||
it.skip("init create with single app", async ({ expect }) => {
|
||||
const initDir = path.join(tmpDir, "init-create-single");
|
||||
fs.mkdirSync(initDir, { recursive: true });
|
||||
|
||||
@ -450,7 +452,7 @@ describe("Stack CLI", () => {
|
||||
expect(stderr).toContain("not found");
|
||||
});
|
||||
|
||||
it("init outputs setup instructions", async ({ expect }) => {
|
||||
it.skip("init outputs setup instructions", async ({ expect }) => {
|
||||
const initDir = path.join(tmpDir, "init-instructions");
|
||||
fs.mkdirSync(initDir, { recursive: true });
|
||||
|
||||
|
||||
@ -844,14 +844,19 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
"created_with" text NOT NULL,
|
||||
"email_draft_id" text,
|
||||
"email_programmatic_call_template_id" text,
|
||||
"theme_id" text,
|
||||
"is_high_priority" boolean NOT NULL DEFAULT false,
|
||||
"rendered_is_transactional" boolean,
|
||||
"rendered_subject" text,
|
||||
"rendered_notification_category_id" text,
|
||||
"started_rendering_at" timestamp without time zone,
|
||||
"finished_rendering_at" timestamp without time zone,
|
||||
"render_error" text,
|
||||
"scheduled_at" timestamp without time zone NOT NULL,
|
||||
"created_at" timestamp without time zone NOT NULL,
|
||||
"started_sending_at" timestamp without time zone,
|
||||
"finished_sending_at" timestamp without time zone,
|
||||
"server_error" text,
|
||||
"sent_at" timestamp without time zone,
|
||||
"delivered_at" timestamp without time zone,
|
||||
"opened_at" timestamp without time zone,
|
||||
@ -859,8 +864,10 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
"unsubscribed_at" timestamp without time zone,
|
||||
"marked_as_spam_at" timestamp without time zone,
|
||||
"bounced_at" timestamp without time zone,
|
||||
"delivery_delayed_at" timestamp without time zone,
|
||||
"can_have_delivery_info" boolean,
|
||||
"skipped_reason" text,
|
||||
"skipped_details" jsonb,
|
||||
"send_retries" integer NOT NULL DEFAULT 0,
|
||||
"is_paused" boolean NOT NULL DEFAULT false
|
||||
);
|
||||
@ -883,14 +890,19 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
created_with LowCardinality(String),
|
||||
email_draft_id Nullable(String),
|
||||
email_programmatic_call_template_id Nullable(String),
|
||||
theme_id Nullable(String),
|
||||
is_high_priority UInt8,
|
||||
rendered_is_transactional Nullable(UInt8),
|
||||
rendered_subject Nullable(String),
|
||||
rendered_notification_category_id Nullable(String),
|
||||
started_rendering_at Nullable(DateTime64(3, 'UTC')),
|
||||
finished_rendering_at Nullable(DateTime64(3, 'UTC')),
|
||||
render_error Nullable(String),
|
||||
scheduled_at DateTime64(3, 'UTC'),
|
||||
created_at DateTime64(3, 'UTC'),
|
||||
started_sending_at Nullable(DateTime64(3, 'UTC')),
|
||||
finished_sending_at Nullable(DateTime64(3, 'UTC')),
|
||||
server_error Nullable(String),
|
||||
sent_at Nullable(DateTime64(3, 'UTC')),
|
||||
delivered_at Nullable(DateTime64(3, 'UTC')),
|
||||
opened_at Nullable(DateTime64(3, 'UTC')),
|
||||
@ -898,8 +910,10 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
unsubscribed_at Nullable(DateTime64(3, 'UTC')),
|
||||
marked_as_spam_at Nullable(DateTime64(3, 'UTC')),
|
||||
bounced_at Nullable(DateTime64(3, 'UTC')),
|
||||
delivery_delayed_at Nullable(DateTime64(3, 'UTC')),
|
||||
can_have_delivery_info Nullable(UInt8),
|
||||
skipped_reason LowCardinality(Nullable(String)),
|
||||
skipped_details Nullable(String),
|
||||
send_retries Int32,
|
||||
is_paused UInt8,
|
||||
sync_sequence_id Int64,
|
||||
@ -922,14 +936,19 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
"EmailOutbox"."createdWith"::text AS "created_with",
|
||||
"EmailOutbox"."emailDraftId" AS "email_draft_id",
|
||||
"EmailOutbox"."emailProgrammaticCallTemplateId" AS "email_programmatic_call_template_id",
|
||||
"EmailOutbox"."themeId" AS "theme_id",
|
||||
"EmailOutbox"."isHighPriority" AS "is_high_priority",
|
||||
"EmailOutbox"."renderedIsTransactional" AS "rendered_is_transactional",
|
||||
"EmailOutbox"."renderedSubject" AS "rendered_subject",
|
||||
"EmailOutbox"."renderedNotificationCategoryId" AS "rendered_notification_category_id",
|
||||
"EmailOutbox"."startedRenderingAt" AS "started_rendering_at",
|
||||
"EmailOutbox"."finishedRenderingAt" AS "finished_rendering_at",
|
||||
"EmailOutbox"."renderErrorExternalMessage" AS "render_error",
|
||||
"EmailOutbox"."scheduledAt" AS "scheduled_at",
|
||||
"EmailOutbox"."createdAt" AS "created_at",
|
||||
"EmailOutbox"."startedSendingAt" AS "started_sending_at",
|
||||
"EmailOutbox"."finishedSendingAt" AS "finished_sending_at",
|
||||
"EmailOutbox"."sendServerErrorExternalMessage" AS "server_error",
|
||||
"EmailOutbox"."sentAt" AS "sent_at",
|
||||
"EmailOutbox"."deliveredAt" AS "delivered_at",
|
||||
"EmailOutbox"."openedAt" AS "opened_at",
|
||||
@ -937,8 +956,10 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
"EmailOutbox"."unsubscribedAt" AS "unsubscribed_at",
|
||||
"EmailOutbox"."markedAsSpamAt" AS "marked_as_spam_at",
|
||||
"EmailOutbox"."bouncedAt" AS "bounced_at",
|
||||
"EmailOutbox"."deliveryDelayedAt" AS "delivery_delayed_at",
|
||||
"EmailOutbox"."canHaveDeliveryInfo" AS "can_have_delivery_info",
|
||||
"EmailOutbox"."skippedReason"::text AS "skipped_reason",
|
||||
"EmailOutbox"."skippedDetails" AS "skipped_details",
|
||||
"EmailOutbox"."sendRetries" AS "send_retries",
|
||||
"EmailOutbox"."isPaused" AS "is_paused",
|
||||
"EmailOutbox"."sequenceId" AS "sync_sequence_id",
|
||||
@ -961,14 +982,19 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
"EmailOutbox"."createdWith"::text AS "created_with",
|
||||
"EmailOutbox"."emailDraftId" AS "email_draft_id",
|
||||
"EmailOutbox"."emailProgrammaticCallTemplateId" AS "email_programmatic_call_template_id",
|
||||
"EmailOutbox"."themeId" AS "theme_id",
|
||||
"EmailOutbox"."isHighPriority" AS "is_high_priority",
|
||||
"EmailOutbox"."renderedIsTransactional" AS "rendered_is_transactional",
|
||||
"EmailOutbox"."renderedSubject" AS "rendered_subject",
|
||||
"EmailOutbox"."renderedNotificationCategoryId" AS "rendered_notification_category_id",
|
||||
"EmailOutbox"."startedRenderingAt" AS "started_rendering_at",
|
||||
"EmailOutbox"."finishedRenderingAt" AS "finished_rendering_at",
|
||||
"EmailOutbox"."renderErrorExternalMessage" AS "render_error",
|
||||
"EmailOutbox"."scheduledAt" AS "scheduled_at",
|
||||
"EmailOutbox"."createdAt" AS "created_at",
|
||||
"EmailOutbox"."startedSendingAt" AS "started_sending_at",
|
||||
"EmailOutbox"."finishedSendingAt" AS "finished_sending_at",
|
||||
"EmailOutbox"."sendServerErrorExternalMessage" AS "server_error",
|
||||
"EmailOutbox"."sentAt" AS "sent_at",
|
||||
"EmailOutbox"."deliveredAt" AS "delivered_at",
|
||||
"EmailOutbox"."openedAt" AS "opened_at",
|
||||
@ -976,8 +1002,10 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
"EmailOutbox"."unsubscribedAt" AS "unsubscribed_at",
|
||||
"EmailOutbox"."markedAsSpamAt" AS "marked_as_spam_at",
|
||||
"EmailOutbox"."bouncedAt" AS "bounced_at",
|
||||
"EmailOutbox"."deliveryDelayedAt" AS "delivery_delayed_at",
|
||||
"EmailOutbox"."canHaveDeliveryInfo" AS "can_have_delivery_info",
|
||||
"EmailOutbox"."skippedReason"::text AS "skipped_reason",
|
||||
"EmailOutbox"."skippedDetails" AS "skipped_details",
|
||||
"EmailOutbox"."sendRetries" AS "send_retries",
|
||||
"EmailOutbox"."isPaused" AS "is_paused",
|
||||
"EmailOutbox"."sequenceId" AS "sequence_id",
|
||||
@ -1000,28 +1028,35 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
$4::text AS "created_with",
|
||||
$5::text AS "email_draft_id",
|
||||
$6::text AS "email_programmatic_call_template_id",
|
||||
$7::boolean AS "is_high_priority",
|
||||
$8::boolean AS "rendered_is_transactional",
|
||||
$9::text AS "rendered_subject",
|
||||
$10::text AS "rendered_notification_category_id",
|
||||
$11::timestamp without time zone AS "scheduled_at",
|
||||
$12::timestamp without time zone AS "created_at",
|
||||
$13::timestamp without time zone AS "started_sending_at",
|
||||
$14::timestamp without time zone AS "finished_sending_at",
|
||||
$15::timestamp without time zone AS "sent_at",
|
||||
$16::timestamp without time zone AS "delivered_at",
|
||||
$17::timestamp without time zone AS "opened_at",
|
||||
$18::timestamp without time zone AS "clicked_at",
|
||||
$19::timestamp without time zone AS "unsubscribed_at",
|
||||
$20::timestamp without time zone AS "marked_as_spam_at",
|
||||
$21::timestamp without time zone AS "bounced_at",
|
||||
$22::boolean AS "can_have_delivery_info",
|
||||
$23::text AS "skipped_reason",
|
||||
$24::integer AS "send_retries",
|
||||
$25::boolean AS "is_paused",
|
||||
$26::bigint AS "sequence_id",
|
||||
$27::boolean AS "is_deleted",
|
||||
$28::text AS "mapping_name"
|
||||
$7::text AS "theme_id",
|
||||
$8::boolean AS "is_high_priority",
|
||||
$9::boolean AS "rendered_is_transactional",
|
||||
$10::text AS "rendered_subject",
|
||||
$11::text AS "rendered_notification_category_id",
|
||||
$12::timestamp without time zone AS "started_rendering_at",
|
||||
$13::timestamp without time zone AS "finished_rendering_at",
|
||||
$14::text AS "render_error",
|
||||
$15::timestamp without time zone AS "scheduled_at",
|
||||
$16::timestamp without time zone AS "created_at",
|
||||
$17::timestamp without time zone AS "started_sending_at",
|
||||
$18::timestamp without time zone AS "finished_sending_at",
|
||||
$19::text AS "server_error",
|
||||
$20::timestamp without time zone AS "sent_at",
|
||||
$21::timestamp without time zone AS "delivered_at",
|
||||
$22::timestamp without time zone AS "opened_at",
|
||||
$23::timestamp without time zone AS "clicked_at",
|
||||
$24::timestamp without time zone AS "unsubscribed_at",
|
||||
$25::timestamp without time zone AS "marked_as_spam_at",
|
||||
$26::timestamp without time zone AS "bounced_at",
|
||||
$27::timestamp without time zone AS "delivery_delayed_at",
|
||||
$28::boolean AS "can_have_delivery_info",
|
||||
$29::text AS "skipped_reason",
|
||||
$30::jsonb AS "skipped_details",
|
||||
$31::integer AS "send_retries",
|
||||
$32::boolean AS "is_paused",
|
||||
$33::bigint AS "sequence_id",
|
||||
$34::boolean AS "is_deleted",
|
||||
$35::text AS "mapping_name"
|
||||
),
|
||||
deleted AS (
|
||||
DELETE FROM "email_outboxes" eo
|
||||
@ -1037,14 +1072,19 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
"created_with",
|
||||
"email_draft_id",
|
||||
"email_programmatic_call_template_id",
|
||||
"theme_id",
|
||||
"is_high_priority",
|
||||
"rendered_is_transactional",
|
||||
"rendered_subject",
|
||||
"rendered_notification_category_id",
|
||||
"started_rendering_at",
|
||||
"finished_rendering_at",
|
||||
"render_error",
|
||||
"scheduled_at",
|
||||
"created_at",
|
||||
"started_sending_at",
|
||||
"finished_sending_at",
|
||||
"server_error",
|
||||
"sent_at",
|
||||
"delivered_at",
|
||||
"opened_at",
|
||||
@ -1052,8 +1092,10 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
"unsubscribed_at",
|
||||
"marked_as_spam_at",
|
||||
"bounced_at",
|
||||
"delivery_delayed_at",
|
||||
"can_have_delivery_info",
|
||||
"skipped_reason",
|
||||
"skipped_details",
|
||||
"send_retries",
|
||||
"is_paused"
|
||||
)
|
||||
@ -1064,14 +1106,19 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
p."created_with",
|
||||
p."email_draft_id",
|
||||
p."email_programmatic_call_template_id",
|
||||
p."theme_id",
|
||||
p."is_high_priority",
|
||||
p."rendered_is_transactional",
|
||||
p."rendered_subject",
|
||||
p."rendered_notification_category_id",
|
||||
p."started_rendering_at",
|
||||
p."finished_rendering_at",
|
||||
p."render_error",
|
||||
p."scheduled_at",
|
||||
p."created_at",
|
||||
p."started_sending_at",
|
||||
p."finished_sending_at",
|
||||
p."server_error",
|
||||
p."sent_at",
|
||||
p."delivered_at",
|
||||
p."opened_at",
|
||||
@ -1079,8 +1126,10 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
p."unsubscribed_at",
|
||||
p."marked_as_spam_at",
|
||||
p."bounced_at",
|
||||
p."delivery_delayed_at",
|
||||
p."can_have_delivery_info",
|
||||
p."skipped_reason",
|
||||
p."skipped_details",
|
||||
p."send_retries",
|
||||
p."is_paused"
|
||||
FROM params p
|
||||
@ -1091,14 +1140,19 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
"created_with" = EXCLUDED."created_with",
|
||||
"email_draft_id" = EXCLUDED."email_draft_id",
|
||||
"email_programmatic_call_template_id" = EXCLUDED."email_programmatic_call_template_id",
|
||||
"theme_id" = EXCLUDED."theme_id",
|
||||
"is_high_priority" = EXCLUDED."is_high_priority",
|
||||
"rendered_is_transactional" = EXCLUDED."rendered_is_transactional",
|
||||
"rendered_subject" = EXCLUDED."rendered_subject",
|
||||
"rendered_notification_category_id" = EXCLUDED."rendered_notification_category_id",
|
||||
"started_rendering_at" = EXCLUDED."started_rendering_at",
|
||||
"finished_rendering_at" = EXCLUDED."finished_rendering_at",
|
||||
"render_error" = EXCLUDED."render_error",
|
||||
"scheduled_at" = EXCLUDED."scheduled_at",
|
||||
"created_at" = EXCLUDED."created_at",
|
||||
"started_sending_at" = EXCLUDED."started_sending_at",
|
||||
"finished_sending_at" = EXCLUDED."finished_sending_at",
|
||||
"server_error" = EXCLUDED."server_error",
|
||||
"sent_at" = EXCLUDED."sent_at",
|
||||
"delivered_at" = EXCLUDED."delivered_at",
|
||||
"opened_at" = EXCLUDED."opened_at",
|
||||
@ -1106,8 +1160,10 @@ export const DEFAULT_DB_SYNC_MAPPINGS = {
|
||||
"unsubscribed_at" = EXCLUDED."unsubscribed_at",
|
||||
"marked_as_spam_at" = EXCLUDED."marked_as_spam_at",
|
||||
"bounced_at" = EXCLUDED."bounced_at",
|
||||
"delivery_delayed_at" = EXCLUDED."delivery_delayed_at",
|
||||
"can_have_delivery_info" = EXCLUDED."can_have_delivery_info",
|
||||
"skipped_reason" = EXCLUDED."skipped_reason",
|
||||
"skipped_details" = EXCLUDED."skipped_details",
|
||||
"send_retries" = EXCLUDED."send_retries",
|
||||
"is_paused" = EXCLUDED."is_paused"
|
||||
RETURNING 1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user