{"id":20019,"date":"2025-10-30T20:12:38","date_gmt":"2025-10-30T20:12:38","guid":{"rendered":"https:\/\/www.ruoomsoftware.com\/?p=20019"},"modified":"2025-10-30T21:38:17","modified_gmt":"2025-10-30T21:38:17","slug":"code-review-2-evaluating-the-ai-generated-google-calendar-export","status":"publish","type":"post","link":"https:\/\/www.ruoomsoftware.com\/ko\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/","title":{"rendered":"Code Review 2: Evaluating the AI-Generated Google Calendar Export"},"content":{"rendered":"<p>We recently published a <a href=\"https:\/\/www.ruoomsoftware.com\/ko\/llm-prompting-experiment-publishing-events-from-ruooms-crm-to-google-calendar\/\" target=\"_blank\" rel=\"noreferrer noopener\">blog<\/a> describing our LLM-prompting experiment in which we created a Google Calendar export\/publication feature. The feature allows users to publish events within the Ruoom open source CRM calendar to their personal Google Calendar.<\/p>\n\n\n\n<p>Just like our <a href=\"https:\/\/www.ruoomsoftware.com\/ko\/llm-prompting-experiment-integrating-a-google-calendar-into-ruooms-crm\/\" target=\"_blank\" rel=\"noreferrer noopener\">first LLM prompting experiment<\/a> (<a href=\"https:\/\/www.ruoomsoftware.com\/ko\/code-review-evaluating-the-ai-generated-google-calendar-integration\/\" target=\"_blank\" rel=\"noreferrer noopener\">and as noted in our first review blog<\/a>), we ended the blog with a functional feature that did what we asked of the LLM.\u00a0<\/p>\n\n\n\n<p>But just because it\u2019s a working feature doesn\u2019t make it a good feature, or one that won\u2019t cause issues in our larger codebase.<\/p>\n\n\n\n<p>In this blog, we\u2019ll take a look under the hood at the code quality.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><strong>Reviewing the Code<\/strong><\/strong><\/h2>\n\n\n\n<p>We have all of our code posted to our public repository: <a href=\"https:\/\/github.com\/Ruoom\/ruoom-core\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/Ruoom\/ruoom-core\/<\/a><\/p>\n\n\n\n<p>The code for this experiment was pushed to a specific branch found at: <a href=\"https:\/\/github.com\/Ruoom\/ruoom-core\/tree\/llm_experiment\/gcal_export\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/Ruoom\/ruoom-core\/tree\/llm_experiment\/gcal_export<\/a><\/p>\n\n\n\n<p>We have isolated only the changes made by the LLM at the commit: <a href=\"https:\/\/github.com\/Ruoom\/ruoom-core\/commit\/0413561261a2fc01caf72e097c516abe6e171060\">https:\/\/github.com\/Ruoom\/ruoom-core\/commit\/0413561261a2fc01caf72e097c516abe6e171060<\/a><\/p>\n\n\n\n<p>Let\u2019s start by reviewing the files that have changed:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"285\" height=\"588\" src=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-31.png\" alt=\"\" class=\"wp-image-20023\" srcset=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-31.png 285w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-31-145x300.png 145w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-31-6x12.png 6w\" sizes=\"auto, (max-width: 285px) 100vw, 285px\" \/><\/figure>\n\n\n\n<p>The LLM did not create any files, so we can isolate the files with meaningful edits to the code worth reviewing in this blog:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>schedule.js<\/li>\n\n\n\n<li>schedule.html<\/li>\n\n\n\n<li>administration\/urls.py<\/li>\n\n\n\n<li>administration\/views.py<\/li>\n\n\n\n<li>registration\/models.py<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong><strong><strong>Populating Skeleton Events (schedule.js)<\/strong><\/strong><\/strong><\/h2>\n\n\n\n<p>In the LLM prompting experiment, we began with core open source code that did not natively support a database model for events. To populate events, we created a skeleton<em> Event<\/em> object based on our <a href=\"https:\/\/www.ruoomsoftware.com\/ko\/code-lab\/\" target=\"_blank\" rel=\"noreferrer noopener\">Booking plugin<\/a>. All this occurred prior to letting the LLM loose on the code.<\/p>\n\n\n\n<p>When we began with the LLM, we asked it to start by adding events to our CRM calendar. It has done this in an efficient manner which is very similar to how Google Calendar events were added in our first blog experiment:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"657\" height=\"492\" src=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-32.png\" alt=\"\" class=\"wp-image-20024\" srcset=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-32.png 657w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-32-300x225.png 300w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-32-16x12.png 16w\" sizes=\"auto, (max-width: 657px) 100vw, 657px\" \/><\/figure>\n\n\n\n<p>However, not to be annoyingly repetitive, but the removal of the first <em>Events<\/em> line we don\u2019t think is necessary, and it will interfere with our Booking plugin code. We discussed this at length in our last review blog, so let\u2019s move on.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Publish Calendar Button (schedule.html)<\/strong><\/h2>\n\n\n\n<p>In our Schedule page, the LLM has simply added a button to manually publish the CRM calendar to Google Calendar:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"373\" height=\"71\" src=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-33.png\" alt=\"\" class=\"wp-image-20025\" srcset=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-33.png 373w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-33-300x57.png 300w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-33-18x3.png 18w\" sizes=\"auto, (max-width: 373px) 100vw, 373px\" \/><\/figure>\n\n\n\n<p>Reminder of our original prompt:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><em>I need you to create a feature by which a user might publish the objects in the Events database to their personal Google Calendar account.<\/em><\/p>\n<\/blockquote>\n\n\n\n<p>The LLM has decided to make this a manual, one-off action, not a continuous sync. You could argue that our prompt left this open to interpretation, so fine.<\/p>\n\n\n\n<p>A continuous sync of events would be more functional than a manual push-button, but this at least addresses our request and proves the concept.<\/p>\n\n\n\n<p>We will be going in-depth into the UI\/UX design of the LLM in a future blog, but for this review we\u2019ll just call out the complete lack of a UI that the LLM chose to create here. When the user clicks the button for the first time, they are taken to a Google Single Sign-on page. After this, there is no feedback given to the user whether they are currently synced or if the \u201cPublish\u201d was successful.<\/p>\n\n\n\n<p>In the first Google Calendar integration experiment regarding importing events, the LLM created a UI element indicating <em>Google Calendar Connected.<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"135\" src=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-34-1024x135.png\" alt=\"\" class=\"wp-image-20027\" srcset=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-34-1024x135.png 1024w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-34-300x40.png 300w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-34-768x101.png 768w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-34-18x2.png 18w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-34.png 1382w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Last time, we thought this was bare minimum. This time, we\u2019ve learned just how many corners the LLM might cut.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"482\" src=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-35.png\" alt=\"\" class=\"wp-image-20029\" srcset=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-35.png 640w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-35-300x226.png 300w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-35-16x12.png 16w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/figure>\n\n\n\n<p>A simple <em>Connected<\/em> badge would have been valuable, or some varying UI elements depending if the user was already authenticated.<\/p>\n\n\n\n<p>Finally, the biggest issue with the UI on this page was that the first <em>Publish<\/em> button press doesn\u2019t actually <em>Publish<\/em>; it just authenticates the user. Users have to click <em>Publish<\/em> a second time to get it to actually work, and are greeted with this charming page:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"627\" height=\"120\" src=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-36.png\" alt=\"\" class=\"wp-image-20032\" srcset=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-36.png 627w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-36-300x57.png 300w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-36-18x3.png 18w\" sizes=\"auto, (max-width: 627px) 100vw, 627px\" \/><\/figure>\n\n\n\n<p>It has never been more clear that the LLM will not build you common-sense UI elements unless you explicitly ask for them.<\/p>\n\n\n\n<p>Stay tuned for a future blog when we dive into this in more detail.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Augmented Event Model for Google ID (registration\/models.py)<\/strong><\/h2>\n\n\n\n<p>In order to synchronize &amp; update events between Ruoom and Google, the LLM thought it necessary to add one new property to our Event model:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"165\" src=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-37-1024x165.png\" alt=\"\" class=\"wp-image-20033\" srcset=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-37-1024x165.png 1024w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-37-300x48.png 300w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-37-768x124.png 768w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-37-18x3.png 18w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-37.png 1162w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>This was a great idea.<\/p>\n\n\n\n<p>It serves an important function and it is well executed. No notes!<\/p>\n\n\n\n<p>Without this property, Ruoom would be constantly creating events in Google, not knowing if they were already created.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Back-end Google Integration (administration\/urls.py and views.py)<\/strong><\/h2>\n\n\n\n<p>The LLM made 4 URL endpoints for this integration:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ScheduleEvents<\/li>\n\n\n\n<li>GoogleOAuthStart<\/li>\n\n\n\n<li>GoogleOAuthCallback<\/li>\n\n\n\n<li>PublishEventsToGoogleCalendar<\/li>\n<\/ul>\n\n\n\n<p>Looking at views.py, we can evaluate each back-end function.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><strong>ScheduleEvents<\/strong><\/p>\n\n\n\n<p>ScheduleEvents is the endpoint created to populate the Schedule page calendar with the skeleton Event database model. It receives a <em>start date, end date, and location<\/em><strong><em> <\/em><\/strong>from the front end and returns a list of events as a JSON response. It seems to have decent error handling. But where it does the event filtering, we\u2019re seeing a small problem:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"417\" height=\"183\" src=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-38.png\" alt=\"\" class=\"wp-image-20034\" style=\"width:581px;height:auto\" srcset=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-38.png 417w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-38-300x132.png 300w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-38-18x8.png 18w\" sizes=\"auto, (max-width: 417px) 100vw, 417px\" \/><\/figure>\n\n\n\n<p>In this <strong>if\/then block<\/strong>, the LLM is trying to filter events in <em>qs<\/em> that start after <em>start_dt <\/em>and end before <em>end_dt<\/em> (by the way, the variable name qs is weird and we don\u2019t know what it\u2019s supposed to stand for\u2026).<\/p>\n\n\n\n<p>However, the first <strong>if statement<\/strong>, which is supposed to check both <em>start_dt <\/em>and <em>end_dt<\/em>, only checks for <em>end_dt<\/em>! We\u2019re not filtering based on <em>start_dt <\/em>at all and eventually we\u2019re going to crash the front end by asking it to render a thousand events at once. We only had 2 events in the database this time so we didn\u2019t notice the issue.<\/p>\n\n\n\n<p>To fix it, we\u2019d probably just remove the first <strong>if statement <\/strong>altogether and let it filter independently on <em>start_dt<\/em><strong><em> <\/em><\/strong>and <em>end_dt<\/em>.<br><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">GoogleOAuthStart and GoogleOAuthCallback<\/h3>\n\n\n\n<p>These two functions serve the same purposes as functions written by the LLM in the last experiment. Comparing the two implementations, we can make the following observations:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>In the first experiment, the LLM used a series of smaller functions to break up commonly used code (DRY: Don\u2019t Repeat Yourself).\n<ul class=\"wp-block-list\">\n<li>In the second, each function was a longer series of commands with no sub-functions.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>In the first, the LLM had functions untethered to any larger class.\n<ul class=\"wp-block-list\">\n<li>In the second, each function was a formal View class.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Both implementations preserve the same general sequence of API actions for performing OAuth.<\/li>\n\n\n\n<li>Both implementations are very sparse in their use of comments.<\/li>\n\n\n\n<li>Neither implementation encrypted user credentials in the database. Come on, are we the only ones who see that?<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"956\" height=\"736\" src=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-30-at-2.37.30\u202fPM.png\" alt=\"\" class=\"wp-image-20040\" srcset=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-30-at-2.37.30\u202fPM.png 956w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-30-at-2.37.30\u202fPM-300x231.png 300w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-30-at-2.37.30\u202fPM-768x591.png 768w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/Screenshot-2025-10-30-at-2.37.30\u202fPM-16x12.png 16w\" sizes=\"auto, (max-width: 956px) 100vw, 956px\" \/><\/figure>\n\n\n\n<p>In summary, the use of DRY code makes the first implementation stronger. However, we prefer the View class usage of the second implementation. These are subjective differences, but the best code would be obtained by taking the best parts of each implementation. And adding more comments.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">PublishEventsToGoogleCalendar<\/h3>\n\n\n\n<p>This endpoint runs the primary function of our feature. It fetches Google OAuth credentials, fetches a list of events to push, and submits the new or updated events to Google Calendar. If the event already exists in Google Calendar, it simply updates the event. All of this works well from a user\u2019s perspective (as long as they are already authenticated), which is a great start.<\/p>\n\n\n\n<p>The first thing we notice is there is not a <strong>single<\/strong> comment. Ugh for real.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-40-1024x576.png\" alt=\"\" class=\"wp-image-20041\" srcset=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-40-1024x576.png 1024w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-40-300x169.png 300w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-40-768x432.png 768w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-40-18x10.png 18w, https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/image-40.png 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Next, if the user is not authenticated, the function redirects them straight to OAuth. There is no mechanism to redirect a user from OAuth back to this function, meaning the user has to click the button a second time to get the <em>Publish<\/em> to work. Not great.<\/p>\n\n\n\n<p>The next observation: <\/p>\n\n\n\n<p>When it fetches events to push to Google Calendar, it filters the database for ALL EVENTS before publishing them one by one. This is highly likely to slow down or time-out our app at some point.<\/p>\n\n\n\n<p>To avoid a crash, we should simply fetch events for the current calendar view, or maybe even the current month or year. We might need some UI language to educate the user on what range of events to expect to be published.<\/p>\n\n\n\n<p>Finally, the returned value of this endpoint is the JSON indicating the successful creation or update of Google Calendar events. Remember, when the user enters the workflow, they are taken to a <strong>plaintext page displaying this JSON<\/strong>. <\/p>\n\n\n\n<p>We believe this is a miscommunication between the LLM and itself. It wrote the front-end believing that the back-end would redirect to an HTML page. It wrote the back-end believing that the front-end was using a javascript REST call to fetch information &amp; display it dynamically. We would have expected this from two siloed developers, but not from a single LLM prompt.<br><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusions<\/strong><\/h2>\n\n\n\n<p>Another LLM experiment, and another list of ways that the LLM can misdirect you and let you down! It continues to be an immensely powerful tools, with a range of pitfalls. Some predictable, and some completely wild.<\/p>\n\n\n\n<p>For many of the common pitfalls (no comments in the code, unencrypted credentials, etc) we should be able to create an \u201cAgent\u201d by indicating to the LLM common coding patterns we with it to adhere to. Other pitfalls are always going to be unpredictable, which just highlights the need for human oversight.<\/p>\n\n\n\n<p>There do exist AI tools to review code. Perhaps we will explore these tools in a future blog. <\/p>\n\n\n\n<p>Will they find the same issues as we do, and will they automate their correction?Stay tuned over the next few weeks as we keep exploring.<\/p>\n\n\n\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>Our latest code review analyzes the LLM prompting experiment that built a Google Calendar export feature on Ruoom\u2019s open source CRM, revealing logic gaps and UI oversights.<\/p>","protected":false},"author":5,"featured_media":20047,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[23],"tags":[],"class_list":["post-20019","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Code Review 2: Evaluating the AI-Generated Google Calendar Export | Ruoom<\/title>\n<meta name=\"description\" content=\"Code review of an LLM prompting experiment building a Google Calendar export on Ruoom\u2019s open source code, exposing UI flaws and logic gaps.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.ruoomsoftware.com\/ko\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/\" \/>\n<meta property=\"og:locale\" content=\"ko_KR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Code Review 2: Evaluating the AI-Generated Google Calendar Export | Ruoom\" \/>\n<meta property=\"og:description\" content=\"Code review of an LLM prompting experiment building a Google Calendar export on Ruoom\u2019s open source code, exposing UI flaws and logic gaps.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.ruoomsoftware.com\/ko\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/\" \/>\n<meta property=\"og:site_name\" content=\"Ruoom\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/ruoomsoftware\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-30T20:12:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-10-30T21:38:17+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/art-attack-Qqn9VFkdV6E-unsplash-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"2560\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Kevin Morrissey\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/\"},\"author\":{\"name\":\"Kevin Morrissey\",\"@id\":\"https:\/\/www.ruoomsoftware.com\/#\/schema\/person\/920db29c61fde2fdd472f380831c5731\"},\"headline\":\"Code Review 2: Evaluating the AI-Generated Google Calendar Export\",\"datePublished\":\"2025-10-30T20:12:38+00:00\",\"dateModified\":\"2025-10-30T21:38:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/\"},\"wordCount\":1618,\"publisher\":{\"@id\":\"https:\/\/www.ruoomsoftware.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/art-attack-Qqn9VFkdV6E-unsplash-scaled.jpg\",\"articleSection\":[\"Software\"],\"inLanguage\":\"ko-KR\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/\",\"url\":\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/\",\"name\":\"Code Review 2: Evaluating the AI-Generated Google Calendar Export | Ruoom\",\"isPartOf\":{\"@id\":\"https:\/\/www.ruoomsoftware.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/art-attack-Qqn9VFkdV6E-unsplash-scaled.jpg\",\"datePublished\":\"2025-10-30T20:12:38+00:00\",\"dateModified\":\"2025-10-30T21:38:17+00:00\",\"description\":\"Code review of an LLM prompting experiment building a Google Calendar export on Ruoom\u2019s open source code, exposing UI flaws and logic gaps.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#breadcrumb\"},\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#primaryimage\",\"url\":\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/art-attack-Qqn9VFkdV6E-unsplash-scaled.jpg\",\"contentUrl\":\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/art-attack-Qqn9VFkdV6E-unsplash-scaled.jpg\",\"width\":2560,\"height\":2560},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.ruoomsoftware.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Code Review 2: Evaluating the AI-Generated Google Calendar Export\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.ruoomsoftware.com\/#website\",\"url\":\"https:\/\/www.ruoomsoftware.com\/\",\"name\":\"Ruoom\",\"description\":\"Designed to fit how your small business works.\",\"publisher\":{\"@id\":\"https:\/\/www.ruoomsoftware.com\/#organization\"},\"alternateName\":\"Ruoom\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.ruoomsoftware.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ko-KR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.ruoomsoftware.com\/#organization\",\"name\":\"Ruoom\",\"alternateName\":\"Ruoom\",\"url\":\"https:\/\/www.ruoomsoftware.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.ruoomsoftware.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2024\/11\/Ruoom-logo-svg.svg\",\"contentUrl\":\"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2024\/11\/Ruoom-logo-svg.svg\",\"width\":150,\"height\":122,\"caption\":\"Ruoom\"},\"image\":{\"@id\":\"https:\/\/www.ruoomsoftware.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/ruoomsoftware\",\"https:\/\/www.instagram.com\/ruoomsoftware\/\",\"https:\/\/www.youtube.com\/channel\/UC5LVZyGRCNlQEqQEItCYb3Q\",\"https:\/\/www.linkedin.com\/company\/ruoom-inc\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.ruoomsoftware.com\/#\/schema\/person\/920db29c61fde2fdd472f380831c5731\",\"name\":\"Kevin Morrissey\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.ruoomsoftware.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e55fe9811e3194b318c957a3578a6b39bdcfb5d8d247bdec2cd1d30a98823d4e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e55fe9811e3194b318c957a3578a6b39bdcfb5d8d247bdec2cd1d30a98823d4e?s=96&d=mm&r=g\",\"caption\":\"Kevin Morrissey\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Code Review 2: Evaluating the AI-Generated Google Calendar Export | Ruoom","description":"Code review of an LLM prompting experiment building a Google Calendar export on Ruoom\u2019s open source code, exposing UI flaws and logic gaps.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.ruoomsoftware.com\/ko\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/","og_locale":"ko_KR","og_type":"article","og_title":"Code Review 2: Evaluating the AI-Generated Google Calendar Export | Ruoom","og_description":"Code review of an LLM prompting experiment building a Google Calendar export on Ruoom\u2019s open source code, exposing UI flaws and logic gaps.","og_url":"https:\/\/www.ruoomsoftware.com\/ko\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/","og_site_name":"Ruoom","article_publisher":"https:\/\/www.facebook.com\/ruoomsoftware","article_published_time":"2025-10-30T20:12:38+00:00","article_modified_time":"2025-10-30T21:38:17+00:00","og_image":[{"width":2560,"height":2560,"url":"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/art-attack-Qqn9VFkdV6E-unsplash-scaled.jpg","type":"image\/jpeg"}],"author":"Kevin Morrissey","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#article","isPartOf":{"@id":"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/"},"author":{"name":"Kevin Morrissey","@id":"https:\/\/www.ruoomsoftware.com\/#\/schema\/person\/920db29c61fde2fdd472f380831c5731"},"headline":"Code Review 2: Evaluating the AI-Generated Google Calendar Export","datePublished":"2025-10-30T20:12:38+00:00","dateModified":"2025-10-30T21:38:17+00:00","mainEntityOfPage":{"@id":"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/"},"wordCount":1618,"publisher":{"@id":"https:\/\/www.ruoomsoftware.com\/#organization"},"image":{"@id":"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#primaryimage"},"thumbnailUrl":"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/art-attack-Qqn9VFkdV6E-unsplash-scaled.jpg","articleSection":["Software"],"inLanguage":"ko-KR"},{"@type":"WebPage","@id":"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/","url":"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/","name":"Code Review 2: Evaluating the AI-Generated Google Calendar Export | Ruoom","isPartOf":{"@id":"https:\/\/www.ruoomsoftware.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#primaryimage"},"image":{"@id":"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#primaryimage"},"thumbnailUrl":"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/art-attack-Qqn9VFkdV6E-unsplash-scaled.jpg","datePublished":"2025-10-30T20:12:38+00:00","dateModified":"2025-10-30T21:38:17+00:00","description":"Code review of an LLM prompting experiment building a Google Calendar export on Ruoom\u2019s open source code, exposing UI flaws and logic gaps.","breadcrumb":{"@id":"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#breadcrumb"},"inLanguage":"ko-KR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/"]}]},{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#primaryimage","url":"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/art-attack-Qqn9VFkdV6E-unsplash-scaled.jpg","contentUrl":"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2025\/10\/art-attack-Qqn9VFkdV6E-unsplash-scaled.jpg","width":2560,"height":2560},{"@type":"BreadcrumbList","@id":"https:\/\/www.ruoomsoftware.com\/code-review-2-evaluating-the-ai-generated-google-calendar-export\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.ruoomsoftware.com\/"},{"@type":"ListItem","position":2,"name":"Code Review 2: Evaluating the AI-Generated Google Calendar Export"}]},{"@type":"WebSite","@id":"https:\/\/www.ruoomsoftware.com\/#website","url":"https:\/\/www.ruoomsoftware.com\/","name":"Ruoom","description":"Designed to fit how your small business works.","publisher":{"@id":"https:\/\/www.ruoomsoftware.com\/#organization"},"alternateName":"Ruoom","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.ruoomsoftware.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ko-KR"},{"@type":"Organization","@id":"https:\/\/www.ruoomsoftware.com\/#organization","name":"Ruoom","alternateName":"Ruoom","url":"https:\/\/www.ruoomsoftware.com\/","logo":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.ruoomsoftware.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2024\/11\/Ruoom-logo-svg.svg","contentUrl":"https:\/\/www.ruoomsoftware.com\/wp-content\/uploads\/2024\/11\/Ruoom-logo-svg.svg","width":150,"height":122,"caption":"Ruoom"},"image":{"@id":"https:\/\/www.ruoomsoftware.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/ruoomsoftware","https:\/\/www.instagram.com\/ruoomsoftware\/","https:\/\/www.youtube.com\/channel\/UC5LVZyGRCNlQEqQEItCYb3Q","https:\/\/www.linkedin.com\/company\/ruoom-inc\/"]},{"@type":"Person","@id":"https:\/\/www.ruoomsoftware.com\/#\/schema\/person\/920db29c61fde2fdd472f380831c5731","name":"Kevin Morrissey","image":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.ruoomsoftware.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e55fe9811e3194b318c957a3578a6b39bdcfb5d8d247bdec2cd1d30a98823d4e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e55fe9811e3194b318c957a3578a6b39bdcfb5d8d247bdec2cd1d30a98823d4e?s=96&d=mm&r=g","caption":"Kevin Morrissey"}}]}},"_links":{"self":[{"href":"https:\/\/www.ruoomsoftware.com\/ko\/wp-json\/wp\/v2\/posts\/20019","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ruoomsoftware.com\/ko\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.ruoomsoftware.com\/ko\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.ruoomsoftware.com\/ko\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ruoomsoftware.com\/ko\/wp-json\/wp\/v2\/comments?post=20019"}],"version-history":[{"count":8,"href":"https:\/\/www.ruoomsoftware.com\/ko\/wp-json\/wp\/v2\/posts\/20019\/revisions"}],"predecessor-version":[{"id":20055,"href":"https:\/\/www.ruoomsoftware.com\/ko\/wp-json\/wp\/v2\/posts\/20019\/revisions\/20055"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.ruoomsoftware.com\/ko\/wp-json\/wp\/v2\/media\/20047"}],"wp:attachment":[{"href":"https:\/\/www.ruoomsoftware.com\/ko\/wp-json\/wp\/v2\/media?parent=20019"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.ruoomsoftware.com\/ko\/wp-json\/wp\/v2\/categories?post=20019"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.ruoomsoftware.com\/ko\/wp-json\/wp\/v2\/tags?post=20019"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}