Navigating Data Discrepancies in Development

Last week, I had the opportunity to develop a new feature. It was specifically designed for cleaning up items data as their data count is erroneous due to the experiment and error logic across the application. Addressing these issues was crucial for resolving bugs in future fixes. The new feature I worked on aimed to rectify these data discrepancies. When a user clicks a designated button, the feature automatically cleans up the data.

I began by outlining the necessary tasks in Trello and understanding the database’s data flow where the data originated, where it was headed, and which parts needed cleaning. I brainstormed and devised a theoretical framework for the cleanup process.

To kickstart the project, I created a new cleanup folder within the project feature directory and defined essential CQRS components in the command and commandHandler. I meticulously determined the placement of a new service and registered it accordingly. With the fundamental groundwork in place, I concentrated on the logic required to retrieve and recalculate the data before updating them. During this brainstorming phase, I also developed the basic page layout, aligning it with the structure of the main list page. My initial draft of the logic for the clean up service consisted of a list of items that users wanted to clean up, each item paired with its corresponding data.

At this point, Mr. Peter noticed my confusion and patiently explained the key aspects I needed to understand. He emphasized the importance of using a list of Barcodes from the UI. From these Barcodes, I had to calculate the correct data and compare them. If disparities were found, the newly calculated data should overwrite the inaccurate data. Unfortunately, my progress was cut short at the end of the week, and will continue working on this task in this coming week.

Attention to Detail and Lessons from Bug Resolutions

Over the past few weeks, I dedicated my time to identifying and resolving bugs and errors in the recently developed feature. Mr. Peter provided me with a list of critical bugs that surfaced during production, requiring immediate attention to ensure the application runs smoothly and error-free for users.

Some of these bugs were unforeseeable, but others resulted from my oversight. This experience taught me the importance of meticulous attention to detail and comprehensive testing across various scenarios. Most of the issues originated from the Module, such as a problem where the comboBox of an entity in a view page failed to display any address information. I resolved this issue by including the address in the Context and mapping it to the UI.

Furthermore, enhancements were implemented to improve the user experience. One concern involved the lack of a clear indicator for obsolete data on the entity view page’s user interface. It was crucial for users to distinguish between outdated and current information. To resolve this issue, I introduced a new column in the view list. Additionally, I modified the entity’s comboBox by setting the Obsolete status to false, guaranteeing that only the most recent entities were displayed. Later, Mr. Peter noticed that I had employed GetAwaiter().GetResult in a section of my code, causing asynchronous operations to be blocked and their results fetched synchronously. This synchronous blocking of asynchronous code can significantly impair performance, especially in applications requiring swift responsiveness. Consequently, Mr. Peter suggested transitioning to using await asynchronous and incorporating Loading Bar dialog. This change ensured that users were kept informed about the loading process, eradicating the frustration of waiting for an unspecified action.

Throughout the process of resolving these bugs, I encountered a significant challenge related to parent-child relationships. Even after deleting data, the parent name persisted when navigating to the next set of data. Initially, I attempted to solve this issue by creating a new list, intending to refresh the data. However, this approach did not address the root cause of the bug. It was only after Mr. Peter explained the underlying issue that I realized my mistake. I had failed to fully grasp the nature of the bug and hastily attempted a solution without a complete understanding.

From this experience, I learned the importance of approaching problems with a deeper understanding before attempting solutions. Rushed attempts to fix issues without fully comprehending the underlying complexities can lead to ineffective solutions and wasted effort. It emphasized the significance of thorough analysis, seeking guidance when needed, and acknowledging the continuous learning process in software development.

Feature Testing and SQL Script Generation from Latest Migrations

Last week, as a continuation from the previous week, Mr. Peter demonstrated the process of generating certificates with expiration dates a few months from now. These certificates were meant to replace the old ones and could only be used in a designated location. Unfortunately, a portion of the code contained an error, possibly due to a minor oversight. In the initial hours, I made efforts to identify and resolve the bugs. Regrettably, I’m uncertain about the source of the problem and how to rectify it, leading me to revert back to the previous certificate system and moving on to the next task.

