Completing In-Memory Cache with Expiry

Monday, July 21, 2025 – Last week, I continued my work by implementing the in-memory cache for the query I built earlier. I started by drafting an initial structure based on what Mr. Peter previously explained. Later, he provided an example using Microsoft’s IDistributedCache.

To avoid repeating cache logic across the codebase, I encapsulated the caching functionality into a reusable cache service. This service allows caching data by simply passing a unique key and the data list. The data is serialized and stored in memory. To retrieve the cache, we just pass the same key.

I also implemented a time-based expiration using DistributedCacheEntryOptions, so that cached items are automatically removed after a set duration. However, as Mr. Peter pointed out, we must also guard against unbounded cache growth. So I added a cache size limit to prevent excessive memory usage.

To handle cases where the cache reaches its size limit, I implemented a cache eviction policy to remove the oldest entry before adding a new one. Since standard in-memory cache doesn’t track insertion order, I built a registry system to track the order of cached items. This registry makes it possible to identify and remove the oldest entry when needed.

By the end of the week, I had fully implemented the caching system. The last remaining task was to ensure that all related cache entries are cleared when the underlying data changes (specifically when the quantity of a cached entity is updated). I created a method to clear all relevant caches and, with Mr. Peter’s help, integrated this method into the necessary update flows.

Creating an API Query and UI Integration

Monday, July 14, 2025 – Last week, I was assigned to build a new API query for an existing UI. Previously, the UI directly accessed the repository without going through an API layer. To improve separation of concerns and promote loose coupling, I was tasked to create an API query so that the UI now communicates with a proper API endpoint instead of directly interacting with the repository. This helps enforce dependency inversion, where the higher-level UI module no longer depends on lower-level data modules directly, but instead communicates through defined interfaces (API).

In addition to creating the new query, I was also tasked with implementing caching for this API but without using Redis. Instead, I would need to use in-memory caching. Before tackling the cache, I focused on completing the query.

One key difference with this new query is that it pulls two separate item lists from two different databases, yet still returns them in a single response. Despite the difference, the implementation remained relatively straightforward.

Once the query was complete, I wrote a simple test and moved on to the next task: implementing the UI. I followed the previous design pattern with one main difference. Previously, the system used two separate views merged into one page. However, since the new query provides both lists in one call, only one view and one view model were needed. This change helped simplify the UI structure.

By the end of the week, I had completed the UI. However, more testing and refinement are still needed, especially since this UI will be reused in multiple features. I also need to finalize the caching mechanism, which I plan to continue next week.

Query Filters, and Hosted Service

Monday, June 23, 2025 – My first task last week was to update and rearrange the UI for the a printing feature in the Next.js project. After discussing the expected result with Mr. Peter, I immediately began working on the UI changes. I started by changing the layout from vertical to horizontal to reduce unnecessary scrolling for the user. Then, I refined each section individually, adjusting styles to make the design appear cleaner and more user-friendly, without altering the core logic. Once the UI updates were complete, I conducted thorough testing to ensure everything worked without bugs.

After completing that, I moved on to another task: adding new UI filters to reflect the updated API list queries. These included additional query parameters. After implementing one feature, I carefully verified all other related features to make sure no API query properties were missed. Missing such updates could trigger errors, making this a critical step.

Later in the week, I was assigned a new task, creating a hosted service to update MongoDB whenever changes were made in the main system. Mr. Peter guided me through the intended logic and even provided examples. I rushed to complete the implementation before the week ended. Although I managed to finish writing the code, I didn’t get a chance to properly test the logic or notify the team before pushing my changes.

Resolving UI Bugs on the Next.js Project

Monday, July 7, 2025 – Last week, I conducted thorough testing on the Next.js project to identify and resolve as many unhandled errors and bugs as possible. Several minor issues were uncovered, and I worked swiftly to address each one before moving on to the next.

One notable bug occurred on the detail view page, where an image viewing feature was integrated. If the image size extended to half the height of the page, the top and bottom parts of the image became hidden. Fortunately, this bug was found as it would be a critical bug since user won’t be able to close the page. Thankfully this was an easy fix, by enabling scroll on the page and making minor layout adjustments, the issue was resolved.

Another more intriguing bug appeared on the entity number adjustment page. When a user entered a value into the final input field and pressed “Enter,” a confirmation dialog was expected to appear. However, pressing “Enter” on one of the dialog buttons did not trigger any action, unless it was pressed twice. After investigating, I discovered that the issue stemmed from the main page using ref.focus, which interfered with the alert dialog’s focus.

To resolve this, I introduced a useState variable to track whether the focus was currently on the alert dialog or the main page. Additionally, I enhanced the GeneralAlert component to automatically focus the primary action button when the alert appears. These changes successfully resolved the issue.

Towards the end of the week, I was assigned an interesting new task, which I look forward to continuing this week.

Export Page and Browser Limitations

Monday, June 30, 2025 – My first task last week was to add a new feature to the Next.js project, a UI page for exporting data. I began by designing the UI, which included a date range selector (start and end dates) and buttons necessary for triggering data export. Once the UI layout was polished, I tested the date picker and buttons to ensure they worked as expected.

One of the main goals for this page was to allow users to choose a local folder where exported files would be saved. Initially, I was able to trigger the folder picker popup successfully. However, selecting a folder consistently threw errors. Upon further investigation, I discovered that while this functionality works on desktop applications, browsers restrict access to full file paths (e.g., C:/exports) for security and privacy reasons. Instead, APIs like showDirectoryPicker() only provide a secure handle to the selected folder without revealing its actual path. Due to these browser limitations, the original objective couldn’t be achieved. As a workaround, I adjusted the functionality so users only need to click one button, and the exported file will automatically download to their default Downloads folder.

Import Page Simplification and UI Refinements

Monday, June 16, 2025 –  Last week, I returned to the Next.js project. My first task was to create a new page for the Import Entity feature. Fortunately, the process was simple and straightforward, I only needed to add logic to retrieve files and send them directly to the API. I didn’t have to handle any filtering or validation, as all the data processing was managed on the backend. The implementation was notably clean and efficient, thanks to Mr. Peter’s foresight in designing a simplified UI experience.

Later on, I was also assigned to make a few minor updates to existing features from the backend and reflect those changes on the UI side.

Integrating Entity and Enhancing API Query Logic

Monday, June 9, 2025 –  Previously, I was working on updating a new small entity, which I’ll refer to as Entity D in this writing. The goal was to integrate this entity into the update command of an existing item entity. After some trial and error, the implementation was finally successful when I discovered that certain renamed fields needed to remain consistent in order to map correctly.

Following that, I moved on to the next task, which involved updating the API list query for the item entity. This new task included incorporating Entity D that I had previously added. Additionally, I was required to extend the query by introducing several conditional booleans. What set this API apart from the previous ones was that it combined data from both MongoDB and MySQL, with only minimal logic changes needed for the integration.