From 371f31c3bbbdc64ba5617785ae232911ce756a73 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Fri, 26 Jun 2026 13:44:01 -0400 Subject: [PATCH 01/19] Folder structure changes for shared files in Sign up and User Profile --- js/src/features/{sign-up => }/api/schemas.ts | 2 +- .../sign-up/components/SignUpForm.tsx | 34 +++++++++---------- .../sign-up/components/signUpFormConfig.ts | 8 ----- js/src/features/{sign-up => }/types.ts | 2 +- .../user-profile/UserProfile.page.tsx | 0 5 files changed, 19 insertions(+), 27 deletions(-) rename js/src/features/{sign-up => }/api/schemas.ts (96%) rename js/src/features/{sign-up => }/types.ts (85%) create mode 100644 js/src/features/user-profile/UserProfile.page.tsx diff --git a/js/src/features/sign-up/api/schemas.ts b/js/src/features/api/schemas.ts similarity index 96% rename from js/src/features/sign-up/api/schemas.ts rename to js/src/features/api/schemas.ts index b0eb526..b7ee25d 100644 --- a/js/src/features/sign-up/api/schemas.ts +++ b/js/src/features/api/schemas.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -export const signUpFormSchema = z.object({ +export const userProfileSchema = z.object({ fullName: z.string().min(1, "Full Name is required."), email: z .string() diff --git a/js/src/features/sign-up/components/SignUpForm.tsx b/js/src/features/sign-up/components/SignUpForm.tsx index 958ce5c..769400c 100644 --- a/js/src/features/sign-up/components/SignUpForm.tsx +++ b/js/src/features/sign-up/components/SignUpForm.tsx @@ -1,9 +1,9 @@ -import { signUpFormSchema } from "@/features/sign-up/api/schemas"; +import { userProfileSchema } from "@/features/api/schemas"; import { INDUSTRIES, MATCHING_PREFERENCES, } from "@/features/sign-up/components/signUpFormConfig"; -import { SignUpFormValues } from "@/features/sign-up/types"; +import { UserProfileValues } from "@/features/types"; import { Alert, Button, @@ -27,7 +27,7 @@ const matchingPreferenceOptions = MATCHING_PREFERENCES.map((v) => ({ const industryOptions = INDUSTRIES.map((v) => ({ value: v, label: v })); // Define initial values -const initialFormValues: SignUpFormValues = { +const initialFormValues: UserProfileValues = { fullName: "", email: "", linkedin: "", @@ -42,12 +42,12 @@ const initialFormValues: SignUpFormValues = { export function SignUpForm() { // State management - const [values, setValues] = useState(() => ({ + const [values, setValues] = useState(() => ({ ...initialFormValues, })); const [errors, setErrors] = useState< - Partial> + Partial> >({}); const [isSubmitting, setIsSubmitting] = useState(false); @@ -65,9 +65,9 @@ export function SignUpForm() { }; // Handlers - const handleFieldChange = ( + const handleFieldChange = ( field: K, - value: SignUpFormValues[K], + value: UserProfileValues[K], ) => { setValues((current) => ({ ...current, [field]: value })); setErrors((current) => ({ ...current, [field]: undefined })); @@ -76,11 +76,11 @@ export function SignUpForm() { }; const handleFieldBlur = ( - field: keyof SignUpFormValues, + field: keyof UserProfileValues, overrideValue?: string, ) => { const valueToValidate = overrideValue ?? values[field]; - const fieldSchema = signUpFormSchema.pick({ [field]: true } as Record< + const fieldSchema = userProfileSchema.pick({ [field]: true } as Record< typeof field, true >); @@ -92,15 +92,15 @@ export function SignUpForm() { }; // Validation logic - const validateForm = (values: SignUpFormValues) => { - const result = signUpFormSchema.safeParse(values); + const validateForm = (values: UserProfileValues) => { + const result = userProfileSchema.safeParse(values); const fieldErrors = result.success ? {} : result.error?.flatten().fieldErrors; - const errors = {} as Partial>; + const errors = {} as Partial>; for (const key in fieldErrors) { - if (fieldErrors[key as keyof SignUpFormValues]?.[0]) { - errors[key as keyof SignUpFormValues] = - fieldErrors[key as keyof SignUpFormValues]?.[0]; + if (fieldErrors[key as keyof UserProfileValues]?.[0]) { + errors[key as keyof UserProfileValues] = + fieldErrors[key as keyof UserProfileValues]?.[0]; } } return errors; @@ -211,7 +211,7 @@ export function SignUpForm() { onChange={(value) => handleFieldChange( "matchingPreference", - (value || "") as SignUpFormValues["matchingPreference"], + (value || "") as UserProfileValues["matchingPreference"], ) } onBlur={() => handleFieldBlur("matchingPreference")} @@ -225,7 +225,7 @@ export function SignUpForm() { onChange={(value) => handleFieldChange( "industry", - (value || "") as SignUpFormValues["industry"], + (value || "") as UserProfileValues["industry"], ) } onBlur={() => handleFieldBlur("industry")} diff --git a/js/src/features/sign-up/components/signUpFormConfig.ts b/js/src/features/sign-up/components/signUpFormConfig.ts index 5a97228..9ae4139 100644 --- a/js/src/features/sign-up/components/signUpFormConfig.ts +++ b/js/src/features/sign-up/components/signUpFormConfig.ts @@ -5,14 +5,6 @@ export const MATCHING_PREFERENCES = [ "No Preference - I am open to any type of match", ] as const; -export const TALKING_POINTS = [ - "Career journey", - "Advice", - "Current events", - "Hobbies", - "Other", -] as const; - export const INDUSTRIES = [ "Technology", "Finance", diff --git a/js/src/features/sign-up/types.ts b/js/src/features/types.ts similarity index 85% rename from js/src/features/sign-up/types.ts rename to js/src/features/types.ts index c1a08e4..1268fc3 100644 --- a/js/src/features/sign-up/types.ts +++ b/js/src/features/types.ts @@ -1,4 +1,4 @@ -export interface SignUpFormValues { +export interface UserProfileValues { fullName: string; email: string; linkedin: string; diff --git a/js/src/features/user-profile/UserProfile.page.tsx b/js/src/features/user-profile/UserProfile.page.tsx new file mode 100644 index 0000000..e69de29 From 05d4e644a85c5b5ba548dd109c072bb3cad3b2d1 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Fri, 26 Jun 2026 14:18:54 -0400 Subject: [PATCH 02/19] Folder structure changes for User Profile / Sign up form shared files --- js/src/features/sign-up/components/SignUpForm.tsx | 4 ++-- js/src/features/{ => user-profile}/api/schemas.ts | 0 js/src/features/{ => user-profile}/types.ts | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename js/src/features/{ => user-profile}/api/schemas.ts (100%) rename js/src/features/{ => user-profile}/types.ts (100%) diff --git a/js/src/features/sign-up/components/SignUpForm.tsx b/js/src/features/sign-up/components/SignUpForm.tsx index 769400c..2a90e52 100644 --- a/js/src/features/sign-up/components/SignUpForm.tsx +++ b/js/src/features/sign-up/components/SignUpForm.tsx @@ -1,9 +1,9 @@ -import { userProfileSchema } from "@/features/api/schemas"; import { INDUSTRIES, MATCHING_PREFERENCES, } from "@/features/sign-up/components/signUpFormConfig"; -import { UserProfileValues } from "@/features/types"; +import { userProfileSchema } from "@/features/user-profile/api/schemas"; +import { UserProfileValues } from "@/features/user-profile/types"; import { Alert, Button, diff --git a/js/src/features/api/schemas.ts b/js/src/features/user-profile/api/schemas.ts similarity index 100% rename from js/src/features/api/schemas.ts rename to js/src/features/user-profile/api/schemas.ts diff --git a/js/src/features/types.ts b/js/src/features/user-profile/types.ts similarity index 100% rename from js/src/features/types.ts rename to js/src/features/user-profile/types.ts From 548c654bab13572c3c2a5917e02cfbb4f57db092 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Fri, 26 Jun 2026 16:10:01 -0400 Subject: [PATCH 03/19] Added content to UserProfile.page --- js/src/features/user-profile/UserProfile.page.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/js/src/features/user-profile/UserProfile.page.tsx b/js/src/features/user-profile/UserProfile.page.tsx index e69de29..dc5a411 100644 --- a/js/src/features/user-profile/UserProfile.page.tsx +++ b/js/src/features/user-profile/UserProfile.page.tsx @@ -0,0 +1,9 @@ +import { Stack, Title } from "@mantine/core"; + +export function UserProfilePage() { + return ( + + User Profile + + ); +} From dfcda10a9bdfc3afd718a23df89b7e2e1aeae0c6 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 29 Jun 2026 13:34:29 -0400 Subject: [PATCH 04/19] Folder structure for members backend --- .../patchats/api/member/MemberController.java | 1 + .../patchats/api/member/MemberService.java | 1 + .../common/db/models/member/Member.java | 96 +++++++++++++++++++ .../common/db/repos/member/MemberRepo.java | 1 + .../patchats/common/dto/member/MemberDto.java | 1 + 5 files changed, 100 insertions(+) create mode 100644 src/main/java/org/patinanetwork/patchats/api/member/MemberController.java create mode 100644 src/main/java/org/patinanetwork/patchats/api/member/MemberService.java create mode 100644 src/main/java/org/patinanetwork/patchats/common/db/models/member/Member.java create mode 100644 src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java create mode 100644 src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java diff --git a/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java b/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java @@ -0,0 +1 @@ + diff --git a/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java b/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java @@ -0,0 +1 @@ + diff --git a/src/main/java/org/patinanetwork/patchats/common/db/models/member/Member.java b/src/main/java/org/patinanetwork/patchats/common/db/models/member/Member.java new file mode 100644 index 0000000..6f6627b --- /dev/null +++ b/src/main/java/org/patinanetwork/patchats/common/db/models/member/Member.java @@ -0,0 +1,96 @@ +package org.patinanetwork.codebloom.common.db.models.member; + +import java.util.ArrayList; +import java.util.List; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.SuperBuilder; +import org.patinanetwork.codebloom.common.db.helper.annotations.JoinColumn; +import org.patinanetwork.codebloom.common.db.helper.annotations.NotNullColumn; +import org.patinanetwork.codebloom.common.db.helper.annotations.NullColumn; +import org.patinanetwork.codebloom.common.db.models.achievements.Achievement; +import org.patinanetwork.codebloom.common.db.models.usertag.UserTag; + +@Getter +@Setter +@SuperBuilder +@ToString +@EqualsAndHashCode +public class Member { + + @NotNullColumn + private java.util.UUID id; + + @NotNullColumn + private String fullName; + + @NotNullColumn + private String email; + + @NullColumn + private String linkedInUrl; + + @NotNullColumn + private String introduction; + + @NullColumn + private String referralSource; + + @NotNullColumn + private boolean active; + + @NullColumn + private String matchPref; + + @NullColumn + private String industryPref; + + @NullColumn + private String rolePref; + + @NullColumn + private String topics; + + @NullColumn + private String extraNotes; + + @NotNullColumn + private String createdAt; + + @NotNullColumn + private String updatedAt; + /** + * If you want to update tags in the database, you have to use the + * {@link org.patinanetwork.codebloom.common.db.repos.usertag.UserTagRepository} + */ + @JoinColumn + @Builder.Default + private List tags = new ArrayList<>(); + + /** + * If you want to update achievements in the database, you have to use the + * {@link org.patinanetwork.codebloom.common.db.repos.achievements.AchievementRepository} + */ + @JoinColumn + @Builder.Default + private List achievements = new ArrayList<>(); + + /** + * This operation is permitted, but the tag will not be used in update operations in the UserRepository. Instead + * call this method with the parameter being the add method from + * {@link org.patinanetwork.codebloom.common.db.repos.usertag.UserTagRepository} + * + *

Essentially, this operation should be used to keep the User model up-to-date with any Tag operations without + * needlessly querying the database for the full User object. + */ + public void addTag(final UserTag tag) { + if (tag == null) { + return; + } + + tags.add(tag); + } +} diff --git a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java @@ -0,0 +1 @@ + diff --git a/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java b/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java @@ -0,0 +1 @@ + From 5abe3c3d71dbc6f37e0f1a272b841fbbb10d5a4a Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 29 Jun 2026 13:55:51 -0400 Subject: [PATCH 05/19] Member.java done --- .../common/db/models/member/Member.java | 72 ++++--------------- 1 file changed, 15 insertions(+), 57 deletions(-) diff --git a/src/main/java/org/patinanetwork/patchats/common/db/models/member/Member.java b/src/main/java/org/patinanetwork/patchats/common/db/models/member/Member.java index 6f6627b..432b52b 100644 --- a/src/main/java/org/patinanetwork/patchats/common/db/models/member/Member.java +++ b/src/main/java/org/patinanetwork/patchats/common/db/models/member/Member.java @@ -1,96 +1,54 @@ -package org.patinanetwork.codebloom.common.db.models.member; +package org.patinanetwork.patchats.common.db.models.member; -import java.util.ArrayList; -import java.util.List; +import java.util.UUID; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; -import lombok.experimental.SuperBuilder; -import org.patinanetwork.codebloom.common.db.helper.annotations.JoinColumn; -import org.patinanetwork.codebloom.common.db.helper.annotations.NotNullColumn; -import org.patinanetwork.codebloom.common.db.helper.annotations.NullColumn; -import org.patinanetwork.codebloom.common.db.models.achievements.Achievement; -import org.patinanetwork.codebloom.common.db.models.usertag.UserTag; @Getter -@Setter -@SuperBuilder +@Builder @ToString @EqualsAndHashCode public class Member { - @NotNullColumn - private java.util.UUID id; + private UUID id; - @NotNullColumn + @Setter private String fullName; - @NotNullColumn + @Setter private String email; - @NullColumn + @Setter private String linkedInUrl; - @NotNullColumn + @Setter private String introduction; - @NullColumn + @Setter private String referralSource; - @NotNullColumn + @Setter private boolean active; - @NullColumn + @Setter private String matchPref; - @NullColumn + @Setter private String industryPref; - @NullColumn + @Setter private String rolePref; - @NullColumn + @Setter private String topics; - @NullColumn + @Setter private String extraNotes; - @NotNullColumn private String createdAt; - @NotNullColumn private String updatedAt; - /** - * If you want to update tags in the database, you have to use the - * {@link org.patinanetwork.codebloom.common.db.repos.usertag.UserTagRepository} - */ - @JoinColumn - @Builder.Default - private List tags = new ArrayList<>(); - - /** - * If you want to update achievements in the database, you have to use the - * {@link org.patinanetwork.codebloom.common.db.repos.achievements.AchievementRepository} - */ - @JoinColumn - @Builder.Default - private List achievements = new ArrayList<>(); - - /** - * This operation is permitted, but the tag will not be used in update operations in the UserRepository. Instead - * call this method with the parameter being the add method from - * {@link org.patinanetwork.codebloom.common.db.repos.usertag.UserTagRepository} - * - *

Essentially, this operation should be used to keep the User model up-to-date with any Tag operations without - * needlessly querying the database for the full User object. - */ - public void addTag(final UserTag tag) { - if (tag == null) { - return; - } - - tags.add(tag); - } } From 6dcf71b7939bddeb6d4bfba4c06f890da5cf7ae1 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 29 Jun 2026 14:29:52 -0400 Subject: [PATCH 06/19] Updated field named in members db, MemberRepo.java done --- db/migration/V0001__Create_members_table.sql | 8 ++-- .../common/db/repos/member/MemberRepo.java | 45 +++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/db/migration/V0001__Create_members_table.sql b/db/migration/V0001__Create_members_table.sql index a69ad4e..3f017c4 100644 --- a/db/migration/V0001__Create_members_table.sql +++ b/db/migration/V0001__Create_members_table.sql @@ -2,13 +2,13 @@ CREATE TABLE IF NOT EXISTS "members" ( id UUID PRIMARY KEY, full_name TEXT NOT NULL, email TEXT UNIQUE NOT NULL, - linked_url TEXT, - bio TEXT, + linked_in_url TEXT, + introduction TEXT NOT NULL, referral_source TEXT, active BOOLEAN, match_pref TEXT, - industry TEXT, - role TEXT, + industry_pref TEXT, + role_pref TEXT, topics TEXT, extra_notes TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), diff --git a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java index 8b13789..7b0a4bb 100644 --- a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java +++ b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java @@ -1 +1,46 @@ +package org.patinanetwork.patchats.common.db.repos.member; +import java.util.Optional; +import java.util.UUID; +import org.patinanetwork.patchats.common.db.models.member.Member; + +public interface MemberRepo { + /** + * @note - The provided object's methods will be overridden with any returned data from the database. + * @param member - required fields: + *

    + *
  • id + *
  • fullName + *
  • email + *
  • introduction + *
  • createdAt + *
  • updatedAt + *
+ */ + Member createMember(Member member); + + /** + * @note - The provided object's methods will be overridden with any returned data from the database. + * @param member - overridden fields: + *
    + *
  • fullName + *
  • email + *
  • linkedInUrl + *
  • introduction + *
  • referralSource + *
  • active + *
  • matchPref + *
  • industryPref + *
  • rolePref + *
  • topics + *
  • extraNotes + *
+ */ + boolean editMember(Member member); + + Optional getMemberById(UUID id); + + Optional getMemberByEmail(String email); + + boolean deleteMemberById(UUID id); +} From 3f518c9a84290fd5c42edc350ba272d67ff9d3c4 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 29 Jun 2026 15:02:47 -0400 Subject: [PATCH 07/19] Active updated to required, MemberDto.java done --- db/migration/V0001__Create_members_table.sql | 2 +- .../common/db/repos/member/MemberRepo.java | 1 + .../patchats/common/dto/member/MemberDto.java | 76 +++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/db/migration/V0001__Create_members_table.sql b/db/migration/V0001__Create_members_table.sql index 3f017c4..f006d33 100644 --- a/db/migration/V0001__Create_members_table.sql +++ b/db/migration/V0001__Create_members_table.sql @@ -5,7 +5,7 @@ CREATE TABLE IF NOT EXISTS "members" ( linked_in_url TEXT, introduction TEXT NOT NULL, referral_source TEXT, - active BOOLEAN, + active BOOLEAN NOT NULL DEFAULT TRUE, match_pref TEXT, industry_pref TEXT, role_pref TEXT, diff --git a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java index 7b0a4bb..a3dd729 100644 --- a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java +++ b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java @@ -13,6 +13,7 @@ public interface MemberRepo { *
  • fullName *
  • email *
  • introduction + *
  • active *
  • createdAt *
  • updatedAt * diff --git a/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java b/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java index 8b13789..2992132 100644 --- a/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java +++ b/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java @@ -1 +1,77 @@ +package org.patinanetwork.patchats.common.dto.member; +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.UUID; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import org.patinanetwork.patchats.common.db.models.member.Member; + +@Getter +@Builder +@ToString +@EqualsAndHashCode +public class MemberDto { + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private UUID id; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String fullName; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String email; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED, nullable = true) + private String linkedInUrl; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String introduction; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED, nullable = true) + private String referralSource; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private boolean active; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED, nullable = true) + private String matchPref; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED, nullable = true) + private String industryPref; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED, nullable = true) + private String rolePref; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED, nullable = true) + private String topics; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED, nullable = true) + private String extraNotes; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String createdAt; + + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) + private String updatedAt; + + public static MemberDto from(final Member member) { + return MemberDto.builder() + .id(member.getId()) + .fullName(member.getFullName()) + .email(member.getEmail()) + .linkedInUrl(member.getLinkedInUrl()) + .introduction(member.getIntroduction()) + .referralSource(member.getReferralSource()) + .active(member.isActive()) + .matchPref(member.getMatchPref()) + .industryPref(member.getIndustryPref()) + .rolePref(member.getRolePref()) + .topics(member.getTopics()) + .extraNotes(member.getExtraNotes()) + .createdAt(member.getCreatedAt()) + .updatedAt(member.getUpdatedAt()) + .build(); + } +} From 1dddd3a4a5de5c564122cda5a4c866ea95738e1c Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 29 Jun 2026 17:44:06 -0400 Subject: [PATCH 08/19] MemberService.java, modified return types in MemberRepo.java --- .../patchats/api/member/MemberService.java | 48 +++++++++++++++++++ .../common/db/repos/member/MemberRepo.java | 4 +- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java b/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java index 8b13789..5eca217 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java @@ -1 +1,49 @@ +package org.patinanetwork.patchats.api.member; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.patinanetwork.patchats.common.db.models.member.Member; +import org.patinanetwork.patchats.common.db.repos.member.MemberRepo; +import org.patinanetwork.patchats.common.dto.member.MemberDto; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +@Service +@RequiredArgsConstructor +public class MemberService { + + private final MemberRepo memberRepo; + + public MemberDto createMember(Member member) { + if (memberRepo.getMemberByEmail(member.getEmail()).isPresent()) { + throw new ResponseStatusException( + HttpStatus.CONFLICT, "Member with email " + member.getEmail() + " already exists"); + } + member.setId(UUID.randomUUID()); + member.setActive(true); + Member createdMember = memberRepo.createMember(member); + return MemberDto.from(createdMember); + } + + public MemberDto editMember(Member member) { + return memberRepo + .editMember(member) + .map(MemberDto::from) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Member not found")); + } + + public MemberDto getMemberById(UUID id) { + return memberRepo + .getMemberById(id) + .map(MemberDto::from) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Member not found")); + } + + public MemberDto deactivateMemberById(UUID id) { + return memberRepo + .deactivateMemberById(id) + .map(MemberDto::from) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Member not found")); + } +} diff --git a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java index a3dd729..a9f4831 100644 --- a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java +++ b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java @@ -37,11 +37,11 @@ public interface MemberRepo { *
  • extraNotes * */ - boolean editMember(Member member); + Optional editMember(Member member); Optional getMemberById(UUID id); Optional getMemberByEmail(String email); - boolean deleteMemberById(UUID id); + Optional deactivateMemberById(UUID id); } From 164cbcda003f6ba5694d8fac4284d06c79d5be41 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 6 Jul 2026 14:40:14 -0400 Subject: [PATCH 09/19] added dto records CreateMemberRequest and UpdateMemberRequest. Updated MemberService to convert requests into members for createMember and updateMember. --- .../patchats/api/member/MemberService.java | 47 +++++++++++++++---- .../dto/member/CreateMemberRequest.java | 16 +++++++ .../dto/member/UpdateMemberRequest.java | 16 +++++++ 3 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/patinanetwork/patchats/common/dto/member/CreateMemberRequest.java create mode 100644 src/main/java/org/patinanetwork/patchats/common/dto/member/UpdateMemberRequest.java diff --git a/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java b/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java index 5eca217..5033723 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java @@ -4,7 +4,9 @@ import lombok.RequiredArgsConstructor; import org.patinanetwork.patchats.common.db.models.member.Member; import org.patinanetwork.patchats.common.db.repos.member.MemberRepo; +import org.patinanetwork.patchats.common.dto.member.CreateMemberRequest; import org.patinanetwork.patchats.common.dto.member.MemberDto; +import org.patinanetwork.patchats.common.dto.member.UpdateMemberRequest; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; @@ -15,22 +17,47 @@ public class MemberService { private final MemberRepo memberRepo; - public MemberDto createMember(Member member) { - if (memberRepo.getMemberByEmail(member.getEmail()).isPresent()) { + public MemberDto createMember(CreateMemberRequest request) { + if (memberRepo.getMemberByEmail(request.email()).isPresent()) { throw new ResponseStatusException( - HttpStatus.CONFLICT, "Member with email " + member.getEmail() + " already exists"); + HttpStatus.CONFLICT, "Member with email " + request.email() + " already exists"); } - member.setId(UUID.randomUUID()); - member.setActive(true); + Member member = Member.builder() + .id(UUID.randomUUID()) + .fullName(request.fullName()) + .email(request.email()) + .linkedInUrl(request.linkedInUrl()) + .introduction(request.introduction()) + .referralSource(request.referralSource()) + .active(true) + .matchPref(request.matchPref()) + .industryPref(request.industryPref()) + .rolePref(request.rolePref()) + .topics(request.topics()) + .extraNotes(request.extraNotes()) + .build(); Member createdMember = memberRepo.createMember(member); return MemberDto.from(createdMember); } - public MemberDto editMember(Member member) { - return memberRepo - .editMember(member) - .map(MemberDto::from) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Member not found")); + public MemberDto updateMember(UpdateMemberRequest request, UUID id) { + if (memberRepo.getMemberById(id).isEmpty()) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Member with ID " + id + " does not exist"); + } + Member member = Member.builder() + .id(id) + .fullName(request.fullName()) + .email(request.email()) + .linkedInUrl(request.linkedInUrl()) + .introduction(request.introduction()) + .matchPref(request.matchPref()) + .industryPref(request.industryPref()) + .rolePref(request.rolePref()) + .topics(request.topics()) + .extraNotes(request.extraNotes()) + .build(); + Member updatedMember = memberRepo.updateMember(member); + return MemberDto.from(updatedMember); } public MemberDto getMemberById(UUID id) { diff --git a/src/main/java/org/patinanetwork/patchats/common/dto/member/CreateMemberRequest.java b/src/main/java/org/patinanetwork/patchats/common/dto/member/CreateMemberRequest.java new file mode 100644 index 0000000..30fc669 --- /dev/null +++ b/src/main/java/org/patinanetwork/patchats/common/dto/member/CreateMemberRequest.java @@ -0,0 +1,16 @@ +package org.patinanetwork.patchats.common.dto.member; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; + +public record CreateMemberRequest( + @NotBlank String fullName, + @NotBlank @Email String email, + String linkedInUrl, + @NotBlank String introduction, + String referralSource, + String matchPref, + String industryPref, + String rolePref, + String topics, + String extraNotes) {} diff --git a/src/main/java/org/patinanetwork/patchats/common/dto/member/UpdateMemberRequest.java b/src/main/java/org/patinanetwork/patchats/common/dto/member/UpdateMemberRequest.java new file mode 100644 index 0000000..d1a91b2 --- /dev/null +++ b/src/main/java/org/patinanetwork/patchats/common/dto/member/UpdateMemberRequest.java @@ -0,0 +1,16 @@ +package org.patinanetwork.patchats.common.dto.member; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; + +public record UpdateMemberRequest( + @NotBlank String fullName, + // TODO: Changes to email require verification after authentication is implemented + @NotBlank @Email String email, + String linkedInUrl, + @NotBlank String introduction, + String matchPref, + String industryPref, + String rolePref, + String topics, + String extraNotes) {} From aa8023fb96408e1b9cc879ab4e1799772e03a421 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 6 Jul 2026 14:42:18 -0400 Subject: [PATCH 10/19] Naming convention editMember -> updateMember in MemberRepo. Created MemberSqlRepo for implementation --- .../patchats/common/db/repos/member/MemberRepo.java | 2 +- .../patchats/common/db/repos/member/MemberSqlRepo.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberSqlRepo.java diff --git a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java index a9f4831..1e45e31 100644 --- a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java +++ b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java @@ -37,7 +37,7 @@ public interface MemberRepo { *
  • extraNotes * */ - Optional editMember(Member member); + Optional updateMember(Member member); Optional getMemberById(UUID id); diff --git a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberSqlRepo.java b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberSqlRepo.java new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberSqlRepo.java @@ -0,0 +1 @@ + From b3a97867b02c7c974ff4c0db3419895ed91885d0 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 6 Jul 2026 14:48:17 -0400 Subject: [PATCH 11/19] Added MemberController --- .../patchats/api/member/MemberController.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java b/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java index 8b13789..d127377 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java @@ -1 +1,52 @@ +package org.patinanetwork.patchats.api.member; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.patinanetwork.patchats.common.dto.ApiResponder; +import org.patinanetwork.patchats.common.dto.member.CreateMemberRequest; +import org.patinanetwork.patchats.common.dto.member.MemberDto; +import org.patinanetwork.patchats.common.dto.member.UpdateMemberRequest; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/members") +@Tag(name = "Member") +@RequiredArgsConstructor +public class MemberController { + + private final MemberService memberService; + + @PostMapping + public ResponseEntity> createMember(@Valid @RequestBody final CreateMemberRequest request) { + final MemberDto response = memberService.createMember(request); + return ResponseEntity.ok(ApiResponder.success("Member created successfully", response)); + } + + @PatchMapping("/{id}") + public ResponseEntity> updateMember(@Valid @RequestBody final UpdateMemberRequest request) { + final MemberDto response = memberService.updateMember(request); + return ResponseEntity.ok(ApiResponder.success("Member updated successfully", response)); + } + + @GetMapping("/{id}") + public ResponseEntity> getMember(@PathVariable final UUID id) { + final MemberDto response = memberService.getMemberById(id); + return ResponseEntity.ok(ApiResponder.success("Member retrieved successfully", response)); + } + + @DeleteMapping("/{id}") + public ResponseEntity> deactivateMember(@PathVariable final UUID id) { + final MemberDto response = memberService.deactivateMemberById(id); + return ResponseEntity.ok(ApiResponder.success("Member deactivated successfully", response)); + } +} From db591a2c3fb7c6b1fbd717712ffcd6ba20535863 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 6 Jul 2026 14:50:37 -0400 Subject: [PATCH 12/19] Removed member fields not accessible by frontend from Mem berDto --- .../patchats/common/dto/member/MemberDto.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java b/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java index 2992132..52251c9 100644 --- a/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java +++ b/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java @@ -8,6 +8,7 @@ import lombok.ToString; import org.patinanetwork.patchats.common.db.models.member.Member; +// TODO: Separate AdminMemberDto and PublicMemberDto @Getter @Builder @ToString @@ -20,6 +21,7 @@ public class MemberDto { @Schema(requiredMode = Schema.RequiredMode.REQUIRED) private String fullName; + // TODO: Changes to email require verification after authentication is implemented @Schema(requiredMode = Schema.RequiredMode.REQUIRED) private String email; @@ -29,12 +31,6 @@ public class MemberDto { @Schema(requiredMode = Schema.RequiredMode.REQUIRED) private String introduction; - @Schema(requiredMode = Schema.RequiredMode.REQUIRED, nullable = true) - private String referralSource; - - @Schema(requiredMode = Schema.RequiredMode.REQUIRED) - private boolean active; - @Schema(requiredMode = Schema.RequiredMode.REQUIRED, nullable = true) private String matchPref; @@ -63,8 +59,6 @@ public static MemberDto from(final Member member) { .email(member.getEmail()) .linkedInUrl(member.getLinkedInUrl()) .introduction(member.getIntroduction()) - .referralSource(member.getReferralSource()) - .active(member.isActive()) .matchPref(member.getMatchPref()) .industryPref(member.getIndustryPref()) .rolePref(member.getRolePref()) From 8763c21a80d2e4f6c43185442510c7efb45c1d69 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 6 Jul 2026 15:54:51 -0400 Subject: [PATCH 13/19] MemberController - Added id as param in updateMember, MemberService - updatedMember throws error if member not found --- .../patinanetwork/patchats/api/member/MemberController.java | 5 +++-- .../org/patinanetwork/patchats/api/member/MemberService.java | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java b/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java index d127377..7cabf02 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java @@ -33,8 +33,9 @@ public ResponseEntity> createMember(@Valid @RequestBody } @PatchMapping("/{id}") - public ResponseEntity> updateMember(@Valid @RequestBody final UpdateMemberRequest request) { - final MemberDto response = memberService.updateMember(request); + public ResponseEntity> updateMember( + @Valid @RequestBody final UpdateMemberRequest request, @PathVariable final UUID id) { + final MemberDto response = memberService.updateMember(request, id); return ResponseEntity.ok(ApiResponder.success("Member updated successfully", response)); } diff --git a/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java b/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java index 5033723..2ec75d2 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java @@ -56,7 +56,9 @@ public MemberDto updateMember(UpdateMemberRequest request, UUID id) { .topics(request.topics()) .extraNotes(request.extraNotes()) .build(); - Member updatedMember = memberRepo.updateMember(member); + Member updatedMember = memberRepo + .updateMember(member) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Member not found")); return MemberDto.from(updatedMember); } From 68e821f7e3bd240a07060cd1ab440884ffd22ded Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Fri, 10 Jul 2026 14:22:32 -0400 Subject: [PATCH 14/19] Removed member files from common and moved to api/member --- .../{common/db/models/member => api/member/db/models}/Member.java | 0 .../db/repos/member => api/member/db/repos}/MemberRepo.java | 0 .../db/repos/member => api/member/db/repos}/MemberSqlRepo.java | 0 .../dto/member => api/member/dto}/CreateMemberRequest.java | 0 .../patchats/{common/dto/member => api/member/dto}/MemberDto.java | 0 .../dto/member => api/member/dto}/UpdateMemberRequest.java | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename src/main/java/org/patinanetwork/patchats/{common/db/models/member => api/member/db/models}/Member.java (100%) rename src/main/java/org/patinanetwork/patchats/{common/db/repos/member => api/member/db/repos}/MemberRepo.java (100%) rename src/main/java/org/patinanetwork/patchats/{common/db/repos/member => api/member/db/repos}/MemberSqlRepo.java (100%) rename src/main/java/org/patinanetwork/patchats/{common/dto/member => api/member/dto}/CreateMemberRequest.java (100%) rename src/main/java/org/patinanetwork/patchats/{common/dto/member => api/member/dto}/MemberDto.java (100%) rename src/main/java/org/patinanetwork/patchats/{common/dto/member => api/member/dto}/UpdateMemberRequest.java (100%) diff --git a/src/main/java/org/patinanetwork/patchats/common/db/models/member/Member.java b/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java similarity index 100% rename from src/main/java/org/patinanetwork/patchats/common/db/models/member/Member.java rename to src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java diff --git a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java b/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberRepo.java similarity index 100% rename from src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberRepo.java rename to src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberRepo.java diff --git a/src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberSqlRepo.java b/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java similarity index 100% rename from src/main/java/org/patinanetwork/patchats/common/db/repos/member/MemberSqlRepo.java rename to src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java diff --git a/src/main/java/org/patinanetwork/patchats/common/dto/member/CreateMemberRequest.java b/src/main/java/org/patinanetwork/patchats/api/member/dto/CreateMemberRequest.java similarity index 100% rename from src/main/java/org/patinanetwork/patchats/common/dto/member/CreateMemberRequest.java rename to src/main/java/org/patinanetwork/patchats/api/member/dto/CreateMemberRequest.java diff --git a/src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java b/src/main/java/org/patinanetwork/patchats/api/member/dto/MemberDto.java similarity index 100% rename from src/main/java/org/patinanetwork/patchats/common/dto/member/MemberDto.java rename to src/main/java/org/patinanetwork/patchats/api/member/dto/MemberDto.java diff --git a/src/main/java/org/patinanetwork/patchats/common/dto/member/UpdateMemberRequest.java b/src/main/java/org/patinanetwork/patchats/api/member/dto/UpdateMemberRequest.java similarity index 100% rename from src/main/java/org/patinanetwork/patchats/common/dto/member/UpdateMemberRequest.java rename to src/main/java/org/patinanetwork/patchats/api/member/dto/UpdateMemberRequest.java From 1444c48a8842abf4f5eb0c2c2a88cb02bedaec2a Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Fri, 10 Jul 2026 16:19:20 -0400 Subject: [PATCH 15/19] Updated imports due to folder structure change --- .../patchats/api/member/db/models/Member.java | 2 +- .../api/member/db/repos/MemberRepo.java | 4 +-- .../api/member/db/repos/MemberSqlRepo.java | 36 +++++++++++++++++++ .../api/member/dto/CreateMemberRequest.java | 2 +- .../patchats/api/member/dto/MemberDto.java | 4 +-- .../api/member/dto/UpdateMemberRequest.java | 2 +- 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java b/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java index 432b52b..a875a79 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java @@ -1,4 +1,4 @@ -package org.patinanetwork.patchats.common.db.models.member; +package org.patinanetwork.patchats.api.member.db.models; import java.util.UUID; import lombok.Builder; diff --git a/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberRepo.java b/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberRepo.java index 1e45e31..a37a108 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberRepo.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberRepo.java @@ -1,8 +1,8 @@ -package org.patinanetwork.patchats.common.db.repos.member; +package org.patinanetwork.patchats.api.member.db.repos; import java.util.Optional; import java.util.UUID; -import org.patinanetwork.patchats.common.db.models.member.Member; +import org.patinanetwork.patchats.api.member.db.models.Member; public interface MemberRepo { /** diff --git a/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java b/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java index 8b13789..673a9fc 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java @@ -1 +1,37 @@ +package org.patinanetwork.patchats.api.member.db.repos; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.patinanetwork.patchats.api.member.db.models.Member; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class MemberSqlRepo implements MemberRepo { + + @Override + public Member createMember(Member member) { + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public Optional updateMember(Member member) { + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public Optional getMemberById(UUID id) { + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public Optional getMemberByEmail(String email) { + throw new UnsupportedOperationException("Not implemented yet"); + } + + @Override + public Optional deactivateMemberById(UUID id) { + throw new UnsupportedOperationException("Not implemented yet"); + } +} diff --git a/src/main/java/org/patinanetwork/patchats/api/member/dto/CreateMemberRequest.java b/src/main/java/org/patinanetwork/patchats/api/member/dto/CreateMemberRequest.java index 30fc669..f95a4d7 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/dto/CreateMemberRequest.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/dto/CreateMemberRequest.java @@ -1,4 +1,4 @@ -package org.patinanetwork.patchats.common.dto.member; +package org.patinanetwork.patchats.api.member.dto; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; diff --git a/src/main/java/org/patinanetwork/patchats/api/member/dto/MemberDto.java b/src/main/java/org/patinanetwork/patchats/api/member/dto/MemberDto.java index 52251c9..b1c2094 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/dto/MemberDto.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/dto/MemberDto.java @@ -1,4 +1,4 @@ -package org.patinanetwork.patchats.common.dto.member; +package org.patinanetwork.patchats.api.member.dto; import io.swagger.v3.oas.annotations.media.Schema; import java.util.UUID; @@ -6,7 +6,7 @@ import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; -import org.patinanetwork.patchats.common.db.models.member.Member; +import org.patinanetwork.patchats.api.member.db.models.Member; // TODO: Separate AdminMemberDto and PublicMemberDto @Getter diff --git a/src/main/java/org/patinanetwork/patchats/api/member/dto/UpdateMemberRequest.java b/src/main/java/org/patinanetwork/patchats/api/member/dto/UpdateMemberRequest.java index d1a91b2..92b6a29 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/dto/UpdateMemberRequest.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/dto/UpdateMemberRequest.java @@ -1,4 +1,4 @@ -package org.patinanetwork.patchats.common.dto.member; +package org.patinanetwork.patchats.api.member.dto; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; From 677a83c18b7ae08fb8cb86d171bc11d5477adb18 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Fri, 10 Jul 2026 16:21:30 -0400 Subject: [PATCH 16/19] Separated exceptions from MemberService.java, created new classes for exceptions --- .../patchats/api/member/MemberController.java | 43 ++++++++----------- .../patchats/api/member/MemberService.java | 43 ++++++++++--------- .../common/web/ApiExceptionHandler.java | 13 ++++++ .../exception/MemberDuplicateException.java | 7 +++ .../exception/MemberNotFoundException.java | 9 ++++ 5 files changed, 71 insertions(+), 44 deletions(-) create mode 100644 src/main/java/org/patinanetwork/patchats/common/web/exception/MemberDuplicateException.java create mode 100644 src/main/java/org/patinanetwork/patchats/common/web/exception/MemberNotFoundException.java diff --git a/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java b/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java index 7cabf02..1d615d6 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/MemberController.java @@ -2,17 +2,11 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; -import java.util.UUID; import lombok.RequiredArgsConstructor; +import org.patinanetwork.patchats.api.member.dto.CreateMemberRequest; +import org.patinanetwork.patchats.api.member.dto.MemberDto; import org.patinanetwork.patchats.common.dto.ApiResponder; -import org.patinanetwork.patchats.common.dto.member.CreateMemberRequest; -import org.patinanetwork.patchats.common.dto.member.MemberDto; -import org.patinanetwork.patchats.common.dto.member.UpdateMemberRequest; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -32,22 +26,23 @@ public ResponseEntity> createMember(@Valid @RequestBody return ResponseEntity.ok(ApiResponder.success("Member created successfully", response)); } - @PatchMapping("/{id}") - public ResponseEntity> updateMember( - @Valid @RequestBody final UpdateMemberRequest request, @PathVariable final UUID id) { - final MemberDto response = memberService.updateMember(request, id); - return ResponseEntity.ok(ApiResponder.success("Member updated successfully", response)); - } + // TODO: Implement these endpoints after createMember is fully functional and tested + // @PatchMapping("/{id}") + // public ResponseEntity> updateMember( + // @Valid @RequestBody final UpdateMemberRequest request, @PathVariable final UUID id) { + // final MemberDto response = memberService.updateMember(request, id); + // return ResponseEntity.ok(ApiResponder.success("Member updated successfully", response)); + // } - @GetMapping("/{id}") - public ResponseEntity> getMember(@PathVariable final UUID id) { - final MemberDto response = memberService.getMemberById(id); - return ResponseEntity.ok(ApiResponder.success("Member retrieved successfully", response)); - } + // @GetMapping("/{id}") + // public ResponseEntity> getMember(@PathVariable final UUID id) { + // final MemberDto response = memberService.getMemberById(id); + // return ResponseEntity.ok(ApiResponder.success("Member retrieved successfully", response)); + // } - @DeleteMapping("/{id}") - public ResponseEntity> deactivateMember(@PathVariable final UUID id) { - final MemberDto response = memberService.deactivateMemberById(id); - return ResponseEntity.ok(ApiResponder.success("Member deactivated successfully", response)); - } + // @DeleteMapping("/{id}") + // public ResponseEntity> deactivateMember(@PathVariable final UUID id) { + // final MemberDto response = memberService.deactivateMemberById(id); + // return ResponseEntity.ok(ApiResponder.success("Member deactivated successfully", response)); + // } } diff --git a/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java b/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java index 2ec75d2..6e46563 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/MemberService.java @@ -2,11 +2,13 @@ import java.util.UUID; import lombok.RequiredArgsConstructor; -import org.patinanetwork.patchats.common.db.models.member.Member; -import org.patinanetwork.patchats.common.db.repos.member.MemberRepo; -import org.patinanetwork.patchats.common.dto.member.CreateMemberRequest; -import org.patinanetwork.patchats.common.dto.member.MemberDto; -import org.patinanetwork.patchats.common.dto.member.UpdateMemberRequest; +import org.patinanetwork.patchats.api.member.db.models.Member; +import org.patinanetwork.patchats.api.member.db.repos.MemberRepo; +import org.patinanetwork.patchats.api.member.dto.CreateMemberRequest; +import org.patinanetwork.patchats.api.member.dto.MemberDto; +import org.patinanetwork.patchats.api.member.dto.UpdateMemberRequest; +import org.patinanetwork.patchats.common.web.exception.MemberDuplicateException; +import org.patinanetwork.patchats.common.web.exception.MemberNotFoundException; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import org.springframework.web.server.ResponseStatusException; @@ -19,8 +21,7 @@ public class MemberService { public MemberDto createMember(CreateMemberRequest request) { if (memberRepo.getMemberByEmail(request.email()).isPresent()) { - throw new ResponseStatusException( - HttpStatus.CONFLICT, "Member with email " + request.email() + " already exists"); + throw new MemberDuplicateException(request.email()); } Member member = Member.builder() .id(UUID.randomUUID()) @@ -42,8 +43,9 @@ public MemberDto createMember(CreateMemberRequest request) { public MemberDto updateMember(UpdateMemberRequest request, UUID id) { if (memberRepo.getMemberById(id).isEmpty()) { - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Member with ID " + id + " does not exist"); + throw new MemberNotFoundException(id); } + // TODO: Implement partial update instead of full update Member member = Member.builder() .id(id) .fullName(request.fullName()) @@ -62,17 +64,18 @@ public MemberDto updateMember(UpdateMemberRequest request, UUID id) { return MemberDto.from(updatedMember); } - public MemberDto getMemberById(UUID id) { - return memberRepo - .getMemberById(id) - .map(MemberDto::from) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Member not found")); - } + // TODO: Implement these methods after createMember and updateMember is fully functional and tested + // public MemberDto getMemberById(UUID id) { + // return memberRepo + // .getMemberById(id) + // .map(MemberDto::from) + // .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Member not found")); + // } - public MemberDto deactivateMemberById(UUID id) { - return memberRepo - .deactivateMemberById(id) - .map(MemberDto::from) - .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Member not found")); - } + // public MemberDto deactivateMemberById(UUID id) { + // return memberRepo + // .deactivateMemberById(id) + // .map(MemberDto::from) + // .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Member not found")); + // } } diff --git a/src/main/java/org/patinanetwork/patchats/common/web/ApiExceptionHandler.java b/src/main/java/org/patinanetwork/patchats/common/web/ApiExceptionHandler.java index 302916b..7501ad8 100644 --- a/src/main/java/org/patinanetwork/patchats/common/web/ApiExceptionHandler.java +++ b/src/main/java/org/patinanetwork/patchats/common/web/ApiExceptionHandler.java @@ -2,6 +2,9 @@ import java.util.stream.Collectors; import org.patinanetwork.patchats.common.dto.ApiResponder; +import org.patinanetwork.patchats.common.web.exception.MemberDuplicateException; +import org.patinanetwork.patchats.common.web.exception.MemberNotFoundException; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; @@ -21,6 +24,16 @@ public ResponseEntity> handleValidation(final MethodArgumentN return ResponseEntity.badRequest().body(ApiResponder.failure(message)); } + @ExceptionHandler(MemberNotFoundException.class) + public ResponseEntity> handleMemberNotFound(final MemberNotFoundException ex) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ApiResponder.failure(ex.getMessage())); + } + + @ExceptionHandler(MemberDuplicateException.class) + public ResponseEntity> handleMemberDuplicate(final MemberDuplicateException ex) { + return ResponseEntity.status(HttpStatus.CONFLICT).body(ApiResponder.failure(ex.getMessage())); + } + private String formatError(final FieldError error) { return error.getField() + " " + error.getDefaultMessage(); } diff --git a/src/main/java/org/patinanetwork/patchats/common/web/exception/MemberDuplicateException.java b/src/main/java/org/patinanetwork/patchats/common/web/exception/MemberDuplicateException.java new file mode 100644 index 0000000..798bd98 --- /dev/null +++ b/src/main/java/org/patinanetwork/patchats/common/web/exception/MemberDuplicateException.java @@ -0,0 +1,7 @@ +package org.patinanetwork.patchats.common.web.exception; + +public class MemberDuplicateException extends RuntimeException { + public MemberDuplicateException(String email) { + super("Member with email " + email + " already exists"); + } +} diff --git a/src/main/java/org/patinanetwork/patchats/common/web/exception/MemberNotFoundException.java b/src/main/java/org/patinanetwork/patchats/common/web/exception/MemberNotFoundException.java new file mode 100644 index 0000000..6bfee93 --- /dev/null +++ b/src/main/java/org/patinanetwork/patchats/common/web/exception/MemberNotFoundException.java @@ -0,0 +1,9 @@ +package org.patinanetwork.patchats.common.web.exception; + +import java.util.UUID; + +public class MemberNotFoundException extends RuntimeException { + public MemberNotFoundException(UUID id) { + super("Member with ID " + id + " not found"); + } +} From f5d3ae4fcbf8e2da5ddb5b7161942716f4a6a351 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 13 Jul 2026 11:55:10 -0400 Subject: [PATCH 17/19] createMember implemented in MemberSqlRepo. createdAt and updatedAt are type instant in entity. --- .../patchats/api/member/db/models/Member.java | 4 +- .../api/member/db/repos/MemberSqlRepo.java | 48 ++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java b/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java index a875a79..47bad4b 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java @@ -48,7 +48,7 @@ public class Member { @Setter private String extraNotes; - private String createdAt; + private Instant createdAt; - private String updatedAt; + private Instant updatedAt; } diff --git a/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java b/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java index 673a9fc..910baee 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java @@ -1,18 +1,64 @@ package org.patinanetwork.patchats.api.member.db.repos; +import java.sql.SQLException; import java.util.Optional; import java.util.UUID; import lombok.RequiredArgsConstructor; import org.patinanetwork.patchats.api.member.db.models.Member; +import org.springframework.jdbc.core.simple.JdbcClient; import org.springframework.stereotype.Repository; @Repository @RequiredArgsConstructor public class MemberSqlRepo implements MemberRepo { + private final JdbcClient jdbc; + + private Member parseResultSetToMember(final ResultSet rs) throws SQLException { + var id = rs.getString("id"); + return Member.builder() + .id(id) + .fullName(rs.getString("full_name")) + .email(rs.getString("email")) + .linkedInUrl(rs.getString("linked_in_url")) + .introduction(rs.getString("introduction")) + .referralSource(rs.getString("referral_source")) + .active(rs.getBoolean("active")) + .matchPref(rs.getString("match_pref")) + .industryPref(rs.getString("industry_pref")) + .rolePref(rs.getString("role_pref")) + .topics(rs.getString("topics")) + .extraNotes(rs.getString("extra_notes")) + .createdAt(rs.getTimestamp("created_at").toInstant()) + .updatedAt(rs.getTimestamp("updated_at").toInstant()) + .build(); + } + @Override public Member createMember(Member member) { - throw new UnsupportedOperationException("Not implemented yet"); + String sql = """ + INSERT INTO "members" + (id, "full_name", "email","linked_in_url","introduction","referral_source",active, "match_pref", "industry_pref", "role_pref", "topics", "extra_notes") + VALUES + (:id, :full_name, :email, :linked_in_url, :introduction, :referral_source, :active , :match_pref, :industry_pref, :role_pref, :topics, :extra_notes) + RETURNING + * + """; + return jdbc.sql(sql) + .param("id", member.getId()) + .param("full_name", member.getFullName()) + .param("email", member.getEmail()) + .param("linked_in_url", member.getLinkedInUrl()) + .param("introduction", member.getIntroduction()) + .param("referral_source", member.getReferralSource()) + .param("active", member.isActive()) + .param("match_pref", member.getMatchPref()) + .param("industry_pref", member.getIndustryPref()) + .param("role_pref", member.getRolePref()) + .param("topics", member.getTopics()) + .param("extra_notes", member.getExtraNotes()) + .query((rs, rowNum) -> parseResultSetToMember(rs)) + .single(); } @Override From 9ac716f11268ad9271f1aa68fbcc96191ce0e3a4 Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 13 Jul 2026 12:49:15 -0400 Subject: [PATCH 18/19] MemberSqlRepo createMember --- .../patinanetwork/patchats/api/member/db/models/Member.java | 1 + .../patchats/api/member/db/repos/MemberSqlRepo.java | 4 ++-- .../org/patinanetwork/patchats/api/member/dto/MemberDto.java | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java b/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java index 47bad4b..9ecbbd6 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/db/models/Member.java @@ -1,5 +1,6 @@ package org.patinanetwork.patchats.api.member.db.models; +import java.time.Instant; import java.util.UUID; import lombok.Builder; import lombok.EqualsAndHashCode; diff --git a/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java b/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java index 910baee..13b5c1e 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/db/repos/MemberSqlRepo.java @@ -1,5 +1,6 @@ package org.patinanetwork.patchats.api.member.db.repos; +import java.sql.ResultSet; import java.sql.SQLException; import java.util.Optional; import java.util.UUID; @@ -15,9 +16,8 @@ public class MemberSqlRepo implements MemberRepo { private final JdbcClient jdbc; private Member parseResultSetToMember(final ResultSet rs) throws SQLException { - var id = rs.getString("id"); return Member.builder() - .id(id) + .id(UUID.fromString(rs.getString("id"))) .fullName(rs.getString("full_name")) .email(rs.getString("email")) .linkedInUrl(rs.getString("linked_in_url")) diff --git a/src/main/java/org/patinanetwork/patchats/api/member/dto/MemberDto.java b/src/main/java/org/patinanetwork/patchats/api/member/dto/MemberDto.java index b1c2094..9e9bda3 100644 --- a/src/main/java/org/patinanetwork/patchats/api/member/dto/MemberDto.java +++ b/src/main/java/org/patinanetwork/patchats/api/member/dto/MemberDto.java @@ -1,6 +1,7 @@ package org.patinanetwork.patchats.api.member.dto; import io.swagger.v3.oas.annotations.media.Schema; +import java.time.Instant; import java.util.UUID; import lombok.Builder; import lombok.EqualsAndHashCode; @@ -47,10 +48,10 @@ public class MemberDto { private String extraNotes; @Schema(requiredMode = Schema.RequiredMode.REQUIRED) - private String createdAt; + private Instant createdAt; @Schema(requiredMode = Schema.RequiredMode.REQUIRED) - private String updatedAt; + private Instant updatedAt; public static MemberDto from(final Member member) { return MemberDto.builder() From e100bb08c7d9b14d7a28d53b0d336f1e366c6faa Mon Sep 17 00:00:00 2001 From: Allison Lee Date: Mon, 13 Jul 2026 12:49:51 -0400 Subject: [PATCH 19/19] Restored V0001 db create members, added V0004 alter members --- db/migration/V0001__Create_members_table.sql | 10 +++++----- db/migration/V0004__Alter_members_table.sql | 7 +++++++ 2 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 db/migration/V0004__Alter_members_table.sql diff --git a/db/migration/V0001__Create_members_table.sql b/db/migration/V0001__Create_members_table.sql index f006d33..a69ad4e 100644 --- a/db/migration/V0001__Create_members_table.sql +++ b/db/migration/V0001__Create_members_table.sql @@ -2,13 +2,13 @@ CREATE TABLE IF NOT EXISTS "members" ( id UUID PRIMARY KEY, full_name TEXT NOT NULL, email TEXT UNIQUE NOT NULL, - linked_in_url TEXT, - introduction TEXT NOT NULL, + linked_url TEXT, + bio TEXT, referral_source TEXT, - active BOOLEAN NOT NULL DEFAULT TRUE, + active BOOLEAN, match_pref TEXT, - industry_pref TEXT, - role_pref TEXT, + industry TEXT, + role TEXT, topics TEXT, extra_notes TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), diff --git a/db/migration/V0004__Alter_members_table.sql b/db/migration/V0004__Alter_members_table.sql new file mode 100644 index 0000000..a5d7cf9 --- /dev/null +++ b/db/migration/V0004__Alter_members_table.sql @@ -0,0 +1,7 @@ +ALTER TABLE members RENAME COLUMN linked_url TO linked_in_url; +ALTER TABLE members RENAME COLUMN bio TO introduction; +ALTER TABLE members RENAME COLUMN industry TO industry_pref; +ALTER TABLE members RENAME COLUMN role TO role_pref; + +ALTER TABLE members ALTER COLUMN introduction SET NOT NULL; +ALTER TABLE members ALTER COLUMN active SET NOT NULL DEFAULT TRUE; \ No newline at end of file