mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-05-12 16:52:43 +02:00
better project deletion cleanup
This commit is contained in:
parent
376e308186
commit
29e4a8fb9e
11 changed files with 113 additions and 4 deletions
|
|
@ -88,4 +88,12 @@ export interface IComposioTriggerDeploymentsRepository {
|
||||||
* @returns Promise resolving to the number of records deleted
|
* @returns Promise resolving to the number of records deleted
|
||||||
*/
|
*/
|
||||||
deleteByConnectedAccountId(connectedAccountId: string): Promise<number>;
|
deleteByConnectedAccountId(connectedAccountId: string): Promise<number>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all trigger deployments associated with a specific project.
|
||||||
|
*
|
||||||
|
* @param projectId - The unique identifier of the project
|
||||||
|
* @returns Promise resolving to void
|
||||||
|
*/
|
||||||
|
deleteByProjectId(projectId: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
@ -37,4 +37,12 @@ export interface IConversationsRepository {
|
||||||
// add turn data to conversation
|
// add turn data to conversation
|
||||||
// returns the created turn
|
// returns the created turn
|
||||||
addTurn(conversationId: string, data: z.infer<typeof AddTurnData>): Promise<z.infer<typeof Turn>>;
|
addTurn(conversationId: string, data: z.infer<typeof AddTurnData>): Promise<z.infer<typeof Turn>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all conversations associated with a specific project.
|
||||||
|
*
|
||||||
|
* @param projectId - The unique identifier of the project
|
||||||
|
* @returns Promise resolving to void
|
||||||
|
*/
|
||||||
|
deleteByProjectId(projectId: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
@ -139,4 +139,12 @@ export interface IJobsRepository {
|
||||||
cursor?: string,
|
cursor?: string,
|
||||||
limit?: number
|
limit?: number
|
||||||
): Promise<z.infer<ReturnType<typeof PaginatedList<typeof ListedJobItem>>>>;
|
): Promise<z.infer<ReturnType<typeof PaginatedList<typeof ListedJobItem>>>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all jobs associated with a specific project.
|
||||||
|
*
|
||||||
|
* @param projectId - The unique identifier of the project
|
||||||
|
* @returns Promise resolving to void
|
||||||
|
*/
|
||||||
|
deleteByProjectId(projectId: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
@ -89,4 +89,12 @@ export interface IRecurringJobRulesRepository {
|
||||||
* @returns Promise resolving to true if the rule was deleted, false if not found
|
* @returns Promise resolving to true if the rule was deleted, false if not found
|
||||||
*/
|
*/
|
||||||
delete(id: string): Promise<boolean>;
|
delete(id: string): Promise<boolean>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all recurring job rules associated with a specific project.
|
||||||
|
*
|
||||||
|
* @param projectId - The unique identifier of the project
|
||||||
|
* @returns Promise resolving to void
|
||||||
|
*/
|
||||||
|
deleteByProjectId(projectId: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,4 +95,12 @@ export interface IScheduledJobRulesRepository {
|
||||||
* @returns Promise resolving to true if the rule was deleted, false if not found
|
* @returns Promise resolving to true if the rule was deleted, false if not found
|
||||||
*/
|
*/
|
||||||
delete(id: string): Promise<boolean>;
|
delete(id: string): Promise<boolean>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all scheduled job rules associated with a specific project.
|
||||||
|
*
|
||||||
|
* @param projectId - The unique identifier of the project
|
||||||
|
* @returns Promise resolving to void
|
||||||
|
*/
|
||||||
|
deleteByProjectId(projectId: string): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
@ -6,6 +6,13 @@ import { IApiKeysRepository } from "../../repositories/api-keys.repository.inter
|
||||||
import { IDataSourceDocsRepository } from "../../repositories/data-source-docs.repository.interface";
|
import { IDataSourceDocsRepository } from "../../repositories/data-source-docs.repository.interface";
|
||||||
import { IDataSourcesRepository } from "../../repositories/data-sources.repository.interface";
|
import { IDataSourcesRepository } from "../../repositories/data-sources.repository.interface";
|
||||||
import { qdrantClient } from "@/app/lib/qdrant";
|
import { qdrantClient } from "@/app/lib/qdrant";
|
||||||
|
import { IComposioTriggerDeploymentsRepository } from "../../repositories/composio-trigger-deployments.repository.interface";
|
||||||
|
import { IConversationsRepository } from "../../repositories/conversations.repository.interface";
|
||||||
|
import { IJobsRepository } from "../../repositories/jobs.repository.interface";
|
||||||
|
import { IRecurringJobRulesRepository } from "../../repositories/recurring-job-rules.repository.interface";
|
||||||
|
import { IScheduledJobRulesRepository } from "../../repositories/scheduled-job-rules.repository.interface";
|
||||||
|
import { NotFoundError } from "@/src/entities/errors/common";
|
||||||
|
import { deleteConnectedAccount } from "../../lib/composio/composio";
|
||||||
|
|
||||||
export const InputSchema = z.object({
|
export const InputSchema = z.object({
|
||||||
projectId: z.string(),
|
projectId: z.string(),
|
||||||
|
|
@ -25,14 +32,24 @@ export class DeleteProjectUseCase implements IDeleteProjectUseCase {
|
||||||
private readonly apiKeysRepository: IApiKeysRepository;
|
private readonly apiKeysRepository: IApiKeysRepository;
|
||||||
private readonly dataSourceDocsRepository: IDataSourceDocsRepository;
|
private readonly dataSourceDocsRepository: IDataSourceDocsRepository;
|
||||||
private readonly dataSourcesRepository: IDataSourcesRepository;
|
private readonly dataSourcesRepository: IDataSourcesRepository;
|
||||||
|
private readonly composioTriggerDeploymentsRepository: IComposioTriggerDeploymentsRepository;
|
||||||
|
private readonly conversationsRepository: IConversationsRepository;
|
||||||
|
private readonly jobsRepository: IJobsRepository;
|
||||||
|
private readonly recurringJobRulesRepository: IRecurringJobRulesRepository;
|
||||||
|
private readonly scheduledJobRulesRepository: IScheduledJobRulesRepository;
|
||||||
|
|
||||||
constructor({ projectsRepository, projectMembersRepository, projectActionAuthorizationPolicy, apiKeysRepository, dataSourceDocsRepository, dataSourcesRepository}: {
|
constructor({ projectsRepository, projectMembersRepository, projectActionAuthorizationPolicy, apiKeysRepository, dataSourceDocsRepository, dataSourcesRepository, composioTriggerDeploymentsRepository, conversationsRepository, jobsRepository, recurringJobRulesRepository, scheduledJobRulesRepository }: {
|
||||||
projectsRepository: IProjectsRepository,
|
projectsRepository: IProjectsRepository,
|
||||||
projectMembersRepository: IProjectMembersRepository,
|
projectMembersRepository: IProjectMembersRepository,
|
||||||
projectActionAuthorizationPolicy: IProjectActionAuthorizationPolicy,
|
projectActionAuthorizationPolicy: IProjectActionAuthorizationPolicy,
|
||||||
apiKeysRepository: IApiKeysRepository,
|
apiKeysRepository: IApiKeysRepository,
|
||||||
dataSourceDocsRepository: IDataSourceDocsRepository,
|
dataSourceDocsRepository: IDataSourceDocsRepository,
|
||||||
dataSourcesRepository: IDataSourcesRepository,
|
dataSourcesRepository: IDataSourcesRepository,
|
||||||
|
composioTriggerDeploymentsRepository: IComposioTriggerDeploymentsRepository,
|
||||||
|
conversationsRepository: IConversationsRepository,
|
||||||
|
jobsRepository: IJobsRepository,
|
||||||
|
recurringJobRulesRepository: IRecurringJobRulesRepository,
|
||||||
|
scheduledJobRulesRepository: IScheduledJobRulesRepository,
|
||||||
}) {
|
}) {
|
||||||
this.projectsRepository = projectsRepository;
|
this.projectsRepository = projectsRepository;
|
||||||
this.projectMembersRepository = projectMembersRepository;
|
this.projectMembersRepository = projectMembersRepository;
|
||||||
|
|
@ -40,6 +57,11 @@ export class DeleteProjectUseCase implements IDeleteProjectUseCase {
|
||||||
this.apiKeysRepository = apiKeysRepository;
|
this.apiKeysRepository = apiKeysRepository;
|
||||||
this.dataSourceDocsRepository = dataSourceDocsRepository;
|
this.dataSourceDocsRepository = dataSourceDocsRepository;
|
||||||
this.dataSourcesRepository = dataSourcesRepository;
|
this.dataSourcesRepository = dataSourcesRepository;
|
||||||
|
this.composioTriggerDeploymentsRepository = composioTriggerDeploymentsRepository;
|
||||||
|
this.conversationsRepository = conversationsRepository;
|
||||||
|
this.jobsRepository = jobsRepository;
|
||||||
|
this.recurringJobRulesRepository = recurringJobRulesRepository;
|
||||||
|
this.scheduledJobRulesRepository = scheduledJobRulesRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(request: z.infer<typeof InputSchema>): Promise<void> {
|
async execute(request: z.infer<typeof InputSchema>): Promise<void> {
|
||||||
|
|
@ -51,12 +73,39 @@ export class DeleteProjectUseCase implements IDeleteProjectUseCase {
|
||||||
projectId,
|
projectId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const project = await this.projectsRepository.fetch(projectId);
|
||||||
|
if (!project) {
|
||||||
|
throw new NotFoundError('Project not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete connected accounts
|
||||||
|
await Promise.all(
|
||||||
|
Object.values(project.composioConnectedAccounts || {}).map(account =>
|
||||||
|
deleteConnectedAccount(account.id)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// delete memberships
|
// delete memberships
|
||||||
await this.projectMembersRepository.deleteByProjectId(projectId);
|
await this.projectMembersRepository.deleteByProjectId(projectId);
|
||||||
|
|
||||||
// delete api keys
|
// delete api keys
|
||||||
await this.apiKeysRepository.deleteAll(projectId);
|
await this.apiKeysRepository.deleteAll(projectId);
|
||||||
|
|
||||||
|
// delete composio trigger deployments
|
||||||
|
await this.composioTriggerDeploymentsRepository.deleteByProjectId(projectId);
|
||||||
|
|
||||||
|
// delete conversations
|
||||||
|
await this.conversationsRepository.deleteByProjectId(projectId);
|
||||||
|
|
||||||
|
// delete jobs
|
||||||
|
await this.jobsRepository.deleteByProjectId(projectId);
|
||||||
|
|
||||||
|
// delete recurring job rules
|
||||||
|
await this.recurringJobRulesRepository.deleteByProjectId(projectId);
|
||||||
|
|
||||||
|
// delete scheduled job rules
|
||||||
|
await this.scheduledJobRulesRepository.deleteByProjectId(projectId);
|
||||||
|
|
||||||
// delete data sources data
|
// delete data sources data
|
||||||
await this.dataSourceDocsRepository.deleteByProjectId(projectId);
|
await this.dataSourceDocsRepository.deleteByProjectId(projectId);
|
||||||
await this.dataSourcesRepository.deleteByProjectId(projectId);
|
await this.dataSourcesRepository.deleteByProjectId(projectId);
|
||||||
|
|
@ -68,9 +117,6 @@ export class DeleteProjectUseCase implements IDeleteProjectUseCase {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// delete project members
|
|
||||||
await this.projectMembersRepository.deleteByProjectId(projectId);
|
|
||||||
|
|
||||||
// delete project
|
// delete project
|
||||||
await this.projectsRepository.delete(projectId);
|
await this.projectsRepository.delete(projectId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -172,4 +172,11 @@ export class MongodbComposioTriggerDeploymentsRepository implements IComposioTri
|
||||||
|
|
||||||
return result.deletedCount;
|
return result.deletedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes all trigger deployments associated with a specific project.
|
||||||
|
*/
|
||||||
|
async deleteByProjectId(projectId: string): Promise<void> {
|
||||||
|
await this.collection.deleteMany({ projectId });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -109,4 +109,8 @@ export class MongoDBConversationsRepository implements IConversationsRepository
|
||||||
nextCursor: hasNextPage ? results[limit - 1]._id.toString() : null,
|
nextCursor: hasNextPage ? results[limit - 1]._id.toString() : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteByProjectId(projectId: string): Promise<void> {
|
||||||
|
await this.collection.deleteMany({ projectId });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -267,4 +267,8 @@ export class MongoDBJobsRepository implements IJobsRepository {
|
||||||
nextCursor: hasNextPage ? results[_limit - 1]._id.toString() : null,
|
nextCursor: hasNextPage ? results[_limit - 1]._id.toString() : null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteByProjectId(projectId: string): Promise<void> {
|
||||||
|
await this.collection.deleteMany({ projectId });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -238,4 +238,8 @@ export class MongoDBRecurringJobRulesRepository implements IRecurringJobRulesRep
|
||||||
|
|
||||||
return this.convertDocToModel(result);
|
return this.convertDocToModel(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteByProjectId(projectId: string): Promise<void> {
|
||||||
|
await this.collection.deleteMany({ projectId });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -218,4 +218,8 @@ export class MongoDBScheduledJobRulesRepository implements IScheduledJobRulesRep
|
||||||
|
|
||||||
return result.deletedCount > 0;
|
return result.deletedCount > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async deleteByProjectId(projectId: string): Promise<void> {
|
||||||
|
await this.collection.deleteMany({ projectId });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue