diff --git a/src/db/schema/user.schema.ts b/src/db/schema/user.schema.ts index 2a30368fedd07be5a516d670c81a56dd891196a8..88f9f00f8b82934dc31c45eb5bd261c4f0f445cb 100644 --- a/src/db/schema/user.schema.ts +++ b/src/db/schema/user.schema.ts @@ -62,8 +62,6 @@ const userUpdateSchema = createSelectSchema(userTable) .partial() .required({ id: true }) const userProfileSchema = userModelSchema.omit({ - id: true, - user_stats_id: true, password: true, birthday: true, cpf: true, diff --git a/src/documentation/userDescriber.ts b/src/documentation/userDescriber.ts index ecbf433f764f7702e4f6047840cac834f1ed6b41..55288c1f4bac31d4a96a8ae85e63a85a8b01fa80 100644 --- a/src/documentation/userDescriber.ts +++ b/src/documentation/userDescriber.ts @@ -1,313 +1,368 @@ import { describeRoute } from 'hono-openapi'; - -const followUserRoute = describeRoute({ - method: "POST", - path: "/follow", - summary: "Seguir um usuário.", - description: "Cria uma relação de seguidor entre dois usuários, aumentando o número de seguidores e seguidos.", - request: { - body: { - type: "object", - properties: { - follower_id: { type: "number", description: "ID do usuário que está seguindo." }, - user_id: { type: "number", description: "ID do usuário que está sendo seguido." } - }, - required: ["follower_id", "user_id"] +const meUserRoute = describeRoute({ + method: "GET", + path: "/me", + tags: ["User"], + summary: "Obter o perfil do usuário autenticado.", + description: "Retorna as informações do perfil do usuário que está autenticado com o JWT.", + request: { + headers: { + "Authorization": { + type: "string", + description: "Token JWT do usuário autenticado. Deve ser passado no cabeçalho da requisição." } - }, - response: { - 200: { - description: "Usuário seguido com sucesso.", - content: { - "application/json": { - followRelation: { - type: "object", - properties: { - id: { type: "number" }, - follower_id: { type: "number" }, - user_id: { type: "number" } - } + } + }, + response: { + 200: { + description: "Perfil do usuário retornado com sucesso.", + content: { + "application/json": { + user: { + type: "object", + properties: { + id: { type: "string", description: "ID único do usuário." }, + name: { type: "string", description: "Nome do usuário." }, + email: { type: "string", description: "Email do usuário." }, + // Adicione outros campos do perfil, se necessário. } } } - }, - 400: { description: "Erro ao seguir usuário." } - } - }); - - const unfollowUserRoute = describeRoute({ - method: "POST", - path: "/unfollow", - summary: "Deixar de seguir um usuário.", - description: "Remove a relação de seguidor entre dois usuários, reduzindo o número de seguidores e seguidos.", - request: { - body: { - type: "object", - properties: { - follower_id: { type: "number", description: "ID do usuário que está deixando de seguir." }, - user_id: { type: "number", description: "ID do usuário que está sendo deixado de seguir." } - }, - required: ["follower_id", "user_id"] } }, - response: { - 200: { - description: "Usuário deixou de ser seguido com sucesso.", - content: { - "application/json": { - followRelation: { - type: "object", - properties: { - id: { type: "number" }, - follower_id: { type: "number" }, - user_id: { type: "number" } - } - } - } + 400: { + description: "Erro ao tentar encontrar o usuário.", + content: { + "application/json": { + status: { type: "string", example: "error" }, + message: { type: "string", example: "could not find the user" }, + code: { type: "number", example: 400 }, + path: { type: "string", example: "/me" }, + suggestion: { type: "string", example: "login again" } } + } + } + } +}); + +const followUserRoute = describeRoute({ + method: "POST", + path: "/follow", + tagss: ["User"], + summary: "Seguir um usuário.", + description: "Cria uma relação de seguidor entre dois usuários, aumentando o número de seguidores e seguidos.", + request: { + body: { + type: "object", + properties: { + follower_id: { type: "number", description: "ID do usuário que está seguindo." }, + user_id: { type: "number", description: "ID do usuário que está sendo seguido." } }, - 400: { description: "Erro ao deixar de seguir usuário." } + required: ["follower_id", "user_id"] } - }); - - const getFollowsRoute = describeRoute({ - method: "GET", - path: "/follows/:id", - summary: "Listar usuários seguidos.", - description: "Retorna a lista de usuários que o ID especificado segue.", - request: { - params: { - id: { type: "number", description: "ID do usuário." } - } - }, - response: { - 200: { - description: "Lista de usuários seguidos.", - content: { - "application/json": { - follows: { - type: "array", - items: { type: "object" } + }, + response: { + 200: { + description: "Usuário seguido com sucesso.", + content: { + "application/json": { + followRelation: { + type: "object", + properties: { + id: { type: "number" }, + follower_id: { type: "number" }, + user_id: { type: "number" } } } } - }, - 404: { description: "Usuário não encontrado." } - } - }); - - const getFollowersRoute = describeRoute({ - method: "GET", - path: "/followers/:id", - summary: "Listar seguidores.", - description: "Retorna a lista de usuários que seguem o ID especificado.", - request: { - params: { - id: { type: "number", description: "ID do usuário." } } }, - response: { - 200: { - description: "Lista de seguidores.", - content: { - "application/json": { - followers: { - type: "array", - items: { type: "object" } + 400: { description: "Erro ao seguir usuário." } + } +}); + +const unfollowUserRoute = describeRoute({ + method: "POST", + path: "/unfollow", + tags: ["User"], + summary: "Deixar de seguir um usuário.", + description: "Remove a relação de seguidor entre dois usuários, reduzindo o número de seguidores e seguidos.", + request: { + body: { + type: "object", + properties: { + follower_id: { type: "number", description: "ID do usuário que está deixando de seguir." }, + user_id: { type: "number", description: "ID do usuário que está sendo deixado de seguir." } + }, + required: ["follower_id", "user_id"] + } + }, + response: { + 200: { + description: "Usuário deixou de ser seguido com sucesso.", + content: { + "application/json": { + followRelation: { + type: "object", + properties: { + id: { type: "number" }, + follower_id: { type: "number" }, + user_id: { type: "number" } } } } - }, - 404: { description: "Usuário não encontrado." } + } + }, + 400: { description: "Erro ao deixar de seguir usuário." } + } +}); + +const getFollowsRoute = describeRoute({ + method: "GET", + path: "/follows/:id", + tags: ["User"], + summary: "Listar usuários seguidos.", + description: "Retorna a lista de usuários que o ID especificado segue.", + request: { + params: { + id: { type: "number", description: "ID do usuário." } } - }); - - const getUsersRoute = describeRoute({ - method: "GET", - path: "/users", - summary: "Listar todos os usuários.", - description: "Retorna a lista de todos os usuários cadastrados.", - response: { - 200: { - description: "Lista de usuários.", - content: { - "application/json": { - users: { - type: "array", - items: { type: "object" } - } + }, + response: { + 200: { + description: "Lista de usuários seguidos.", + content: { + "application/json": { + follows: { + type: "array", + items: { type: "object" } } } } + }, + 404: { description: "Usuário não encontrado." } + } +}); + +const getFollowersRoute = describeRoute({ + method: "GET", + path: "/followers/:id", + tags: ["User"], + summary: "Listar seguidores.", + description: "Retorna a lista de usuários que seguem o ID especificado.", + request: { + params: { + id: { type: "number", description: "ID do usuário." } } - }); - - const getUserByUsernameRoute = describeRoute({ - method: "GET", - path: "/:username", - summary: "Obter detalhes de um usuário pelo nome de usuário.", - description: "Retorna as informações de um usuário com base no seu nome de usuário.", - request: { - params: { - username: { type: "string", description: "Nome de usuário." } + }, + response: { + 200: { + description: "Lista de seguidores.", + content: { + "application/json": { + followers: { + type: "array", + items: { type: "object" } + } + } } }, - response: { - 200: { - description: "Usuário encontrado.", - content: { - "application/json": { - user: { type: "object" } + 404: { description: "Usuário não encontrado." } + } +}); + +const getUsersRoute = describeRoute({ + method: "GET", + path: "/users", + tags: ["User"], + summary: "Listar todos os usuários.", + description: "Retorna a lista de todos os usuários cadastrados.", + response: { + 200: { + description: "Lista de usuários.", + content: { + "application/json": { + users: { + type: "array", + items: { type: "object" } } } - }, - 404: { description: "Usuário não encontrado." } + } } - }); - + } +}); -const updateUserRoute = describeRoute({ - method: "POST", - path: "/update", - summary: "Atualiza as informações de um usuário.", - description: "Recebe os novos dados do usuário e atualiza no banco de dados.", - request: { - body: { - type: "object", - properties: { - id: { type: "number", description: "ID do usuário a ser atualizado." }, - name: { type: "string", description: "Novo nome do usuário." }, - email: { type: "string", description: "Novo e-mail do usuário." }, - password: { type: "string", description: "Nova senha do usuário." } - }, - required: ["id"] +const getUserByUsernameRoute = describeRoute({ + method: "GET", + path: "/:username", + tags: ["User"], + summary: "Obter detalhes de um usuário pelo nome de usuário.", + description: "Retorna as informações de um usuário com base no seu nome de usuário.", + request: { + params: { + username: { type: "string", description: "Nome de usuário." } + } + }, + response: { + 200: { + description: "Usuário encontrado.", + content: { + "application/json": { + user: { type: "object" } + } } }, - response: { - 200: { - description: "Usuário atualizado com sucesso.", - content: { - "application/json": { - user: { - type: "object", - properties: { - id: { type: "number" }, - name: { type: "string" }, - email: { type: "string" }, - updated_at: { type: "string", description: "Data da última atualização." } - } + 404: { description: "Usuário não encontrado." } + } +}); + + +const updateUserRoute = describeRoute({ + method: "POST", + path: "/update", + tags: ["User"], + summary: "Atualiza as informações de um usuário.", + description: "Recebe os novos dados do usuário e atualiza no banco de dados.", + request: { + body: { + type: "object", + properties: { + id: { type: "number", description: "ID do usuário a ser atualizado." }, + name: { type: "string", description: "Novo nome do usuário." }, + email: { type: "string", description: "Novo e-mail do usuário." }, + password: { type: "string", description: "Nova senha do usuário." } + }, + required: ["id"] + } + }, + response: { + 200: { + description: "Usuário atualizado com sucesso.", + content: { + "application/json": { + user: { + type: "object", + properties: { + id: { type: "number" }, + name: { type: "string" }, + email: { type: "string" }, + updated_at: { type: "string", description: "Data da última atualização." } } } } - }, - 400: { description: "Erro ao atualizar usuário." } - } - }); - - const confirmUserRoute = describeRoute({ - method: "POST", - path: "/confirmation/:email", - summary: "Confirma o e-mail do usuário.", - description: "Atualiza o status de confirmação do usuário baseado no e-mail informado.", - request: { - params: { - email: { type: "string", description: "E-mail do usuário a ser confirmado." } } }, - response: { - 200: { - description: "Usuário confirmado com sucesso.", - content: { - "application/json": { - id: { type: "number" }, - email: { type: "string" }, - confirmed_at: { type: "string", description: "Data de confirmação do e-mail." } - } - } - }, - 400: { description: "Erro ao confirmar usuário." } + 400: { description: "Erro ao atualizar usuário." } + } +}); + +const confirmUserRoute = describeRoute({ + method: "POST", + path: "/confirmation/:email", + tags: ["User"], + summary: "Confirma o e-mail do usuário.", + description: "Atualiza o status de confirmação do usuário baseado no e-mail informado.", + request: { + params: { + email: { type: "string", description: "E-mail do usuário a ser confirmado." } } - }); - - const reactivateUserRoute = describeRoute({ - method: "POST", - path: "/reactivate/:email", - summary: "Reativa um usuário inativo.", - description: "Altera o status do usuário para ativo e atualiza a data de reativação.", - request: { - params: { - email: { type: "string", description: "E-mail do usuário a ser reativado." } + }, + response: { + 200: { + description: "Usuário confirmado com sucesso.", + content: { + "application/json": { + id: { type: "number" }, + email: { type: "string" }, + confirmed_at: { type: "string", description: "Data de confirmação do e-mail." } + } } }, - response: { - 200: { - description: "Usuário reativado com sucesso.", - content: { - "application/json": { - id: { type: "number" }, - email: { type: "string" }, - active: { type: "boolean", description: "Status de atividade do usuário." }, - reactivated_at: { type: "string", description: "Data da reativação." } - } - } - }, - 400: { description: "Erro ao reativar usuário." } + 400: { description: "Erro ao confirmar usuário." } + } +}); + +const reactivateUserRoute = describeRoute({ + method: "POST", + path: "/reactivate/:email", + tags: ["User"], + summary: "Reativa um usuário inativo.", + description: "Altera o status do usuário para ativo e atualiza a data de reativação.", + request: { + params: { + email: { type: "string", description: "E-mail do usuário a ser reativado." } } - }); - - const deleteUserRoute = describeRoute({ - method: "POST", - path: "/delete/:id", - summary: "Desativa um usuário.", - description: "Marca um usuário como inativo e registra a data de exclusão.", - request: { - params: { - id: { type: "number", description: "ID do usuário a ser desativado." } + }, + response: { + 200: { + description: "Usuário reativado com sucesso.", + content: { + "application/json": { + id: { type: "number" }, + email: { type: "string" }, + active: { type: "boolean", description: "Status de atividade do usuário." }, + reactivated_at: { type: "string", description: "Data da reativação." } + } } }, - response: { - 200: { - description: "Usuário desativado com sucesso.", - content: { - "application/json": { - id: { type: "number" }, - active: { type: "boolean", description: "Status de atividade do usuário (falso)." }, - deleted_at: { type: "string", description: "Data da desativação." } - } - } - }, - 400: { description: "Erro ao desativar usuário." } + 400: { description: "Erro ao reativar usuário." } + } +}); + +const deleteUserRoute = describeRoute({ + method: "POST", + path: "/delete/:id", + tags: ["User"], + summary: "Desativa um usuário.", + description: "Marca um usuário como inativo e registra a data de exclusão.", + request: { + params: { + id: { type: "number", description: "ID do usuário a ser desativado." } } - }); - - const systemDeleteUserRoute = describeRoute({ - method: "POST", - path: "/delete/system/:id", - summary: "Exclui um usuário permanentemente.", - description: "Remove um usuário do banco de dados de forma definitiva.", - request: { - params: { - id: { type: "number", description: "ID do usuário a ser removido permanentemente." } + }, + response: { + 200: { + description: "Usuário desativado com sucesso.", + content: { + "application/json": { + id: { type: "number" }, + active: { type: "boolean", description: "Status de atividade do usuário (falso)." }, + deleted_at: { type: "string", description: "Data da desativação." } + } } }, - response: { - 200: { - description: "Usuário excluÃdo permanentemente.", - content: { - "application/json": { - id: { type: "number" }, - deleted: { type: "boolean", description: "Confirmação da exclusão." } - } - } - }, - 400: { description: "Erro ao excluir usuário." } + 400: { description: "Erro ao desativar usuário." } + } +}); + +const systemDeleteUserRoute = describeRoute({ + method: "POST", + path: "/delete/system/:id", + tags: ["User"], + summary: "Exclui um usuário permanentemente.", + description: "Remove um usuário do banco de dados de forma definitiva.", + request: { + params: { + id: { type: "number", description: "ID do usuário a ser removido permanentemente." } } - }); - + }, + response: { + 200: { + description: "Usuário excluÃdo permanentemente.", + content: { + "application/json": { + id: { type: "number" }, + deleted: { type: "boolean", description: "Confirmação da exclusão." } + } + } + }, + 400: { description: "Erro ao excluir usuário." } + } +}); + -export -{ +export { followUserRoute, unfollowUserRoute, getFollowsRoute, @@ -318,5 +373,6 @@ export confirmUserRoute, reactivateUserRoute, deleteUserRoute, - systemDeleteUserRoute + systemDeleteUserRoute, + meUserRoute } \ No newline at end of file diff --git a/src/routes/user.route.ts b/src/routes/user.route.ts index 38d4c77849b54bd61e0e7aff401082bb6ed1938c..af4790d29824fa329970fac58e50f15eefed2a22 100644 --- a/src/routes/user.route.ts +++ b/src/routes/user.route.ts @@ -20,7 +20,8 @@ import { confirmUserRoute, reactivateUserRoute, deleteUserRoute, - systemDeleteUserRoute + systemDeleteUserRoute, + meUserRoute } from "../documentation/userDescriber" const service = Container.get(UserService) @@ -28,6 +29,28 @@ const followService = Container.get(FollowRelationService) const userStatsService = Container.get(UserStatsService) export const userRouter = honoWithJwt() + .get('/me', meUserRoute, + async (c) => { + const userId = c.get('jwtPayload').id; + try { + const user = userSchemas.userProfileSchema.parse( await service.findById(userId)); + + + return c.json({ user }); + } catch { + return c.json( + createApexError({ + status: 'error', + message: 'could not find the user', + code: HttpStatus.BAD_REQUEST, + path: c.req.routePath, + suggestion: 'login again' + }), + HttpStatus.BAD_REQUEST) + } + + } + ) .post('/follow/:user_to_follow_id', followUserRoute, async (c) => { try { @@ -303,4 +326,3 @@ export const userRouter = honoWithJwt() ) } }) - \ No newline at end of file