Transitioning to the next task, I was tasked with identifying any issues in a new feature introduced by Mr. Peter. After multiple tests, so far, there are no errors in this feature. Consequently, I proceeded to the subsequent task, which involves cleaning up the data. While I was in the process of establishing the basic CQRS pattern on the application side and adding a button in the module side, I received another assignment to uncover bugs in another part of the application system. Prioritizing this task is crucial since it also aligns with the cleanup initiative.

Reflecting on last week’s progress, I also learnt something new: generating an SQL script from the latest migration. Initially, I believed I had to perform this task using SQL, but Mr. Peter guided me in the correct approach. To generate an SQL script from the latest migration, I first ensured that the EF Core CLI was installed in the migration folder. Next, I listed the migrations that had been created and inserted a command to generate the SQL script for the most recent migration.

Identifying and Resolving Bugs in New Feature

Last week, I was assigned the task of identifying bugs in a new feature introduced by Mr. Peter. Initially, I began by familiarizing myself with the feature, exploring various functionalities, and observing how data submissions were handled. Later in the day, Mr. Peter provided me with a guided tour of the feature, which significantly improved my understanding of its intricacies. With a clearer picture in mind, I delved into the testing phase, aiming to uncover as many bugs as possible to ensure a smooth and error-free production process.

I documented the bugs I discovered on a Trello board in the form of a checklist. Most of the issues were related to the user interface (UI). Mr. Peter then suggested to mark the list of errors with the ones I intended to address. I selected a few and left aside the remaining errors that I wasn’t confident in resolving.

Around mid-week, Mr. Peter tasked me to replace a dependency I had been using with its source code. This step was crucial for debugging and resolving the identified bugs. It took me a while to replace it because I encountered a few problems after doing it and needed some time to figure them out. 

Subsequently, I began tackling the smaller bugs on the list. However, during one of my attempts to fix an issue, Mr. Peter supplied valuable guidance on a different approach, pointing out the root cause of the problem and to reconsider my approach, which turns out resulted in a simpler and more sensible solution.

Towards the end of the week, Mr. Peter demonstrated how to generate certificates that would expire in a few months, replacing the old ones and ensuring they were used in only one designated location. Unfortunately, a part of the code had an error, possibly stemming from a minor oversight. However, as the week came to a close, I had to postpone addressing this issue until the following week.

Configuration Setup

During the previous week, my primary focus was resolving a query related to the entity’s unfulfilled list, ensuring the accurate transmission of data. Initially, I crafted a comprehensive query that retrieves all data without any specific conditions. Once I confirmed the success of this initial test, I proceeded to construct a query with two main conditions. These conditions revolved around the status of the fulfillment date, if it was enabled, the query would retrieve a list of unfulfilled dates based on certain criteria, otherwise, it would generate the standard list. Following thorough testing to ensure the correctness of these implementations, I committed the changes before transitioning to my next task.

My subsequent task involved updating a migration in accordance with Mr. Peter’s instructions. Later on, I moved on to the next task, which entailed pulling changes from another branch for a new feature update. During the initial attempt to pull these changes, I encountered a conflict stemming from a test. After successfully resolving the conflict and merging the changes without issues, I proceeded to rebuild the application.

Continuing to follow the provided guide, I encountered errors, one of which was due to my oversight in not copying the necessary files from cloud before editing and using them. This experience taught me to always remember to update files into my own folders instead of directly using them from cloud. Various tasks, including migration, setting up DBs, configuring certificates, and establishing the access key, were primarily handled by Mr. Peter due to my limited competence in following instructions and addressing bugs throughout the process.

The week concluded with Mr. Peter introducing me to the new feature, with my upcoming responsibilities focused on bug identification and prompt reporting to Mr. Peter if any issues arise. Although last week was marked by significant debugging, stemming from my own limitations, I am determined to learn from these experiences and avoid repeating similar mistakes in the future.

Progress on Implemented Feature: Developing Get List Query for the entity

Continuing from the previous week, while wrapping up the implementation of a new feature, I encountered an issue stemming from an outdated wrapper that constrained my ability to configure it according to my requirements. To address this, I took the initiative to create a new wrapper tailored specifically for the feature. However, this decision necessitated adding mappings for the new wrapper. As I approached the final mapping for the feature, Mr. Peter noticed that I had been using the wrong service throughout the process. This led to me creating a read operation for the entity’s list using the CQRS pattern. To guide me, Mr. Peter provided a similarly-pattern example from another entity.

