mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
improvement(tables): make max row size env-configurable and raise default to 400KB (#5338)
This commit is contained in:
@@ -94,6 +94,7 @@ export const env = createEnv({
|
||||
TEAM_TABLE_ROWS_LIMIT: z.number().optional(), // Max rows per table on team tier (default: 500000)
|
||||
ENTERPRISE_TABLES_LIMIT: z.number().optional(), // Max user tables per workspace on enterprise tier (default: 10000)
|
||||
ENTERPRISE_TABLE_ROWS_LIMIT: z.number().optional(), // Max rows per table on enterprise tier (default: 1000000)
|
||||
TABLE_MAX_ROW_SIZE_BYTES: z.number().optional(), // Max serialized size in bytes of a single user-table row (default: 409600)
|
||||
|
||||
// Credit-tier Stripe prices (monthly)
|
||||
STRIPE_PRICE_TIER_25_MO: z.string().min(1).optional(), // Pro: $25/mo (6,000 credits)
|
||||
|
||||
@@ -8,7 +8,7 @@ import { env, envNumber } from '@/lib/core/config/env'
|
||||
export const TABLE_LIMITS = {
|
||||
MAX_TABLES_PER_WORKSPACE: 100,
|
||||
MAX_ROWS_PER_TABLE: 10000,
|
||||
MAX_ROW_SIZE_BYTES: 100 * 1024, // 100KB
|
||||
MAX_ROW_SIZE_BYTES: 400 * 1024, // 400KB
|
||||
MAX_COLUMNS_PER_TABLE: 50,
|
||||
MAX_TABLE_NAME_LENGTH: 128,
|
||||
MAX_COLUMN_NAME_LENGTH: 50,
|
||||
@@ -61,6 +61,18 @@ export const DEFAULT_TABLE_PLAN_LIMITS = {
|
||||
},
|
||||
} as const
|
||||
|
||||
/**
|
||||
* Maximum serialized size in bytes of a single row. Defaults to
|
||||
* `TABLE_LIMITS.MAX_ROW_SIZE_BYTES`; overridable via the
|
||||
* `TABLE_MAX_ROW_SIZE_BYTES` env var (server-only, read at call time).
|
||||
*/
|
||||
export function getMaxRowSizeBytes(): number {
|
||||
return envNumber(env.TABLE_MAX_ROW_SIZE_BYTES, TABLE_LIMITS.MAX_ROW_SIZE_BYTES, {
|
||||
min: 1,
|
||||
integer: true,
|
||||
})
|
||||
}
|
||||
|
||||
export type PlanName = keyof typeof DEFAULT_TABLE_PLAN_LIMITS
|
||||
|
||||
export interface TablePlanLimits {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { userTableRows } from '@sim/db/schema'
|
||||
import { and, eq, or, type SQL, sql } from 'drizzle-orm'
|
||||
import { NextResponse } from 'next/server'
|
||||
import { getColumnId } from '@/lib/table/column-keys'
|
||||
import { COLUMN_TYPES, NAME_PATTERN, TABLE_LIMITS } from '@/lib/table/constants'
|
||||
import { COLUMN_TYPES, getMaxRowSizeBytes, NAME_PATTERN, TABLE_LIMITS } from '@/lib/table/constants'
|
||||
import { withSeqscanOff } from '@/lib/table/planner'
|
||||
import type {
|
||||
ColumnDefinition,
|
||||
@@ -356,11 +356,12 @@ export function coerceRowToSchema(data: RowData, schema: TableSchema): Validatio
|
||||
|
||||
/** Validates row data size is within limits. */
|
||||
export function validateRowSize(data: RowData): ValidationResult {
|
||||
const maxRowSizeBytes = getMaxRowSizeBytes()
|
||||
const size = JSON.stringify(data).length
|
||||
if (size > TABLE_LIMITS.MAX_ROW_SIZE_BYTES) {
|
||||
if (size > maxRowSizeBytes) {
|
||||
return {
|
||||
valid: false,
|
||||
errors: [`Row size exceeds limit (${size} bytes > ${TABLE_LIMITS.MAX_ROW_SIZE_BYTES} bytes)`],
|
||||
errors: [`Row size exceeds limit (${size} bytes > ${maxRowSizeBytes} bytes)`],
|
||||
}
|
||||
}
|
||||
return { valid: true, errors: [] }
|
||||
|
||||
Reference in New Issue
Block a user