<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Toy Projects | eecczz's page</title><link>https://eecczz.github.io/en/toy-projects/</link><atom:link href="https://eecczz.github.io/en/toy-projects/index.xml" rel="self" type="application/rss+xml"/><description>Toy Projects</description><generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en</language><lastBuildDate>Wed, 01 Jul 2026 00:00:00 +0000</lastBuildDate><image><url>https://eecczz.github.io/media/icon_hu107733296a429e9339b15589e162cf6f_1739_512x512_fill_lanczos_center_3.png</url><title>Toy Projects</title><link>https://eecczz.github.io/en/toy-projects/</link></image><item><title>Streaming API</title><link>https://eecczz.github.io/en/toy-projects/streaming-api/</link><pubDate>Sun, 12 Jul 2026 00:00:00 +0000</pubDate><guid>https://eecczz.github.io/en/toy-projects/streaming-api/</guid><description>&lt;div class="case-study-lead">&lt;p class="case-study-kicker">BACKEND · AI · SYSTEM CASE STUDY&lt;/p>&lt;p>A streaming service connecting a React browsing and playback UI with Spring Boot, AWS S3, Lambda, and MediaConvert.&lt;/p>&lt;div class="case-study-meta">&lt;span>&lt;b>Role&lt;/b> Personal project · upload, media pipeline, post API, playback UI&lt;/span>&lt;span>&lt;b>Validation&lt;/b> Large-file upload and HLS playback tests&lt;/span>&lt;/div>&lt;/div>
&lt;h2 id="key-screens">Key Screens&lt;/h2>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Content library and video exploration screen" srcset="
/en/toy-projects/streaming-api/detail-library_hu41c70f00b40e78806d6c8c51035764d8_633206_022d34d8391fe1456702d8dedffb162a.webp 400w,
/en/toy-projects/streaming-api/detail-library_hu41c70f00b40e78806d6c8c51035764d8_633206_9629ed57a67ee67dd0719a0ca9fc22e1.webp 760w,
/en/toy-projects/streaming-api/detail-library_hu41c70f00b40e78806d6c8c51035764d8_633206_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/streaming-api/detail-library_hu41c70f00b40e78806d6c8c51035764d8_633206_022d34d8391fe1456702d8dedffb162a.webp"
width="760"
height="428"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Upload screen for large video files" srcset="
/en/toy-projects/streaming-api/detail-upload_hu7ee5e3fbac015abcc71f450785679a0c_130555_73b0213dc5dc700469bfc2a34e634174.webp 400w,
/en/toy-projects/streaming-api/detail-upload_hu7ee5e3fbac015abcc71f450785679a0c_130555_7ef9cfa579e46a558f071e6410815945.webp 760w,
/en/toy-projects/streaming-api/detail-upload_hu7ee5e3fbac015abcc71f450785679a0c_130555_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/streaming-api/detail-upload_hu7ee5e3fbac015abcc71f450785679a0c_130555_73b0213dc5dc700469bfc2a34e634174.webp"
width="760"
height="428"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Playback screen using a stored video URL" srcset="
/en/toy-projects/streaming-api/detail-player_hufa4438dc2b9899083b5757f6f2fc8acc_617142_d977b669f22e3028e58eed18089c82d4.webp 400w,
/en/toy-projects/streaming-api/detail-player_hufa4438dc2b9899083b5757f6f2fc8acc_617142_31be7b626b1f7953e36687bef4582d26.webp 760w,
/en/toy-projects/streaming-api/detail-player_hufa4438dc2b9899083b5757f6f2fc8acc_617142_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/streaming-api/detail-player_hufa4438dc2b9899083b5757f6f2fc8acc_617142_d977b669f22e3028e58eed18089c82d4.webp"
width="760"
height="692"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h2 id="troubleshooting">Troubleshooting&lt;/h2>
&lt;h3 id="1-uploading-and-converting-large-videos-through-the-spring-server-held-requests-for-too-long">1. Uploading and converting large videos through the Spring server held requests for too long&lt;/h3>
&lt;p>The browser uploads raw video to S3, then an S3 trigger invokes Lambda and MediaConvert for transcoding. The application manages metadata and lifecycle states instead of carrying the raw file through the API server.
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Direct-upload and multipart boundary"
src="https://eecczz.github.io/en/toy-projects/streaming-api/code-multipart.svg"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h3 id="2-large-browser-uploads-were-blocked-even-after-aws-had-been-configured">2. Large browser uploads were blocked even after AWS had been configured&lt;/h3>
&lt;p>The failure was server-side CORS. &lt;code>WebConfig&lt;/code> permits the browser origin and maps &lt;code>/files/**&lt;/code> to the runtime upload directory so post-upload resources are served from the files actually written by the controller.
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="CORS and upload-file serving configuration"
src="https://eecczz.github.io/en/toy-projects/streaming-api/code-cors.svg"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;h3 id="3-a-raw-video-file-still-needed-to-appear-as-a-searchable-post">3. A raw video file still needed to appear as a searchable post&lt;/h3>
&lt;p>The post record stores title, author, description, and &lt;code>videoUrl&lt;/code> as metadata. The playback screen resolves the media through that URL without storing the video binary in the database.&lt;/p>
&lt;h2 id="technology-choices">Technology Choices&lt;/h2>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Technology&lt;/th>
&lt;th>Why it was used&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>&lt;strong>React&lt;/strong>&lt;/td>
&lt;td>For content discovery, upload, and playback interactions.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>Spring Boot&lt;/strong>&lt;/td>
&lt;td>For post metadata, API boundaries, and upload lifecycle handling.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>S3 · Lambda · MediaConvert&lt;/strong>&lt;/td>
&lt;td>To separate large-file transfer and transcoding from the application server.&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>&lt;strong>HLS&lt;/strong>&lt;/td>
&lt;td>To deliver converted video segments for browser playback.&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;h2 id="system-flow">System Flow&lt;/h2>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Streaming API system flow"
src="https://eecczz.github.io/en/toy-projects/streaming-api/architecture.svg"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;ol>
&lt;li>The client obtains an upload target and sends raw media to S3.&lt;/li>
&lt;li>S3 triggers Lambda and MediaConvert to create HLS output.&lt;/li>
&lt;li>Spring Boot persists the post metadata and result URL.&lt;/li>
&lt;li>The library and player load metadata first, then resolve media at playback.&lt;/li>
&lt;/ol>
&lt;h2 id="next-implementation-plan">Next Implementation Plan&lt;/h2>
&lt;ul>
&lt;li>Add queue-backed conversion status and retry visibility.&lt;/li>
&lt;li>Collect playback, conversion, and storage-cost metrics.&lt;/li>
&lt;/ul></description></item><item><title>Job API Project</title><link>https://eecczz.github.io/en/toy-projects/job-api/</link><pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate><guid>https://eecczz.github.io/en/toy-projects/job-api/</guid><description>&lt;p>Job API Project is a Spring Boot REST API project that crawls Saramin job postings, stores them in MariaDB, and exposes search/filter APIs for the saved listings. Beyond basic CRUD, it covers real job-posting collection, conditional search, application/bookmark flows, and JWT-based authentication.&lt;/p>
&lt;p>The crawler extracts company name, posting title, location, experience, education, employment type, deadline, tech stack, salary, and source URL from Saramin search results. Duplicate postings are filtered by URL before saving, and the &lt;code>/jobs&lt;/code> endpoint supports keyword, company, position, sector, location, experience, salary, sorting, and pagination parameters.&lt;/p>
&lt;ul>
&lt;li>Tech stack: Java, Spring Boot, Spring Web, Spring Data JPA, Querydsl, MariaDB, JWT, Gradle, Jsoup&lt;/li>
&lt;li>Implementation focus: Saramin crawling, job search/filtering, applications, bookmarks, authentication and authorization flow&lt;/li>
&lt;li>Repository: &lt;a href="https://github.com/eecczz/jobAPI" target="_blank" rel="noopener">eecczz/jobAPI&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="key-implementation-points">Key Implementation Points&lt;/h2>
&lt;h3 id="job-listing-screen">Job Listing Screen&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Job Listing Screen" srcset="
/en/toy-projects/job-api/job-list_hu790750dfa26deecad750ee8670e658a4_73445_cc2570cab9d6d42f800e45b7e348cc39.webp 400w,
/en/toy-projects/job-api/job-list_hu790750dfa26deecad750ee8670e658a4_73445_8734e9c4360886f811662922ac0f3e69.webp 760w,
/en/toy-projects/job-api/job-list_hu790750dfa26deecad750ee8670e658a4_73445_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/job-api/job-list_hu790750dfa26deecad750ee8670e658a4_73445_cc2570cab9d6d42f800e45b7e348cc39.webp"
width="760"
height="428"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>The listing screen shows crawled job postings with searchable filters for location, experience, salary, tech stack, and deadline. Each row presents company, location, experience, salary, stack, and an apply action.&lt;/p>
&lt;h3 id="search-api-implementation">Search API Implementation&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Search API Implementation" srcset="
/en/toy-projects/job-api/api-source_hu14ba695e1acf4d6e686af5ee7c9983fd_110107_6ef4a0361b6f6ff1e5cfc8cfd3bdf7d8.webp 400w,
/en/toy-projects/job-api/api-source_hu14ba695e1acf4d6e686af5ee7c9983fd_110107_1746e81f3aa5773ab900af850143e11a.webp 760w,
/en/toy-projects/job-api/api-source_hu14ba695e1acf4d6e686af5ee7c9983fd_110107_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/job-api/api-source_hu14ba695e1acf4d6e686af5ee7c9983fd_110107_6ef4a0361b6f6ff1e5cfc8cfd3bdf7d8.webp"
width="760"
height="428"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>The &lt;code>GET /jobs&lt;/code> endpoint accepts query parameters such as keyword, location, sector, and sort order, builds Specification-based filters, and returns a response map with &lt;code>jobPostings&lt;/code>, &lt;code>sortOrder&lt;/code>, and &lt;code>pagenum&lt;/code>. This image is based on the actual controller implementation rather than a Postman mock.&lt;/p>
&lt;h3 id="saramin-crawl-dump">Saramin Crawl Dump&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Saramin Crawl Dump" srcset="
/en/toy-projects/job-api/crawl-dump_hu7f94d799cce0186227dcecd1b002426b_78426_fe95500ed66097d73ddea07f9ef27bb6.webp 400w,
/en/toy-projects/job-api/crawl-dump_hu7f94d799cce0186227dcecd1b002426b_78426_dcc44e6ad1f4b773321a91888e85ce1b.webp 760w,
/en/toy-projects/job-api/crawl-dump_hu7f94d799cce0186227dcecd1b002426b_78426_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/job-api/crawl-dump_hu7f94d799cce0186227dcecd1b002426b_78426_fe95500ed66097d73ddea07f9ef27bb6.webp"
width="760"
height="428"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>The &lt;code>POST /jobs/crawl&lt;/code> flow collects Saramin search results page by page, extracts posting fields with Jsoup selectors, skips duplicate source URLs, and saves the remaining postings to MariaDB.&lt;/p></description></item><item><title>MetaXR Project</title><link>https://eecczz.github.io/en/toy-projects/metaxr-project/</link><pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate><guid>https://eecczz.github.io/en/toy-projects/metaxr-project/</guid><description>&lt;p>A Unity XR action prototype using Meta/XR device input for tactile combat, monster encounters, and escape flow.&lt;/p>
&lt;ul>
&lt;li>Tech focus: implementation, interaction design, backend/API structure, and project delivery&lt;/li>
&lt;li>Repository or reference: &lt;a href="https://github.com/eecczz/MetaXR-Project" target="_blank" rel="noopener">https://github.com/eecczz/MetaXR-Project&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="key-implementation-points">Key Implementation Points&lt;/h2>
&lt;h3 id="xr-combat-input">XR Combat Input&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="XR Combat Input" srcset="
/en/toy-projects/metaxr-project/featured_huf562b41212e31cf19bb7ce838834f0c1_612207_613ae85d120ed6175befab5caa029d60.webp 400w,
/en/toy-projects/metaxr-project/featured_huf562b41212e31cf19bb7ce838834f0c1_612207_e3fd2b08b8cb1db65b2e0063d19ba398.webp 760w,
/en/toy-projects/metaxr-project/featured_huf562b41212e31cf19bb7ce838834f0c1_612207_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/metaxr-project/featured_huf562b41212e31cf19bb7ce838834f0c1_612207_613ae85d120ed6175befab5caa029d60.webp"
width="760"
height="622"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Mapped controller movement to attack and defense interactions.&lt;/p>
&lt;h3 id="close-interaction">Close Interaction&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Close Interaction" srcset="
/en/toy-projects/metaxr-project/detail-unity_hu15b53b9daea9f254f7ba82e90be40f03_539154_045be04e9c4eb69e8c8dc89c18f48539.webp 400w,
/en/toy-projects/metaxr-project/detail-unity_hu15b53b9daea9f254f7ba82e90be40f03_539154_d6da332894bf017e802bd88b317f7a37.webp 760w,
/en/toy-projects/metaxr-project/detail-unity_hu15b53b9daea9f254f7ba82e90be40f03_539154_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/metaxr-project/detail-unity_hu15b53b9daea9f254f7ba82e90be40f03_539154_045be04e9c4eb69e8c8dc89c18f48539.webp"
width="760"
height="369"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Composed close-range action scenes where the player faces monsters directly.&lt;/p>
&lt;h3 id="unity-prototype">Unity Prototype&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Unity Prototype" srcset="
/en/toy-projects/metaxr-project/detail-xr_hu878ec5f9d7dfc358aea345b8f968c19c_491936_95f19cda197f9ce00365c5fc66d01415.webp 400w,
/en/toy-projects/metaxr-project/detail-xr_hu878ec5f9d7dfc358aea345b8f968c19c_491936_b12b4cb1c157f36b6ba69da3fbf5a9c1.webp 760w,
/en/toy-projects/metaxr-project/detail-xr_hu878ec5f9d7dfc358aea345b8f968c19c_491936_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/metaxr-project/detail-xr_hu878ec5f9d7dfc358aea345b8f968c19c_491936_95f19cda197f9ce00365c5fc66d01415.webp"
width="760"
height="367"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Validated XR input, collision, and monster reactions in a fast action prototype.&lt;/p></description></item><item><title>My 3D Horror Game</title><link>https://eecczz.github.io/en/toy-projects/my3dhorrorgame/</link><pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate><guid>https://eecczz.github.io/en/toy-projects/my3dhorrorgame/</guid><description>&lt;p>A Unity 3D horror prototype experimenting with first-person exploration, tense atmosphere, pursuit flow, and simple interactions.&lt;/p>
&lt;ul>
&lt;li>Tech focus: implementation, interaction design, backend/API structure, and project delivery&lt;/li>
&lt;li>Repository or reference: &lt;a href="https://github.com/eecczz/my3dhorrorgame" target="_blank" rel="noopener">https://github.com/eecczz/my3dhorrorgame&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="key-implementation-points">Key Implementation Points&lt;/h2>
&lt;h3 id="first-person-encounter">First-person Encounter&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="The player encounters an enemy while exploring a hospital corridor" srcset="
/en/toy-projects/my3dhorrorgame/featured_hu713c6924e6b0a6787d5beea2f9ffcfb6_9386_c6feb3ad3669f2d10ddf4c81645ae11c.webp 400w,
/en/toy-projects/my3dhorrorgame/featured_hu713c6924e6b0a6787d5beea2f9ffcfb6_9386_cec2a16e108262b2a46040ec65fe1910.webp 760w,
/en/toy-projects/my3dhorrorgame/featured_hu713c6924e6b0a6787d5beea2f9ffcfb6_9386_1200x1200_fit_q75_h2_lanczos_2.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/my3dhorrorgame/featured_hu713c6924e6b0a6787d5beea2f9ffcfb6_9386_c6feb3ad3669f2d10ddf4c81645ae11c.webp"
width="760"
height="276"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>This in-game scene shows the first-person exploration flow and the enemy encounter staged in a narrow hospital corridor.&lt;/p></description></item><item><title>My Movie Web</title><link>https://eecczz.github.io/en/toy-projects/my-movie-web/</link><pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate><guid>https://eecczz.github.io/en/toy-projects/my-movie-web/</guid><description>&lt;p>A React web application using the TMDb API for movie search, popular movie browsing, wishlist management, filtering, and sorting.&lt;/p>
&lt;ul>
&lt;li>Tech focus: implementation, interaction design, backend/API structure, and project delivery&lt;/li>
&lt;li>Repository or reference: &lt;a href="https://github.com/eecczz/my-movie-web" target="_blank" rel="noopener">https://github.com/eecczz/my-movie-web&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="key-implementation-points">Key Implementation Points&lt;/h2>
&lt;h3 id="movie-discovery-ui">Movie Discovery UI&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Movie Discovery UI" srcset="
/en/toy-projects/my-movie-web/featured_huddf40324fc89d0ae7f4794df48f326bb_11694_476b4a259ae5284a219fd76b1a654151.webp 400w,
/en/toy-projects/my-movie-web/featured_huddf40324fc89d0ae7f4794df48f326bb_11694_37f07d37bd1349cbfbcb63c71792f478.webp 760w,
/en/toy-projects/my-movie-web/featured_huddf40324fc89d0ae7f4794df48f326bb_11694_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/my-movie-web/featured_huddf40324fc89d0ae7f4794df48f326bb_11694_476b4a259ae5284a219fd76b1a654151.webp"
width="589"
height="487"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Organized popular and top-rated movies around poster-focused browsing.&lt;/p>
&lt;h3 id="search-and-filtering">Search and Filtering&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Search and Filtering" srcset="
/en/toy-projects/my-movie-web/detail-explore_hub184b924ee337dbb1f8cc7087325df63_1695978_8dd4af248a9078f8669f9dfbbf36b8a7.webp 400w,
/en/toy-projects/my-movie-web/detail-explore_hub184b924ee337dbb1f8cc7087325df63_1695978_47b14cbcb62b31fdcfc0831639f8e687.webp 760w,
/en/toy-projects/my-movie-web/detail-explore_hub184b924ee337dbb1f8cc7087325df63_1695978_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/my-movie-web/detail-explore_hub184b924ee337dbb1f8cc7087325df63_1695978_8dd4af248a9078f8669f9dfbbf36b8a7.webp"
width="760"
height="380"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Built a flow for searching, sorting, and filtering TMDb API results.&lt;/p>
&lt;h3 id="wishlist">Wishlist&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Wishlist" srcset="
/en/toy-projects/my-movie-web/detail-wishlist_hu01e893d33f163eb26d7df58df2b009ef_520730_a0b34a7d8167cc404a0d94d522538a95.webp 400w,
/en/toy-projects/my-movie-web/detail-wishlist_hu01e893d33f163eb26d7df58df2b009ef_520730_637638c825ce76b38c44be3d193b1f26.webp 760w,
/en/toy-projects/my-movie-web/detail-wishlist_hu01e893d33f163eb26d7df58df2b009ef_520730_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/my-movie-web/detail-wishlist_hu01e893d33f163eb26d7df58df2b009ef_520730_a0b34a7d8167cc404a0d94d522538a95.webp"
width="760"
height="377"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Implemented a client-side state flow for saving and revisiting favorite movies.&lt;/p></description></item><item><title>Restaurant ReAct Agent</title><link>https://eecczz.github.io/en/toy-projects/restaurant-agent/</link><pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate><guid>https://eecczz.github.io/en/toy-projects/restaurant-agent/</guid><description>&lt;p>A FastAPI-based AI agent that parses user conditions, calls restaurant search/filtering tools, and generates explainable recommendations.&lt;/p>
&lt;ul>
&lt;li>Tech focus: implementation, interaction design, backend/API structure, and project delivery&lt;/li>
&lt;li>Repository or reference: &lt;a href="https://github.com/eecczz/restaurant_recommend_agentAI" target="_blank" rel="noopener">https://github.com/eecczz/restaurant_recommend_agentAI&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="key-implementation-points">Key Implementation Points&lt;/h2>
&lt;h3 id="react-loop">ReAct Loop&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="ReAct Loop" srcset="
/en/toy-projects/restaurant-agent/featured_hu16ace187a93bd94a5b9b5aa8cbaac406_30732_6017ef55e483d151a16d57513f62277e.webp 400w,
/en/toy-projects/restaurant-agent/featured_hu16ace187a93bd94a5b9b5aa8cbaac406_30732_6037760380ad229e79e9bd7f2eff27b7.webp 760w,
/en/toy-projects/restaurant-agent/featured_hu16ace187a93bd94a5b9b5aa8cbaac406_30732_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/restaurant-agent/featured_hu16ace187a93bd94a5b9b5aa8cbaac406_30732_6017ef55e483d151a16d57513f62277e.webp"
width="728"
height="747"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Interprets requests, calls tools, observes results, and generates final recommendations.&lt;/p>
&lt;h3 id="search-tool">Search Tool&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Search Tool" srcset="
/en/toy-projects/restaurant-agent/detail-result_hu2b831af388afd60d77e516ce4378b425_353680_138d672532124e7ac1138acf7c89f4d9.webp 400w,
/en/toy-projects/restaurant-agent/detail-result_hu2b831af388afd60d77e516ce4378b425_353680_fc4a5456e0a95087e1d252174672b02a.webp 760w,
/en/toy-projects/restaurant-agent/detail-result_hu2b831af388afd60d77e516ce4378b425_353680_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/restaurant-agent/detail-result_hu2b831af388afd60d77e516ce4378b425_353680_138d672532124e7ac1138acf7c89f4d9.webp"
width="760"
height="433"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Uses Kakao Local API and a sample dataset for regional restaurant search.&lt;/p>
&lt;h3 id="filtering-and-recommendation">Filtering and Recommendation&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Filtering and Recommendation" srcset="
/en/toy-projects/restaurant-agent/detail-trace_hu138c4d8905a1b0e209fd1210b79ab3d6_183337_e7f60ea26fde780727811cf1cdc26e32.webp 400w,
/en/toy-projects/restaurant-agent/detail-trace_hu138c4d8905a1b0e209fd1210b79ab3d6_183337_f76f725466a9b4c6ada6684c857b285e.webp 760w,
/en/toy-projects/restaurant-agent/detail-trace_hu138c4d8905a1b0e209fd1210b79ab3d6_183337_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/restaurant-agent/detail-trace_hu138c4d8905a1b0e209fd1210b79ab3d6_183337_e7f60ea26fde780727811cf1cdc26e32.webp"
width="760"
height="428"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Reflects price, context, and review conditions to provide explainable recommendations.&lt;/p></description></item><item><title>Shopping Mall Project</title><link>https://eecczz.github.io/en/toy-projects/shopping-mall/</link><pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate><guid>https://eecczz.github.io/en/toy-projects/shopping-mall/</guid><description>&lt;p>A Spring Boot and MariaDB shopping mall demo covering product browsing, cart, purchase, and payment verification flows.&lt;/p>
&lt;ul>
&lt;li>Tech focus: implementation, interaction design, backend/API structure, and project delivery&lt;/li>
&lt;li>Repository or reference: &lt;a href="https://github.com/eecczz/shoppingmall-springboot" target="_blank" rel="noopener">https://github.com/eecczz/shoppingmall-springboot&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="key-implementation-points">Key Implementation Points&lt;/h2>
&lt;h3 id="product-list">Product List&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Product List" srcset="
/en/toy-projects/shopping-mall/capture-list_huc75df1e51dcda34110788da60ce2c3a2_311519_cd87ae636250a1a71a21ffb8c554c104.webp 400w,
/en/toy-projects/shopping-mall/capture-list_huc75df1e51dcda34110788da60ce2c3a2_311519_102505033b97c839af3b8bfe31cf4f9f.webp 760w,
/en/toy-projects/shopping-mall/capture-list_huc75df1e51dcda34110788da60ce2c3a2_311519_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/shopping-mall/capture-list_huc75df1e51dcda34110788da60ce2c3a2_311519_cd87ae636250a1a71a21ffb8c554c104.webp"
width="760"
height="535"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Implemented the basic shopping flow from product list to cart and purchase pages.&lt;/p>
&lt;h3 id="cart-flow">Cart Flow&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Cart Flow" srcset="
/en/toy-projects/shopping-mall/capture-cart_huba2632785718c0a7563e2d2fb2f0ee2c_36712_2ab63b126e0a6043c4902e1786d2037f.webp 400w,
/en/toy-projects/shopping-mall/capture-cart_huba2632785718c0a7563e2d2fb2f0ee2c_36712_45fc20859a6466d55f9d5f200ab231a3.webp 760w,
/en/toy-projects/shopping-mall/capture-cart_huba2632785718c0a7563e2d2fb2f0ee2c_36712_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/shopping-mall/capture-cart_huba2632785718c0a7563e2d2fb2f0ee2c_36712_2ab63b126e0a6043c4902e1786d2037f.webp"
width="760"
height="535"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Handled quantity updates, total price calculation, and checkout entry.&lt;/p>
&lt;h3 id="login-screen">Login Screen&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Login Screen" srcset="
/en/toy-projects/shopping-mall/capture-signin_huedf4bde09bff095358a3e6e0f45a4a23_21604_a6e7b53ae2014660e3fd6d1d2c2a2058.webp 400w,
/en/toy-projects/shopping-mall/capture-signin_huedf4bde09bff095358a3e6e0f45a4a23_21604_a7f90850f5e232d86a95bd47dfbb75eb.webp 760w,
/en/toy-projects/shopping-mall/capture-signin_huedf4bde09bff095358a3e6e0f45a4a23_21604_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/shopping-mall/capture-signin_huedf4bde09bff095358a3e6e0f45a4a23_21604_a6e7b53ae2014660e3fd6d1d2c2a2058.webp"
width="760"
height="535"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Connected cart and payment flows to a session-based authentication screen.&lt;/p></description></item><item><title>Sports Analysis AI</title><link>https://eecczz.github.io/en/toy-projects/sports-analyzer/</link><pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate><guid>https://eecczz.github.io/en/toy-projects/sports-analyzer/</guid><description>&lt;p>A Next.js + FastAPI MVP that selects YouTube sports clips and streams AI-based motion analysis.&lt;/p>
&lt;ul>
&lt;li>Tech focus: implementation, interaction design, backend/API structure, and project delivery&lt;/li>
&lt;li>Repository or reference: &lt;a href="https://github.com/eecczz/sports-analyzer" target="_blank" rel="noopener">https://github.com/eecczz/sports-analyzer&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="key-implementation-points">Key Implementation Points&lt;/h2>
&lt;h3 id="clip-selection">Clip Selection&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Clip Selection" srcset="
/en/toy-projects/sports-analyzer/featured_hucd074b81d4c457f7e320282035604d99_1446829_920c9cb86b6d1b675a649804d633c348.webp 400w,
/en/toy-projects/sports-analyzer/featured_hucd074b81d4c457f7e320282035604d99_1446829_f5ae7f01e7b71d186f90e9a52c08f327.webp 760w,
/en/toy-projects/sports-analyzer/featured_hucd074b81d4c457f7e320282035604d99_1446829_1200x1200_fit_q75_h2_lanczos_3.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/sports-analyzer/featured_hucd074b81d4c457f7e320282035604d99_1446829_920c9cb86b6d1b675a649804d633c348.webp"
width="760"
height="528"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Lets users choose the segment to analyze and extracts only that portion server-side.&lt;/p>
&lt;h3 id="ai-analysis-streaming">AI Analysis Streaming&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://images.unsplash.com/photo-1574629810360-7efbbe195018?auto=format&amp;amp;fit=crop&amp;amp;w=720&amp;amp;q=80" alt="AI Analysis Streaming" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Streams analysis results from FastAPI with SSE.&lt;/p>
&lt;h3 id="provider-switching">Provider Switching&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img src="https://images.unsplash.com/photo-1492691527719-9d1e07e534b4?auto=format&amp;amp;fit=crop&amp;amp;w=720&amp;amp;q=80" alt="Provider Switching" loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Designed an analysis pipeline that can switch between Gemini/Kimi model providers.&lt;/p></description></item><item><title>Wii Swordplay Remake</title><link>https://eecczz.github.io/en/toy-projects/swordplay/</link><pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate><guid>https://eecczz.github.io/en/toy-projects/swordplay/</guid><description>&lt;p>A Unity project recreating Wii Sports Resort swordplay controls and hit feedback for a PC/WebGL environment.&lt;/p>
&lt;ul>
&lt;li>Tech focus: implementation, interaction design, backend/API structure, and project delivery&lt;/li>
&lt;li>Repository or reference: &lt;a href="https://github.com/eecczz/swordplay" target="_blank" rel="noopener">https://github.com/eecczz/swordplay&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="key-implementation-points">Key Implementation Points&lt;/h2>
&lt;h3 id="sword-controls">Sword Controls&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Sword Controls" srcset="
/en/toy-projects/swordplay/featured_hu8fb47b9acb7a79f6427c3880623bc535_448955_c2d95009aa713055072e48c5cd088f23.webp 400w,
/en/toy-projects/swordplay/featured_hu8fb47b9acb7a79f6427c3880623bc535_448955_9984561782833a905a514efec08f16a4.webp 760w,
/en/toy-projects/swordplay/featured_hu8fb47b9acb7a79f6427c3880623bc535_448955_1200x1200_fit_q75_h2_lanczos.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/swordplay/featured_hu8fb47b9acb7a79f6427c3880623bc535_448955_c2d95009aa713055072e48c5cd088f23.webp"
width="760"
height="760"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Converted mouse input into sword rotation and position for a direct swinging feel.&lt;/p>
&lt;h3 id="hit-reaction">Hit Reaction&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Hit Reaction" srcset="
/en/toy-projects/swordplay/detail-hit-reaction_hu95869620e25e48a2321dbad1731b5fac_1029118_e84ac1a8cb1c5eb6f304b11e46a44cc6.webp 400w,
/en/toy-projects/swordplay/detail-hit-reaction_hu95869620e25e48a2321dbad1731b5fac_1029118_438072cde58fb7288cb4bee6c73d7c1c.webp 760w,
/en/toy-projects/swordplay/detail-hit-reaction_hu95869620e25e48a2321dbad1731b5fac_1029118_1200x1200_fit_q75_h2_lanczos.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/swordplay/detail-hit-reaction_hu95869620e25e48a2321dbad1731b5fac_1029118_e84ac1a8cb1c5eb6f304b11e46a44cc6.webp"
width="760"
height="760"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Strengthened impact feedback with a self-balancing recovery flow.&lt;/p>
&lt;h3 id="wii-like-shader">Wii-like Shader&lt;/h3>
&lt;p>
&lt;figure >
&lt;div class="d-flex justify-content-center">
&lt;div class="w-100" >&lt;img alt="Wii-like Shader" srcset="
/en/toy-projects/swordplay/detail-shader_hu9a74d59b2249f059cac2ec36bfb754ac_250432_e7a33c8a2481adf89562494a31421728.webp 400w,
/en/toy-projects/swordplay/detail-shader_hu9a74d59b2249f059cac2ec36bfb754ac_250432_58c5bc112a73ec0e0bf84a8b33c68dec.webp 760w,
/en/toy-projects/swordplay/detail-shader_hu9a74d59b2249f059cac2ec36bfb754ac_250432_1200x1200_fit_q75_h2_lanczos.webp 1200w"
src="https://eecczz.github.io/en/toy-projects/swordplay/detail-shader_hu9a74d59b2249f059cac2ec36bfb754ac_250432_e7a33c8a2481adf89562494a31421728.webp"
width="760"
height="760"
loading="lazy" data-zoomable />&lt;/div>
&lt;/div>&lt;/figure>
&lt;/p>
&lt;p>Used simple colors, low gloss, and outline-like styling to echo the original visual tone.&lt;/p></description></item></channel></rss>