I started by making a specific folder for the entity’s Get List Query, initialising the properties query, and creating the List Dto. The Get List Query Handler class that I created later implemented the IRequestHandler interface and took control of handling the request to obtain a list of entities. It used a particular service interface and the IMapper. I followed the example given within the Handle function, but I soon realised that a new service was needed to obtain the entity list because the current service was unable to satisfy the conditions required. Additionally, I also added a new controller responsible for handling GET requests to retrieve a list of entities based on query and also provide Swagger documentation for the API.

My next step involved creating a new service exclusively for retrieving the entity’s list. Initially, I designed a straightforward query to retrieve the list without any specific conditions. Nevertheless, I made sure the methods were implemented asynchronously.  By implementing these methods in an asynchronous manner, I ensure that the retrieval operations can be performed efficiently and non-blocking. This enables better scalability and responsiveness in the application, especially when dealing with a large number of entities or concurrent requests. To validate the correctness of my implementation, I incorporated unit tests that verified successful scenarios for Read List methods. These tests employed a client to emulate HTTP requests and validate the returned status codes and data.

With the foundational work on the backend completed, I shifted my focus to the UI to confirm that data was being transmitted correctly as intended. After some debugging, I successfully verified its functionality and the data was passing. However, the week concluded, and in the upcoming week, my priority is to ensure that the query for retrieving the list functions flawlessly before I can proceed to the next task.

A Week of Feature Implementation

Last week presented an exciting challenge as I embarked on adding a new feature to an existing entity. The task involved creating a dialog that would display a filtered list of orders based on their fulfillment date, allowing users to conveniently cancel orders that had passed their fulfillment date. To kickstart the project, I organized my plan on Trello, ensuring a clear roadmap for the upcoming tasks.

I began by establishing a new view page, harmonizing its design with the entity’s main page to maintain consistency in user interface. With the interface in place, I moved on to the view model, where I initialized the necessary properties for data binding. Ensuring that the properties were successfully linked with the view, I focused on populating the DataGrid with the list of entities. As I delved into modifying the query to fit the desired conditions, a realization struck: the current service I was using at the time didn’t provide the fulfillment date to match the needed requirements.

Seeking guidance, I consulted Mr. Peter, who advised me to tweak the existing service rather than creating a new one. Following his advice, I made the necessary adjustments to the service to accommodate the desired functionality. With the list loading seamlessly, I directed my attention to enhancing the user experience by enabling the selection and deselection of all orders through checkboxes.

Although I successfully bound the checkboxes and established their interaction mechanism, a stumbling block emerged. The binding required the usage of DataContext and ancestor properties, a revelation kindly pointed out by Mr. Peter. His guidance clarified this issue and explained the mechanics behind it.

Moving ahead, I tackled the cancel order functionality, laying out the logic and implementing the function to update cancellation quantities. At this juncture, Mr. Peter recommended incorporating a progress bar dialog due to the potentially extensive list of orders to cancel. Implementing this not only improved the user experience but also added a practical element to the feature.

My only issue remained the inability to refresh the list after successfully cancelling an order, with all other components functioning without a hitch. I turned to Mr. Peter for advice, which he advised using ‘Dispatch.Invoke’. Although I initially found myself puzzled and embarked on reading about threads and dispatch, I still lacked a clear understanding of their usage. To my pleasant surprise, Mr. Peter demonstrated the process, and it turned out to be a concise solution of just three lines of code. As a result, the pages now function perfectly. The first objective for this week is to make a few changes to the page before moving on to the task.

Resolving Issues and New Feature in Sights

The past week was occupied by debugging and troubleshooting sessions to ensure the seamless functionality of the sandbox application for the upcoming task. I continued to test the data entry pages for each entity to ensure that they could be saved and edited successfully, building on the work I had done the week before, which involved developing three unique seed generators for various entities. 

However, I encountered an issue with editing one of the entities, which prompted me to dive into another round of debugging in order to identify and resolve the error. Despite spending a considerable amount of time on this, the source of the error remained unresolved Fortunately, later in the day, Mr. Peter aided me. He assessed the error and stated that it may be related to the function I was using. He pointed me in the direction of a different function, one more suited to the seed generator of this specific entity.

