Skip to content

Commit 3a569bc

Browse files
committed
harden supabase read models
1 parent 6c9d1df commit 3a569bc

16 files changed

Lines changed: 1197 additions & 113 deletions

File tree

src/app/(core)/(interact)/(centered)/listings/[slug]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const getListingData = cache(async (slug: string) => {
4343
data: { user },
4444
} = await supabase.auth.getUser();
4545
const { data: listing } = await supabase
46-
.from(user ? "listings_private_data" : "listings_public_data")
46+
.from(user ? "listing_contact_cards" : "public_listings")
4747
.select()
4848
.match({ slug })
4949
.single();

src/app/(core)/(interact)/(stretched)/map/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const getInitialData = cache(async (listingSlug: string | undefined) => {
2929

3030
const listingResponse = listingSlug
3131
? await supabase
32-
.from(user ? "listings_private_data" : "listings_public_data")
32+
.from(user ? "listing_contact_cards" : "public_listings")
3333
.select()
3434
.eq("slug", listingSlug)
3535
.single()

src/app/(forms)/profile/listings/[slug]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export default async function EditListingPage({
4141
.eq("id", user.id)
4242
.single(),
4343
supabase
44-
.from("listings_private_data")
44+
.from("listing_contact_cards")
4545
.select(
4646
`
4747
id,

src/app/(photo)/listings/[slug]/photos/[...photoPath]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const getListingData = cache(async (slug: string) => {
2525
const {
2626
data: { user },
2727
} = await supabase.auth.getUser();
28-
const tableName = user ? "listings_private_data" : "listings_public_data";
28+
const tableName = user ? "listing_contact_cards" : "public_listings";
2929
const selectColumns = user
3030
? "name, owner_first_name, photos, type"
3131
: "name, photos, type";

src/app/actions.ts

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -188,25 +188,6 @@ export const signUpAction = async (formData: FormData, request?: Request) => {
188188
}
189189
}
190190

191-
// Check if user exists in auth.users
192-
const { data: existingAuthUser, error: authError } = await supabase.rpc(
193-
"check_if_email_exists",
194-
{
195-
email_to_check: email,
196-
}
197-
);
198-
199-
if (authError) {
200-
console.error("Error checking email:", authError);
201-
redirectUrl.searchParams.append("error", t("genericLater"));
202-
return redirect(redirectUrl.toString());
203-
}
204-
205-
if (existingAuthUser) {
206-
redirectUrl.searchParams.append("error", t("accountExists"));
207-
return redirect(redirectUrl.toString());
208-
}
209-
210191
const {
211192
data: { user },
212193
error,
@@ -243,6 +224,20 @@ export const signUpAction = async (formData: FormData, request?: Request) => {
243224
redirectUrl.searchParams.append("error", t("generic"));
244225
return redirect(redirectUrl.toString());
245226
}
227+
228+
const accountExistsPatterns = [
229+
"already registered",
230+
"already exists",
231+
"User already registered",
232+
];
233+
const accountExists = accountExistsPatterns.some((pattern) =>
234+
error?.message?.toLowerCase().includes(pattern.toLowerCase())
235+
);
236+
if (accountExists) {
237+
redirectUrl.searchParams.append("error", t("accountExists"));
238+
return redirect(redirectUrl.toString());
239+
}
240+
246241
// Back to general error catching
247242
console.error(
248243
error?.code + " " + error?.message || "No user returned from sign up"

src/app/sitemap.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
1111
const supabase = await createClient();
1212

1313
const { data: listings } = await supabase
14-
.from("listings_public_data")
14+
.from("public_listings")
1515
.select("slug, created_at")
1616
.in("type", ["community", "business"]);
1717

src/components/ChatWindow/chatWindowController.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,9 @@ export function getThreadMessages(
1313
existingThread?: {
1414
messages?: ChatMessageRecord[] | null;
1515
chat_messages?: ChatMessageRecord[] | null;
16-
chat_messages_with_senders?: ChatMessageRecord[] | null;
1716
} | null
1817
) {
19-
return (
20-
existingThread?.messages ??
21-
existingThread?.chat_messages_with_senders ??
22-
existingThread?.chat_messages ??
23-
[]
24-
);
18+
return existingThread?.messages ?? existingThread?.chat_messages ?? [];
2519
}
2620

2721
export async function loadThreadMessages({
@@ -32,8 +26,8 @@ export async function loadThreadMessages({
3226
threadId: string;
3327
}): Promise<InlineActionResult<ChatMessageRecord[]>> {
3428
const { data, error } = await supabase
35-
.from("chat_messages_with_senders")
36-
.select()
29+
.from("chat_messages")
30+
.select("id, content, created_at, read_at, sender_id, thread_id")
3731
.eq("thread_id", threadId)
3832
.order("created_at", { ascending: true });
3933

src/components/ListingRead/ListingRead.tsx

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,8 @@ const ListingRead = memo(function Listing({
113113
async function loadExistingThread() {
114114
if (!supabase) return;
115115
const { data: thread, error } = await supabase
116-
.from("chat_threads_with_participants")
117-
.select(
118-
`
119-
*,
120-
chat_messages_with_senders (*)
121-
`
122-
)
116+
.from("chat_threads")
117+
.select("id, created_at, listing_id, initiator_id, owner_id")
123118
.match({
124119
listing_id: listingId,
125120
initiator_id: userId,
@@ -132,11 +127,31 @@ const ListingRead = memo(function Listing({
132127
return;
133128
}
134129

135-
setExistingThread(thread);
130+
if (!thread) {
131+
setExistingThread(null);
132+
return;
133+
}
134+
135+
const { data: messages, error: messagesError } = await supabase
136+
.from("chat_messages")
137+
.select("id, content, created_at, read_at, sender_id, thread_id")
138+
.eq("thread_id", thread.id)
139+
.order("created_at", { ascending: true });
140+
141+
if (messagesError) {
142+
console.error("Error loading thread messages:", messagesError);
143+
return;
144+
}
145+
146+
setExistingThread({
147+
...thread,
148+
listing: realListing,
149+
messages: messages ?? [],
150+
});
136151
}
137152

138153
loadExistingThread();
139-
}, [listingId, listingOwnerId, userId, isDemo, supabase]);
154+
}, [listingId, listingOwnerId, userId, isDemo, supabase, realListing]);
140155

141156
const initialZoomLevel = 14;
142157
const listingDisplayNameCopy = useMemo(

src/components/PeelsFeaturedHostsPhotos/PeelsFeaturedHostsPhotos.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ function PeelsFeaturedHostsPhotos() {
8888
useEffect(() => {
8989
const loadListings = async () => {
9090
const { data, error } = await supabase
91-
.from("listings_public_data")
91+
.from("public_listings")
9292
.select(
9393
"slug, name, photos, type, is_stub, homepage_featured, homepage_featured_photo_indexes"
9494
)

src/data/demo/threads.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
type DemoThread = {
22
id: string;
3-
chat_messages_with_senders: Array<{
3+
messages: Array<{
44
id: string;
55
content: string;
66
created_at: string;
@@ -15,7 +15,7 @@ export const DEMO_CHAT_REFERENCE_TIME = "2025-05-02T09:02:00.000Z";
1515
export const demoThreads: DemoThread[] = [
1616
{
1717
id: "demo-thread-1",
18-
chat_messages_with_senders: [
18+
messages: [
1919
{
2020
id: "demo-thread-1-message-1",
2121
content: "Hey Becca, are you still accepting food scraps?",

0 commit comments

Comments
 (0)