Rename to limit id

This commit is contained in:
Owen
2026-06-29 15:22:35 -04:00
parent 4718c489d3
commit ff89a64453
24 changed files with 159 additions and 154 deletions

View File

@@ -20,7 +20,7 @@ import { getOrgTierData } from "#dynamic/lib/billing";
import { deleteOrgById, sendTerminationMessages } from "@server/lib/deleteOrg";
import { UserType } from "@server/types/UserTypes";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing";
import { LimitId } from "@server/lib/billing";
const deleteMyAccountBody = z.strictObject({
password: z.string().optional(),
@@ -220,7 +220,7 @@ export async function deleteMyAccount(
await trx.delete(users).where(eq(users.userId, userId));
// loop through the other orgs and decrement the count
for (const userOrg of otherOrgsTheUserWasIn) {
await usageService.add(userOrg.orgId, FeatureId.USERS, -1, trx);
await usageService.add(userOrg.orgId, LimitId.USERS, -1, trx);
}
});

View File

@@ -17,7 +17,7 @@ import { subdomainSchema } from "@server/lib/schemas";
import { generateId } from "@server/auth/sessions/app";
import { eq, and } from "drizzle-orm";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing";
import { LimitId } from "@server/lib/billing";
import { isSecondLevelDomain, isValidDomain } from "@server/lib/validators";
import { build } from "@server/build";
import config from "@server/lib/config";
@@ -120,7 +120,7 @@ export async function createOrgDomain(
}
if (build == "saas") {
const usage = await usageService.getUsage(orgId, FeatureId.DOMAINS);
const usage = await usageService.getUsage(orgId, LimitId.DOMAINS);
if (!usage) {
return next(
createHttpError(
@@ -132,7 +132,7 @@ export async function createOrgDomain(
const rejectDomains = await usageService.checkLimitSet(
orgId,
FeatureId.DOMAINS,
LimitId.DOMAINS,
{
...usage,
instantaneousValue: (usage.instantaneousValue || 0) + 1
@@ -346,7 +346,7 @@ export async function createOrgDomain(
await trx.insert(dnsRecords).values(recordsToInsert);
}
await usageService.add(orgId, FeatureId.DOMAINS, 1, trx);
await usageService.add(orgId, LimitId.DOMAINS, 1, trx);
});
if (!returned) {

View File

@@ -8,7 +8,7 @@ import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { and, eq } from "drizzle-orm";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing";
import { LimitId } from "@server/lib/billing";
const paramsSchema = z.strictObject({
domainId: z.string(),
@@ -77,7 +77,7 @@ export async function deleteAccountDomain(
await trx.delete(domains).where(eq(domains.domainId, domainId));
await usageService.add(orgId, FeatureId.DOMAINS, -1, trx);
await usageService.add(orgId, LimitId.DOMAINS, -1, trx);
});
return response<DeleteAccountDomainResponse>(res, {

View File

@@ -6,7 +6,7 @@ import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";
import response from "@server/lib/response";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing/features";
import { LimitId } from "@server/lib/billing/features";
import { checkExitNodeOrg } from "#dynamic/lib/exitNodes";
import { build } from "@server/build";
@@ -171,8 +171,9 @@ export async function flushSiteBandwidthToDb(): Promise<void> {
}
// PostgreSQL: batch UPDATE … FROM (VALUES …) - single round-trip per chunk.
const valuesList = chunk.map(([publicKey, { bytesIn, bytesOut }]) =>
sql`(${publicKey}::text, ${bytesIn}::real, ${bytesOut}::real)`
const valuesList = chunk.map(
([publicKey, { bytesIn, bytesOut }]) =>
sql`(${publicKey}::text, ${bytesIn}::real, ${bytesOut}::real)`
);
const valuesClause = sql.join(valuesList, sql`, `);
return dbQueryRows<{ orgId: string; pubKey: string }>(sql`
@@ -228,7 +229,7 @@ export async function flushSiteBandwidthToDb(): Promise<void> {
const totalBandwidth = orgUsageMap.get(orgId)!;
const bandwidthUsage = await usageService.add(
orgId,
FeatureId.EGRESS_DATA_MB,
LimitId.EGRESS_DATA_MB,
totalBandwidth
);
if (bandwidthUsage) {
@@ -236,7 +237,7 @@ export async function flushSiteBandwidthToDb(): Promise<void> {
usageService
.checkLimitSet(
orgId,
FeatureId.EGRESS_DATA_MB,
LimitId.EGRESS_DATA_MB,
bandwidthUsage
)
.catch((error: any) => {
@@ -247,10 +248,7 @@ export async function flushSiteBandwidthToDb(): Promise<void> {
});
}
} catch (error) {
logger.error(
`Error processing usage for org ${orgId}:`,
error
);
logger.error(`Error processing usage for org ${orgId}:`, error);
// Continue with other orgs.
}
}

View File

@@ -31,7 +31,7 @@ import {
} from "@server/auth/sessions/app";
import { decrypt } from "@server/lib/crypto";
import { UserType } from "@server/types/UserTypes";
import { FeatureId } from "@server/lib/billing";
import { LimitId } from "@server/lib/billing";
import { usageService } from "@server/lib/billing/usageService";
import { build } from "@server/build";
import { calculateUserClientsForOrgs } from "@server/lib/calculateUserClientsForOrgs";
@@ -645,7 +645,7 @@ export async function validateOidcCallback(
for (const orgCount of orgUserCounts) {
await usageService.updateCount(
orgCount.orgId,
FeatureId.USERS,
LimitId.USERS,
orgCount.userCount
);
}

View File

@@ -25,7 +25,7 @@ import { getUniqueSiteName } from "@server/db/names";
import moment from "moment";
import { build } from "@server/build";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing";
import { LimitId } from "@server/lib/billing";
import { INSPECT_MAX_BYTES } from "buffer";
import { getNextAvailableClientSubnet } from "@server/lib/ip";
@@ -169,7 +169,7 @@ export async function registerNewt(
// SaaS billing check
if (build == "saas") {
const usage = await usageService.getUsage(orgId, FeatureId.SITES);
const usage = await usageService.getUsage(orgId, LimitId.SITES);
if (!usage) {
return next(
createHttpError(
@@ -180,7 +180,7 @@ export async function registerNewt(
}
const rejectSites = await usageService.checkLimitSet(
orgId,
FeatureId.SITES,
LimitId.SITES,
{
...usage,
instantaneousValue: (usage.instantaneousValue || 0) + 1
@@ -274,7 +274,7 @@ export async function registerNewt(
)
);
await usageService.add(orgId, FeatureId.SITES, 1, trx);
await usageService.add(orgId, LimitId.SITES, 1, trx);
});
} finally {
await releaseSubnetLock();

View File

@@ -27,7 +27,7 @@ import { OpenAPITags, registry } from "@server/openApi";
import { isValidCIDR } from "@server/lib/validators";
import { createCustomer } from "#dynamic/lib/billing";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId, limitsService, freeLimitSet } from "@server/lib/billing";
import { LimitId, limitsService, freeLimitSet } from "@server/lib/billing";
import { build } from "@server/build";
import { calculateUserClientsForOrgs } from "@server/lib/calculateUserClientsForOrgs";
import { doCidrsOverlap } from "@server/lib/ip";
@@ -202,7 +202,7 @@ export async function createOrg(
if (build == "saas" && billingOrgIdForNewOrg) {
const usage = await usageService.getUsage(
billingOrgIdForNewOrg,
FeatureId.ORGINIZATIONS
LimitId.ORGINIZATIONS
);
if (!usage) {
return next(
@@ -214,7 +214,7 @@ export async function createOrg(
}
const rejectOrgs = await usageService.checkLimitSet(
billingOrgIdForNewOrg,
FeatureId.ORGINIZATIONS,
LimitId.ORGINIZATIONS,
{
...usage,
instantaneousValue: (usage.instantaneousValue || 0) + 1
@@ -421,7 +421,7 @@ export async function createOrg(
if (customerId) {
await usageService.updateCount(
orgId,
FeatureId.USERS,
LimitId.USERS,
1,
customerId
); // Only 1 because we are creating the org
@@ -431,7 +431,7 @@ export async function createOrg(
if (numOrgs) {
usageService.updateCount(
billingOrgIdForNewOrg || orgId,
FeatureId.ORGINIZATIONS,
LimitId.ORGINIZATIONS,
numOrgs
);
}

View File

@@ -19,7 +19,7 @@ import { getNextAvailableClientSubnet, isIpInCidr } from "@server/lib/ip";
import { verifyExitNodeOrgAccess } from "#dynamic/lib/exitNodes";
import { build } from "@server/build";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing";
import { LimitId } from "@server/lib/billing";
import { generateId } from "@server/auth/sessions/app";
const createSiteParamsSchema = z.strictObject({
@@ -160,7 +160,7 @@ export async function createSite(
}
if (build == "saas") {
const usage = await usageService.getUsage(orgId, FeatureId.SITES);
const usage = await usageService.getUsage(orgId, LimitId.SITES);
if (!usage) {
return next(
createHttpError(
@@ -172,7 +172,7 @@ export async function createSite(
const rejectSites = await usageService.checkLimitSet(
orgId,
FeatureId.SITES,
LimitId.SITES,
{
...usage,
instantaneousValue: (usage.instantaneousValue || 0) + 1
@@ -519,7 +519,7 @@ export async function createSite(
});
}
await usageService.add(orgId, FeatureId.SITES, 1, trx);
await usageService.add(orgId, LimitId.SITES, 1, trx);
});
} finally {
await releaseSubnetLock?.();

View File

@@ -13,7 +13,7 @@ import { sendToClient } from "#dynamic/routers/ws";
import { OpenAPITags, registry } from "@server/openApi";
import { cleanupSiteAssociations } from "@server/lib/rebuildClientAssociations";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing";
import { LimitId } from "@server/lib/billing";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import {
deleteAssociatedResourcesForSite,
@@ -177,7 +177,7 @@ export async function deleteSite(
}
await trx.delete(sites).where(eq(sites.siteId, siteId));
await usageService.add(site.orgId, FeatureId.SITES, -1, trx);
await usageService.add(site.orgId, LimitId.SITES, -1, trx);
});
if (deleteResources) {

View File

@@ -17,7 +17,7 @@ import { fromError } from "zod-validation-error";
import { checkValidInvite } from "@server/auth/checkValidInvite";
import { verifySession } from "@server/auth/sessions/verifySession";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing";
import { LimitId } from "@server/lib/billing";
import { calculateUserClientsForOrgs } from "@server/lib/calculateUserClientsForOrgs";
import { build } from "@server/build";
import { assignUserToOrg } from "@server/lib/userOrg";
@@ -104,7 +104,7 @@ export async function acceptInvite(
if (build == "saas") {
const usage = await usageService.getUsage(
existingInvite.orgId,
FeatureId.USERS
LimitId.USERS
);
if (!usage) {
return next(
@@ -117,7 +117,7 @@ export async function acceptInvite(
const rejectUsers = await usageService.checkLimitSet(
existingInvite.orgId,
FeatureId.USERS,
LimitId.USERS,
{
...usage,
instantaneousValue: (usage.instantaneousValue || 0) + 1

View File

@@ -12,7 +12,7 @@ import { and, eq, inArray } from "drizzle-orm";
import { idp, idpOidcConfig, roles, userOrgs, users } from "@server/db";
import { generateId } from "@server/auth/sessions/app";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing";
import { LimitId } from "@server/lib/billing";
import { build } from "@server/build";
import { calculateUserClientsForOrgs } from "@server/lib/calculateUserClientsForOrgs";
import { isSubscribed } from "#dynamic/lib/isSubscribed";
@@ -123,7 +123,7 @@ export async function createOrgUser(
} = parsedBody.data;
if (build == "saas") {
const usage = await usageService.getUsage(orgId, FeatureId.USERS);
const usage = await usageService.getUsage(orgId, LimitId.USERS);
if (!usage) {
return next(
createHttpError(
@@ -135,7 +135,7 @@ export async function createOrgUser(
const rejectUsers = await usageService.checkLimitSet(
orgId,
FeatureId.USERS,
LimitId.USERS,
{
...usage,
instantaneousValue: (usage.instantaneousValue || 0) + 1

View File

@@ -25,7 +25,7 @@ import SendInviteLink from "@server/emails/templates/SendInviteLink";
import { OpenAPITags, registry } from "@server/openApi";
import { UserType } from "@server/types/UserTypes";
import { usageService } from "@server/lib/billing/usageService";
import { FeatureId } from "@server/lib/billing";
import { LimitId } from "@server/lib/billing";
import { TierFeature, tierMatrix } from "@server/lib/billing/tierMatrix";
import { build } from "@server/build";
import cache from "#dynamic/lib/cache";
@@ -73,7 +73,6 @@ const InviteUserResponseDataSchema = z.object({
expiresAt: z.number()
});
registry.registerPath({
method: "post",
path: "/org/{orgId}/create-invite",
@@ -94,7 +93,9 @@ registry.registerPath({
description: "Successful response",
content: {
"application/json": {
schema: createApiResponseSchema(InviteUserResponseDataSchema)
schema: createApiResponseSchema(
InviteUserResponseDataSchema
)
}
}
}
@@ -181,7 +182,7 @@ export async function inviteUser(
}
if (build == "saas") {
const usage = await usageService.getUsage(orgId, FeatureId.USERS);
const usage = await usageService.getUsage(orgId, LimitId.USERS);
if (!usage) {
return next(
createHttpError(
@@ -192,7 +193,7 @@ export async function inviteUser(
}
const rejectUsers = await usageService.checkLimitSet(
orgId,
FeatureId.USERS,
LimitId.USERS,
{
...usage,
instantaneousValue: (usage.instantaneousValue || 0) + 1