mirror of https://github.com/buster-so/buster.git
user to organization method
This commit is contained in:
parent
2e73d97ffc
commit
a9b8acbb80
|
@ -37,9 +37,9 @@
|
|||
"typescript.suggest.includeCompletionsForModuleExports": true,
|
||||
"typescript.workspaceSymbols.scope": "allOpenProjects",
|
||||
"typescript.references.enabled": true,
|
||||
"typescript.implementationsCodeLens.enabled": true,
|
||||
"typescript.referencesCodeLens.enabled": true,
|
||||
"typescript.referencesCodeLens.showOnAllFunctions": true,
|
||||
"typescript.implementationsCodeLens.enabled": false,
|
||||
"typescript.referencesCodeLens.enabled": false,
|
||||
"typescript.referencesCodeLens.showOnAllFunctions": false,
|
||||
"typescript.validate.enable": true,
|
||||
"typescript.format.enable": true,
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
"ai": "catalog:",
|
||||
"drizzle-kit": "^0.31.4",
|
||||
"drizzle-orm": "catalog:",
|
||||
"drizzle-zod": "^0.8.2",
|
||||
"postgres": "^3.4.7",
|
||||
"zod": "catalog:"
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import { and, eq, isNull, like } from 'drizzle-orm';
|
||||
import { type InferSelectModel, and, eq, isNull, like } from 'drizzle-orm';
|
||||
import { z } from 'zod';
|
||||
import { db } from '../../connection';
|
||||
import { users, usersToOrganizations } from '../../schema';
|
||||
import { getUserOrganizationId } from '../organizations/organizations';
|
||||
|
||||
type RawOrganizationUser = InferSelectModel<typeof usersToOrganizations>;
|
||||
type RawUser = InferSelectModel<typeof users>;
|
||||
|
||||
// Input schema for type safety
|
||||
const GetUserToOrganizationInputSchema = z.object({
|
||||
userId: z.string().uuid('User ID must be a valid UUID'),
|
||||
|
@ -17,74 +20,52 @@ const GetUserToOrganizationInputSchema = z.object({
|
|||
|
||||
export type GetUserToOrganizationInput = z.infer<typeof GetUserToOrganizationInputSchema>;
|
||||
|
||||
// Output schema for type safety
|
||||
export const UserOutputSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
name: z.string().nullable(),
|
||||
email: z.string(),
|
||||
avatarUrl: z.string().nullable(),
|
||||
role: z.string(),
|
||||
status: z.string(),
|
||||
});
|
||||
|
||||
export type UserWithRole = z.infer<typeof UserOutputSchema>;
|
||||
export type OrganizationUser = Pick<RawUser, 'id' | 'name' | 'email' | 'avatarUrl'> &
|
||||
Pick<RawOrganizationUser, 'role' | 'status'>;
|
||||
|
||||
export const getUserToOrganization = async ({
|
||||
userId,
|
||||
filters,
|
||||
}: GetUserToOrganizationInput): Promise<UserWithRole[]> => {
|
||||
}: GetUserToOrganizationInput): Promise<OrganizationUser[]> => {
|
||||
// Validate input
|
||||
const validated = GetUserToOrganizationInputSchema.parse({ userId, filters });
|
||||
|
||||
try {
|
||||
// First, get the user's organization ID using the existing function
|
||||
const userOrg = await getUserOrganizationId(validated.userId);
|
||||
|
||||
if (!userOrg) {
|
||||
throw new Error('User not found in any organization');
|
||||
}
|
||||
|
||||
const organizationId = userOrg.organizationId;
|
||||
|
||||
// Build the where conditions for the join
|
||||
const joinConditions = and(
|
||||
eq(users.id, usersToOrganizations.userId),
|
||||
eq(usersToOrganizations.organizationId, organizationId),
|
||||
isNull(usersToOrganizations.deletedAt)
|
||||
);
|
||||
|
||||
// Build the where conditions for filtering
|
||||
const conditions = [];
|
||||
if (validated.filters?.userName) {
|
||||
conditions.push(like(users.name, `%${validated.filters.userName}%`));
|
||||
}
|
||||
if (validated.filters?.email) {
|
||||
conditions.push(like(users.email, `%${validated.filters.email}%`));
|
||||
}
|
||||
|
||||
const baseQuery = db
|
||||
.select({
|
||||
id: users.id,
|
||||
name: users.name,
|
||||
email: users.email,
|
||||
avatarUrl: users.avatarUrl,
|
||||
role: usersToOrganizations.role,
|
||||
status: usersToOrganizations.status,
|
||||
})
|
||||
.from(users)
|
||||
.innerJoin(usersToOrganizations, joinConditions);
|
||||
|
||||
const results =
|
||||
conditions.length > 0
|
||||
? await baseQuery.where(conditions.length === 1 ? conditions[0] : and(...conditions))
|
||||
: await baseQuery;
|
||||
|
||||
// Validate and return results
|
||||
return results.map((user) => UserOutputSchema.parse(user));
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
throw new Error(`Invalid input: ${error.errors.map((e) => e.message).join(', ')}`);
|
||||
}
|
||||
throw error;
|
||||
// Get the user's organization ID
|
||||
const userOrg = await getUserOrganizationId(validated.userId);
|
||||
if (!userOrg) {
|
||||
throw new Error('User not found in any organization');
|
||||
}
|
||||
|
||||
// Build filter conditions
|
||||
const filterConditions = [];
|
||||
if (validated.filters?.userName) {
|
||||
filterConditions.push(like(users.name, `%${validated.filters.userName}%`));
|
||||
}
|
||||
if (validated.filters?.email) {
|
||||
filterConditions.push(like(users.email, `%${validated.filters.email}%`));
|
||||
}
|
||||
|
||||
// Build the complete where condition
|
||||
const whereCondition = and(
|
||||
eq(usersToOrganizations.organizationId, userOrg.organizationId),
|
||||
isNull(usersToOrganizations.deletedAt),
|
||||
...filterConditions
|
||||
);
|
||||
|
||||
// Execute the query
|
||||
const results = await db
|
||||
.select({
|
||||
id: users.id,
|
||||
name: users.name,
|
||||
email: users.email,
|
||||
avatarUrl: users.avatarUrl,
|
||||
role: usersToOrganizations.role,
|
||||
status: usersToOrganizations.status,
|
||||
})
|
||||
.from(users)
|
||||
.innerJoin(usersToOrganizations, eq(users.id, usersToOrganizations.userId))
|
||||
.where(whereCondition);
|
||||
|
||||
// Validate and return results
|
||||
return results;
|
||||
};
|
||||
|
|
|
@ -759,6 +759,9 @@ importers:
|
|||
drizzle-orm:
|
||||
specifier: 'catalog:'
|
||||
version: 0.44.2(@opentelemetry/api@1.9.0)(@types/pg@8.15.4)(mysql2@3.14.1)(pg@8.16.3)(postgres@3.4.7)
|
||||
drizzle-zod:
|
||||
specifier: ^0.8.2
|
||||
version: 0.8.2(drizzle-orm@0.44.2(@opentelemetry/api@1.9.0)(@types/pg@8.15.4)(mysql2@3.14.1)(pg@8.16.3)(postgres@3.4.7))(zod@3.25.1)
|
||||
postgres:
|
||||
specifier: ^3.4.7
|
||||
version: 3.4.7
|
||||
|
@ -5944,6 +5947,7 @@ packages:
|
|||
|
||||
bun@1.2.18:
|
||||
resolution: {integrity: sha512-OR+EpNckoJN4tHMVZPaTPxDj2RgpJgJwLruTIFYbO3bQMguLd0YrmkWKYqsiihcLgm2ehIjF/H1RLfZiRa7+qQ==}
|
||||
cpu: [arm64, x64, aarch64]
|
||||
os: [darwin, linux, win32]
|
||||
hasBin: true
|
||||
|
||||
|
@ -6723,6 +6727,12 @@ packages:
|
|||
sqlite3:
|
||||
optional: true
|
||||
|
||||
drizzle-zod@0.8.2:
|
||||
resolution: {integrity: sha512-9Do/16OjFFNrQDZgvMtxtDDwKWbFOxUAIwNPKX98SfxrP8H18vhN1BvNXbhelLcdgCE7GEaXDJqBjMExSkhpkA==}
|
||||
peerDependencies:
|
||||
drizzle-orm: '>=0.36.0'
|
||||
zod: ^3.25.1
|
||||
|
||||
dt-sql-parser@4.3.1:
|
||||
resolution: {integrity: sha512-WlFB9of+ChwWtc5M222jHGIpzqHx51szLe/11GAwwbA+4hRaVkMpWMf2bbYj4i855edSoTQ52zyLJVOpe+4OVg==}
|
||||
engines: {node: '>=18'}
|
||||
|
@ -18481,6 +18491,11 @@ snapshots:
|
|||
pg: 8.16.3
|
||||
postgres: 3.4.7
|
||||
|
||||
drizzle-zod@0.8.2(drizzle-orm@0.44.2(@opentelemetry/api@1.9.0)(@types/pg@8.15.4)(mysql2@3.14.1)(pg@8.16.3)(postgres@3.4.7))(zod@3.25.1):
|
||||
dependencies:
|
||||
drizzle-orm: 0.44.2(@opentelemetry/api@1.9.0)(@types/pg@8.15.4)(mysql2@3.14.1)(pg@8.16.3)(postgres@3.4.7)
|
||||
zod: 3.25.1
|
||||
|
||||
dt-sql-parser@4.3.1(antlr4ng-cli@1.0.7):
|
||||
dependencies:
|
||||
antlr4-c3: 3.3.7(antlr4ng-cli@1.0.7)
|
||||
|
|
Loading…
Reference in New Issue