Quest Log
This site's adventure journal. Every piece of work earns XP.
- πSide
Widen the Borders of the Archive
Widened the recipe archive from Korean-only to Korean and Japanese, and published Sapporo soup curry. Renamed the native-name field to nativeName and the grocery fields to the asian/asianStoreNeeded pair, then added a cuisine field that drives the country filter, the badges, and schema.org recipeCuisine from one piece of data. The filter only appears once more than one cuisine is present, so a single-cuisine archive looks exactly as it did.
- πSide
Translating the Spellbook into Common Tongue
Rewrote post 012 β the Toss-to-KakaoTalk alert build log β for readers who don't code. Cut all six code blocks and put the actual Korean sentences given to the AI in their place, retitled it around Claude Code + API, and trimmed the intro to three lines so it opens on step one. Also corrected a factual slip: the original showed a crontab line, but the routine actually runs on a Claude Code scheduled task.
- πSide
The Crystal Orb in Your Palm
Built a Scriptable widget that puts sonnyplot on the iPhone home screen. Added a /api/widget endpoint that bundles quotes, the fear & greed index, and the market briefing into a single call (for a widget, every round trip is render latency), and served the widget script from the site itself so a git push updates the phone. Three sizes, with the last successful response shown when offline.
- πSide
The Messenger Bird That Brings the Ledger Each Morning
Published a build log on wiring Toss Securities' Open API to KakaoTalk for a daily portfolio alert. Covers two months of cutting back β from seven per-stock charts down to one summary card β plus fixes for three traps: the IP allowlist, the missing message-sending consent, and KakaoTalk cropping wide images. Korean only, as a deliberate exception to the bilingual rule: a Toss account requires Korean residency.
- πSide
First Dish, Actually Cooked
Published the first real recipe in the archive β Korean spicy chicken skillet with rice cakes, Jikoba style. The four guessed sample recipes were thrown out and replaced with one dish actually cooked.
- βοΈMain
Open the Kitchen Archive
Opened /recipes, a Korean recipe archive separate from the blog β filterable index, detail pages, and structured ingredient data that also feeds schema.org Recipe markup. Photos and sourcing notes are left as optional fields, to be filled in only from actual cooking.
- π‘οΈHunt
Hunted: The Scarecrow Field That Did Nothing When Tapped
In the auction ledger's entry screen, tapping a field labeled 'λλ₯΄μΈμ' (tap here) did nothing. The cause: the chooser lived in a panel below the fields, and on first load that panel was already showing β so tapping the field it belonged to changed nothing on screen. Worse, on a first run with no people registered, that panel held a single small dashed button, giving no clue where to go. Fixed by making a field tap open a modal, and by chaining them: pick the seller and the amount pad opens, confirm the amount and the buyer chooser opens. When no one is registered yet, the modal says so outright and offers one large button.
- βοΈMain
Forged: A Ledger That Does the Village Auction's Arithmetic
Built a settlement ledger web app for a small rural auction house and shipped it at /auction/. The defining quirk of that world: the same person both sells and buys, so at closing time each person's sales and purchases have to be netted against each other β and it's that arithmetic that forces them to hire a clerk who can drive a spreadsheet. Now, when a lot closes, you tap three things β who sold, how much, who bought β and everything else falls out automatically. Per-person statements, a closing screen split into money-out and money-in, and a credit ledger where a short payment is recorded automatically and rides along into the next auction's settlement. Runs from a single file with no server, so it works with the signal down, and backs up to a downloadable file. Built for a user who doesn't use computers: zero typing β names are tapped from a grid, amounts come from a keypad, and confirmation dialogs are gone.
- πSide
Chronicle: v0 Through v13, on a Single Scroll
Published the making-of as blog post 011 in both languages β walking through every version in order (introducing refills, shrinking the board, capping shuffle and hints at once per game, replacing alert() with a confirm modal, offering a bonus when time runs out, weighting the number distribution, the start cover and dramatic timer, raising the reward multiplier). Covered the display/value mismatch bug, the timer that kept running behind a chained notice, and the build-passed-but-deploy-failed debugging story. Added a promo box on the experiment page linking to this post.
- π‘οΈHunt
Hunted: The Ghost Between What You See and What Counts
Two real bugs caught while building this. β The refilled value used for sum-checking updated before the on-screen number did, so dragging over a cell mid-pop-animation would compute the sum against a number you couldn't actually see yet β fixed by updating the display and the logic value at the exact same moment. β‘ When notices chain (stuck β shuffle fails β end-game notice), the first notice's confirm handler unconditionally resumed the timer, letting it quietly tick during the second notice too β fixed by checking whether a new notice appeared before resuming, and handing resume duty to that one instead.
- βοΈMain
Forged: An Apple Game That Hunts Time
Shipped experiment #3, Apple Game: Make 10, at /apple-game and /kr/apple-game β the viral Korean puzzle where dragging a rectangle of numbers that sum to exactly 10 clears them. Cleared cells refill instantly so the round no longer ends early from running out of combinations; instead a shuffle is offered (not silently applied) exactly once per game when the board gets stuck, and the hint only shows once per button press instead of looping automatically. When the timer hits zero with the shuffle still unused, the game offers +15s bonus time instead of ending outright. Clearing cells now banks real bonus time (0.6s per cell) so fast, accurate play can actually outrun the clock. Big numbers like 9 (which can only ever pair with a 1) used to strand a lot of neighboring cells β weighted the number distribution toward smaller values to ease that. The board stays hidden behind a "Start" button until clicked, and the timer is now large and centered, turning amber past 20 seconds and pulsing red like a heartbeat with a tick sound under 10.
- πSide
Chronicle: Three Discarded Designs, Written Down
Published the making-of as blog post 010 in both languages β the five-game fusion that died of complexity, the second pass that stayed luck-driven, the diagnosis that minesweeper is about number clues rather than mines, the variable-name collision that killed the whole script while the console stayed silent, and the leftover debug value that made a working build look broken. Cross-linked with the experiment page and the trot vending machine post.
- βοΈMain
Forged: The Times Table Arcade, Purged of Luck
Shipped experiment #2, Times Table Drop, at /times-table and /kr/times-table. Scrapped both a five-game fusion and a card-and-mine hybrid before landing on falling multiplication β the luck came from importing minesweeper's punishment while leaving its deduction clues behind. Zero hidden information, every answer guaranteed among the labels, the starting column never correct, and wrong stacks shrink when you answer that column right. Hitting a number twice (nΓm, mΓn) swaps it out so positions can't be memorized. Fixed Astro scoped styles not reaching JS-created labels via a global .tt prefix, and replaced global onclick handlers with an IIFE plus addEventListener.
- βοΈMain
Chronicle: Inscribing the Slash-Ward on a Scroll
Published the trailing-slash cleanup as blog post 009 in both languages β why the slash must be unified, the '301-then-404' from redirecting nonexistent pages, the run_worker_first trap, the abs() helper that keeps canonical/hreflang on the same slash, and the regression smoke test. Cross-linked with the earlier English-pivot post.
- πSide
Ward: A Seal Against the URL Wraith's Return
Laid a ward so I don't fall into the same pit twice β a `scripts/check-urls.sh` smoke test (verifies slash 301s, legacy 301s, static assets, and 404s through real requests via `npm run check:urls`) plus a URL-rules section in CLAUDE.md. Also pinned the rule to the deploy checklist: verify worker changes through wrangler dev, not by calling the function directly.
- π‘οΈHunt
Hunt: The Two-Faced URL Wraith
Slew the bug where one post looked like two URLs depending on the trailing slash β the sitemap used slashes, hreflang didn't, and there was no canonical tag at all. Added canonical to Base.astro, normalized hreflang to the slashed form, and made the worker 301 slashless URLs (previously a 307 temporary from ASSETS). The legacy Korean-post 301 now includes the slash too, killing a redirect chain. The 301 didn't take after deploy, so I tracked it down β Cloudflare's static assets were answering before the worker. Enabled run_worker_first in wrangler.jsonc so the worker goes first, and added an existence probe so missing URLs 404 outright instead of redirecting first.
- πSide
Upkeep: The Rite of Titles, Sigil of How-To
Unified all eight blog post titles into how-to form in both languages β "How to ..." in English, "~νλ λ²" in Korean. Slugs and translationKeys left untouched to preserve existing indexing.
- πSide
Chronicle: The Day of the Migration and the Summer Drop
Published blog post 007 (KO/EN) β chronicling the site's English pivot, the vending machine going global, Eolssigu Trot's summer drop, and the Suno automation dig, all in one day's log.
- π‘οΈHunt
Attempt: the Automation Golem, 0 for 1
First attempt at automating Suno song creation via Claude in Chrome (Advanced mode, v5.5). Song 1 hit Create (credits 831β821), but song 2 garbled Korean input and fumbled the form β slower than hand-pasting, so aborted. Left the door open for a retry.
- πSide
Recipe Engraving: Rules for Title and Stage
Added two rules to the trot-song-producer skill and repackaged it β (1) ask before proceeding if no main title is given (so it can sit large on the thumbnail), (2) match singer styling and stage to season and mood, asking first if unspecified.
- πSide
Summer Expedition: 10 Trot Songs vs. the Heat
Produced and uploaded a new Eolssigu Trot batch β concept (woman in her 20sβ30s, powerful vocals, upbeat love trot), a 10-song tracklist (4 metaphor + 6 hook) with lyrics and Suno style tags, and a Higgsfield summer water-festival thumbnail. The 47-minute medley is live on YouTube.
- π‘οΈHunt
Hunt: the Digit Monster
Caught digits leaking into vending machine lyrics during a live test β added 0-9 to the contamination detector and scrubber.
- βοΈMain
The Vending Golem Goes Global
Remodeled the Trot Vending Machine into a K-culture experience β English UI with a genre intro at /trot, Korean at /kr/trot. Lyrics stay Korean, but the English version adds romanization (computed in the worker) and an AI English translation under every line, so anyone can sing along and know what they're singing.
- βοΈMain
The Great Migration: English Becomes the Capital
The site-wide flip β English becomes the root (/), Korean moves to /kr/. All six blog posts rewritten in English with a translation-pair structure (translationKey + hreflang + language chips), the entire quest log translated, and 301 redirects for the old URLs.
- πSide
The Otherworld Book of Titles
Translated all 16 RPG titles into English (룬 μ‘°κ°κ° β Rune Carver), so the English home shows English titles.
- π‘οΈHunt
Hunt: the Descender-Eating Gradient
Fixed the English hero clipping the descenders of 'playground.' β background-clip:text wasn't painting below the box; padding restored the g, p, and y.
- βοΈMain
Rift Gate to the Land of English
Made the home page bilingual β refactored into a shared Home component with a phrase dictionary, added the English landing, hreflang, and the KR/EN toggle.
- πSide
Job Posting at the Adventurers' Guild
Added a 'What I'm looking for' section to About β target roles, industries, location, work permit, and bilingual edge.
- πSide
A Lesson Line for the Story
Expanded the About Spotlight to a 2Γ2 PurposeβProcessβResultβLesson grid and added a QA career spotlight.
- πSide
A Story Panel for the Portrait
Added a Spotlight section to About β cost & pricing work laid out as Purpose β Process β Result flow cards.
- πSide
Chronicle: Two Days of Maintenance
Published the two-day changelog β category drawers, home reshuffle, vending machine service, the mailbox, and the mailto hunt.
- π‘οΈHunt
Hunt: the mailto Monster
Slew the 'unsupported URL' error in mailto-less environments like Plash β the button now copies the address with a 'Copied β' flash.
- πSide
Opening the Carrier Pigeon Post
Opened contact@sonnyplot.com via Cloudflare Email Routing and added an email button to the About page.
- π‘οΈHunt
Hunt: the Hanja Monster
Slew the bug where Chinese characters and English leaked into vending machine lyrics β pure-Hangul rule, detect-and-reroll, and a scrubbing filter.
- πSide
Chronicle: Birth of the Vending Machine
Published the Trot Vending Machine build log.
- βοΈMain
Summoning the Vending Golem
Completed experiment #1, the Trot Vending Machine β the channel's songwriting rules ported into Workers AI behind /api/trot.
- πSide
Chronicle: a Verse of Eolssigu
Published the Eolssigu Trot channel intro and pipeline write-up.
- πSide
Chronicle: Song of the Forest
Published the Sylvamoor channel intro and pipeline write-up.
- πSide
A Bard's Booth in the Square
Home reshuffle β compacted the status window next to the sticky note, and placed two YouTube channel cards (Sylvamoor, Eolssigu Trot) in the freed space.
- πSide
Filing Drawers for the Archive
Built the blog category system β six categories with filter tabs on the index and chips on each post.
- πSide
The Second Chronicle
Published post #2 β the first 24 hours: the RPG awakening, dashboard-ification, monster hunts, and search engine registration.
- πSide
Engraving of Time
Blog dates now show the time of publication (New York, 24h). Excavated the first post's true moment (01:25) from git history.
- πSide
Map for the Google Explorer
Added auto-generated sitemap and robots.txt β a map so Google's bots can find every corner. First provision for the AdSense expedition.
- πSide
Reader of the Skies
The ambient system: the landing subtly shifts with the visitor's weather, sunrise/sunset, and moon phase β sky tints at dawn, dusk, and night, plus rain and snow particles.
- πSide
The Gate and Two Clock Towers
Added Google and Naver search bars to the landing, plus live New York and Seoul clocks updating every second with day/night icons.
- πSide
The Yellow Talisman of Memory
Split the hero to add a sticky-note widget β folded corner, notebook lines, auto-saving to localStorage with a 'Saved β' flash.
- πSide
Archive of the Moon: a Month at a Glance
Merged the New York and Seoul clocks into one card and added a mini calendar β local to the visitor, today highlighted, auto-refreshing at midnight.
- πSide
Falling in Line: the Third Sentinel
Restyled Fear & Greed from a gauge into a ticker card matching the others (score, rating, one-month mini chart), making both market cards symmetric.
- πSide
Compass of Emotions: Fear and Greed
Added the CNN Fear & Greed Index to the US market card, fetched by the worker and shown on a gradient gauge.
- π‘οΈHunt
Hunt: the Broken Character Monster
Slew the bug where US headlines showed raw HTML entities like —. Cause: double-encoded RSS β fixed by decoding twice.
- πSide
Regrouping: Camps of Two Continents
Moved the scattered tickers inside their market briefing cards β US (Nasdaq, S&P, Bitcoin) and Korea (KOSPI, KRW/USD) camps, side by side on desktop.
- πSide
Heralds of Two Continents
Split the briefing into US and Korea sections with independent refresh cycles; weekends keep Friday's close edition.
- πSide
The Herald Arrives: Market Briefings
A briefing system where AI picks and summarizes market headlines twice a day (after Korea and US close). First use of Workers AI.
- βοΈMain
Visual Awakening
An effect system that evolves the site's look with its level. Light particles at Lv.5, with breathing glow, rune engravings, aurora, and a starry sky still sleeping.
- βοΈMain
Soul Pact: the Level System
The site itself became an RPG character. Built the status window and quest log.
- πSide
Portrait of the Adventurer
Published the About page β told the world my name.
- π‘οΈHunt
Hunt: the Fake Data Monster
Slew the bad KOSPI tick from Yahoo (+6% phantom spike) with a filter.
- πSide
Reader of Currents
Added one-month sparkline charts to the ticker cards.
- πSide
Eye of the Market
Built the live market ticker widget (Nasdaq, S&P, KOSPI, KRW/USD, Bitcoin). The site's first backend.
- πSide
The First Chronicle
Published the first blog post β the story of how this site was made.
- βοΈMain
Build the Archive of Records
Built the Astro blog. The archive for experiment logs is open.
- βοΈMain
Wire the Magic Circuit
Built the GitHub auto-deploy pipeline β push, and the world sees it 30 seconds later.
- βοΈMain
Plant the Flag
Connected the sonnyplot.com domain and shipped the first deploy. The playground is born.