import { eq, or, inArray, type Db, projects, teamMembers } from '@mosaicstack/db'; export type Project = typeof projects.$inferSelect; export type NewProject = typeof projects.$inferInsert; export function createProjectsRepo(db: Db) { return { async findAll(): Promise { return db.select().from(projects); }, /** * Return only the projects visible to a given user: * – projects directly owned by the user (ownerType = 'user', ownerId = userId), OR * – projects owned by a team the user belongs to (ownerType = 'team', teamId IN user's teams) */ async findAllForUser(userId: string): Promise { // Fetch the team IDs the user is a member of. const memberRows = await db .select({ teamId: teamMembers.teamId }) .from(teamMembers) .where(eq(teamMembers.userId, userId)); const teamIds = memberRows.map((r) => r.teamId); if (teamIds.length === 0) { // No team memberships — return only directly owned projects. return db.select().from(projects).where(eq(projects.ownerId, userId)); } return db .select() .from(projects) .where(or(eq(projects.ownerId, userId), inArray(projects.teamId, teamIds))); }, async findById(id: string): Promise { const rows = await db.select().from(projects).where(eq(projects.id, id)); return rows[0]; }, async create(data: NewProject): Promise { const rows = await db.insert(projects).values(data).returning(); return rows[0]!; }, async update(id: string, data: Partial): Promise { const rows = await db .update(projects) .set({ ...data, updatedAt: new Date() }) .where(eq(projects.id, id)) .returning(); return rows[0]; }, async remove(id: string): Promise { const rows = await db.delete(projects).where(eq(projects.id, id)).returning(); return rows.length > 0; }, }; } export type ProjectsRepo = ReturnType;