Skip to content

Commit f348312

Browse files
committed
feat: add my notes endpoint
1 parent 391f5bd commit f348312

File tree

4 files changed

+136
-4
lines changed

4 files changed

+136
-4
lines changed

src/domain/service/note.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,24 @@ export default class NoteService {
238238
};
239239
}
240240

241+
/**
242+
* Returns note list created by user
243+
* @param creatorId - id of the note creator
244+
* @param page - number of current page
245+
* @returns list of the notes ordered by updatedAt DESC
246+
*/
247+
public async getMyNoteList(creatorId: User['id'], page: number): Promise<NoteList> {
248+
const offset = (page - 1) * this.noteListPortionSize;
249+
250+
return {
251+
items: await this.noteRepository.getMyNoteList(
252+
creatorId,
253+
offset,
254+
this.noteListPortionSize
255+
),
256+
};
257+
}
258+
241259
/**
242260
* Create note relation
243261
* @param noteId - id of the current note

src/presentation/http/router/noteList.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ interface NoteListRouterOptions {
1111
* Note service instance
1212
*/
1313
noteService: NoteService;
14-
1514
}
1615

1716
/**
@@ -77,6 +76,62 @@ const NoteListRouter: FastifyPluginCallback<NoteListRouterOptions> = (fastify, o
7776
return reply.send(noteListPublic);
7877
});
7978

79+
/**
80+
* Get note list created by the user
81+
*/
82+
fastify.get<{
83+
Querystring: {
84+
page: number;
85+
};
86+
}>(
87+
'/my',
88+
{
89+
config: {
90+
policy: ['authRequired'],
91+
},
92+
schema: {
93+
querystring: {
94+
page: {
95+
type: 'number',
96+
minimum: 1,
97+
maximum: 30,
98+
},
99+
},
100+
101+
response: {
102+
'2xx': {
103+
description: 'Query notelist created by user',
104+
properties: {
105+
items: {
106+
id: { type: 'string' },
107+
content: { type: 'string' },
108+
createdAt: { type: 'string' },
109+
creatorId: { type: 'string' },
110+
updatedAt: { type: 'string' },
111+
},
112+
},
113+
},
114+
},
115+
},
116+
},
117+
async (request, reply) => {
118+
const userId = request.userId as number;
119+
const page = request.query.page;
120+
121+
const noteList = await noteService.getMyNoteList(userId, page);
122+
/**
123+
* Wrapping Notelist for public use
124+
*/
125+
const noteListItemsPublic: NotePublic[] = noteList.items.map(definePublicNote);
126+
127+
const noteListPublic: NoteListPublic = {
128+
items: noteListItemsPublic,
129+
};
130+
131+
return reply.send(noteListPublic);
132+
}
133+
);
134+
80135
done();
81136
};
82137

src/repository/note.repository.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@ export default class NoteRepository {
8282
return await this.storage.getNoteListByUserId(id, offset, limit);
8383
}
8484

85+
/**
86+
* Gets note list created by user
87+
* @param creatorId - id of note creator
88+
* @param offset - number of skipped notes
89+
* @param limit - number of notes to get
90+
*/
91+
public async getMyNoteList(creatorId: number, offset: number, limit: number): Promise<Note[]> {
92+
return await this.storage.getMyNoteList(creatorId, offset, limit);
93+
}
94+
8595
/**
8696
* Get all notes based on their ids
8797
* @param noteIds : list of note ids

src/repository/storage/postgres/orm/sequelize/note.ts

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,55 @@ export default class NoteSequelizeStorage {
285285
});
286286
}
287287

288+
/**
289+
* Gets note list created by user
290+
* @param creatorId - id of note creator
291+
* @param offset - number of skipped notes
292+
* @param limit - number of notes to get
293+
* @returns list of the notes ordered by updatedAt DESC
294+
*/
295+
public async getMyNoteList(creatorId: number, offset: number, limit: number): Promise<Note[]> {
296+
if (!this.settingsModel) {
297+
throw new Error('NoteStorage: Note settings model not initialized');
298+
}
299+
300+
const reply = await this.model.findAll({
301+
offset: offset,
302+
limit: limit,
303+
where: {
304+
creatorId: creatorId,
305+
},
306+
order: [['updatedAt', 'DESC']],
307+
include: [
308+
{
309+
model: this.settingsModel,
310+
as: 'noteSettings',
311+
attributes: ['cover'],
312+
duplicating: false,
313+
},
314+
],
315+
});
316+
317+
/**
318+
* Convert note model data to Note entity with cover property
319+
*/
320+
return reply.map((note) => {
321+
return {
322+
id: note.id,
323+
/**
324+
* noteSettings is required to be, because we make join
325+
*/
326+
cover: note.noteSettings!.cover,
327+
content: note.content,
328+
updatedAt: note.updatedAt,
329+
createdAt: note.createdAt,
330+
publicId: note.publicId,
331+
creatorId: note.creatorId,
332+
tools: note.tools,
333+
};
334+
});
335+
}
336+
288337
/**
289338
* Gets note by id
290339
* @param hostname - custom hostname
@@ -356,18 +405,18 @@ export default class NoteSequelizeStorage {
356405
// Fetch all notes and relations in a recursive query
357406
const query = `
358407
WITH RECURSIVE note_tree AS (
359-
SELECT
408+
SELECT
360409
n.id AS "noteId",
361410
n.content,
362411
n.public_id AS "publicId",
363412
nr.parent_id AS "parentId"
364413
FROM ${String(this.database.literal(this.tableName).val)} n
365414
LEFT JOIN ${String(this.database.literal('note_relations').val)} nr ON n.id = nr.note_id
366415
WHERE n.id = :startNoteId
367-
416+
368417
UNION ALL
369418
370-
SELECT
419+
SELECT
371420
n.id AS "noteId",
372421
n.content,
373422
n.public_id AS "publicId",

0 commit comments

Comments
 (0)