Skip to content
Merged
8 changes: 4 additions & 4 deletions apps/sim/app/api/organizations/[id]/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { db } from '@sim/db'
import { member, organization } from '@sim/db/schema'
import { member, organization, organizationColumns } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { isOrgAdminRole } from '@sim/platform-authz/workspace'
import { and, eq, ne } from 'drizzle-orm'
Expand Down Expand Up @@ -64,7 +64,7 @@ export const GET = withRouteHandler(
}

const organizationEntry = await db
.select()
.select(organizationColumns)
.from(organization)
.where(eq(organization.id, organizationId))
.limit(1)
Expand Down Expand Up @@ -156,7 +156,7 @@ export const PUT = withRouteHandler(
if (name !== undefined || slug !== undefined || logo !== undefined) {
if (slug !== undefined) {
const existingSlug = await db
.select()
.select(organizationColumns)
.from(organization)
.where(and(eq(organization.slug, slug), ne(organization.id, organizationId)))
.limit(1)
Expand All @@ -180,7 +180,7 @@ export const PUT = withRouteHandler(
.update(organization)
.set(updateData)
.where(eq(organization.id, organizationId))
.returning()
.returning(organizationColumns)

if (updatedOrg.length === 0) {
return NextResponse.json({ error: 'Organization not found' }, { status: 404 })
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/v1/admin/organizations/[id]/billing/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/

import { db, dbReplica } from '@sim/db'
import { member, organization } from '@sim/db/schema'
import { member, organization, organizationColumns } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { count, eq } from 'drizzle-orm'
import {
Expand Down Expand Up @@ -155,7 +155,7 @@ export const PATCH = withRouteHandler(
if (!parsed.success) return parsed.response

const [orgData] = await db
.select()
.select(organizationColumns)
.from(organization)
.where(eq(organization.id, organizationId))
.limit(1)
Expand Down
8 changes: 4 additions & 4 deletions apps/sim/app/api/v1/admin/organizations/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {
recordAuditBatch,
} from '@sim/audit'
import { db } from '@sim/db'
import { member, organization, subscription } from '@sim/db/schema'
import { member, organization, organizationColumns, subscription } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { and, count, eq, inArray, isNull, not, or } from 'drizzle-orm'
import {
Expand Down Expand Up @@ -92,7 +92,7 @@ export const GET = withRouteHandler(

try {
const [orgData] = await db
.select()
.select(organizationColumns)
.from(organization)
.where(eq(organization.id, organizationId))
.limit(1)
Expand Down Expand Up @@ -143,7 +143,7 @@ export const PATCH = withRouteHandler(

try {
const [existing] = await db
.select()
.select(organizationColumns)
.from(organization)
.where(eq(organization.id, organizationId))
.limit(1)
Expand Down Expand Up @@ -182,7 +182,7 @@ export const PATCH = withRouteHandler(
.update(organization)
.set(updateData)
.where(eq(organization.id, organizationId))
.returning()
.returning(organizationColumns)

const updatedFields = auditUpdatedFields(updateData)
logger.info(`Admin API: Updated organization ${organizationId}`, { updatedFields })
Expand Down
5 changes: 2 additions & 3 deletions apps/sim/app/api/v1/admin/organizations/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import { AuditAction, AuditResourceType, recordAudit } from '@sim/audit'
import { db, dbReplica } from '@sim/db'
import { member, organization, user } from '@sim/db/schema'
import { member, organization, organizationColumns, user } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { slugify } from '@sim/utils/string'
import { count, eq } from 'drizzle-orm'
Expand Down Expand Up @@ -81,7 +81,6 @@ export const GET = withRouteHandler(
logo: organization.logo,
orgUsageLimit: organization.orgUsageLimit,
storageUsedBytes: organization.storageUsedBytes,
departedMemberUsage: organization.departedMemberUsage,
createdAt: organization.createdAt,
updatedAt: organization.updatedAt,
})
Expand Down Expand Up @@ -152,7 +151,7 @@ export const POST = withRouteHandler(
})

const [createdOrg] = await db
.select()
.select(organizationColumns)
.from(organization)
.where(eq(organization.id, organizationId))
.limit(1)
Expand Down
15 changes: 2 additions & 13 deletions apps/sim/app/api/v1/admin/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,6 @@ export interface AdminOrganization {
logo: string | null
orgUsageLimit: string | null
storageUsedBytes: number
departedMemberUsage: string
createdAt: string
updatedAt: string
}
Expand All @@ -370,15 +369,7 @@ export interface AdminOrganizationDetail extends AdminOrganization {

export type AdminOrganizationSource = Pick<
DbOrganization,
| 'id'
| 'name'
| 'slug'
| 'logo'
| 'orgUsageLimit'
| 'storageUsedBytes'
| 'departedMemberUsage'
| 'createdAt'
| 'updatedAt'
'id' | 'name' | 'slug' | 'logo' | 'orgUsageLimit' | 'storageUsedBytes' | 'createdAt' | 'updatedAt'
>

export function toAdminOrganization(dbOrg: AdminOrganizationSource): AdminOrganization {
Expand All @@ -389,7 +380,6 @@ export function toAdminOrganization(dbOrg: AdminOrganizationSource): AdminOrgani
logo: dbOrg.logo,
orgUsageLimit: dbOrg.orgUsageLimit,
storageUsedBytes: dbOrg.storageUsedBytes,
departedMemberUsage: dbOrg.departedMemberUsage,
createdAt: dbOrg.createdAt.toISOString(),
updatedAt: dbOrg.updatedAt.toISOString(),
}
Expand Down Expand Up @@ -480,8 +470,7 @@ interface AdminUserBilling {
billedOverageThisPeriod: string
storageUsedBytes: number
billingBlocked: boolean
// Copilot usage (active per-period baselines)
currentPeriodCopilotCost: string
// Copilot usage
lastPeriodCopilotCost: string | null
}

Expand Down
18 changes: 14 additions & 4 deletions apps/sim/app/api/v1/admin/users/[id]/billing/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@
*/

import { db } from '@sim/db'
import { member, organization, subscription, user, userStats } from '@sim/db/schema'
import {
member,
organization,
subscription,
user,
userStats,
userStatsColumns,
} from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { generateShortId } from '@sim/utils/id'
import { eq, or } from 'drizzle-orm'
Expand Down Expand Up @@ -78,7 +85,11 @@ export const GET = withRouteHandler(
return notFoundResponse('User')
}

const [stats] = await db.select().from(userStats).where(eq(userStats.userId, userId)).limit(1)
const [stats] = await db
.select(userStatsColumns)
.from(userStats)
.where(eq(userStats.userId, userId))
.limit(1)

// Canonical current-period usage (attributed usage_log, refresh-adjusted)
// comes from the same helper users see.
Expand Down Expand Up @@ -119,7 +130,6 @@ export const GET = withRouteHandler(
billedOverageThisPeriod: stats?.billedOverageThisPeriod ?? '0',
storageUsedBytes: stats?.storageUsedBytes ?? 0,
billingBlocked: stats?.billingBlocked ?? false,
currentPeriodCopilotCost: stats?.currentPeriodCopilotCost ?? '0',
lastPeriodCopilotCost: stats?.lastPeriodCopilotCost ?? null,
subscriptions: subscriptions.map(toAdminSubscription),
organizationMemberships: memberOrgs.map((m) => ({
Expand Down Expand Up @@ -169,7 +179,7 @@ export const PATCH = withRouteHandler(
}

const [existingStats] = await db
.select()
.select(userStatsColumns)
.from(userStats)
.where(eq(userStats.userId, userId))
.limit(1)
Expand Down
11 changes: 8 additions & 3 deletions apps/sim/lib/admin/dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { db } from '@sim/db'
import {
member,
organization,
organizationColumns,
organizationMemberUsageLimit,
outboxEvent,
permissions,
Expand Down Expand Up @@ -651,7 +652,11 @@ export async function listDashboardUsers({ search, limit, offset }: PaginationIn
async function getDashboardOrganizationSummary(organizationId: string) {
const [[org], [memberCountRow], [externalCountRow], latestSubscription, provisionings] =
await Promise.all([
db.select().from(organization).where(eq(organization.id, organizationId)).limit(1),
db
.select(organizationColumns)
.from(organization)
.where(eq(organization.id, organizationId))
.limit(1),
db.select({ value: count() }).from(member).where(eq(member.organizationId, organizationId)),
db
.select({ value: countDistinct(permissions.userId) })
Expand Down Expand Up @@ -1277,7 +1282,7 @@ export async function updateDashboardOrganizationLimits(
const providerBacked = await db.transaction(async (tx) => {
await acquireOrganizationMutationLock(tx, organizationId)
const [org] = await tx
.select()
.select(organizationColumns)
.from(organization)
.where(eq(organization.id, organizationId))
.for('update')
Expand Down Expand Up @@ -1411,7 +1416,7 @@ export async function grantDashboardOrganizationBalance(
}),
operation: async () => {
const [org] = await tx
.select()
.select(organizationColumns)
.from(organization)
.where(eq(organization.id, organizationId))
.for('update')
Expand Down
1 change: 0 additions & 1 deletion apps/sim/lib/api/contracts/v1/admin/organizations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export const adminV1OrganizationSchema = z.object({
logo: z.string().nullable(),
orgUsageLimit: z.string().nullable(),
storageUsedBytes: z.number(),
departedMemberUsage: z.string(),
createdAt: z.string(),
updatedAt: z.string(),
})
Expand Down
1 change: 0 additions & 1 deletion apps/sim/lib/api/contracts/v1/admin/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export const adminV1UserBillingSchema = z.object({
billedOverageThisPeriod: z.string(),
storageUsedBytes: z.number(),
billingBlocked: z.boolean(),
currentPeriodCopilotCost: z.string(),
lastPeriodCopilotCost: z.string().nullable(),
})

Expand Down
1 change: 1 addition & 0 deletions apps/sim/lib/auth/anonymous.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export async function ensureAnonymousUserExists(): Promise<void> {
}

const existingStats = await db.query.userStats.findFirst({
columns: { id: true },
where: eq(schema.userStats.userId, ANONYMOUS_USER_ID),
})

Expand Down
13 changes: 10 additions & 3 deletions apps/sim/lib/billing/core/organization.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { db } from '@sim/db'
import { member, organization, usageLog, user, userStats } from '@sim/db/schema'
import {
member,
organization,
organizationColumns,
usageLog,
user,
userStats,
} from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { and, count, eq, gte, lt, sql } from 'drizzle-orm'
import { isOrganizationBillingBlocked } from '@/lib/billing/core/access'
Expand Down Expand Up @@ -189,7 +196,7 @@ export async function getOrganizationBillingData(
try {
// Get organization info
const orgRecord = await executor
.select()
.select(organizationColumns)
.from(organization)
.where(eq(organization.id, organizationId))
.limit(1)
Expand Down Expand Up @@ -368,7 +375,7 @@ export async function updateOrganizationUsageLimit(
try {
// Validate the organization exists
const orgRecord = await db
.select()
.select(organizationColumns)
.from(organization)
.where(eq(organization.id, organizationId))
.limit(1)
Expand Down
8 changes: 4 additions & 4 deletions apps/sim/lib/billing/core/usage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { db } from '@sim/db'
import { member, organization, settings, user, userStats } from '@sim/db/schema'
import { member, organization, settings, user, userStats, userStatsColumns } from '@sim/db/schema'
import { createLogger } from '@sim/logger'
import { isOrgAdminRole } from '@sim/platform-authz/workspace'
import { generateId } from '@sim/utils/id'
Expand Down Expand Up @@ -207,7 +207,7 @@ export async function getResolvedUserUsageData(
// inserted, which a lagging replica can miss (this path throws on a
// missing row). Stays on the primary deliberately.
db
.select()
.select(userStatsColumns)
.from(userStats)
.where(eq(userStats.userId, userId))
.limit(1),
Expand Down Expand Up @@ -324,7 +324,7 @@ export async function getUserUsageLimitInfo(userId: string): Promise<UsageLimitI
try {
const [subscription, userStatsRecord] = await Promise.all([
getHighestPrioritySubscription(userId),
db.select().from(userStats).where(eq(userStats.userId, userId)).limit(1),
db.select(userStatsColumns).from(userStats).where(eq(userStats.userId, userId)).limit(1),
])

if (userStatsRecord.length === 0) {
Expand Down Expand Up @@ -576,7 +576,7 @@ export async function checkUsageStatus(userId: string): Promise<{
export async function syncUsageLimitsFromSubscription(userId: string): Promise<void> {
const [subscription, currentUserStats] = await Promise.all([
getHighestPrioritySubscription(userId),
db.select().from(userStats).where(eq(userStats.userId, userId)).limit(1),
db.select(userStatsColumns).from(userStats).where(eq(userStats.userId, userId)).limit(1),
])

if (currentUserStats.length === 0) {
Expand Down
13 changes: 0 additions & 13 deletions apps/sim/lib/billing/cycle-close.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,13 +646,6 @@ export async function closeElapsedBillingPeriod(
})
.where(inArray(userStats.userId, memberIds))
}
if (orgScoped) {
await tx
.update(organization)
.set({ departedMemberUsage: '0' })
.where(eq(organization.id, sub.referenceId))
}

const advanced = await claimCloseMarker(tx, sub.id, periodStart)
if (!advanced) {
throw new Error(
Expand Down Expand Up @@ -795,12 +788,6 @@ export async function writeFinalPeriodBookkeeping(sub: {
})
.where(inArray(userStats.userId, memberIds))
}
if (orgScoped) {
await tx
.update(organization)
.set({ departedMemberUsage: '0' })
.where(eq(organization.id, sub.referenceId))
}
})
}

Expand Down
2 changes: 0 additions & 2 deletions apps/sim/lib/billing/organizations/lock-order.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ const GENERIC_ROW = {
status: 'active',
cancelAtPeriodEnd: false,
stripeSubscriptionId: 'stripe-1',
currentPeriodCost: '5',
proPeriodCostSnapshot: '0',
storageUsedBytes: 0,
}

Expand Down
Loading
Loading