33import z from "zod/v4" ;
44import { CommentActionInput } from "./inputs/comment.input" ;
55import { authID } from "./session.actions" ;
6- import {
7- ActionException ,
8- handleActionException ,
9- } from "./RepositoryException" ;
6+ import { ActionException , handleActionException } from "./RepositoryException" ;
107import { persistenceRepository } from "../persistence/persistence-repositories" ;
118import { pgClient } from "../persistence/clients" ;
129import { and , eq , inArray } from "sqlkit" ;
1310import { CommentPresentation } from "../models/domain-models" ;
1411import { inngest } from "@/lib/inngest" ;
12+ import { assertCommentResourceExists } from "./notifications.payload" ;
1513
1614const sql = String . raw ;
1715
1816export const getComments = async (
19- _input : z . infer < typeof CommentActionInput . getComments >
17+ _input : z . infer < typeof CommentActionInput . getComments > ,
2018) : Promise < CommentPresentation [ ] > => {
2119 const input = CommentActionInput . getComments . parse ( _input ) ;
2220
@@ -28,71 +26,22 @@ export const getComments = async (
2826 input . resource_id ,
2927 input . resource_type ,
3028 ] ) ;
31- const rows = execution_response as { rows ?: { comments ?: CommentPresentation [ ] } [ ] } ;
29+ const rows = execution_response as {
30+ rows ?: { comments ?: CommentPresentation [ ] } [ ] ;
31+ } ;
3232 return rows ?. rows ?. [ 0 ] ?. comments || [ ] ;
3333} ;
3434
3535export const createMyComment = async (
36- input : z . infer < typeof CommentActionInput . create >
36+ input : z . infer < typeof CommentActionInput . create > ,
3737) => {
3838 const sessionId = await authID ( ) ;
3939 if ( ! sessionId ) {
4040 throw new ActionException ( "Unauthorized: No session ID found" ) ;
4141 }
4242 const { resource_id, resource_type, body } = input ;
4343
44- let notificationRecipientId : string | null = null ;
45- let notificationPayload : Record < string , string > = { } ;
46-
47- switch ( resource_type ) {
48- case "ARTICLE" : {
49- const [ article ] = await persistenceRepository . article . find ( {
50- where : eq ( "id" , resource_id ) ,
51- limit : 1 ,
52- columns : [ "id" , "author_id" , "title" , "handle" ] ,
53- } ) ;
54- if ( ! article ) throw new ActionException ( "Resource not found" ) ;
55- notificationRecipientId = article . author_id ;
56- const [ articleAuthor ] = await persistenceRepository . user . find ( {
57- where : eq ( "id" , article . author_id ) ,
58- limit : 1 ,
59- columns : [ "id" , "username" ] ,
60- } ) ;
61- notificationPayload = {
62- article_id : article . id ,
63- article_handle : article . handle ,
64- article_title : article . title ,
65- ...( articleAuthor ?. username
66- ? { article_author_username : articleAuthor . username }
67- : { } ) ,
68- } ;
69- break ;
70- }
71- case "COMMENT" : {
72- const [ parentComment ] = await persistenceRepository . comment . find ( {
73- where : eq ( "id" , resource_id ) ,
74- limit : 1 ,
75- columns : [ "id" , "user_id" ] ,
76- } ) ;
77- if ( ! parentComment ) throw new ActionException ( "Parent comment not found" ) ;
78- notificationRecipientId = parentComment . user_id ;
79- notificationPayload = { comment_id : parentComment . id } ;
80- break ;
81- }
82- case "GIST" : {
83- const [ gist ] = await persistenceRepository . gist . find ( {
84- where : eq ( "id" , resource_id ) ,
85- limit : 1 ,
86- columns : [ "id" , "owner_id" , "title" ] ,
87- } ) ;
88- if ( ! gist ) throw new ActionException ( "Resource not found" ) ;
89- notificationRecipientId = gist . owner_id ;
90- notificationPayload = { gist_id : gist . id } ;
91- break ;
92- }
93- default :
94- throw new ActionException ( "Invalid resource type" ) ;
95- }
44+ await assertCommentResourceExists ( resource_id , resource_type ) ;
9645
9746 const created = await persistenceRepository . comment . insert ( [
9847 {
@@ -104,45 +53,26 @@ export const createMyComment = async (
10453 } ,
10554 ] ) ;
10655
107- // Fetch actor info for notification payload
108- const [ actor ] = await persistenceRepository . user . find ( {
109- where : eq ( "id" , sessionId ) ,
110- limit : 1 ,
111- columns : [ "id" , "name" , "username" ] ,
112- } ) ;
113-
114- // Send notification event (log errors, don't fail the mutation)
115- if ( notificationRecipientId ) {
116- const notificationType =
117- resource_type === "ARTICLE"
118- ? "COMMENT_ON_ARTICLE"
119- : resource_type === "COMMENT"
120- ? "REPLY_TO_COMMENT"
121- : "COMMENT_ON_GIST" ;
122- inngest
123- . send ( {
124- name : "app/notification.requested" ,
125- data : {
126- recipient_id : notificationRecipientId ,
127- actor_id : sessionId ,
128- type : notificationType ,
129- payload : {
130- ...notificationPayload ,
131- actor_name : actor ?. name ,
132- actor_username : actor ?. username ,
133- } ,
56+ inngest
57+ . send ( {
58+ name : "app/notification.requested" ,
59+ data : {
60+ actor_id : sessionId ,
61+ comment_request : {
62+ resource_id,
63+ resource_type,
13464 } ,
135- } )
136- . catch ( ( err ) => {
137- console . error ( "[inngest] Failed to send notification event:" , err ) ;
138- } ) ;
139- }
65+ } ,
66+ } )
67+ . catch ( ( err ) => {
68+ console . error ( "[inngest] Failed to send notification event:" , err ) ;
69+ } ) ;
14070
14171 return created ?. rows ?. [ 0 ] ;
14272} ;
14373
14474export const updateMyComment = async (
145- _input : z . infer < typeof CommentActionInput . update >
75+ _input : z . infer < typeof CommentActionInput . update > ,
14676) => {
14777 try {
14878 const input = await CommentActionInput . update . parseAsync ( _input ) ;
@@ -175,7 +105,7 @@ export const updateMyComment = async (
175105
176106/** Deletes the comment and all nested replies; reactions on those comments are removed first. */
177107export const deleteMyComment = async (
178- _input : z . infer < typeof CommentActionInput . delete >
108+ _input : z . infer < typeof CommentActionInput . delete > ,
179109) => {
180110 try {
181111 const input = await CommentActionInput . delete . parseAsync ( _input ) ;
@@ -212,10 +142,7 @@ export const deleteMyComment = async (
212142 }
213143
214144 await persistenceRepository . reaction . delete ( {
215- where : and (
216- eq ( "resource_type" , "COMMENT" ) ,
217- inArray ( "resource_id" , ids )
218- ) ,
145+ where : and ( eq ( "resource_type" , "COMMENT" ) , inArray ( "resource_id" , ids ) ) ,
219146 } ) ;
220147
221148 await persistenceRepository . comment . delete ( {
0 commit comments