diff --git a/apps/rowboat/app/actions/copilot_actions.ts b/apps/rowboat/app/actions/copilot_actions.ts index bf70ddee..2669df58 100644 --- a/apps/rowboat/app/actions/copilot_actions.ts +++ b/apps/rowboat/app/actions/copilot_actions.ts @@ -14,9 +14,9 @@ import { USE_BILLING } from "../lib/feature_flags"; import { WithStringId } from "../lib/types/types"; import { getEditAgentInstructionsResponse } from "../lib/copilot/copilot"; import { container } from "@/di/container"; -import { IUsageQuotaPolicyService } from "@/src/application/services/usage-quota-policy.service.interface"; +import { IUsageQuotaPolicy } from "@/src/application/policies/usage-quota.policy.interface"; -const usageQuotaPolicyService = container.resolve('usageQuotaPolicyService'); +const usageQuotaPolicy = container.resolve('usageQuotaPolicy'); export async function getCopilotResponseStream( projectId: string, @@ -28,7 +28,7 @@ export async function getCopilotResponseStream( streamId: string; } | { billingError: string }> { await projectAuthCheck(projectId); - await usageQuotaPolicyService.assertAndConsume(projectId); + await usageQuotaPolicy.assertAndConsume(projectId); // Check billing authorization const authResponse = await authorizeUserAction({ @@ -39,7 +39,7 @@ export async function getCopilotResponseStream( return { billingError: authResponse.error || 'Billing error' }; } - await usageQuotaPolicyService.assertAndConsume(projectId); + await usageQuotaPolicy.assertAndConsume(projectId); // prepare request const request: z.infer = { @@ -71,7 +71,7 @@ export async function getCopilotAgentInstructions( agentName: string, ): Promise { await projectAuthCheck(projectId); - await usageQuotaPolicyService.assertAndConsume(projectId); + await usageQuotaPolicy.assertAndConsume(projectId); // Check billing authorization const authResponse = await authorizeUserAction({ diff --git a/apps/rowboat/app/api/widget/v1/chats/[chatId]/turn/route.ts b/apps/rowboat/app/api/widget/v1/chats/[chatId]/turn/route.ts index 79d6f777..1e9a500f 100644 --- a/apps/rowboat/app/api/widget/v1/chats/[chatId]/turn/route.ts +++ b/apps/rowboat/app/api/widget/v1/chats/[chatId]/turn/route.ts @@ -9,7 +9,7 @@ import { authorize, getCustomerIdForProject, logUsage } from "@/app/lib/billing" import { USE_BILLING } from "@/app/lib/feature_flags"; import { getResponse } from "@/app/lib/agents"; import { Message, AssistantMessage, AssistantMessageWithToolCalls, ToolMessage } from "@/app/lib/types/types"; -import { IUsageQuotaPolicyService } from "@/src/application/services/usage-quota-policy.service.interface"; +import { IUsageQuotaPolicy } from "@/src/application/policies/usage-quota.policy.interface"; import { container } from "@/di/container"; function convert(messages: z.infer[]): z.infer[] { @@ -125,8 +125,8 @@ export async function POST( } // assert and consume quota - const usageQuotaPolicyService = container.resolve('usageQuotaPolicyService'); - await usageQuotaPolicyService.assertAndConsume(session.projectId); + const usageQuotaPolicy = container.resolve('usageQuotaPolicy'); + await usageQuotaPolicy.assertAndConsume(session.projectId); // parse and validate the request body let body; diff --git a/apps/rowboat/di/container.ts b/apps/rowboat/di/container.ts index 8a8af2da..8054910b 100644 --- a/apps/rowboat/di/container.ts +++ b/apps/rowboat/di/container.ts @@ -9,7 +9,7 @@ import { CreateCachedTurnUseCase } from "@/src/application/use-cases/conversatio import { FetchCachedTurnUseCase } from "@/src/application/use-cases/conversations/fetch-cached-turn.use-case"; import { CreateCachedTurnController } from "@/src/interface-adapters/controllers/conversations/create-cached-turn.controller"; import { RunTurnController } from "@/src/interface-adapters/controllers/conversations/run-turn.controller"; -import { RedisUsageQuotaPolicyService } from "@/src/infrastructure/services/redis.usage-quota-policy.service"; +import { RedisUsageQuotaPolicy } from "@/src/infrastructure/policies/redis.usage-quota.policy"; export const container = createContainer({ injectionMode: InjectionMode.PROXY, @@ -20,7 +20,7 @@ container.register({ // services // --- cacheService: asClass(RedisCacheService).singleton(), - usageQuotaPolicyService: asClass(RedisUsageQuotaPolicyService).singleton(), + usageQuotaPolicy: asClass(RedisUsageQuotaPolicy).singleton(), // conversations // --- diff --git a/apps/rowboat/src/application/services/usage-quota-policy.service.interface.ts b/apps/rowboat/src/application/policies/usage-quota.policy.interface.ts similarity index 74% rename from apps/rowboat/src/application/services/usage-quota-policy.service.interface.ts rename to apps/rowboat/src/application/policies/usage-quota.policy.interface.ts index 6defb4bb..20618588 100644 --- a/apps/rowboat/src/application/services/usage-quota-policy.service.interface.ts +++ b/apps/rowboat/src/application/policies/usage-quota.policy.interface.ts @@ -1,4 +1,4 @@ -export interface IUsageQuotaPolicyService { +export interface IUsageQuotaPolicy { // this method will throw a QuotaExceededError if the quota is exceeded assertAndConsume(projectId: string): Promise; } \ No newline at end of file diff --git a/apps/rowboat/src/application/use-cases/conversations/create-cached-turn.use-case.ts b/apps/rowboat/src/application/use-cases/conversations/create-cached-turn.use-case.ts index 16476d7f..d10d0c0e 100644 --- a/apps/rowboat/src/application/use-cases/conversations/create-cached-turn.use-case.ts +++ b/apps/rowboat/src/application/use-cases/conversations/create-cached-turn.use-case.ts @@ -5,7 +5,7 @@ import { z } from "zod"; import { nanoid } from 'nanoid'; import { ICacheService } from '@/src/application/services/cache.service.interface'; import { CachedTurnRequest, Turn } from '@/src/entities/models/turn'; -import { IUsageQuotaPolicyService } from '../../services/usage-quota-policy.service.interface'; +import { IUsageQuotaPolicy } from '../../policies/usage-quota.policy.interface'; const inputSchema = z.object({ caller: z.enum(["user", "api"]), @@ -22,20 +22,20 @@ export interface ICreateCachedTurnUseCase { export class CreateCachedTurnUseCase implements ICreateCachedTurnUseCase { private readonly cacheService: ICacheService; private readonly conversationsRepository: IConversationsRepository; - private readonly usageQuotaPolicyService: IUsageQuotaPolicyService; + private readonly usageQuotaPolicy: IUsageQuotaPolicy; constructor({ cacheService, conversationsRepository, - usageQuotaPolicyService, + usageQuotaPolicy, }: { cacheService: ICacheService, conversationsRepository: IConversationsRepository, - usageQuotaPolicyService: IUsageQuotaPolicyService, + usageQuotaPolicy: IUsageQuotaPolicy, }) { this.cacheService = cacheService; this.conversationsRepository = conversationsRepository; - this.usageQuotaPolicyService = usageQuotaPolicyService; + this.usageQuotaPolicy = usageQuotaPolicy; } async execute(data: z.infer): Promise<{ key: string }> { @@ -49,7 +49,7 @@ export class CreateCachedTurnUseCase implements ICreateCachedTurnUseCase { const { projectId } = conversation; // assert and consume quota - await this.usageQuotaPolicyService.assertAndConsume(projectId); + await this.usageQuotaPolicy.assertAndConsume(projectId); // if caller is a user, ensure they are a member of project if (data.caller === "user") { diff --git a/apps/rowboat/src/application/use-cases/conversations/create-conversation.use-case.ts b/apps/rowboat/src/application/use-cases/conversations/create-conversation.use-case.ts index ad29e27b..0fb9a35e 100644 --- a/apps/rowboat/src/application/use-cases/conversations/create-conversation.use-case.ts +++ b/apps/rowboat/src/application/use-cases/conversations/create-conversation.use-case.ts @@ -4,7 +4,7 @@ import { IConversationsRepository } from "@/src/application/repositories/convers import { z } from "zod"; import { Conversation } from "@/src/entities/models/conversation"; import { Workflow } from "@/app/lib/types/workflow_types"; -import { IUsageQuotaPolicyService } from '../../services/usage-quota-policy.service.interface'; +import { IUsageQuotaPolicy } from '../../policies/usage-quota.policy.interface'; const inputSchema = z.object({ caller: z.enum(["user", "api"]), @@ -21,17 +21,17 @@ export interface ICreateConversationUseCase { export class CreateConversationUseCase implements ICreateConversationUseCase { private readonly conversationsRepository: IConversationsRepository; - private readonly usageQuotaPolicyService: IUsageQuotaPolicyService; + private readonly usageQuotaPolicy: IUsageQuotaPolicy; constructor({ conversationsRepository, - usageQuotaPolicyService, + usageQuotaPolicy, }: { conversationsRepository: IConversationsRepository, - usageQuotaPolicyService: IUsageQuotaPolicyService, + usageQuotaPolicy: IUsageQuotaPolicy, }) { this.conversationsRepository = conversationsRepository; - this.usageQuotaPolicyService = usageQuotaPolicyService; + this.usageQuotaPolicy = usageQuotaPolicy; } async execute(data: z.infer): Promise> { @@ -40,7 +40,7 @@ export class CreateConversationUseCase implements ICreateConversationUseCase { let workflow = data.workflow; // assert and consume quota - await this.usageQuotaPolicyService.assertAndConsume(projectId); + await this.usageQuotaPolicy.assertAndConsume(projectId); // if caller is a user, ensure they are a member of project if (caller === "user") { diff --git a/apps/rowboat/src/application/use-cases/conversations/fetch-cached-turn.use-case.ts b/apps/rowboat/src/application/use-cases/conversations/fetch-cached-turn.use-case.ts index c17e2ff8..f5047e13 100644 --- a/apps/rowboat/src/application/use-cases/conversations/fetch-cached-turn.use-case.ts +++ b/apps/rowboat/src/application/use-cases/conversations/fetch-cached-turn.use-case.ts @@ -4,7 +4,7 @@ import { IConversationsRepository } from "@/src/application/repositories/convers import { z } from "zod"; import { ICacheService } from '@/src/application/services/cache.service.interface'; import { CachedTurnRequest, Turn } from '@/src/entities/models/turn'; -import { IUsageQuotaPolicyService } from '../../services/usage-quota-policy.service.interface'; +import { IUsageQuotaPolicy } from '../../policies/usage-quota.policy.interface'; const inputSchema = z.object({ caller: z.enum(["user", "api"]), @@ -20,20 +20,20 @@ export interface IFetchCachedTurnUseCase { export class FetchCachedTurnUseCase implements IFetchCachedTurnUseCase { private readonly cacheService: ICacheService; private readonly conversationsRepository: IConversationsRepository; - private readonly usageQuotaPolicyService: IUsageQuotaPolicyService; + private readonly usageQuotaPolicy: IUsageQuotaPolicy; constructor({ cacheService, conversationsRepository, - usageQuotaPolicyService, + usageQuotaPolicy, }: { cacheService: ICacheService, conversationsRepository: IConversationsRepository, - usageQuotaPolicyService: IUsageQuotaPolicyService, + usageQuotaPolicy: IUsageQuotaPolicy, }) { this.cacheService = cacheService; this.conversationsRepository = conversationsRepository; - this.usageQuotaPolicyService = usageQuotaPolicyService; + this.usageQuotaPolicy = usageQuotaPolicy; } async execute(data: z.infer): Promise> { @@ -56,7 +56,7 @@ export class FetchCachedTurnUseCase implements IFetchCachedTurnUseCase { const { projectId } = conversation; // assert and consume quota - await this.usageQuotaPolicyService.assertAndConsume(projectId); + await this.usageQuotaPolicy.assertAndConsume(projectId); // if caller is a user, ensure they are a member of project if (data.caller === "user") { diff --git a/apps/rowboat/src/application/use-cases/conversations/run-conversation-turn.use-case.ts b/apps/rowboat/src/application/use-cases/conversations/run-conversation-turn.use-case.ts index 3d464cbc..67c481f6 100644 --- a/apps/rowboat/src/application/use-cases/conversations/run-conversation-turn.use-case.ts +++ b/apps/rowboat/src/application/use-cases/conversations/run-conversation-turn.use-case.ts @@ -7,7 +7,7 @@ import { IConversationsRepository } from "@/src/application/repositories/convers import { streamResponse } from "@/app/lib/agents"; import { z } from "zod"; import { Message } from "@/app/lib/types/types"; -import { IUsageQuotaPolicyService } from '../../services/usage-quota-policy.service.interface'; +import { IUsageQuotaPolicy } from '../../policies/usage-quota.policy.interface'; const inputSchema = z.object({ caller: z.enum(["user", "api"]), @@ -24,17 +24,17 @@ export interface IRunConversationTurnUseCase { export class RunConversationTurnUseCase implements IRunConversationTurnUseCase { private readonly conversationsRepository: IConversationsRepository; - private readonly usageQuotaPolicyService: IUsageQuotaPolicyService; + private readonly usageQuotaPolicy: IUsageQuotaPolicy; constructor({ conversationsRepository, - usageQuotaPolicyService, + usageQuotaPolicy, }: { conversationsRepository: IConversationsRepository, - usageQuotaPolicyService: IUsageQuotaPolicyService, + usageQuotaPolicy: IUsageQuotaPolicy, }) { this.conversationsRepository = conversationsRepository; - this.usageQuotaPolicyService = usageQuotaPolicyService; + this.usageQuotaPolicy = usageQuotaPolicy; } async *execute(data: z.infer): AsyncGenerator, void, unknown> { @@ -48,7 +48,7 @@ export class RunConversationTurnUseCase implements IRunConversationTurnUseCase { const { id: conversationId, projectId } = conversation; // assert and consume quota - await this.usageQuotaPolicyService.assertAndConsume(projectId); + await this.usageQuotaPolicy.assertAndConsume(projectId); // if caller is a user, ensure they are a member of project if (data.caller === "user") { diff --git a/apps/rowboat/src/infrastructure/services/redis.usage-quota-policy.service.ts b/apps/rowboat/src/infrastructure/policies/redis.usage-quota.policy.ts similarity index 81% rename from apps/rowboat/src/infrastructure/services/redis.usage-quota-policy.service.ts rename to apps/rowboat/src/infrastructure/policies/redis.usage-quota.policy.ts index d3b4c717..05fecbdb 100644 --- a/apps/rowboat/src/infrastructure/services/redis.usage-quota-policy.service.ts +++ b/apps/rowboat/src/infrastructure/policies/redis.usage-quota.policy.ts @@ -1,10 +1,10 @@ -import { IUsageQuotaPolicyService } from "@/src/application/services/usage-quota-policy.service.interface"; +import { IUsageQuotaPolicy } from "@/src/application/policies/usage-quota.policy.interface"; import { redisClient } from "@/app/lib/redis"; import { QuotaExceededError } from "@/src/entities/errors/common"; const MAX_QUERIES_PER_MINUTE = Number(process.env.MAX_QUERIES_PER_MINUTE) || 0; -export class RedisUsageQuotaPolicyService implements IUsageQuotaPolicyService { +export class RedisUsageQuotaPolicy implements IUsageQuotaPolicy { async assertAndConsume(projectId: string): Promise { if (MAX_QUERIES_PER_MINUTE === 0) { return;