{"id":15106937,"url":"https://github.com/stjepanoviccc/sitpass","last_synced_at":"2026-01-18T00:22:49.670Z","repository":{"id":248292312,"uuid":"828281470","full_name":"stjepanoviccc/sitpass","owner":"stjepanoviccc","description":"Sitpass, Fitness Web Application","archived":false,"fork":false,"pushed_at":"2024-07-13T16:54:02.000Z","size":3543,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-11T09:42:29.549Z","etag":null,"topics":["angular","docker","hibernate","jasmine","junit","postgresql","springboot"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stjepanoviccc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2024-07-13T16:52:11.000Z","updated_at":"2024-07-13T16:57:45.000Z","dependencies_parsed_at":"2024-07-13T19:17:05.658Z","dependency_job_id":null,"html_url":"https://github.com/stjepanoviccc/sitpass","commit_stats":null,"previous_names":["stjepanoviccc/sitpass"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stjepanoviccc%2Fsitpass","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stjepanoviccc%2Fsitpass/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stjepanoviccc%2Fsitpass/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stjepanoviccc%2Fsitpass/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stjepanoviccc","download_url":"https://codeload.github.com/stjepanoviccc/sitpass/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247345703,"owners_count":20924098,"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","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":["angular","docker","hibernate","jasmine","junit","postgresql","springboot"],"created_at":"2024-09-25T21:03:26.278Z","updated_at":"2026-01-18T00:22:49.644Z","avatar_url":"https://github.com/stjepanoviccc.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sitpass - Fitness App\n![Spring Boot](https://img.shields.io/badge/Spring%20Boot-black?logo=springboot)\n![Spring Security](https://img.shields.io/badge/Spring%20Security-black?logo=springsecurity)\n![PostgreSQL](https://img.shields.io/badge/PostgreSQL-blue?logo=postgresql\u0026logoColor=white)\n![Hibernate](https://img.shields.io/badge/Hibernate-red?logo=hibernate\u0026logoColor=white)\n![Docker](https://img.shields.io/badge/Docker-blue?logo=docker\u0026logoColor=white)\n![Mockito](https://img.shields.io/badge/Mockito-yellow?logo=mockito\u0026logoColor=white)\n![JUnit](https://img.shields.io/badge/JUnit-brightgreen?logo=junit\u0026logoColor=white)\n![MockMVC](https://img.shields.io/badge/MockMVC-brightgreen?logo=mockmvc\u0026logoColor=white)\n![Angular](https://img.shields.io/badge/Angular-red?logo=angular\u0026logoColor=white)\n![Tailwind CSS](https://img.shields.io/badge/Tailwind%20CSS-blue?logo=tailwind-css\u0026logoColor=white)\n![Karma](https://img.shields.io/badge/Karma-yellow?logo=karma\u0026logoColor=white)\n![Jasmine](https://img.shields.io/badge/Jasmine-brightgreen?logo=jasmine\u0026logoColor=white)\n![Chart.js](https://img.shields.io/badge/Chart.js-brightgreen?logo=chartdotjs)\n\n## Technologies Used\nMain technologies which are used in this project are **Angular**, **Spring Boot** and **PostgreSQL**.\n\n## Overview:  \nSitpass is an application that is very similar to fitpass. It provides recreation and sports services to different cities and countries...  You can read specification for better understanding of app:  \n\nThe **user** of the application has the following functionalities at his disposal:  \n[K1] User registration request. Received registration requests are processed\nsystem administrator (requirement A1). The system administrator is a predefined user in the\nsystem.  \n[K2] Login and logout from the system. When the user successfully logs in to the application\nallow the user to log out. Without logging into the system, it is not possible to access the rest\napplications.  \n[K3] Handling1 objects. Mandatory object fields are city, address, object description,\ndisciplines and working hours. Only the system administrator can handle the object, while\nfacility manager can update facility attributes such as disciplines, working hours\nand impressions. The object may or may not contain images. If it contains them, it must contain them\nmore of them. In addition to the name of the object, show the total, mean value of the object's rating.  \n[K4] Reservation of departure (eng. excercise) to the facility. When making a reservation, the user\nspecifies the date of departure and the time period of the appointment. It is not possible to book an appointment outside\nworking hours of the facility.  \n[K5] Leaving an impression (English review) on the object. When writing, an impression is formed\nrate the object and optionally leave a comment. It is possible to evaluate the object based on the impression\naccording to: 1) equipment; 2) staff; 3) hygiene; 4) room; on a scale of 1-10, where\neach of the listed items has its own rating. Users can only leave an impression\nif they have at least one departure in the given facility at the time of writing the impression. On the\nin the review, display information on how many departures the user has been on at the time of writing\nreviews.  \n[K6] Search and filter objects. It is possible to search all objects in the city,\ndiscipline, grade range or working hours. It is possible to combine search and\nfiltering by multiple cities, disciplines, grade ranges and working hours.  \n[K7] Sorting impressions. On the object's page, it is possible to sort the impressions by ratings and\ndate of publication ascending and descending.  \n[K8] Overview of the home page. Users see objects from it on the home page\ncity ​​as well as a registered user. Users also see: 1) \"most popular objects\",\nthat is, facilities with the most positive ratings; 2) facilities to which the user has already visited; 3)\n\"try new\" objects, ie 5 objects that the user of the system has not been on before\nbooked departure and whose discipline is not a discipline that the user has been to before.\nGive the user the option to explore more new objects by clicking the \"explore more\" button.  \n[K9] Change password. When changing the password, the current password is first entered twice\na new password is entered. After changing the password, an email is sent to the user.  \n[K10] Changing additional data on the profile as well as the picture. You can see the list on the profile\nof all impressions, objects on which the user is the manager and the history of visits to objects for\nof the given user.  \n\nThe facility **manager** has available all the functionalities that he has and registered\nuser as well as:  \n[M1] Update of disciplines, working hours and published pictures on the facility.  \n[M2] Impression handling. The manager has insight into all the impressions that have been left on\nobject by the user and can hide or remove individual impressions. Removed\nimpressions are logically deleted and the grade from the impression is canceled and is not counted in the total grade\nof the object. Marks left on the hidden impression are still counted in the total mark\nof the object.  \n[M3] Leaving a comment on an impression. It is possible to reply to an impression.\nIf the manager has responded to the impression, an ordinary user can respond to\nmanager's comment. An arbitrary number of replies to a comment is possible (reply to\nreply to reply...).  \n[M4] Analytics of objects. For each object the user is on\nmanager, it is possible to see the number of users and the number of object reviews by default\nweekly, monthly and yearly. It is possible to see the periods of the day in which\nwere the most or least users of the facility (most or least traffic periods)\non a daily, weekly and monthly basis. In addition to the default levels, enable\noverview of each of the analytics for a randomly defined time range (start and end\ndate). [For KVT subject]: Use a graphics library for visualization, like\nChart.js, Apache ECharts or similar.  \n\nThe system **administrator** has at his disposal all the functionalities that the manager has\nfacility and registered user, but also:  \n[A1] continuation to K1. Processing of registration requests. The administrator has the right to\naccept or reject the registration request. The user can only log in to the system\nwhen the registration request is accepted. After the request is processed, the user is\nsends an email.  \n[A2] continuation to K3. Facility management and facility managers. Administrator\ncan assign the system user the object manager role. It is possible to add\nremove managers from the facility. A manager that is removed from an object becomes plain\nthe user. If the object has no manager, the object becomes inactive and no\nis displayed in the list of available objects. It is not possible to reserve for inactive objects\nleaving or making an impression. The administrator has insight into all inactive objects and can\nassign a manager, whereby the object goes into active status.  \n\n\n## Getting Started:  \nThere are two different ways to start this project, you can pick to start with on local or docker.  \nI keep them with different branches because there are some changes in configuration so I made it cleaner this way.  \n\n### Start with Docker (branch: main):  \nTo start this project you need to have installed **Docker** and **Docker Compose**. \nIn **docker-compose.yml** in **sitpass-backend** service you will need to change next line:  \n**volumes: - /home/andrej/Projects/sitpass/sitpass-images:/sitpass-images**  \n... Change this **/home/andrej/Projects** path to path where you have cloned/downloaded this repo ... It will be mapped  to **/sitpass-images** (You have sitpass-images folder in root of project with some random images i used to develop project, feel free to use these.)  \nNavigate to root of your project and run **docker-compose up --build** and your app should start.  \n\n**NOTE**: If you get problem with build, you may need to kill services on your local machine.  \nIn order to do that you need next set of commands:  \n\n**Linux**:  \n1. sudo lsof -i :PORT_NUMBER\n2. sudo kill -9 PID\n   \n**Windows**:\n1. netstat -ano | findstr :PORT_NUMBER\n2. tasklist /FI \"PID eq PID_NUMBER\"\n3. taskkill /PID PID_NUMBER /F\n\n   \n### Local Start (branch: local-start-v1):  \nTo start this project locally you need to have installed **JDK17**, **Postgresql**, **Node.js** and **Angular CLI**.\nCreate database with name sitpass_db and you need to change paths from AppConfig based on your preferences **/home/andrej/Projects** is path that need to be changed:  \n\n1. public static final String IMAGE_PATH = \"/home/andrej/Projects/sitpass/sitpass-images\";\n2. public static final String ABSOLUTE_PATH = \"/home/andrej/Projects/sitpass/sitpass-backend/\";  \n   \nAlso you have init.sql file if you want to include some data.\n\n\n## Spring Security:  \nIn this project I implemented **JWT(Json Web Token)** for Authentication.  \nThere are two different roles in this app **(USER, ADMIN)** and subrole **MANAGER**.  \nThere is comprehensive documentation which I have provided in overview to check which role have access to specific endpoints.\n\n## Error Handling:  \n**Global Exception Handling**: Spring Boot's global exception handling mechanism is employed to manage and respond to exceptions effectively throughout the application. This ensures consistency and reliability in handling various types of errors.  \n\n**NotFoundException**: For model-related errors, such as when a requested resource is not found, the application utilizes a custom NotFoundException. This exception is thrown when attempting to access a resource that does not exist, providing clear feedback to the client.  \n\n**BadRequestException**: In cases of technical errors or invalid requests, the application employs BadRequestException. This exception is used to indicate problems with the client's request, such as malformed input or missing parameters. By utilizing this exception, the application can provide meaningful error messages and guide clients towards resolving their requests.  \n\n**UnauthorizedException**: When a client attempts to access a resource without proper authentication or authorization, the application throws UnauthorizedException. This exception signals that the request lacks the necessary credentials or permissions to perform the operation, prompting clients to authenticate or obtain appropriate authorization.\n\n## Testing:  \nSitpass app has been thoroughly tested to ensure reliability and functionality across its features.  \n\n**Unit Tests**  \nUnit tests were implemented to test individual components, methods, and classes in isolation. These tests validate the correctness of business logic and ensure that each unit behaves as expected.   \n\n1. JUnit: Used for writing and executing unit tests.\n2. Mockito: Employed for mocking dependencies and verifying interactions between components.\n3. Jasmine: Used for unit testing Angular components.\n4. Karma: Test runner for executing JavaScript tests.\n\n\n## Deploy:  \n### Dockerfile  \nThe multistage Dockerfiles for this application optimizes the Docker image build process by leveraging separate stages for build and runtime environments. This approach enhances efficiency, security, and maintainability of the Docker image, adhering to best practices for Java application deployment in Docker containers.  \n\n**BACKEND - BUILD STAGE**:  \n\n**Base Image - maven:3.8.4-openjdk-17**: This stage starts with a Maven image that includes JDK 17, suitable for building Java applications.  \n**Working Directory: /app**: Sets the working directory within the container where the application source code will be copied and built.  \n**Copy Files**: Copies pom.xml and the entire src directory into the container also copies the sitpass-bucket directory into the container.     \n**Build Application**: Executes mvn clean package -DskipTests to build the application. It cleans build enviroment, then package and skip tests during build process to speed up process.  \n\n**BACKEND - RUNTIME STAGE**:  \n\n**Base Image: openjdk:17-jdk-slim**: This stage starts with a minimal OpenJDK 17 image, optimized for runtime.  \n**Volume:**: Defines a volume mount point at /tmp, allowing the application to write temporary files inside the container.    \n**Copy Artifact**: Copies the built JAR file (app/target/*.jar) from the build stage into the current runtime stage, renaming it to app.jar.      \n**Entry Point**: Defines the command to run when the container starts. java -jar /app.jar executes the JAR file as the main application entry point.  \n\n**FRONTEND - BUILD STAGE**:  \n\n**Base Image - node:22-alpine3.19**: This stage starts with a Node.js image based on Alpine Linux, suitable for building Angular applications due to its lightweight nature.  \n**Working Directory - /app**: Sets the working directory within the container where the application source code will be copied and built.  \n**Copy Files**: Copies the package.json and package-lock.json files into the container.  \n**Install Angular CLI and Dependencies**:  \n1. Installs the Angular CLI globally using npm install -g @angular/cli.  \n2. Installs the project dependencies using npm install --force.  \n**Copy Application Code**: Copies the entire application code into the container.  \n**Build Application**: Executes ng build to build the Angular application. The build artifacts will be stored in the dist/sitpass-frontend/browser directory.\n\n**FRONTEND - RUNTIME STAGE**:\n**Base Image - nginx:alpine**: This stage starts with a minimal Nginx image based on Alpine Linux, optimized for serving static files.  \n**Copy Build Artifacts**: Copies the built Angular application from the build stage (/app/dist/sitpass-frontend/browser) to the Nginx default HTML directory (/usr/share/nginx/html).  \n**Copy Nginx Configuration**: Copies a custom Nginx configuration file (nginx.conf) into the Nginx configuration directory.  \n**Expose Port**: Exposes port 80 to allow access to the application via HTTP.  \n**Entry Point**: Defines the command to run when the container starts. nginx -g 'daemon off;' starts Nginx in the foreground.  \n\n### docker-compose.yml  \n\nThis Docker Compose file defines a multi-container setup for Sitpass app, including PostgreSQL for the database, Angular for frontend and SpringBoot for backend part. Here's an explanation of each section:  \n\n### Services:  \n\n**1. sitpass-db**:    \n\n**Image**: Uses the official PostgreSQL image.  \n**Environment Variables**: Configures environment variables required for PostgreSQL:  \n1. **POSTGRES_USER**: Specifies the PostgreSQL username as postgres.  \n2. **POSTGRES_PASSWORD**: Specifies the password for the PostgreSQL user as root.  \n3. **POSTGRES_DB**: Specifies the name of the PostgreSQL database as sitpass_db.  \n**Ports Mapping**: Maps port 5432 of the host machine to port 5432 of the PostgreSQL container, allowing access to the PostgreSQL service from outside the container.  \n**Volumes**: Mounts a volume (db_data) to persist PostgreSQL data and init.sql for data initialize.  \n\n**2. sitpass-frontend**:  \n\n**Build**: Building dockerfile from **sitpass-front**.  \n**Ports Mapping**: Maps port 80 of the host machine to port 80 of container.  \n\n**3. sitpass-backend**:  \n\n**Build**: Builds the EMS application using the Dockerfile (Dockerfile) in the current context .  \n**Ports**: Maps host port 8080 to container port 8080 for the app.  \n**Volumes**: Maps local image file system to /sitpass-images which you can use for creating and uploading images.  \n**Enviroment Variables**:  \n1. **SPRING_DATASOURCE_URL**: JDBC URL to connect to PostgreSQL (jdbc:postgresql://psql-db:5432/sitpass_db).  \n2. **SPRING_DATASOURCE_USERNAME**: PostgreSQL username (postgres).  \n3. **SPRING_DATASOURCE_PASSWORD**: PostgreSQL password (root).  \n4. **SPRING_JPA_HIBERNATE_DDL_AUTO**: Hibernate DDL auto strategy.  \n**Depends On**: Specifies dependencies on sitpass-db.\n**Command**: Executes Maven test (./mvnw test) command when starting the container.\n\n**NOTE**: Ensure that **Docker** and **Docker Compose** are installed on your system and that there are no conflicts with ports already in use by other applications. Adjust configurations as needed based on your specific development environment and requirements also **IF YOU FACE ANY PROBLEM, PLEASE CONTACT ME :)**\n\n## Author\n\n**Andrej Stjepanović**  \nStudent at the **Faculty of Technical Sciences** in Novi Sad  \nUndergraduate of Software Engineering\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstjepanoviccc%2Fsitpass","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstjepanoviccc%2Fsitpass","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstjepanoviccc%2Fsitpass/lists"}