[{"content":" JPA - JPQL - DAO # The goal of this phase was to make the persistence layer reflect the real domain: users, register, products. Registrations may have receipts, and products have warranties. I implemented JPA mappings between User, Product, ProductRegistration, Receipt, and Warranty, then built a DAO layer that standardizes CRUD operations through IDAO\u0026lt;T\u0026gt; and uses JPQL for queries that traverse relationships (implemented in RetrieveDAO and selected methods in UserDAO/SecurityDAO).\nA key focus was avoiding overly complex objects: data are handled explicitly (for example with JOIN FETCH when needed), and delete behavior is handled deliberately to avoid unintended cascades.\npublic User getByIDWithRegistrations(Long id) { try (EntityManager em = emf.createEntityManager()) { try { return em.createQuery( \u0026#34;SELECT DISTINCT u FROM User u \u0026#34; + \u0026#34;LEFT JOIN FETCH u.registrationlist \u0026#34; + \u0026#34;WHERE u.id = :id\u0026#34;, User.class) .setParameter(\u0026#34;id\u0026#34;, id) .getSingleResult(); } catch (NoResultException e) { throw new EntityNotFoundException(\u0026#34;No entity found with id: \u0026#34; + id); } } } Issues related to retrieving users with or without a registrationlist caused LazyInitializationException when trying to retrieve users with a registrationlist, using LEFT JOIN FETCH ensures that a user is still returned even if the specific user has no registrationlist.\nWhat # Implemented the persistence layer using JPA by defining the entities User, Product, ProductRegistration, Receipt, and Warranty, along with their relationships. A DAO structure was introduced through IDAO\u0026lt;T\u0026gt;, with concrete implementations such as RetrieveDAO, UserDAO, and SecurityDAO.\nCustom JPQL queries were added to handle relational data, including getByIDWithRegistrations(Long id), which uses LEFT JOIN FETCH to retrieve a User together with its registrationlist.\nWhy # The main problem was ensuring reliable retrieval of related data without encountering LazyInitializationException, while keeping the domain model simple and maintainable. There was also a need to avoid excessive cascading and unintended side effects in persistence operations.\nConstraints included maintaining clear entity relationships, ensuring predictable data access for API use, and supporting testability without overly complex configurations.\nDesign reasoning (tradeoffs) # Aspect Description Choice Use explicit JPQL queries with JOIN FETCH for controlled loading of relationships Alternative(s) Default fetch types (EAGER / LAZY) and cascading strategies Not chosen Default strategies can cause inefficient queries or LazyInitializationException, while cascading may introduce unintended persistence operations Risks downsides More verbose queries and tighter coupling between query logic and entities Mitigations Centralize query logic in DAO classes and reuse methods for consistency Next step Introduce DTOs to handle larger datasets and improve performance ","date":"3 February 2026","externalUrl":null,"permalink":"/Portfolio/posts/warranty/week1/","section":"Posts","summary":"","title":"Introduction","type":"posts"},{"content":" SendGrid \u0026amp; Retsinformation # Integrated external RESTful APIs into the portfolio project to enhance functionality. The Retsinformation API was used to fetch legal documents in XML format, which were parsed using XMLExtractor into LawDataDTO objects and persisted via LawDataDAO. Additionally, the SendGrid API was used to send email notifications for warranties approaching expiration. The WarrantyScheduler class checks all warranties daily and triggers notifications at 90, 60, 30, and 0 days before expiration.\nRetsinformation API returns XML and SendGrid API returns JSON.\nWhy # The goal was to extend the project with real-world REST API integration. Fetching legal data ensures the system stays aligned with current regulations, although it does not directly impact the end-user functionality, it ensures compliance with current legal regulations. Automated warranty notifications improve user experience and prevent expired warranties from being overlooked. Constraints included ensuring reliable API communication, correct XML parsing from REST responses, and safe scheduling of notifications without blocking main application execution.\nTester # Commented TestClassFactory.testClassWarranty(); method in App class. Used to test if SendGrid API works while deployed. Test class checks when a warranty is expired and sends Email notification every 5 minutes because of watchtower when program runs while deployed.\npublic static void testClassWarranty() { User testUser = new User(); testUser.setEmail(\u0026#34;YourEmail@gmail.com\u0026#34;); testUser.setCreatedAt(LocalDateTime.now()); testUser.setPassword(\u0026#34;12345678\u0026#34;); userDAO.create(testUser); Warranty testWarranty = new Warranty(); testWarranty.setStartDate(LocalDate.now().minusMonths(3)); testWarranty.setWarrantyMonths(3); testWarranty.calculateEndDate(); Product product = new Product(); product.setOwner(testUser); product.setProductName(\u0026#34;Test Product\u0026#34;); product.setWarranty(testWarranty); testWarranty.setProduct(product); productDAO.create(product); scheduler.checkWarranties(); } Design reasoning (tradeoffs) # Aspect Description Choice Use dedicated services (XMLExtractor and WarrantyScheduler) to handle RESTful API responses and notifications Alternative(s) Fetch REST data synchronously on the main thread, or send notifications manually without an API Not chosen Synchronous fetching could block application operations; manual notifications would not scale and are error-prone Risks downsides Possible API failures, malformed XML, or missed notifications if the scheduler fails; increased system complexity Mitigations Use exception handling for REST responses, validate XML data, and schedule daily checks with ScheduledExecutorService for reliability ","date":"3 February 2026","externalUrl":null,"permalink":"/Portfolio/posts/warranty/week2/","section":"Posts","summary":"","title":"Restful API","type":"posts"},{"content":" BCrypt \u0026amp; JWT # Implemented core security features in the backend. A PasswordService was added to hash and verify user passwords using BCrypt before persistence. JWT-based authentication was introduced through SecurityControllerService, which handles token creation and validation using JwtTokenService. Tokens are generated during authentication and verified on protected endpoints by extracting them from the Authorization header. Role-based access control was also introduced to restrict endpoint access based on user roles.\nA record-based DTO, AuthUserDTO, was introduced to represent authenticated user data (email and roles) within the token. This DTO is used when generating and validating JWTs, and when enforcing role-based access control on protected endpoints.\nTokens are extracted from the Authorization header and validated per request to ensure secure access to the API.\npublic record AuthUserDTO(String email, Set\u0026lt;String\u0026gt; roles){} Why # The goal was to secure user data and ensure safe authentication within the application. Storing raw passwords is insecure, making hashing necessary to protect user credentials. JWT authentication enables stateless and scalable session management, which is suitable for REST APIs. Constraints included ensuring secure handling of secrets, preventing unauthorized access, and maintaining a clear separation between authentication logic and business logic.\nDesign reasoning (tradeoffs) # Aspect Description Choice Use BCrypt for password hashing, JWT for authentication, and a record-based DTO (AuthUserDTO) to represent authenticated user data Alternative(s) Store plain-text passwords, use session-based authentication, or use a mutable class instead of a record for the DTO Not chosen Plain-text storage is insecure; session-based authentication is less scalable; mutable DTOs increase the risk of unintended modification of security-related data Risks downsides JWTs cannot easily be invalidated before expiration; records are less flexible if the DTO structure needs to change Mitigations Use token expiration, validate tokens on each request, store secrets securely, and extend the record if additional fields are required ","date":"3 February 2026","externalUrl":null,"permalink":"/Portfolio/posts/warranty/week3/","section":"Posts","summary":"","title":"Security","type":"posts"},{"content":" Requests \u0026amp; Tests # Implemented RESTful endpoints for the application using Javalin, covering user and security operations such as /security/register, /security/login, /user/all, and /user/{id}. Requests are tested using an HTTP client setup (http-client.env.json) to support both local and deployed environments, with JWT tokens included in the Authorization header for protected routes.\nIntegration tests were implemented using JUnit and RestAssured. A containerized PostgreSQL database (Testcontainers) is used to run tests in an isolated environment. Tests cover authentication, endpoint protection, and validation, including scenarios such as successful login, unauthorized access, and invalid input handling.\nThe image demonstrates manual testing of the REST API using curl, performed due to the absence of a frontend. A user is registered and then logs in to be authenticated, after which a JWT token is returned and used to authorize access to protected endpoints.\nThe image shows testing of a protected REST endpoint using the browser’s developer console. A fetch request is sent to /user/all with a JWT token included in the Authorization header. The successful response demonstrates that authentication is working and that access to protected resources is granted when a valid token is provided.\nWhy # The goal was to expose application functionality through a REST API and ensure it behaves correctly under different scenarios. REST endpoints allow structured communication between client and backend, while testing ensures reliability and prevents regressions. Constraints included maintaining stateless authentication using JWT, ensuring endpoints are properly secured, and running tests in an environment that closely resembles production.\nDesign reasoning (tradeoffs) # Aspect Description Choice Use REST principles with Javalin, JWT for securing endpoints, and integration testing with JUnit + RestAssured + Testcontainers Alternative(s) Manual testing only, in-memory database testing, or session-based authentication Not chosen Manual testing is unreliable and not repeatable; in-memory databases do not reflect real database behavior; session-based authentication breaks REST stateless design Risks downsides Increased setup complexity for tests (containers, ports); slower test execution due to real database usage Mitigations Use Testcontainers for consistent environments, dynamic ports to avoid conflicts, and automated test setup/teardown to ensure isolation ","date":"3 February 2026","externalUrl":null,"permalink":"/Portfolio/posts/warranty/week4/","section":"Posts","summary":"","title":"REST \u0026 Test","type":"posts"},{"content":" Deployment \u0026amp; DevOps # Implemented a full deployment pipeline for the application using Docker and cloud infrastructure. The application is containerized using a Dockerfile and deployed on an Ubuntu VM hosted on DigitalOcean.\nContinuous Integration and Deployment (CI/CD) is handled using GitHub Actions, where the application is built using Maven, containerized, and pushed to Docker Hub on each push to the main branch. The deployed environment uses Docker Compose to manage services, including the application container and Watchtower, which automatically monitors Docker Hub for new image versions and updates the running container without manual intervention.\nA reverse proxy is configured using Caddy, which routes traffic from a domain (warrantyproject.greymansshop.dk) to the application container. HTTPS is automatically handled via SSL certificates. Environment variables are managed through a .env file to securely configure database connections, JWT secrets, and API keys.\nname: Login to Docker Hub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Build and push uses: docker/build-push-action@v4 with: context: . file: ./Dockerfile push: true tags: ${{ secrets.DOCKERHUB_USERNAME }}/warranty_project:latest The snippet shows the CI/CD workflow responsible for building and deploying the application. After authenticating with Docker Hub, the workflow sets up Docker Buildx, builds the application image from the Dockerfile, and pushes it to Docker Hub. This updated image is then automatically detected by Watchtower on the server, which pulls the latest version and redeploys the container without manual intervention.\nWhy # The goal was to create a scalable and automated deployment process that minimizes manual intervention. Containerization ensures consistency across environments, while CI/CD automates the build and deployment pipeline. Watchtower further reduces manual deployment effort by automatically updating containers when new images are available. Using a reverse proxy with HTTPS improves security and accessibility, and cloud hosting enables the application to be publicly available.\nConstraints included ensuring secure handling of sensitive data (e.g., API keys and secrets), maintaining near zero-downtime updates, and keeping the deployment process reproducible and maintainable.\nDesign reasoning (tradeoffs) # Aspect Description Choice Use Docker for containerization, GitHub Actions for CI/CD, Docker Hub for image storage, Watchtower for automated container updates, and Caddy for reverse proxy and HTTPS Alternative(s) Manual deployment via SSH, traditional VM setups without containers, or using Nginx instead of Caddy Not chosen Manual deployment is error-prone and not scalable; non-containerized setups reduce portability; Nginx requires more manual configuration for SSL compared to Caddy Risks downsides Increased system complexity; reliance on external services; automatic updates may introduce unstable versions Mitigations Use health checks, controlled update intervals in Watchtower, and environment variables for secure configuration ","date":"8 March 2026","externalUrl":null,"permalink":"/Portfolio/posts/warranty/week5/","section":"Posts","summary":"","title":"Deployment \u0026 DevOps","type":"posts"},{"content":" Hey, I\u0026rsquo;m Daniel — Some Call Me Shay # My journey into tech started early, driven by a fascination with computers and, admittedly, mostly games. At the time, I had no real understanding of the creativity and effort that goes into building technology — that perspective came later.\nMy first hands-on experience with software came from setting up Linux on my personal machine. It was challenging and at times overwhelming, but working through it built a solid foundation and a problem-solving mindset that has stayed with me since.\nI am an aspiring Full-Stack Developer with a strong focus on Frontend Development. I enjoy building websites from the ground up — crafting responsive, accessible, and interactive user experiences. Translating ideas into clean, functional interfaces is where I do my best work.\nAlongside frontend development, I have experience building backend systems with an emphasis on performance, scalability, and clean architecture.\n","date":"8 March 2026","externalUrl":null,"permalink":"/Portfolio/","section":"","summary":"","title":"","type":"page"},{"content":" You are welcome to give me feedback on any of my projects! # ","date":"8 March 2026","externalUrl":null,"permalink":"/Portfolio/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":" Warranty Project # Full System Documentation \u0026amp; Development Report # Comprehensive documentation of the design, development, and implementation of a web-based warranty tracker\n1. Introduction # The Warranty Project is developed as part of a third-semester Computer Science program. The purpose of the project is to provide a system that allows users to track and manage product warranties digitally, reducing reliance on physical documentation.\nThe application focuses on simplifying warranty management by centralizing information such as products, registrations, and expiration dates. This enables users to easily monitor their warranties and avoid losing important information stored on paper.\nObjectives:\nDigitize the process of tracking warranties Ensure that users can keep track of warranties in case they are lost or misplaced Model a real-world application that automates warranty tracking after product registration Implement a maintainable and scalable architecture for future improvements 2. Background # Warrantour aims to keep track of products, warranties, and receipts.\nNormally, users must keep track of:\nWhere did I put the receipt? When does my warranty expire? Manually calculating expiration dates Searching through emails or paper documents for warranty information Project goal: so that maintaining an overview and remembering important details is no longer an issue.\n3. Business Understanding # Customer Journey:\nRegister products During registration, provide warranty date and receipt View products on profile Delete or keep products with expired warranties Business Requirements:\nWarranty expiry is calculated based on purchase date and warranty duration Purchase date cannot be changed after registering a product Expired warranties are read-only Only the owner has access to product and warranty data ","date":"3 February 2026","externalUrl":null,"permalink":"/Portfolio/posts/warranty/","section":"Posts","summary":"","title":"Warranty - Introduction","type":"posts"},{"content":"","externalUrl":null,"permalink":"/Portfolio/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/Portfolio/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","externalUrl":null,"permalink":"/Portfolio/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"","externalUrl":null,"permalink":"/Portfolio/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"}]