Documentacao das rotas da API organizadas por controller.
Descricao: Autentica um autor no sistema.
Request Body:
{
"email": "string",
"password": "string"
}Response:
{
"message": "string",
"role": "string",
"email": "string",
"userName": "string",
"profileImageUrl": "string",
"name": "string",
"token": "string",
"emailVerified": "boolean"
}Descricao: Autentica um administrador no sistema.
Request Body:
{
"email": "string",
"password": "string"
}Response:
{
"message": "string",
"role": "string",
"email": "string",
"userName": null,
"profileImageUrl": null,
"name": "string",
"token": "string",
"emailVerified": true
}Descricao: Autentica ou cadastra um autor via Google. Se o email ja existir com login Google, faz login. Se nao existir, cria uma nova conta.
Request Body:
{
"credential": "string (Google ID Token)"
}Response:
{
"message": "string",
"role": "string",
"email": "string",
"userName": "string",
"profileImageUrl": "string",
"name": "string",
"token": "string",
"emailVerified": true
}Erros:
401 Unauthorized- Token do Google invalido ou email nao verificado422 Unprocessable Entity- Email ja registrado com login por senha
Nota: Contas Google sempre tem
emailVerified: truepois o Google ja verifica o email.
Descricao: Valida se o token JWT do usuario ainda e valido.
Response:
200 OK- Token valido401 Unauthorized- Token invalido ou ausente
Descricao: Realiza o logout do usuario, removendo o cookie de autenticacao.
Response: "Logout successful"
Descricao: Verifica o email do autor atraves do token enviado por email. Retorna o userName e um token de login para o frontend redirecionar o usuario logado para seu perfil.
Query Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| token | string | Token JWT de verificacao enviado por email |
Response:
{
"message": "Email verified successfully",
"userName": "string",
"token": "string"
}Erros:
400 Bad Request- Token invalido ou expirado422 Unprocessable Entity- Email ja verificado
Nota: O token de login tambem e setado como cookie HTTP-only.
Descricao: Reenvia o email de verificacao para o autor.
Query Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| string | Email do autor |
Response: "Verification email sent successfully"
Erros:
404 Not Found- Email nao encontrado422 Unprocessable Entity- Email ja verificado ou conta Google (verificacao automatica)
Descricao: Cadastra um novo autor.
Request Body:
{
"email": "string",
"password": "string",
"name": "string",
"userName": "string"
}Response:
{
"message": "Author created successfully. Please check your email to verify your account.",
"id": "UUID",
"email": "string",
"name": "string"
}Nota: Ao criar uma conta, um email de verificacao e enviado automaticamente. O autor deve verificar o email para desbloquear todas as funcionalidades (quando
emailVerificationRequiredestiver ativado no ForumConfig).
Descricao: Atualiza informacoes basicas do perfil do autor autenticado.
Request Body:
{
"name": "string",
"gitHub": "string",
"bio": "string"
}Response:
{
"message": "string",
"name": "string",
"gitHub": "string",
"bio": "string"
}Descricao: Atualiza informacoes do perfil do autor autenticado. Todos os campos sao opcionais. Email e userName devem ser unicos.
Request Body:
{
"email": "string | null",
"password": "string | null",
"name": "string | null",
"userName": "string | null",
"gitHub": "string | null",
"profileImageUrl": "string | null",
"bio": "string | null"
}Validacoes:
| Campo | Regra |
|---|---|
| Deve ser um email valido | |
| password | Minimo 6 caracteres |
| userName | 3-30 caracteres, apenas letras minusculas, numeros e hifens |
| gitHub | URL valida do GitHub (ex: https://github.com/usuario) |
| bio | Maximo 500 caracteres |
Response:
{
"message": "string",
"email": "string",
"name": "string",
"userName": "string",
"gitHub": "string",
"profileImageUrl": "string",
"bio": "string"
}Erros:
409 Conflict- Email ou userName ja existe para outro autor
Descricao: Envia a foto de perfil do autor autenticado. Requer autenticacao de autor. Se ja existir uma imagem de perfil no bucket R2, ela sera deletada automaticamente.
Content-Type: multipart/form-data
Parametros:
| Nome | Tipo | Descricao |
|---|---|---|
| file | MultipartFile | Imagem de perfil (JPG/JPEG, PNG, GIF, WEBP) |
Restricoes:
- Tamanho maximo: 600 KB
- Formatos aceitos: JPG/JPEG, PNG, GIF, WEBP
Response: string (URL da imagem de perfil)
Erros:
400 Bad Request- Arquivo excede 600 KB ou formato invalido401 Unauthorized- Usuario nao autenticado
Descricao: Busca o perfil publico de um autor pelo userName.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| userName | string | Username do autor |
Response:
{
"id": "UUID",
"name": "string",
"userName": "string",
"gitHub": "string",
"profileImageUrl": "string",
"bio": "string",
"bugCoins": "int",
"title": "string",
"articleCount": "long",
"topicCount": "long",
"commentCount": "long",
"emailVerified": "boolean"
}Descricao: Lista artigos de um autor paginados.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| userName | string | Username do autor |
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
| sort | AuthorContentSortType | RECENT | Ordenacao (RECENT, OLDEST, LIKES, SAVES, COMMENTS) |
Response: ArticlePageResponse (mesmo formato de /article)
Descricao: Lista topicos de um autor paginados.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| userName | string | Username do autor |
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
| sort | AuthorContentSortType | RECENT | Ordenacao (RECENT, OLDEST, LIKES, COMMENTS) |
Response: TopicPageResponse (mesmo formato de /api/topic)
Descricao: Lista comentarios de um autor paginados.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| userName | string | Username do autor |
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
| sort | AuthorContentSortType | RECENT | Ordenacao (RECENT, OLDEST, LIKES) |
Response: CommentPageResponse (mesmo formato de /api/comment)
Todas as rotas requerem autenticacao de autor.
Descricao: Lista interacoes/notificacoes do autor autenticado (paginado).
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
Response:
{
"interactions": [
{
"id": "UUID",
"actorAuthorId": "UUID",
"actorName": "string",
"actorUserName": "string",
"actorProfileImageUrl": "string | null",
"interactionType": "COMMENT_ON_ARTICLE | COMMENT_ON_TOPIC | REPLY_TO_COMMENT | LIKE_ARTICLE | LIKE_TOPIC | LIKE_COMMENT | SAVE_ARTICLE",
"targetType": "ARTICLE | TOPIC | COMMENT",
"targetId": "UUID",
"targetTitle": "string | null",
"targetSlug": "string | null",
"commentId": "UUID | null",
"parentContentType": "ARTICLE | TOPIC | null",
"parentAuthorUserName": "string | null",
"isRead": "boolean",
"createdAt": "LocalDateTime"
}
],
"page": "int",
"size": "int",
"totalElements": "long",
"totalPages": "int",
"hasNext": "boolean"
}Nota: Para interacoes relacionadas a comentarios (COMMENT_ON_ARTICLE, COMMENT_ON_TOPIC, REPLY_TO_COMMENT, LIKE_COMMENT):
commentId: ID do comentario criado/curtidoparentContentType: indica se o comentario pertence a um ARTICLE ou TOPICparentAuthorUserName: username do autor do artigo/topico pai (necessario para construir a URL correta quando o comentario esta em conteudo de outro autor)targetSlug: slug do artigo/topico paiUse estes campos para construir URLs:
/{parentAuthorUserName}/{targetSlug}?commentId={commentId}
Descricao: Retorna a contagem de interacoes nao lidas.
Response:
{
"count": "long"
}Descricao: Marca uma interacao especifica como lida.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| id | UUID | ID da interacao |
Response: 204 No Content
Descricao: Marca todas as interacoes como lidas.
Response: 204 No Content
Descricao: Cadastra um novo artigo. Requer autenticacao de autor.
Request Body:
{
"title": "string",
"description": "string",
"tags": ["string"],
"originalPost": "string",
"isPrivate": "boolean | null"
}Response:
{
"message": "string",
"id": "UUID",
"title": "string",
"slug": "string"
}Nota: O campo
isPrivatepermite salvar o artigo como rascunho privado. Setrue, o artigo nao aparece em nenhuma listagem publica e os arquivos sao salvos em uma pastaprivate/no R2. Sefalseounull, o artigo e publico. Ao criar um artigo publico, o autor recebe bugCoins automaticamente conforme configurado emForumConfig.coinsPerArticle. Artigos privados nao geram bugCoins ate serem publicados.
Descricao: Edita um artigo existente. Requer autenticacao de autor (dono do artigo). Todos os campos sao opcionais exceto articleId.
Request Body:
{
"articleId": "UUID",
"title": "string | null",
"description": "string | null",
"tags": ["string"] | null,
"originalPost": "string | null",
"deletedImagePaths": ["string"] | null
}Validacoes:
| Campo | Regra |
|---|---|
| articleId | Obrigatorio |
| title | Maximo 255 caracteres |
| description | Maximo 500 caracteres |
| tags | Cada tag: maximo 50 caracteres, apenas letras e numeros |
| originalPost | Deve ser uma URL valida |
| deletedImagePaths | Lista de caminhos de imagens a serem removidas |
Response: 200 OK (corpo vazio)
Descricao: Envia o arquivo com o conteudo do artigo (extensao .md ou .html). Requer autenticacao de autor.
Content-Type: multipart/form-data
Parametros:
| Nome | Tipo | Descricao |
|---|---|---|
| file | MultipartFile | Arquivo .md ou .html |
| articleId | UUID | ID do artigo |
Response: string (URL do conteudo)
Descricao: Envia a capa do artigo (extensao JPG/JPEG, PNG, GIF, WEBP). Requer autenticacao de autor.
Content-Type: multipart/form-data
Parametros:
| Nome | Tipo | Descricao |
|---|---|---|
| file | MultipartFile | Imagem de capa |
| articleId | UUID | ID do artigo |
Response: string (URL da capa)
Descricao: Envia uma imagem para o artigo (extensao JPG/JPEG, PNG, GIF, WEBP). Requer autenticacao de autor.
Content-Type: multipart/form-data
Parametros:
| Nome | Tipo | Descricao |
|---|---|---|
| file | MultipartFile | Imagem |
| articleId | UUID | ID do artigo |
Response: string (URL da imagem)
Descricao: Lista artigos paginados.
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
| sort | FeedSortType | RECENT | Ordenacao (RECENT, OLDEST, LIKES) |
Response:
{
"articles": [
{
"id": "UUID",
"authorId": "UUID",
"authorName": "string",
"authorUserName": "string",
"authorProfileImage": "string | null",
"creationDate": "LocalDateTime",
"isMarkdown": "boolean",
"title": "string",
"slug": "string",
"coverImage": "string",
"originalPost": "string",
"tags": ["string"],
"description": "string",
"urlArticleContent": "string",
"likesCount": "int",
"dislikesCount": "int",
"commentsCount": "int",
"savesCount": "int",
"isLiked": "boolean | null",
"isDisliked": "boolean | null",
"isSaved": "boolean | null",
"isPrivate": "boolean"
}
],
"page": "int",
"size": "int",
"totalElements": "long",
"totalPages": "int",
"hasNext": "boolean"
}Nota: Artigos com
isPrivate: truenao aparecem nesta listagem.
Descricao: Busca artigos por titulo.
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| title | string | obrigatorio | Termo de busca no titulo |
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
| sort | AuthorContentSortType | RECENT | Ordenacao (RECENT, OLDEST, LIKES, SAVES, COMMENTS) |
Response: ArticlePageResponse (mesmo formato de /article)
Descricao: Busca um artigo por ID.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| articleId | UUID | ID do artigo |
Response:
{
"id": "UUID",
"authorId": "UUID",
"authorName": "string",
"authorUserName": "string",
"authorProfileImage": "string | null",
"creationDate": "LocalDateTime",
"isMarkdown": "boolean",
"title": "string",
"slug": "string",
"coverImage": "string",
"originalPost": "string",
"tags": ["string"],
"description": "string",
"urlArticleContent": "string",
"likesCount": "int",
"dislikesCount": "int",
"commentsCount": "int",
"savesCount": "int",
"isLiked": "boolean | null",
"isDisliked": "boolean | null",
"isSaved": "boolean | null",
"isPrivate": "boolean"
}Nota: Artigos privados so podem ser acessados pelo autor dono. Outros usuarios recebem 404.
Descricao: Busca um artigo pelo userName do autor e slug.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| userName | string | Username do autor |
| slug | string | Slug do artigo (URL-friendly) |
Response:
{
"id": "UUID",
"authorId": "UUID",
"authorName": "string",
"authorUserName": "string",
"authorProfileImage": "string | null",
"creationDate": "LocalDateTime",
"isMarkdown": "boolean",
"title": "string",
"slug": "string",
"coverImage": "string",
"originalPost": "string",
"tags": ["string"],
"description": "string",
"urlArticleContent": "string",
"likesCount": "int",
"dislikesCount": "int",
"commentsCount": "int",
"savesCount": "int",
"isLiked": "boolean | null",
"isDisliked": "boolean | null",
"isSaved": "boolean | null",
"isPrivate": "boolean"
}Nota: Apenas artigos publicos podem ser acessados por esta rota.
Descricao: Deleta um artigo. Requer autenticacao de autor (dono do artigo).
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| articleId | UUID | ID do artigo |
Response: 204 No Content
Descricao: Curtir/descurtir um artigo. Requer autenticacao de autor.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| articleId | UUID | ID do artigo |
Response:
{
"isActive": "boolean",
"message": "string"
}Descricao: Dar/remover dislike em um artigo. Requer autenticacao de autor.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| articleId | UUID | ID do artigo |
Response:
{
"isActive": "boolean",
"message": "string"
}Nota: Like e dislike sao mutuamente exclusivos. Ao dar dislike em algo que ja tem like, o like e removido automaticamente.
Descricao: Salvar/remover dos salvos um artigo. Requer autenticacao de autor.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| articleId | UUID | ID do artigo |
Response:
{
"isActive": "boolean",
"message": "string"
}Descricao: Lista artigos privados do autor logado. Requer autenticacao de autor.
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
| sort | AuthorContentSortType | RECENT | Ordenacao (RECENT, OLDEST, LIKES, SAVES, COMMENTS) |
Response: ArticlePageResponse (mesmo formato de /article)
Nota: Retorna apenas artigos com
isPrivate: truedo autor autenticado.
Descricao: Publica um artigo privado, mudando isPrivate de true para false. Requer autenticacao de autor (dono do artigo).
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| articleId | UUID | ID do artigo privado |
Response: 200 OK (corpo vazio)
Erros:
404 Not Found- Artigo nao encontrado ou nao pertence ao autor logado422 Unprocessable Entity- Artigo ja e publico
Nota: Ao publicar um artigo, o autor recebe bugCoins automaticamente conforme configurado em
ForumConfig.coinsPerArticle.
Descricao: Cadastra um novo topico. Requer autenticacao de autor.
Request Body:
{
"title": "string",
"topicContent": "string",
"tags": ["string"] | null
}Response:
{
"id": "UUID",
"title": "string",
"slug": "string"
}Nota: Ao criar um topico, o autor recebe bugCoins automaticamente conforme configurado em
ForumConfig.coinsPerTopic.
Descricao: Edita um topico existente. Requer autenticacao de autor (dono do topico). Todos os campos sao opcionais exceto topicId.
Request Body:
{
"topicId": "UUID",
"title": "string | null",
"topicContent": "string | null",
"tags": ["string"] | null
}Validacoes:
| Campo | Regra |
|---|---|
| topicId | Obrigatorio |
| title | Maximo 255 caracteres |
| topicContent | Maximo 10000 caracteres |
Response: 200 OK (corpo vazio)
Descricao: Lista topicos paginados.
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
| sort | FeedSortType | RECENT | Ordenacao (RECENT, OLDEST, LIKES) |
Response:
{
"topics": [
{
"id": "UUID",
"authorId": "UUID",
"authorName": "string",
"authorUserName": "string",
"authorProfileImage": "string | null",
"creationDate": "LocalDateTime",
"title": "string",
"slug": "string",
"topicContent": "string",
"tags": ["string"],
"likesCount": "int",
"dislikesCount": "int",
"commentsCount": "int",
"isLiked": "boolean | null",
"isDisliked": "boolean | null"
}
],
"page": "int",
"size": "int",
"totalElements": "long",
"totalPages": "int",
"hasNext": "boolean"
}Descricao: Busca topicos por titulo.
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| title | string | obrigatorio | Termo de busca no titulo |
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
| sort | AuthorContentSortType | RECENT | Ordenacao (RECENT, OLDEST, LIKES, COMMENTS) |
Nota: A opcao SAVES nao e suportada para topicos.
Response: TopicPageResponse (mesmo formato de /api/topic)
Descricao: Busca um topico por ID.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| topicId | UUID | ID do topico |
Response:
{
"id": "UUID",
"authorId": "UUID",
"authorName": "string",
"authorUserName": "string",
"authorProfileImage": "string | null",
"creationDate": "LocalDateTime",
"title": "string",
"slug": "string",
"topicContent": "string",
"tags": ["string"],
"likesCount": "int",
"dislikesCount": "int",
"commentsCount": "int",
"isLiked": "boolean | null",
"isDisliked": "boolean | null"
}Descricao: Busca um topico pelo userName do autor e slug.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| userName | string | Username do autor |
| slug | string | Slug do topico (URL-friendly) |
Response:
{
"id": "UUID",
"authorId": "UUID",
"authorName": "string",
"authorUserName": "string",
"authorProfileImage": "string | null",
"creationDate": "LocalDateTime",
"title": "string",
"slug": "string",
"topicContent": "string",
"tags": ["string"],
"likesCount": "int",
"dislikesCount": "int",
"commentsCount": "int",
"isLiked": "boolean | null",
"isDisliked": "boolean | null"
}Descricao: Deleta um topico. Requer autenticacao de autor (dono do topico).
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| topicId | UUID | ID do topico |
Response: 204 No Content
Descricao: Curtir/descurtir um topico. Requer autenticacao de autor.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| topicId | UUID | ID do topico |
Response:
{
"isActive": "boolean",
"message": "string"
}Descricao: Dar/remover dislike em um topico. Requer autenticacao de autor.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| topicId | UUID | ID do topico |
Response:
{
"isActive": "boolean",
"message": "string"
}Nota: Like e dislike sao mutuamente exclusivos. Ao dar dislike em algo que ja tem like, o like e removido automaticamente.
Descricao: Cadastra um novo comentario. Requer autenticacao de autor.
Request Body:
{
"message": "string",
"articleId": "UUID | null",
"topicId": "UUID | null",
"parentId": "UUID | null",
"tags": ["string"] | null
}Nota: Deve-se fornecer
articleIdOUtopicIdpara comentarios raiz.parentIde opcional para respostas.Nota: Ao criar um comentario, o autor recebe bugCoins automaticamente conforme configurado em
ForumConfig.coinsPerComment.
Response:
{
"message": "string",
"id": "UUID",
"content": "string"
}Descricao: Lista todos os comentarios paginados.
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
| sort | FeedSortType | RECENT | Ordenacao (RECENT, OLDEST, LIKES) |
Response:
{
"comments": [
{
"id": "UUID",
"content": "string",
"authorName": "string",
"authorUserName": "string",
"authorProfileImage": "string | null",
"authorId": "UUID",
"createdAt": "LocalDateTime",
"likes": "int",
"dislikes": "int",
"depth": "int",
"replyCount": "long",
"parentId": "UUID | null",
"articleId": "UUID | null",
"topicId": "UUID | null",
"deleted": "boolean",
"parentAuthorUserName": "string | null",
"parentTitle": "string | null",
"parentSlug": "string | null",
"isLiked": "boolean | null",
"isDisliked": "boolean | null",
"isOwner": "boolean | null",
"tags": ["string"] | null
}
],
"page": "int",
"size": "int",
"totalElements": "long",
"totalPages": "int",
"hasNext": "boolean"
}Nota: Os campos
parentAuthorUserName,parentTitleeparentSlugindicam o autor, titulo e slug do artigo/topico ao qual o comentario pertence. UseparentSlugjunto comparentAuthorUserNamepara construir URLs SEO-friendly (ex:/{parentAuthorUserName}/{parentSlug}).Nota: Os campos
isLiked,isDislikedeisOwnersao preenchidos apenas quando o usuario esta autenticado.Nota: Quando
deleted: true, os camposcontent,authorName,authorUserName,authorProfileImage,authorId,likesedislikesretornamnullou0. O comentario permanece na arvore para manter a estrutura de respostas, permitindo que o front exiba como "[comentario removido]".
Descricao: Busca comentarios raiz de um artigo (paginado).
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| articleId | UUID | ID do artigo |
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
Response: CommentPageResponse (mesmo formato acima)
Descricao: Busca comentarios raiz de um topico (paginado).
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| topicId | UUID | ID do topico |
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
Response: CommentPageResponse (mesmo formato acima)
Descricao: Busca respostas diretas de um comentario.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| commentId | UUID | ID do comentario |
Response:
[
{
"id": "UUID",
"content": "string",
"authorName": "string",
"authorUserName": "string",
"authorProfileImage": "string | null",
"authorId": "UUID",
"createdAt": "LocalDateTime",
"likes": "int",
"dislikes": "int",
"depth": "int",
"replyCount": "long",
"parentId": "UUID",
"articleId": "UUID | null",
"topicId": "UUID | null",
"deleted": "boolean",
"parentAuthorUserName": "string | null",
"parentTitle": "string | null",
"parentSlug": "string | null",
"isLiked": "boolean | null",
"isDisliked": "boolean | null",
"isOwner": "boolean | null",
"tags": ["string"] | null
}
]Descricao: Busca um comentario por ID.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| commentId | UUID | ID do comentario |
Response: CommentResponse (mesmo formato acima)
Descricao: Deleta um comentario. Requer autenticacao de autor (dono do comentario).
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| commentId | UUID | ID do comentario |
Response: 204 No Content
Nota: Se o comentario possui respostas, ele sera marcado como deletado (soft delete) e seu conteudo sera removido, mas permanecera visivel como "[comentario removido]". Se nao possui respostas, sera removido completamente (hard delete).
Descricao: Curtir/descurtir um comentario. Requer autenticacao de autor.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| commentId | UUID | ID do comentario |
Response:
{
"isActive": "boolean",
"message": "string"
}Descricao: Dar/remover dislike em um comentario. Requer autenticacao de autor.
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| commentId | UUID | ID do comentario |
Response:
{
"isActive": "boolean",
"message": "string"
}Nota: Like e dislike sao mutuamente exclusivos. Ao dar dislike em algo que ja tem like, o like e removido automaticamente.
Todas as rotas requerem autenticacao de administrador.
Descricao: Deleta um artigo (admin).
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| articleId | UUID | ID do artigo |
Response: 204 No Content
Descricao: Deleta um autor (admin).
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| authorId | UUID | ID do autor |
Response: 204 No Content
Descricao: Deleta um comentario (admin).
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| commentId | UUID | ID do comentario |
Response: 204 No Content
Descricao: Deleta um topico (admin).
Path Parameters:
| Nome | Tipo | Descricao |
|---|---|---|
| topicId | UUID | ID do topico |
Response: 204 No Content
Descricao: Lista feed unificado (artigos, topicos e comentarios).
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
| sort | FeedSortType | RECENT | Ordenacao (RECENT, OLDEST, LIKES) |
| type | FeedItemType | null | Filtro por tipo (ARTICLE, TOPIC, COMMENT) |
Response:
{
"items": [
{
"id": "UUID",
"type": "ARTICLE | TOPIC | COMMENT",
"title": "string",
"slug": "string | null",
"content": "string",
"authorId": "UUID",
"authorName": "string",
"authorUserName": "string",
"authorProfileImage": "string | null",
"createdAt": "LocalDateTime",
"likesCount": "int",
"dislikesCount": "int",
"commentsCount": "int",
"savesCount": "int",
"coverImage": "string | null",
"tags": ["string"] | null,
"parentType": "ARTICLE | TOPIC | null",
"parentAuthorUserName": "string | null",
"parentTitle": "string | null",
"parentSlug": "string | null",
"isLiked": "boolean | null",
"isDisliked": "boolean | null",
"isSaved": "boolean | null",
"isOwner": "boolean | null"
}
],
"page": "int",
"size": "int",
"totalElements": "long",
"totalPages": "int",
"hasNext": "boolean"
}Nota: O campo
sluge preenchido para itens do tipo ARTICLE e TOPIC. Para COMMENT, o slug e null.Nota: Os campos
parentType,parentAuthorUserName,parentTitleeparentSlugsao preenchidos apenas para itens do tipo COMMENT, indicando o artigo ou topico ao qual o comentario pertence. UseparentSlugpara construir URLs SEO-friendly.Nota: Os campos
isLiked,isDisliked,isSavedeisOwnersao preenchidos apenas quando o usuario esta autenticado.
Descricao: Busca artigos, topicos e comentarios que contenham pelo menos uma das tags especificadas.
Query Parameters:
| Nome | Tipo | Default | Descricao |
|---|---|---|---|
| tags | List | obrigatorio | Tags para buscar (retorna conteudos que contenham pelo menos uma) |
| type | SearchContentType | ALL | Filtro por tipo (ALL, ARTICLE, TOPIC, COMMENT) |
| sort | FeedSortType | RECENT | Ordenacao (RECENT, OLDEST, LIKES) |
| page | int | 0 | Numero da pagina |
| size | int | 20 | Tamanho da pagina |
Response:
{
"items": [
{
"id": "UUID",
"type": "ARTICLE | TOPIC | COMMENT",
"title": "string | null",
"slug": "string | null",
"content": "string",
"authorId": "UUID",
"authorName": "string",
"authorUserName": "string",
"createdAt": "LocalDateTime",
"likesCount": "int",
"isLiked": "boolean",
"coverImage": "string | null",
"tags": ["string"],
"parentType": "ARTICLE | TOPIC | null",
"parentAuthorUserName": "string | null",
"parentSlug": "string | null"
}
],
"page": "int",
"size": "int",
"totalElements": "long",
"totalPages": "int",
"hasNext": "boolean"
}Nota: O campo
sluge preenchido para itens do tipo ARTICLE e TOPIC. Para COMMENT, o slug e null.Nota: Os campos
parentType,parentAuthorUserNameeparentSlugsao preenchidos apenas para itens do tipo COMMENT, indicando o artigo ou topico ao qual o comentario pertence. UseparentSlugjunto comparentAuthorUserNamepara construir URLs SEO-friendly (ex:/{parentAuthorUserName}/{parentSlug}).
Descricao: Retorna estatisticas do forum (com cache).
Response:
{
"totalArticles": "long",
"totalTopics": "long",
"totalComments": "long"
}Endpoints de teste para verificar autenticacao.
Descricao: Dashboard do admin (requer autenticacao de admin).
Response: "Welcome to Admin Dashboard, {username}!"
Descricao: Perfil do autor (requer autenticacao de autor).
Response: "Welcome to Author Profile, {username}!"
Descricao: Endpoint publico (sem autenticacao).
Response: "This is a public endpoint!"
RECENT - Ordenar por mais recentes
OLDEST - Ordenar por mais antigos
LIKES - Ordenar por mais curtidos
ARTICLE - Artigos
TOPIC - Topicos
COMMENT - Comentarios
RECENT - Ordenar por mais recentes
OLDEST - Ordenar por mais antigos
LIKES - Ordenar por mais curtidos
SAVES - Ordenar por mais salvos (apenas para artigos)
COMMENTS - Ordenar por mais comentados
ALL - Todos os tipos de conteudo
ARTICLE - Apenas artigos
TOPIC - Apenas topicos
COMMENT - Apenas comentarios
COMMENT_ON_ARTICLE - Alguem comentou no seu artigo
COMMENT_ON_TOPIC - Alguem comentou no seu topico
REPLY_TO_COMMENT - Alguem respondeu ao seu comentario
LIKE_ARTICLE - Alguem curtiu seu artigo
LIKE_TOPIC - Alguem curtiu seu topico
LIKE_COMMENT - Alguem curtiu seu comentario
SAVE_ARTICLE - Alguem salvou seu artigo
ARTICLE - Artigo
TOPIC - Topico
COMMENT - Comentario
O sistema de bugCoins recompensa autores por suas contribuicoes no forum. As configuracoes sao gerenciadas pela entidade ForumConfig.
| Propriedade | Descricao |
|---|---|
coinsPerArticle |
Quantidade de bugCoins recebidos ao criar um artigo |
coinsPerTopic |
Quantidade de bugCoins recebidos ao criar um topico |
coinsPerComment |
Quantidade de bugCoins recebidos ao criar um comentario |
amountCoinsStart |
Quantidade inicial de bugCoins para novos usuarios |
coinsFirstArticle |
Bonus de bugCoins pelo primeiro artigo (futuro) |
coinsFirstTopic |
Bonus de bugCoins pelo primeiro topico (futuro) |
coinsFirstComment |
Bonus de bugCoins pelo primeiro comentario (futuro) |
| Propriedade | Descricao |
|---|---|
articleCreationUnlocked |
Permite criacao de artigos |
topicCreationUnlocked |
Permite criacao de topicos |
commentUnlocked |
Permite criacao de comentarios |
emailVerificationRequired |
Exige verificacao de email para criar artigos, topicos e comentarios |
storeUnlocked |
Habilita a loja (futuro) |
userTitleUnlocked |
Permite titulos personalizados (futuro) |
Nota: O saldo de bugCoins de um autor pode ser visualizado no endpoint
GET /api/authors/{userName}no campobugCoins.
O sistema de verificacao de email garante que os autores confirmem a propriedade do email cadastrado.
-
Cadastro tradicional (
POST /api/authors/create)- Email de verificacao e enviado automaticamente
emailVerified = falseate confirmacao
-
Cadastro via Google (
POST /auth/google)emailVerified = trueautomaticamente (Google ja verifica)
-
Usuario clica no link do email
- Link redireciona para
{frontend-url}/verify-email?token=xxx - Frontend chama
GET /auth/verify-email?token=xxx
- Link redireciona para
-
Resposta da verificacao
- Retorna
userNameetokende login - Frontend pode redirecionar logado para o perfil
- Retorna
Quando emailVerificationRequired = true no ForumConfig:
| Acao | Email Verificado | Resultado |
|---|---|---|
| Criar artigo | Sim | Permitido |
| Criar artigo | Nao | Erro 422: "You must verify your email before creating articles" |
| Criar topico | Sim | Permitido |
| Criar topico | Nao | Erro 422: "You must verify your email before creating topics" |
| Criar comentario | Sim | Permitido |
| Criar comentario | Nao | Erro 422: "You must verify your email before commenting" |
Nota: Quando
emailVerificationRequired = false, a verificacao de email nao e obrigatoria para nenhuma acao.