{"id":27957428,"url":"https://github.com/jchojdak/forumengine","last_synced_at":"2026-04-10T23:35:34.824Z","repository":{"id":258719979,"uuid":"855705495","full_name":"jchojdak/forumengine","owner":"jchojdak","description":"Community platform. AWS, Github Actions, Java, Spring Boot, Spring Security, Spring Data JPA, MySQL, Docker - monolithic architecture.","archived":false,"fork":false,"pushed_at":"2025-05-02T17:43:56.000Z","size":367,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-07T18:12:57.819Z","etag":null,"topics":["aws-ec2","github-actions","java-17","junit5","liquibase","mockito","mysql","spring-boot-3","spring-data-jpa","spring-security"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jchojdak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-09-11T10:26:02.000Z","updated_at":"2025-05-02T17:43:59.000Z","dependencies_parsed_at":"2024-10-20T09:57:18.454Z","dependency_job_id":"f0990a54-426b-4566-bb35-0e94b3885aea","html_url":"https://github.com/jchojdak/forumengine","commit_stats":null,"previous_names":["jchojdak/forumengine"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jchojdak/forumengine","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchojdak%2Fforumengine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchojdak%2Fforumengine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchojdak%2Fforumengine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchojdak%2Fforumengine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jchojdak","download_url":"https://codeload.github.com/jchojdak/forumengine/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchojdak%2Fforumengine/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273649440,"owners_count":25143634,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-04T02:00:08.968Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-ec2","github-actions","java-17","junit5","liquibase","mockito","mysql","spring-boot-3","spring-data-jpa","spring-security"],"created_at":"2025-05-07T18:12:56.225Z","updated_at":"2026-04-10T23:35:34.796Z","avatar_url":"https://github.com/jchojdak.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# ForumEngine\r\n\r\n\u003e [!NOTE]\r\n\u003e This application is not `business oriented` and my focus is mostly on technical part, I just want to implement a sample with using monolithic architecture pattern.\r\n\r\n\u003e [!WARNING]  \r\n\u003e This project is in progress.\r\n\r\n**~~ONLINE DEMO: [http://api.forumengine.jchojdak.com:8080/swagger-ui/index.html](http://api.forumengine.jchojdak.com:8080/swagger-ui/index.html)~~**\r\n\r\n- [About](#-about)\r\n- - [Monolithic architecture pattern](#-monolithic-architecture-pattern)\r\n- [Technology stack](#-technology-stack)\r\n- - [Backend](#-backend)\r\n- - [Frontend](#-frontend)\r\n- - [Database](#-database)\r\n- - [Testing](#-testing)\r\n- - [Containerization](#-containerization)\r\n- - [CI/CD](#-cicd)\r\n- - [Amazon Web Services](#-amazon-web-services)\r\n- [API documentation](#-api-documentation)\r\n- - [Swagger UI](#-swagger-ui)\r\n- - [Postman](#-postman)\r\n- [Starting up](#-starting-up)\r\n- [Endpoints](#-endpoints)\r\n- - [Security](#-security)\r\n\r\n## 📌 About\r\n\r\nA CRUD application where people can sign up, log in, create, update and delete posts. Additionally, users can reply to posts in the comment section and use other features. It’s a great platform for building a community where people can interact and share knowledge.\r\n\r\n\u003cimg width=\"1200\" height=\"1200\" alt=\"forumengine\" src=\"https://github.com/user-attachments/assets/5d015771-7bfd-4893-a72e-c5765ced4e45\" /\u003e\r\n\r\n### 🔗 Monolithic architecture pattern\r\n\r\n![image](https://github.com/user-attachments/assets/28a2af73-d795-4659-93f7-14ab5a477321)\r\n\r\n## 🔨 Technology stack\r\n\r\n### 💻 Backend\r\n\r\n- Java 17\r\n- Spring Boot 3.3.2\r\n- Spring Data JPA\r\n- Spring Security\r\n- Lombok\r\n\r\n### 💻 Frontend\r\n\r\n- JavaScript\r\n- React.js 18.2\r\n\r\n### 🐬 Database\r\n\r\n- MySQL 8.0\r\n- Liquibase\r\n\r\n### 🧪 Testing\r\n\r\n![code_coverage](https://github.com/user-attachments/assets/7789aeb7-46c4-4831-9f3b-6cea2bc56998)\r\n\r\nUnit \u0026 integration tests\r\n\r\n- JUnit 5\r\n- Mockito\r\n- SpringBootTest\r\n- Testcontainers\r\n\r\n### 📦 Containerization\r\n\r\n- Docker\r\n- Three containers are configured in the `docker-compose.yml` file:\r\n  - **mysql_db**: MySQL 8.0 database\r\n  - **backend**: Java 17 (Spring Boot 3.3.2) application\r\n  - **frontend**: JavaScript (React.js 18.2)\r\n\r\n### 🔁 CI/CD\r\n\r\nThis repository uses **GitHub Actions** for automatic building and testing on every `push` and `pull request` to the `master` branch.\r\n\r\nAdditionally, a complete CI/CD pipeline has been configured, which includes:\r\n\r\n- Building the application's Docker image.\r\n- Pushing the generated image to Docker Hub.\r\n- Deploying the application on an AWS EC2 instance.\r\n- Using AWS RDS as the application's database.\r\n\r\n### 🌐 Amazon Web Services\r\n\r\n- **AWS EC2**: The application is deployed on an AWS EC2 (Elastic Compute Cloud) instance.\r\n- **AWS RDS**: The application's database is hosted on AWS RDS (Relational Database Service).\r\n\r\n~~http://api.forumengine.jchojdak.com:8080~~\r\n\r\n## 📄 API documentation\r\n\r\n### 📍 Swagger UI\r\n\r\nThe application generates interactive API documentation Swagger UI (SpringDoc OpenAPI).\r\n\r\n```\r\nhttp://localhost:8080/swagger-ui/index.html\r\n```\r\n\r\n### 📍 Postman\r\n\r\nCollection to import:\r\n\r\n```\r\nhttps://github.com/jchojdak/forumengine/blob/master/postman_collection/forumengine.json\r\n```\r\n\r\n## 🚀 Starting up\r\n\r\nTo launch the application, follow the steps:\r\n\r\n1. Clone project\r\n\r\n```\r\ngit clone https://github.com/jchojdak/forumengine.git\r\n```\r\n\r\n2. Open cloned directory\r\n\r\n```\r\ncd forumengine\r\n```\r\n\r\n3. Build backend\r\n\r\n```\r\ncd backend\r\n\r\n./mvnw clean install\r\n```\r\n\r\n4. Start the application using docker-compose\r\n\r\n```\r\ndocker-compose up -d\r\n```\r\n\r\n5. Application address\r\n\r\n```\r\nBackend: http://localhost:8080\r\n\r\nFrontend: http://localhost:3000\r\n```\r\n\r\n6. Swagger\r\n\r\n```\r\nhttp://localhost:8080/swagger-ui/index.html\r\n```\r\n\r\n7. Default admin account\r\n\r\n```\r\nusername: admin\r\npassword: admin\r\n```\r\n\r\n## 📜 Endpoints\r\n\r\n| #   | Method | Endpoint                               | Description                               | Authorization                                      |\r\n| --- | ------ | -------------------------------------- | ----------------------------------------- | -------------------------------------------------- |\r\n| 1   | POST   | `/auth/register`                       | User registration                         | No                                                 |\r\n| 2   | POST   | `/auth/login`                          | User login                                | No                                                 |\r\n| 3   | PATCH  | `/auth/password`                       | Change the password of the logged in user | Yes (authenticated user)                           |\r\n| 4   | GET    | `/categories`                          | Get all categories                        | No                                                 |\r\n| 5   | POST   | `/categories`                          | Add a new category                        | Yes (admin)                                        |\r\n| 6   | GET    | `/categories/{id}`                     | Get category by ID                        | No                                                 |\r\n| 7   | DELETE | `/categories/{id}`                     | Delete category by ID                     | Yes (admin)                                        |\r\n| 8   | POST   | `/posts`                               | Add a new post                            | Yes (authenticated user)                           |\r\n| 9   | GET    | `/posts`                               | Get all posts                             | No                                                 |\r\n| 10  | GET    | `/posts/{id}`                          | Get post by ID                            | No                                                 |\r\n| 11  | DELETE | `/posts/{id}`                          | Delete post by ID                         | Yes (authenticated author or admin)                |\r\n| 12  | PATCH  | `/posts/{id}`                          | Update post by ID                         | Yes (authenticated author)                         |\r\n| 13  | POST   | `/posts/{postId}/comments`             | Add a new comment to the post             | Yes (authenticated user)                           |\r\n| 14  | GET    | `/posts/{postId}/comments`             | Get all comments                          | No                                                 |\r\n| 15  | DELETE | `/posts/{postId}/comments/{commentId}` | Delete comment by ID                      | Yes (authenticated author of the comment or admin) |\r\n| 16  | GET    | `/posts/{postId}/comments/{commentId}` | Get comment by ID                         | No                                                 |\r\n| 17  | PATCH  | `/posts/{postId}/comments/{commentId}` | Update comment by ID                      | Yes (authenticated author of the comment)          |\r\n| 18  | PATCH  | `/users`                               | Update logged in user details             | Yes (authenticated user)                           |\r\n| 19  | GET    | `/users/{userId}`                      | Get user by ID                            | No                                                 |\r\n| 20  | DELETE | `/users/{userId}`                      | Delete user by ID                         | Yes (admin)                                        |\r\n| 21  | POST   | `/users/{userId}/roles/{roleId}`       | Assign role to the user                   | Yes (admin)                                        |\r\n| 22  | DELETE | `/users/{userId}/roles/{roleId}`       | Remove role from the user                 | Yes (admin)                                        |\r\n\r\n### 🔑 Security\r\n\r\nTo access some resources you need to use `header` authorization.\r\n\r\n```\r\nAuthorization: Bearer \u003ctoken\u003e\r\n```\r\n\r\nThe token can be generated using POST `/login` endpoint.\r\n\r\n### 1. User registration\r\n\r\n**Endpoint:** `/auth/register`\r\n\r\n**Method:** `POST`\r\n\r\n**Request body:**\r\n\r\n```json\r\n{\r\n  \"username\": \"example\",\r\n  \"password\": \"ExamplePassword\",\r\n  \"email\": \"example.example@gmail.com\"\r\n}\r\n```\r\n\r\n### 2. User login\r\n\r\n**Endpoint:** `/auth/login`\r\n\r\n**Method:** `POST`\r\n\r\n**Request body:**\r\n\r\n```json\r\n{\r\n  \"username\": \"example\",\r\n  \"password\": \"ExamplePassword\"\r\n}\r\n```\r\n\r\n### 3. Change the password of the logged in user\r\n\r\n**Endpoint:** `/auth/password`\r\n\r\n**Method:** `PATCH`\r\n\r\n**Request body:**\r\n\r\n```json\r\n{\r\n  \"oldPassword\": \"oldPassword123\",\r\n  \"newPassword\": \"newPassword123\"\r\n}\r\n```\r\n\r\n### 4. Get all categories\r\n\r\n**Endpoint:** `/categories`\r\n\r\n**Method:** `GET`\r\n\r\n### 5. Add a new category\r\n\r\n**Endpoint:** `/categories`\r\n\r\n**Method:** `POST`\r\n\r\n**Request body:**\r\n\r\n```json\r\n{\r\n  \"name\": \"exampleNameOfCategory\",\r\n  \"description\": \"exampleDescription\"\r\n}\r\n```\r\n\r\n### 6. Get category by ID\r\n\r\n**Endpoint:** `/categories/{id}`\r\n\r\n**Method:** `GET`\r\n\r\n### 7. Delete category by ID\r\n\r\n**Endpoint:** `/categories/{id}`\r\n\r\n**Method:** `DELETE`\r\n\r\n### 8. Add a new post\r\n\r\n**Endpoint:** `/posts`\r\n\r\n**Method:** `POST`\r\n\r\n**Request body:**\r\n\r\n```json\r\n{\r\n  \"categoryId\": 1,\r\n  \"title\": \"Example post title\",\r\n  \"content\": \"Example post content\"\r\n}\r\n```\r\n\r\n### 9. Get all posts\r\n\r\n**Endpoint:** `/posts`\r\n\r\n**Method:** `GET`\r\n\r\n**Request parameters:**\r\n\r\n- `page` (Integer, optional): The page number to retrieve. Default value is 0.\r\n- `size` (Integer, optional): The number of posts per page. Default value is 10.\r\n- `sort` (Sort.Direction, optional): The sorting direction. Default value is ASC.\r\n- `categoryId` (Long, optional): Get by category ID. Not required.\r\n\r\n_Example:_ `/posts?page=3\u0026size=20\u0026sort=DESC\u0026categoryId=2`\r\n\r\n### 10. Get post by ID\r\n\r\n**Endpoint:** `/posts/{id}`\r\n\r\n**Method:** `GET`\r\n\r\n### 11. Delete post by ID\r\n\r\n**Endpoint:** `/posts/{id}`\r\n\r\n**Method:** `DELETE`\r\n\r\n### 12. Update post by ID\r\n\r\n**Endpoint:** `/posts/{id}`\r\n\r\n**Method:** `PATCH`\r\n\r\n**Request body:**\r\n\r\n```json\r\n{\r\n  \"title\": \"Example new title\",\r\n  \"content\": \"Example new content\"\r\n}\r\n```\r\n\r\n### 13. Add a new comment to the post\r\n\r\n**Endpoint:** `/posts/{postId}/comments`\r\n\r\n**Method:** `POST`\r\n\r\n**Request body:**\r\n\r\n```json\r\n{\r\n  \"content\": \"Example comment content\"\r\n}\r\n```\r\n\r\n### 14. Get all comments\r\n\r\n**Endpoint:** `/posts/{postId}/comments`\r\n\r\n**Method:** `GET`\r\n\r\n**Request parameters:**\r\n\r\n- `page` (Integer, optional): The page number to retrieve. Default value is 0.\r\n- `size` (Integer, optional): The number of posts per page. Default value is 10.\r\n- `sort` (Sort.Direction, optional): The sorting direction. Default value is ASC.\r\n\r\n_Example:_ `/posts/{postId}/comments?page=3\u0026size=20\u0026sort=DESC`\r\n\r\n### 15. Delete comment by ID\r\n\r\n**Endpoint:** `/posts/{postId}/comments/{commentId}`\r\n\r\n**Method:** `DELETE`\r\n\r\n### 16. Get comment by ID\r\n\r\n**Endpoint:** `/posts/{postId}/comments/{commentId}`\r\n\r\n**Method:** `GET`\r\n\r\n### 17. Update comment by ID\r\n\r\n**Endpoint:** `/posts/{postId}/comments/{commentId}`\r\n\r\n**Method:** `PATCH`\r\n\r\n**Request body:**\r\n\r\n```json\r\n{\r\n  \"content\": \"Example new content\"\r\n}\r\n```\r\n\r\n### 18. Update logged in user details\r\n\r\n**Endpoint:** `/users`\r\n\r\n**Method:** `PATCH`\r\n\r\n**Request body:**\r\n\r\n```json\r\n{\r\n  \"firstName\": \"John\",\r\n  \"lastName\": \"Smith\",\r\n  \"mobile\": \"+48123123123\",\r\n  \"email\": \"john.smith@gmail.com\"\r\n}\r\n```\r\n\r\n### 19. Get user by ID\r\n\r\n**Endpoint:** `/users/{userId}`\r\n\r\n**Method:** `GET`\r\n\r\n### 20. Delete user by ID\r\n\r\n**Endpoint:** `/users/{userId}`\r\n\r\n**Method:** `DELETE`\r\n\r\n### 21. Assign role to the user\r\n\r\n**Endpoint:** `/users/{userId}/roles/{roleId}`\r\n\r\n**Method:** `POST`\r\n\r\n### 22. Remove role from the user\r\n\r\n**Endpoint:** `/users/{userId}/roles/{roleId}`\r\n\r\n**Method:** `DELETE`\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchojdak%2Fforumengine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjchojdak%2Fforumengine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchojdak%2Fforumengine/lists"}