1+ import { NextRequest , NextResponse } from 'next/server'
2+ import { and , eq , isNull } from 'drizzle-orm'
3+ import { createLogger } from '@/lib/logs/console-logger'
4+ import { db } from '@/db'
5+ import { memory } from '@/db/schema'
6+
7+ const logger = createLogger ( 'MemoryByIdAPI' )
8+
9+ export const dynamic = 'force-dynamic'
10+ export const runtime = 'nodejs'
11+
12+ /**
13+ * GET handler for retrieving a specific memory by ID
14+ */
15+ export async function GET (
16+ request : NextRequest ,
17+ { params } : { params : Promise < { id : string } > }
18+ ) {
19+ const requestId = crypto . randomUUID ( ) . slice ( 0 , 8 )
20+ const { id } = await params
21+
22+ try {
23+ logger . info ( `[${ requestId } ] Processing memory get request for ID: ${ id } ` )
24+
25+ // Get workflowId from query parameter (required)
26+ const url = new URL ( request . url )
27+ const workflowId = url . searchParams . get ( 'workflowId' )
28+
29+ if ( ! workflowId ) {
30+ logger . warn ( `[${ requestId } ] Missing required parameter: workflowId` )
31+ return NextResponse . json (
32+ {
33+ success : false ,
34+ error : {
35+ message : 'workflowId parameter is required' ,
36+ } ,
37+ } ,
38+ { status : 400 }
39+ )
40+ }
41+
42+ // Query the database for the memory
43+ const memories = await db
44+ . select ( )
45+ . from ( memory )
46+ . where (
47+ and (
48+ eq ( memory . key , id ) ,
49+ eq ( memory . workflowId , workflowId ) ,
50+ isNull ( memory . deletedAt )
51+ )
52+ )
53+ . orderBy ( memory . createdAt )
54+ . limit ( 1 )
55+
56+ if ( memories . length === 0 ) {
57+ logger . warn ( `[${ requestId } ] Memory not found: ${ id } for workflow: ${ workflowId } ` )
58+ return NextResponse . json (
59+ {
60+ success : false ,
61+ error : {
62+ message : 'Memory not found' ,
63+ } ,
64+ } ,
65+ { status : 404 }
66+ )
67+ }
68+
69+ logger . info ( `[${ requestId } ] Memory retrieved successfully: ${ id } for workflow: ${ workflowId } ` )
70+ return NextResponse . json (
71+ {
72+ success : true ,
73+ data : memories [ 0 ] ,
74+ } ,
75+ { status : 200 }
76+ )
77+
78+ } catch ( error : any ) {
79+ return NextResponse . json (
80+ {
81+ success : false ,
82+ error : {
83+ message : error . message || 'Failed to retrieve memory' ,
84+ } ,
85+ } ,
86+ { status : 500 }
87+ )
88+ }
89+ }
90+
91+ /**
92+ * DELETE handler for removing a specific memory
93+ */
94+ export async function DELETE (
95+ request : NextRequest ,
96+ { params } : { params : Promise < { id : string } > }
97+ ) {
98+ const requestId = crypto . randomUUID ( ) . slice ( 0 , 8 )
99+ const { id } = await params
100+
101+ try {
102+ logger . info ( `[${ requestId } ] Processing memory delete request for ID: ${ id } ` )
103+
104+ // Get workflowId from query parameter (required)
105+ const url = new URL ( request . url )
106+ const workflowId = url . searchParams . get ( 'workflowId' )
107+
108+ if ( ! workflowId ) {
109+ logger . warn ( `[${ requestId } ] Missing required parameter: workflowId` )
110+ return NextResponse . json (
111+ {
112+ success : false ,
113+ error : {
114+ message : 'workflowId parameter is required' ,
115+ } ,
116+ } ,
117+ { status : 400 }
118+ )
119+ }
120+
121+ // Verify memory exists before attempting to delete
122+ const existingMemory = await db
123+ . select ( { id : memory . id } )
124+ . from ( memory )
125+ . where (
126+ and (
127+ eq ( memory . key , id ) ,
128+ eq ( memory . workflowId , workflowId ) ,
129+ isNull ( memory . deletedAt )
130+ )
131+ )
132+ . limit ( 1 )
133+
134+ if ( existingMemory . length === 0 ) {
135+ logger . warn ( `[${ requestId } ] Memory not found: ${ id } for workflow: ${ workflowId } ` )
136+ return NextResponse . json (
137+ {
138+ success : false ,
139+ error : {
140+ message : 'Memory not found' ,
141+ } ,
142+ } ,
143+ { status : 404 }
144+ )
145+ }
146+
147+ // Soft delete by setting deletedAt timestamp
148+ await db
149+ . update ( memory )
150+ . set ( {
151+ deletedAt : new Date ( ) ,
152+ updatedAt : new Date ( )
153+ } )
154+ . where (
155+ and (
156+ eq ( memory . key , id ) ,
157+ eq ( memory . workflowId , workflowId )
158+ )
159+ )
160+
161+ logger . info ( `[${ requestId } ] Memory deleted successfully: ${ id } for workflow: ${ workflowId } ` )
162+ return NextResponse . json (
163+ {
164+ success : true ,
165+ data : { message : 'Memory deleted successfully' } ,
166+ } ,
167+ { status : 200 }
168+ )
169+
170+ } catch ( error : any ) {
171+ return NextResponse . json (
172+ {
173+ success : false ,
174+ error : {
175+ message : error . message || 'Failed to delete memory' ,
176+ } ,
177+ } ,
178+ { status : 500 }
179+ )
180+ }
181+ }
182+
183+ /**
184+ * PUT handler for updating a specific memory
185+ */
186+ export async function PUT (
187+ request : NextRequest ,
188+ { params } : { params : Promise < { id : string } > }
189+ ) {
190+ const requestId = crypto . randomUUID ( ) . slice ( 0 , 8 )
191+ const { id } = await params
192+
193+ try {
194+ logger . info ( `[${ requestId } ] Processing memory update request for ID: ${ id } ` )
195+
196+ // Parse request body
197+ const body = await request . json ( )
198+ const { data, workflowId } = body
199+
200+ if ( ! data ) {
201+ logger . warn ( `[${ requestId } ] Missing required field: data` )
202+ return NextResponse . json (
203+ {
204+ success : false ,
205+ error : {
206+ message : 'Memory data is required' ,
207+ } ,
208+ } ,
209+ { status : 400 }
210+ )
211+ }
212+
213+ if ( ! workflowId ) {
214+ logger . warn ( `[${ requestId } ] Missing required field: workflowId` )
215+ return NextResponse . json (
216+ {
217+ success : false ,
218+ error : {
219+ message : 'workflowId is required' ,
220+ } ,
221+ } ,
222+ { status : 400 }
223+ )
224+ }
225+
226+ // Verify memory exists before attempting to update
227+ const existingMemories = await db
228+ . select ( )
229+ . from ( memory )
230+ . where (
231+ and (
232+ eq ( memory . key , id ) ,
233+ eq ( memory . workflowId , workflowId ) ,
234+ isNull ( memory . deletedAt )
235+ )
236+ )
237+ . limit ( 1 )
238+
239+ if ( existingMemories . length === 0 ) {
240+ logger . warn ( `[${ requestId } ] Memory not found: ${ id } for workflow: ${ workflowId } ` )
241+ return NextResponse . json (
242+ {
243+ success : false ,
244+ error : {
245+ message : 'Memory not found' ,
246+ } ,
247+ } ,
248+ { status : 404 }
249+ )
250+ }
251+
252+ const existingMemory = existingMemories [ 0 ]
253+
254+ // Validate memory data based on the existing memory type
255+ if ( existingMemory . type === 'agent' ) {
256+ if ( ! data . role || ! data . content ) {
257+ logger . warn ( `[${ requestId } ] Missing agent memory fields` )
258+ return NextResponse . json (
259+ {
260+ success : false ,
261+ error : {
262+ message : 'Agent memory requires role and content' ,
263+ } ,
264+ } ,
265+ { status : 400 }
266+ )
267+ }
268+
269+ if ( ! [ 'user' , 'assistant' , 'system' ] . includes ( data . role ) ) {
270+ logger . warn ( `[${ requestId } ] Invalid agent role: ${ data . role } ` )
271+ return NextResponse . json (
272+ {
273+ success : false ,
274+ error : {
275+ message : 'Agent role must be user, assistant, or system' ,
276+ } ,
277+ } ,
278+ { status : 400 }
279+ )
280+ }
281+ }
282+
283+ // Update the memory with new data
284+ await db
285+ . update ( memory )
286+ . set ( {
287+ data,
288+ updatedAt : new Date ( )
289+ } )
290+ . where (
291+ and (
292+ eq ( memory . key , id ) ,
293+ eq ( memory . workflowId , workflowId )
294+ )
295+ )
296+
297+ // Fetch the updated memory
298+ const updatedMemories = await db
299+ . select ( )
300+ . from ( memory )
301+ . where (
302+ and (
303+ eq ( memory . key , id ) ,
304+ eq ( memory . workflowId , workflowId )
305+ )
306+ )
307+ . limit ( 1 )
308+
309+ logger . info ( `[${ requestId } ] Memory updated successfully: ${ id } for workflow: ${ workflowId } ` )
310+ return NextResponse . json (
311+ {
312+ success : true ,
313+ data : updatedMemories [ 0 ] ,
314+ } ,
315+ { status : 200 }
316+ )
317+
318+ } catch ( error : any ) {
319+ return NextResponse . json (
320+ {
321+ success : false ,
322+ error : {
323+ message : error . message || 'Failed to update memory' ,
324+ } ,
325+ } ,
326+ { status : 500 }
327+ )
328+ }
329+ }
0 commit comments