Skip to content

Commit 176fda9

Browse files
committed
Make user_avatar_url nullable in comments: update schema, ensure nullable handling in queries, and prevent errors when avatars are missing.
1 parent 292256c commit 176fda9

7 files changed

Lines changed: 27 additions & 10 deletions

File tree

backend/api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@compass/api",
3-
"version": "1.62.0",
3+
"version": "1.62.1",
44
"private": true,
55
"description": "Backend API endpoints",
66
"main": "src/serve.ts",

backend/api/src/create-comment.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ export const createComment: APIHandler<'create-comment'> = async (
3333
creator.id,
3434
creator.name,
3535
creator.username,
36-
creator.avatarUrl,
36+
// Nullable in the DB even though `User.avatarUrl` is typed `string` — see the vote-comment
37+
// handler for the same coercion.
38+
creator.avatarUrl ?? null,
3739
userId,
3840
content,
3941
replyToCommentId,

backend/api/src/create-vote-comment.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ export const createVoteComment: APIHandler<'create-vote-comment'> = async (
6565
creator.id,
6666
creator.name,
6767
creator.username,
68-
creator.avatarUrl,
68+
// `User.avatarUrl` is typed `string`, but `users.avatar_url` is nullable — coerced explicitly
69+
// so a member without an avatar posts a comment instead of a 500.
70+
creator.avatarUrl ?? null,
6971
content,
7072
parentId,
7173
stance ?? null,

backend/supabase/migration.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,5 @@ BEGIN;
7070
\i backend/supabase/migrations/20260808_add_vote_comments.sql
7171
\i backend/supabase/migrations/20260808_extend_vote_comment_stances.sql
7272
\i backend/supabase/migrations/20260808_vote_top_arguments.sql
73+
\i backend/supabase/migrations/20260809_vote_comment_avatar_nullable.sql
7374
COMMIT;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-- `user_avatar_url` was copied as NOT NULL from profile_comments, but `users.avatar_url` is nullable
2+
-- and `User.avatarUrl` is only typed `string` — TS says it is always there, Postgres disagrees. A
3+
-- member without an avatar posting an argument hit the constraint and got a 500.
4+
--
5+
-- Nullable is also the honest shape now: the comment row is the only avatar source for the thread
6+
-- (it stopped fetching profiles per comment), and `Avatar` already falls back to an initial when it
7+
-- has nothing, so "no avatar" needs to be representable rather than rejected.
8+
ALTER TABLE vote_comments
9+
ALTER COLUMN user_avatar_url DROP NOT NULL;
10+
11+
ALTER TABLE profile_comments
12+
ALTER COLUMN user_avatar_url DROP NOT NULL;

common/src/supabase/comment.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const convertComment = (row: Row<'profile_comments'>): ProfileComment =>
1212
createdTime: tsToMillis(row.created_time),
1313
userName: row.user_name,
1414
userUsername: row.user_username,
15-
userAvatarUrl: row.user_avatar_url,
15+
userAvatarUrl: row.user_avatar_url ?? undefined,
1616
hidden: row.hidden,
1717
visibility: 'public',
1818
content: row.content as JSONContent,
@@ -28,7 +28,7 @@ export const convertVoteComment = (row: Row<'vote_comments'>): VoteComment => ({
2828
createdTime: tsToMillis(row.created_time),
2929
userName: row.user_name,
3030
userUsername: row.user_username,
31-
userAvatarUrl: row.user_avatar_url,
31+
userAvatarUrl: row.user_avatar_url ?? undefined,
3232
hidden: row.hidden,
3333
visibility: 'public',
3434
content: row.content as JSONContent,

common/src/supabase/schema.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ export type Database = {
10161016
id: number
10171017
on_user_id: string
10181018
reply_to_comment_id: number | null
1019-
user_avatar_url: string
1019+
user_avatar_url: string | null
10201020
user_id: string
10211021
user_name: string
10221022
user_username: string
@@ -1028,7 +1028,7 @@ export type Database = {
10281028
id?: number
10291029
on_user_id: string
10301030
reply_to_comment_id?: number | null
1031-
user_avatar_url: string
1031+
user_avatar_url?: string | null
10321032
user_id: string
10331033
user_name: string
10341034
user_username: string
@@ -1040,7 +1040,7 @@ export type Database = {
10401040
id?: number
10411041
on_user_id?: string
10421042
reply_to_comment_id?: number | null
1043-
user_avatar_url?: string
1043+
user_avatar_url?: string | null
10441044
user_id?: string
10451045
user_name?: string
10461046
user_username?: string
@@ -1860,7 +1860,7 @@ export type Database = {
18601860
id: number
18611861
reply_to_comment_id: number | null
18621862
stance: string | null
1863-
user_avatar_url: string
1863+
user_avatar_url: string | null
18641864
user_id: string
18651865
user_name: string
18661866
user_username: string
@@ -1873,7 +1873,7 @@ export type Database = {
18731873
id?: never
18741874
reply_to_comment_id?: number | null
18751875
stance?: string | null
1876-
user_avatar_url: string
1876+
user_avatar_url?: string | null
18771877
user_id: string
18781878
user_name: string
18791879
user_username: string

0 commit comments

Comments
 (0)