Skip to content

Commit 2b3106d

Browse files
committed
Handle merge issues
1 parent 725135f commit 2b3106d

File tree

2 files changed

+58
-10
lines changed

2 files changed

+58
-10
lines changed

core/lib/authentication/actions.ts

+19-10
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@ import { captureException } from "@sentry/nextjs";
66
import * as Sentry from "@sentry/nextjs";
77
import { z } from "zod";
88

9-
import type { Communities, CommunitiesId, CommunityMemberships, Users, UsersId } from "db/public";
9+
import type {
10+
Communities,
11+
CommunitiesId,
12+
CommunityMemberships,
13+
FormsId,
14+
Users,
15+
UsersId,
16+
} from "db/public";
1017
import { AuthTokenType, MemberRole } from "db/public";
1118
import { logger } from "logger";
1219

13-
import type { Prettify, XOR } from "../types";
14-
import type { SafeUser } from "~/lib/server/user";
20+
import type { Prettify } from "../types";
1521
import { compiledSignupFormSchema } from "~/app/components/Signup/schema";
1622
import { db } from "~/kysely/database";
1723
import { isUniqueConstraintError } from "~/kysely/errors";
@@ -29,9 +35,8 @@ import {
2935
import { LAST_VISITED_COOKIE } from "../../app/components/LastVisitedCommunity/constants";
3036
import { findCommunityBySlug } from "../server/community";
3137
import * as Email from "../server/email";
32-
import { insertCommunityMember, selectCommunityMember } from "../server/member";
38+
import { insertCommunityMemberships, selectCommunityMemberships } from "../server/member";
3339
import { invalidateTokensForUser } from "../server/token";
34-
import { isClientExceptionOptions } from "../serverActions";
3540
import { SignupErrors } from "./errors";
3641
import { getLoginData } from "./loginData";
3742

@@ -214,22 +219,24 @@ const addUserToCommunity = defineServerAction(async function addUserToCommunity(
214219
* @default MemberRole.contributor
215220
*/
216221
role?: MemberRole;
222+
forms: FormsId[];
217223
}) {
218-
const existingMembership = await selectCommunityMember({
224+
const existingMemberships = await selectCommunityMemberships({
219225
userId: props.userId,
220226
communityId: props.communityId,
221227
}).executeTakeFirst();
222228

223-
if (existingMembership) {
229+
if (existingMemberships) {
224230
return {
225231
error: "User already in community",
226232
};
227233
}
228234

229-
const newMembership = await insertCommunityMember({
235+
const newMembership = await insertCommunityMemberships({
230236
userId: props.userId,
231237
communityId: props.communityId,
232238
role: props.role ?? MemberRole.contributor,
239+
forms: props.forms,
233240
}).executeTakeFirstOrThrow();
234241

235242
return {
@@ -268,10 +275,11 @@ export const publicJoinCommunity = defineServerAction(async function joinCommuni
268275
return SignupErrors.NOT_ALLOWED({ communityName: community.name });
269276
}
270277

271-
const member = await insertCommunityMember({
278+
const member = await insertCommunityMemberships({
272279
userId: user.id,
273280
communityId: community.id,
274281
role: toBeGrantedRole,
282+
forms: [], // TODO: fetch these from invite token as well maybe?
275283
}).executeTakeFirstOrThrow();
276284

277285
// don't redirect, better to do it client side, better ux
@@ -349,11 +357,12 @@ export const publicSignup = defineServerAction(async function signup(props: {
349357
});
350358

351359
// TODO: add to community
352-
const newMember = await insertCommunityMember(
360+
const newMember = await insertCommunityMemberships(
353361
{
354362
userId: newUser.id,
355363
communityId: community.id,
356364
role: props.role ?? MemberRole.contributor,
365+
forms: [], //TODO: make these customizable
357366
},
358367
trx
359368
).executeTakeFirstOrThrow();

core/lib/server/member.ts

+39
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { jsonObjectFrom } from "kysely/helpers/postgres";
22

33
import type {
44
CommunitiesId,
5+
CommunityMembershipsId,
56
FormsId,
67
MemberRole,
78
NewCommunityMemberships,
@@ -10,11 +11,49 @@ import type {
1011
UsersId,
1112
} from "db/public";
1213

14+
import type { XOR } from "../types";
1315
import { db } from "~/kysely/database";
1416
import { autoCache } from "./cache/autoCache";
1517
import { autoRevalidate } from "./cache/autoRevalidate";
1618
import { SAFE_USER_SELECT } from "./user";
1719

20+
/**
21+
* Either get a membership by its community membership id, or all memberships by userId and communityId
22+
* TODO: this should probably return a user with the community memberships attached
23+
*/
24+
export const selectCommunityMemberships = (
25+
props: XOR<{ id: CommunityMembershipsId }, { userId: UsersId; communityId: CommunitiesId }>,
26+
trx = db
27+
) => {
28+
return autoCache(
29+
trx
30+
.selectFrom("community_memberships")
31+
.select((eb) => [
32+
"community_memberships.id",
33+
"community_memberships.userId",
34+
"community_memberships.createdAt",
35+
"community_memberships.updatedAt",
36+
"community_memberships.role",
37+
"community_memberships.communityId",
38+
jsonObjectFrom(
39+
eb
40+
.selectFrom("users")
41+
.select(SAFE_USER_SELECT)
42+
.whereRef("users.id", "=", "community_memberships.userId")
43+
)
44+
.$notNull()
45+
.as("user"),
46+
])
47+
.$if(Boolean(props.userId), (eb) =>
48+
eb.where("community_memberships.userId", "=", props.userId!)
49+
)
50+
.$if(Boolean(props.communityId), (eb) =>
51+
eb.where("community_memberships.communityId", "=", props.communityId!)
52+
)
53+
.$if(Boolean(props.id), (eb) => eb.where("community_memberships.id", "=", props.id!))
54+
);
55+
};
56+
1857
export const selectAllCommunityMemberships = (
1958
{ communityId }: { communityId: CommunitiesId },
2059
trx = db

0 commit comments

Comments
 (0)