feat: implement automation feature
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import * as schema from '@db/schema';
|
||||
|
||||
import { and, desc, eq, isNull } from 'drizzle-orm';
|
||||
import { and, count, desc, eq, isNull } from 'drizzle-orm';
|
||||
|
||||
import { db } from '@db/drizzle';
|
||||
import type { TNewOrganizationApiKey, TOrganizationApiKey, TOrganizationApiKeyType } from '@db/types';
|
||||
@@ -42,6 +42,29 @@ export const listOrganizationApiKeys = async (
|
||||
}
|
||||
};
|
||||
|
||||
export const countActiveOrganizationApiKeys = async (
|
||||
organizationId: string,
|
||||
type: TOrganizationApiKeyType
|
||||
): Promise<number> => {
|
||||
try {
|
||||
const [row] = await db
|
||||
.select({ total: count() })
|
||||
.from(schema.organizationApiKey)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.organizationApiKey.organizationId, organizationId),
|
||||
eq(schema.organizationApiKey.type, type),
|
||||
isNull(schema.organizationApiKey.revokedAt)
|
||||
)
|
||||
);
|
||||
|
||||
return Number(row?.total ?? 0);
|
||||
} catch (error) {
|
||||
console.error('countActiveOrganizationApiKeys error:', error);
|
||||
throw new Error('Failed to count active organization API keys');
|
||||
}
|
||||
};
|
||||
|
||||
export const getOrganizationApiKeyById = async (
|
||||
organizationId: string,
|
||||
keyId: string
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
import * as schema from '@db/schema';
|
||||
|
||||
import { and, count, desc, eq, gte, sql } from 'drizzle-orm';
|
||||
|
||||
import { db } from '@db/drizzle';
|
||||
import type { TAutomationUsageCategory, TNewOrganizationAutomationUsage, TOrganizationApiKeyType } from '@db/types';
|
||||
|
||||
export const createOrganizationAutomationUsage = async (data: TNewOrganizationAutomationUsage) => {
|
||||
try {
|
||||
const [row] = await db.insert(schema.organizationAutomationUsage).values(data).returning();
|
||||
|
||||
if (!row) {
|
||||
throw new Error('Failed to create organization automation usage');
|
||||
}
|
||||
|
||||
return row;
|
||||
} catch (error) {
|
||||
console.error('createOrganizationAutomationUsage error:', error);
|
||||
throw new Error('Failed to create organization automation usage');
|
||||
}
|
||||
};
|
||||
|
||||
export const countOrganizationAutomationUsageSinceByKey = async (
|
||||
organizationApiKeyId: string,
|
||||
category: TAutomationUsageCategory,
|
||||
since: string
|
||||
): Promise<number> => {
|
||||
try {
|
||||
const [row] = await db
|
||||
.select({ total: count() })
|
||||
.from(schema.organizationAutomationUsage)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.organizationAutomationUsage.organizationApiKeyId, organizationApiKeyId),
|
||||
eq(schema.organizationAutomationUsage.category, category),
|
||||
gte(schema.organizationAutomationUsage.createdAt, since)
|
||||
)
|
||||
);
|
||||
|
||||
return Number(row?.total ?? 0);
|
||||
} catch (error) {
|
||||
console.error('countOrganizationAutomationUsageSinceByKey error:', error);
|
||||
throw new Error('Failed to count organization automation usage by key');
|
||||
}
|
||||
};
|
||||
|
||||
export const countOrganizationAutomationUsageSince = async (
|
||||
organizationId: string,
|
||||
type: TOrganizationApiKeyType,
|
||||
category: TAutomationUsageCategory,
|
||||
since: string
|
||||
): Promise<number> => {
|
||||
try {
|
||||
const [row] = await db
|
||||
.select({ total: count() })
|
||||
.from(schema.organizationAutomationUsage)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.organizationAutomationUsage.organizationId, organizationId),
|
||||
eq(schema.organizationAutomationUsage.type, type),
|
||||
eq(schema.organizationAutomationUsage.category, category),
|
||||
gte(schema.organizationAutomationUsage.createdAt, since)
|
||||
)
|
||||
);
|
||||
|
||||
return Number(row?.total ?? 0);
|
||||
} catch (error) {
|
||||
console.error('countOrganizationAutomationUsageSince error:', error);
|
||||
throw new Error('Failed to count organization automation usage');
|
||||
}
|
||||
};
|
||||
|
||||
export const getOrganizationAutomationCreditsUsedSince = async (
|
||||
organizationId: string,
|
||||
type: TOrganizationApiKeyType,
|
||||
since: string
|
||||
): Promise<number> => {
|
||||
try {
|
||||
const [row] = await db
|
||||
.select({
|
||||
total: sql<number>`COALESCE(SUM(${schema.organizationAutomationUsage.creditsConsumed}), 0)`
|
||||
})
|
||||
.from(schema.organizationAutomationUsage)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.organizationAutomationUsage.organizationId, organizationId),
|
||||
eq(schema.organizationAutomationUsage.type, type),
|
||||
gte(schema.organizationAutomationUsage.createdAt, since)
|
||||
)
|
||||
);
|
||||
|
||||
return Number(row?.total ?? 0);
|
||||
} catch (error) {
|
||||
console.error('getOrganizationAutomationCreditsUsedSince error:', error);
|
||||
throw new Error('Failed to get organization automation credits used');
|
||||
}
|
||||
};
|
||||
|
||||
export const listRecentOrganizationAutomationUsage = async (
|
||||
organizationId: string,
|
||||
type: TOrganizationApiKeyType,
|
||||
limit = 10
|
||||
) => {
|
||||
try {
|
||||
return await db
|
||||
.select({
|
||||
action: schema.organizationAutomationUsage.action,
|
||||
creditsConsumed: schema.organizationAutomationUsage.creditsConsumed,
|
||||
createdAt: schema.organizationAutomationUsage.createdAt
|
||||
})
|
||||
.from(schema.organizationAutomationUsage)
|
||||
.where(
|
||||
and(
|
||||
eq(schema.organizationAutomationUsage.organizationId, organizationId),
|
||||
eq(schema.organizationAutomationUsage.type, type)
|
||||
)
|
||||
)
|
||||
.orderBy(desc(schema.organizationAutomationUsage.createdAt))
|
||||
.limit(limit);
|
||||
} catch (error) {
|
||||
console.error('listRecentOrganizationAutomationUsage error:', error);
|
||||
throw new Error('Failed to list recent organization automation usage');
|
||||
}
|
||||
};
|
||||
@@ -2,3 +2,4 @@ export * from './organization';
|
||||
export * from './quiz';
|
||||
export * from './invite';
|
||||
export * from './automation-key';
|
||||
export * from './automation-usage';
|
||||
|
||||
@@ -677,3 +677,13 @@ export const getOrganizationPlanStatus = async (orgId: string) => {
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const getActiveOrganizationPlan = async (orgId: string) => {
|
||||
const [plan] = await db
|
||||
.select()
|
||||
.from(schema.organizationPlan)
|
||||
.where(and(eq(schema.organizationPlan.orgId, orgId), eq(schema.organizationPlan.isActive, true)))
|
||||
.limit(1);
|
||||
|
||||
return plan ?? null;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user