The following morning brought a pleasant surprise, as everything operated smoothly without any errors cropping up. In an effort to introduce diversity and practicality to the generated data rather than producing the same type repeatedly I incorporated the use of the Random() function. This allowed the application to select data at random from the available options whenever new seed data was being created.

With the application’s functionality well in hand, Mr. Peter assigned me a fresh task: implementing additional features within an entity’s list page. Specifically, the task involved on unfulfilled orders that had surpassed their fulfillment dates, and granting them the ability to cancel these orders. After the briefing, I comprehended the feature’s concept and proceeded to outline the necessary steps to plan out the execution of the task in the upcoming week.

Emerging Issues with Mapping and Batch Seed Data Generators

Following the successful generation of batch commits as previously discussed, I delved into the primary reason for the creation of the seed generator over the last week. This objective was to facilitate testing of the pages and an entity combo box, employed within a dropdown button. The goal was to monitor the response and ensure the correct appearance of the dropdown button, as well as accurate data display. In line with Mr Peter’s predictions, the button that should have displayed a comprehensive list of entities was not displayed as expected.

To address this, I initiated a debugging phase. My digging eventually led me to the conclusion that the problem could be solved by adjusting the query’s page size limit when invoking the list of entities. Due to my lack of knowledge about setting up an unlimited page size, I initially manually set the page size to display 100,000 entries. Mr. Peter, thankfully, provided guidance, recommending the use of “-1” to indicate an unlimited page size. After getting familiar with this method, the entity successfully transmitted its whole list without issue.

Following that, I discovered another entity within the seed data generator that did not yet have 5000 records. It also revealed a new error that only appeared when attempting to generate over 100 records on the fly, halting at 100. My first thought was that there was an issue with the entity mapping because I wasn’t able to edit any existing data for this entity. After I successfully solved the mapping issue, I attempted to create 5000 data entries once more. Regrettably, this endeavor failed once more, with an error message referencing time parsing.  The issue was ultimately resolved after I adjusted the date format inside a method that processes a list of objects in batches, that was generating and accumulating SQL INSERT statements to save the object data into a database using batch operations. 

My next attempt was met with yet another setback, this time with an error message indicating a ‘batch too large’ problem. Looking for solutions from other developers who faced similar issues from stack overflow, I discovered that inserting multiple inserts (> 10) into a batch for can have a negative impact on performance. As a result, increasing the batch limit was not an option. After some experimentation, I discovered that only by setting the batch maximum to 15 was I able to generate data that exceeded the 100-entry threshold.

Generating Batch Commit

Continuing from last week’s progress, I needed to add two more seed generators, each representing different entities. This time, the process was more straightforward as I didn’t have to register for additional classes. All I had to do was initialize the required data and create buttons for each entity. Once the setup was done, I eagerly tested the new additions to see if everything was functioning correctly. After a few debugging sessions, I confirmed that both new seed generators were working as intended.

I decided to test the app with 1,000 entities first. The test took an average of 2 minutes to complete, which was reasonable and within an acceptable range. However, a larger workload was actually the goal which is to generate 10,000 for this one entity and 5,000 for another 2 entities.

Feeling ambitious, I decided to raise the stakes and test the app with 5,000 entities this time. To my dismay, the process took significantly longer, stretching beyond 10 minutes. During this time, the entire application froze, and it was evident that the main thread was being used to create all 5,000 data, causing the freezing issue.

Thankfully, Mr. Peter taught me how to create the entities in batches, implementing BackgroundWorker to handle the process more efficiently. This way, the application wouldn’t freeze, and users could continue interacting with it while the data was being generated in the background. By implementing BackgroundWorker, the app was now capable of handling large data generation tasks while keeping the user interface responsive. The experience was smooth, even with 5,000 entities being generated. The background process took some time, but the users could still interact with the app, explore other functionalities, and initiate new data generation tasks without any hindrance.

Furthermore, I enhanced the text box input interface responsible for specifying the desired number of data to be generated. This improvement ensured that non-numeric input was restricted from being displayed on the screen. By following Mr. Peter’s recommendation, I took cues from another entity’s UI to achieve an overall design improvement. In conclusion, the addition of two more seed generators increased the application’s diversity and complexity. Thanks to Mr. Peter’s guidance and the successful integration of BackgroundWorker, the app’s performance and user experience were significantly boosted.