diff --git a/src/domain/entities/note.ts b/src/domain/entities/note.ts index a9a1f79b..91b887ce 100644 --- a/src/domain/entities/note.ts +++ b/src/domain/entities/note.ts @@ -1,3 +1,5 @@ +import type User from '@domain/entities/user.js'; + /** * Note internal id. Used to query Note by internal API */ @@ -28,9 +30,9 @@ export interface Note { content: JSON; /** - * Note creator + * Note creator id */ - creatorId: number; + creatorId: User['id']; /** * When note was created diff --git a/src/domain/entities/noteList.ts b/src/domain/entities/noteList.ts new file mode 100644 index 00000000..25753407 --- /dev/null +++ b/src/domain/entities/noteList.ts @@ -0,0 +1,9 @@ +import type { Note } from '@domain/entities/note.js'; + +/** + * Note list entity. + * An object with the "items" property containing a list of all existing notes created by the user + */ +export type NoteList = { + items: Note[]; +}; diff --git a/src/domain/index.ts b/src/domain/index.ts index ca0af9d8..d7742b11 100644 --- a/src/domain/index.ts +++ b/src/domain/index.ts @@ -1,4 +1,5 @@ import NoteService from '@domain/service/note.js'; +import NoteListService from '@domain/service/noteList.js'; import NoteSettingsService from './service/noteSettings.js'; import type { Repositories } from '@repository/index.js'; import AuthService from '@domain/service/auth.js'; @@ -16,6 +17,11 @@ export interface DomainServices { */ noteService: NoteService, + /** + * Note List service instance + */ + noteListService: NoteListService, + /** * Note settings service instance */ @@ -48,6 +54,8 @@ export function init(repositories: Repositories, appConfig: AppConfig): DomainSe const noteService = new NoteService(repositories.noteRepository); const noteSettingsService = new NoteSettingsService(repositories.noteSettingsRepository); + const noteListService = new NoteListService(repositories.noteRepository); + const authService = new AuthService( appConfig.auth.accessSecret, appConfig.auth.accessExpiresIn, @@ -62,6 +70,7 @@ export function init(repositories: Repositories, appConfig: AppConfig): DomainSe return { noteService, + noteListService, noteSettingsService, userService, authService, diff --git a/src/domain/service/noteList.ts b/src/domain/service/noteList.ts new file mode 100644 index 00000000..4503610d --- /dev/null +++ b/src/domain/service/noteList.ts @@ -0,0 +1,33 @@ +import type NoteRepository from '@repository/note.repository'; +import type { NoteList } from '@domain/entities/noteList'; + +/** + * Note list service + */ +export default class NoteListService { + /** + * Note repository + */ + public repository: NoteRepository; + + /** + * Note service constructor + * + * @param repository - note repository + */ + constructor(repository: NoteRepository) { + this.repository = repository; + } + + /** + * Returns note list by creator id + * + * @param id - note creator id + * @returns { Promise } note + */ + public async getNoteListByCreatorId(id: number): Promise { + return { + items: await this.repository.getNoteListByCreatorId(id), + }; + } +} diff --git a/src/presentation/http/http-api.ts b/src/presentation/http/http-api.ts index e66b871d..25155898 100644 --- a/src/presentation/http/http-api.ts +++ b/src/presentation/http/http-api.ts @@ -22,6 +22,7 @@ import { NoteSchema } from './schema/Note.js'; import Policies from './policies/index.js'; import type { RequestParams, Response } from '@presentation/api.interface.js'; import NoteSettingsRouter from './router/noteSettings.js'; +import NoteListRouter from '@presentation/http/router/noteList.js'; const appServerLogger = getLogger('appServer'); @@ -191,6 +192,11 @@ export default class HttpApi implements Api { noteSettingsService: domainServices.noteSettingsService, }); + await this.server?.register(NoteListRouter, { + prefix: '/notes', + noteListService: domainServices.noteListService, + }); + await this.server?.register(NoteSettingsRouter, { prefix: '/note-settings', noteSettingsService: domainServices.noteSettingsService, diff --git a/src/presentation/http/router/noteList.ts b/src/presentation/http/router/noteList.ts new file mode 100644 index 00000000..76595d57 --- /dev/null +++ b/src/presentation/http/router/noteList.ts @@ -0,0 +1,44 @@ +import type { FastifyPluginCallback } from 'fastify'; +import type NoteListService from '@domain/service/noteList.js'; + +/** + * Interface for the noteList router. + */ +interface NoteListRouterOptions { + /** + * Note list service instance + */ + noteListService: NoteListService, + +} + +/** + * Note list router plugin + * + * @param fastify - fastify instance + * @param opts - empty options + * @param done - callback + */ +const NoteListRouter: FastifyPluginCallback = (fastify, opts, done) => { + + const noteListService = opts.noteListService; + + /** + * Get note list by userId + */ + fastify.get('/', { + config: { + policy: [ + 'authRequired', + ], + }, + }, async (request, reply) => { + const { userId } = request; + const noteList = await noteListService.getNoteListByCreatorId(userId as number); + + return reply.send(noteList); + }); + + done(); +}; +export default NoteListRouter; diff --git a/src/repository/note.repository.ts b/src/repository/note.repository.ts index d6405b54..f47f1bab 100644 --- a/src/repository/note.repository.ts +++ b/src/repository/note.repository.ts @@ -1,5 +1,6 @@ import type { Note, NoteCreationAttributes, NoteInternalId, NotePublicId } from '@domain/entities/note.js'; import type NoteStorage from '@repository/storage/note.storage.js'; +import type { NoteList } from '@domain/entities/noteList.js'; /** * Repository allows accessing data from business-logic (domain) level @@ -34,6 +35,7 @@ export default class NoteRepository { * * @param id - note internal id * @param content - new content + * @returns Note on success, null on failure */ public async updateNoteContentById(id: NoteInternalId, content: Note['content'] ): Promise { return await this.storage.updateNoteContentById(id, content); @@ -67,4 +69,14 @@ export default class NoteRepository { public async getNoteByPublicId(publicId: NotePublicId): Promise { return await this.storage.getNoteByPublicId(publicId); } + + /** + * Gets note list by creator id + * + * @param id - note creator id + * @returns { Promise } note + */ + public async getNoteListByCreatorId(id: number): Promise { + return await this.storage.getNoteListByCreatorId(id); + } } diff --git a/src/repository/storage/postgres/orm/sequelize/note.ts b/src/repository/storage/postgres/orm/sequelize/note.ts index 68084e01..8c6b16bb 100644 --- a/src/repository/storage/postgres/orm/sequelize/note.ts +++ b/src/repository/storage/postgres/orm/sequelize/note.ts @@ -1,9 +1,8 @@ -import type { Sequelize, InferAttributes, InferCreationAttributes, CreationOptional } from 'sequelize'; -import { Model, DataTypes } from 'sequelize'; -import type { ModelStatic } from 'sequelize'; +import type { CreationOptional, InferAttributes, InferCreationAttributes, ModelStatic, Sequelize } from 'sequelize'; +import { DataTypes, Model } from 'sequelize'; import type Orm from '@repository/storage/postgres/orm/sequelize/index.js'; -import type { Note, NoteInternalId, NotePublicId } from '@domain/entities/note.js'; -import type { NoteCreationAttributes } from '@domain/entities/note.js'; +import type { Note, NoteCreationAttributes, NoteInternalId, NotePublicId } from '@domain/entities/note.js'; +import type { NoteList } from '@domain/entities/noteList.js'; import type { NoteSettingsModel } from '@repository/storage/postgres/orm/sequelize/noteSettings.js'; import { UserModel } from '@repository/storage/postgres/orm/sequelize/user.js'; @@ -187,6 +186,21 @@ export default class NoteSequelizeStorage { return note; } + /** + * Gets note list by creator id + * + * @param creatorId - note creator id + * @returns { Promise } note + */ + public async getNoteListByCreatorId(creatorId: number): Promise { + const noteList = await this.model.findAll({ + where: { + creatorId, + }, + }); + + return noteList; + } /** * Gets note by id *