ddd refactor: project-members

This commit is contained in:
Ramnique Singh 2025-08-15 13:50:58 +05:30
parent f9d2c31238
commit 85adfcd139
8 changed files with 140 additions and 51 deletions

View file

@ -1,7 +1,7 @@
'use server';
import { redirect } from "next/navigation";
import { ObjectId } from "mongodb";
import { db, dataSourcesCollection, projectsCollection, projectMembersCollection, dataSourceDocsCollection } from "../lib/mongodb";
import { db, dataSourcesCollection, projectsCollection, dataSourceDocsCollection } from "../lib/mongodb";
import { z } from 'zod';
import crypto from 'crypto';
import { revalidatePath } from "next/cache";
@ -19,6 +19,7 @@ import { ICreateApiKeyController } from "@/src/interface-adapters/controllers/ap
import { IListApiKeysController } from "@/src/interface-adapters/controllers/api-keys/list-api-keys.controller";
import { IDeleteApiKeyController } from "@/src/interface-adapters/controllers/api-keys/delete-api-key.controller";
import { IApiKeysRepository } from "@/src/application/repositories/api-keys.repository.interface";
import { IProjectMembersRepository } from "@/src/application/repositories/project-members.repository.interface";
const KLAVIS_API_KEY = process.env.KLAVIS_API_KEY || '';
const projectActionAuthorizationPolicy = container.resolve<IProjectActionAuthorizationPolicy>('projectActionAuthorizationPolicy');
@ -26,6 +27,7 @@ const createApiKeyController = container.resolve<ICreateApiKeyController>('creat
const listApiKeysController = container.resolve<IListApiKeysController>('listApiKeysController');
const deleteApiKeyController = container.resolve<IDeleteApiKeyController>('deleteApiKeyController');
const apiKeysRepository = container.resolve<IApiKeysRepository>('apiKeysRepository');
const projectMembersRepository = container.resolve<IProjectMembersRepository>('projectMembersRepository');
export async function listTemplates() {
const templatesArray = Object.entries(templates)
@ -94,11 +96,9 @@ async function createBaseProject(
});
// Add user to project
await projectMembersCollection.insertOne({
await projectMembersRepository.create({
userId: user._id,
projectId: projectId,
createdAt: (new Date()).toISOString(),
lastUpdatedAt: (new Date()).toISOString(),
projectId,
});
// Add first api key
@ -159,9 +159,13 @@ export async function getProjectConfig(projectId: string): Promise<WithStringId<
export async function listProjects(): Promise<z.infer<typeof Project>[]> {
const user = await authCheck();
const memberships = await projectMembersCollection.find({
userId: user._id,
}).toArray();
const memberships = [];
let cursor = undefined;
do {
const result = await projectMembersRepository.findByUserId(user._id, cursor);
memberships.push(...result.items);
cursor = result.nextCursor;
} while (cursor);
const projectIds = memberships.map((m) => m.projectId);
const projects = await projectsCollection.find({
_id: { $in: projectIds },
@ -251,9 +255,7 @@ export async function deleteProject(projectId: string) {
});
// delete project members
await projectMembersCollection.deleteMany({
projectId,
});
await projectMembersRepository.deleteByProjectId(projectId);
// delete workflow versions
await db.collection('agent_workflows').deleteMany({

View file

@ -1,6 +1,6 @@
import { z } from "zod";
import { ObjectId } from "mongodb";
import { usersCollection, projectsCollection, projectMembersCollection } from "./mongodb";
import { usersCollection } from "./mongodb";
import { auth0 } from "./auth0";
import { User, WithStringId } from "./types/types";
import { USE_AUTH } from "./feature_flags";
@ -59,11 +59,6 @@ export async function requireAuth(): Promise<WithStringId<z.infer<typeof User>>>
console.log(`creating new user id ${doc._id.toString()} for session id ${user.sub}`);
await usersCollection.insertOne(doc);
// since auth feature was rolled out later,
// set all project authors to new user id instead
// of user.sub
await updateProjectRefs(user.sub, doc._id.toString());
dbUser = {
...doc,
_id: doc._id.toString(),
@ -77,25 +72,6 @@ export async function requireAuth(): Promise<WithStringId<z.infer<typeof User>>>
};
}
async function updateProjectRefs(sessionUserId: string, dbUserId: string) {
await projectsCollection.updateMany({
createdByUserId: sessionUserId
}, {
$set: {
createdByUserId: dbUserId,
lastUpdatedAt: new Date().toISOString(),
}
});
await projectMembersCollection.updateMany({
userId: sessionUserId
}, {
$set: {
userId: dbUserId,
}
});
}
export async function getUserFromSessionId(sessionUserId: string): Promise<WithStringId<z.infer<typeof User>> | null> {
if (!USE_AUTH) {
return GUEST_DB_USER;

View file

@ -2,7 +2,7 @@ import { MongoClient } from "mongodb";
import { User, Webpage } from "./types/types";
import { Workflow } from "./types/workflow_types";
import { ApiKey } from "@/src/entities/models/api-key";
import { ProjectMember } from "./types/project_types";
import { ProjectMember } from "@/src/entities/models/project-member";
import { Project } from "./types/project_types";
import { EmbeddingDoc } from "./types/datasource_types";
import { DataSourceDoc } from "./types/datasource_types";
@ -17,7 +17,6 @@ export const db = client.db("rowboat");
export const dataSourcesCollection = db.collection<z.infer<typeof DataSource>>("sources");
export const dataSourceDocsCollection = db.collection<z.infer<typeof DataSourceDoc>>("source_docs");
export const projectsCollection = db.collection<z.infer<typeof Project>>("projects");
export const projectMembersCollection = db.collection<z.infer<typeof ProjectMember>>("project_members");
export const agentWorkflowsCollection = db.collection<z.infer<typeof Workflow>>("agent_workflows");
export const chatsCollection = db.collection<z.infer<typeof apiV1.Chat>>("chats");
export const chatMessagesCollection = db.collection<z.infer<typeof apiV1.ChatMessage>>("chat_messages");

View file

@ -34,11 +34,4 @@ export const Project = z.object({
mcpServers: z.array(MCPServer).optional(),
composioConnectedAccounts: z.record(z.string(), ComposioConnectedAccount).optional(),
customMcpServers: z.record(z.string(), CustomMcpServer).optional(),
});
export const ProjectMember = z.object({
userId: z.string(),
projectId: z.string(),
createdAt: z.string().datetime(),
lastUpdatedAt: z.string().datetime(),
});