-
While checking the post list on the admin page, I noticed a bizarre issue where view counts were completely out of sync.
There were posts I had personally read, and posts visited by actual users, yet the view counts displayed on the blog frontend, the admin dashboard, and the post management list were all completely different.
For a moment, I broke into a cold sweat thinking a deployment might have wiped out a column or an entire table in the D1 database. -
In a panic, I opened a remote D1 terminal to inspect the table schema and actual data, but the result was surprisingly anticlimactic.
npx wrangler d1 execute svelteblog-db --remote --command="PRAGMA table_info(posts);"The
view_countcolumn in thepoststable was perfectly intact, and checking the user DB revealed over 1,000 daily view logs totaling more than 1,400 views, safe and sound.
The data hadn't vanished at all; it was breathing just fine in the database, only invisible on the frontend. -
Tracing back the root cause revealed fragmented pieces left behind while rushing through features with "vibe coding" without cleaning up along the way.
In our blog architecture, the database is split intoBLOG_DB(post content) andUSER_DB(user data and analytics logs). The daily view logging logic was implemented fine, but the sync pipeline to aggregate those stats into the post cache column was left unfinished with a casual thought of "well, it runs without errors." That was the debt.
Real data was accumulating in the user DB, while the admin panel was staring blankly at the empty cache column in the blog DB, so showing 0 was inevitable. -
Thinking "Aha, found the bug!", I updated the admin server code to aggregate totals from the user DB, map them properly, and auto-sync mismatched posts back into the blog DB, then deployed the changes.
// Admin server: Aggregate USER_DB raw views and auto-sync mismatched posts const { results: viewResults } = await userDb.prepare(` SELECT post_id, SUM(views) as total_views FROM post_views GROUP BY post_id `).all(); const posts = (postsRaw || []).map((p: any) => ({ ...p, view_count: viewCountMap[p.id] ?? (p.view_count || 0) }));Now proper numbers like 41 views should have appeared... but even after refreshing, it stubbornly stayed at 0.
Direct queries to D1 clearly showed 41, yet the web page adamantly insisted on displaying 0. It genuinely felt like a ghost in the machine. -
As it turned out, the culprit wasn't just the server; another issue was lurking inside the frontend Svelte component.
A while ago, I had addedlocalStoragecaching to make the admin post list load faster, and that was the trap.// apps/admin/src/routes/posts/+page.svelte (problematic code before fix) } else { // Normal entry: reuse valid cache from localStorage if available const saved = localStorage.getItem(POSTS_CACHE_KEY); if (saved) { cachedPosts = parsed.posts; // <- Blindly overwrites fresh server data with stale localStorage cache } }Inside Svelte 5's
$effect, the moment the server fetched the fresh count of 41 from D1 and handed it to the client, the frontend code immediately pulled the stale list with 0 views from browser storage and plastered it over the screen.
Because there was no expiration time (TTL), no matter how many times you hammered F5, the browser faithfully rendered the stale cache. There was no way the screen would update. -
In the end, incomplete backend data sync met ruthless frontend localStorage overwrites, creating a bizarre collaboration where "both server and DB are intact, but the browser actively overwrites the screen."
Once I ripped out the aggressive localStorage overwrite logic and pointed the UI directly to fresh server data, 41 finally showed up crystal clear.
Vibe coding alongside AI to churn out features fast is great, but when developers don't understand the whole picture and just let things run, these fragments slip by unnoticed. If you don't clean them up in time, they eventually bite you from the strangest angles. -
Testing right after a fresh setup is tough to begin with, and leaving the entire coding process to AI reminded me that while everything is fine when it works, diagnosing issues when things break can become a real headache.
I was planning to touch up the design editor once things stabilized reasonably well, but I have an ominous feeling that reaching that "reasonable" bar might take quite some time.
Should I just wait for AI capabilities to accelerate even further...? -
Vibe coding has already become mainstream, and it comes with a serious side effect: once you experience it, there's no going back.
While we still need human developers to orchestrate the big picture today, I know deep down that the day when you just say "build this" and AI handles all the coordination autonomously isn't far off.
Every time I feel that shift firsthand, it leaves me with quite a bittersweet feeling.
Read in:
0 Comments
Login is required to write comments.