관리자 페이지에서 포스트 목록을 보는데 조회수가 이상하게 찍혀 나오는 기괴한 현상을 발견했다.
분명 내가 들어가서 읽어본 글도 있고 유저들이 오가며 본 글도 있고, 블로그에 나오는 조회수와 어드민의 대시보드에 나오는 조회수, 포스트 관리에 나오는 조회수가 모두 달랐다.
혹시나 배포하다가 D1 데이터베이스 컬럼이나 테이블이 통째로 날아갔나 싶어 순간 식은땀이 흘렀다.놀란 마음에 원격 D1 터미널로 테이블 구조와 실제 데이터를 까봤는데 결과는 허탈했다.
npx wrangler d1 execute svelteblog-db --remote --command="PRAGMA table_info(posts);"posts테이블의view_count컬럼도 멀쩡했고, 유저 DB를 열어보니 일자별 조회수 로그는 무려 1,000건이 넘게, 총합 1,400뷰 이상 아주 잘 살아있었다.
데이터가 날아간 게 아니라 멀쩡히 숨 쉬고 있는데 화면에서만 안 보이고 있던 것이었다.원인을 거슬러 올라가 보니 바이브 코딩으로 빠르게 치고 나가면서 제때 정리하지 않고 넘어간 파편들이 문제였다.
우리 블로그는 글 본문이 있는BLOG_DB와 유저/통계 로그를 담는USER_DB가 쪼개져 있는데, 일자별 통계만 차곡차곡 쌓아두고 정작 본문 쪽 캐시 컬럼으로 합산해 주는 동기화 파이프라인을 온전히 마무리 짓지 않고 '에러없이 도는구만' 하고 넘어갔던 과거의 빚이었다.
진짜 데이터는 유저 DB에 쌓이는데, 어드민은 텅 비어 있는 블로그 DB만 쳐다보고 있었으니 0으로 나오는 게 당연했다.그래서 '아, 원인 찾았네!' 하고 어드민 서버에서 유저 DB의 합계를 읽어와 매핑해주고, 안 맞는 글들은 블로그 DB로 자동 동기화하도록 서버 코드를 고쳐 테스트를 해봤다.
// 어드민 서버: USER_DB 원본 집계 및 불일치 포스트 자동 동기화 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) }));이제 41뷰니 뭐니 정상 숫자가 떠야 하는데... 새로고침을 해도 끝까지 0이 떴다.
DB를 직접 조회해 보면 분명 41인데 웹 화면에선 악착같이 0만 고집하길래 이때 진짜 귀신이 곡하는 줄 알았다.결국 범인은 서버가 아니라 프론트엔드 Svelte 컴포넌트에 남아있던 또 다른 문제도 겹쳐 있었다.
예전에 어드민 목록 로딩 빠르게 만든답시고localStorage캐싱 로직을 넣어뒀었는데, 그게 문제였다.// apps/admin/src/routes/posts/+page.svelte (수정 전 문제 코드) } else { // 일반 진입: localStorage에 유효한 캐시가 있으면 재활용 const saved = localStorage.getItem(POSTS_CACHE_KEY); if (saved) { cachedPosts = parsed.posts; // <- 서버가 준 최신 데이터를 과거 로컬스토리지로 다짜고짜 덮어써버림 } }Svelte 5의
$effect안에서, 서버가 D1에서 41이라는 최신 데이터를 가져와 건네주자마자 프론트엔드 코드가 브라우저 로컬스토리지에 들어있던 과거의 '0 조회수 목록'을 꺼내 화면을 덮어씌워 버리고 있던 것이었다.
만료 시간(TTL)도 없어서 F5를 백날 눌러봐야 브라우저는 옛날 캐시만 꿋꿋하게 보여주고 있었으니 화면이 바뀔 리가 없었다.결국 백엔드의 데이터 동기화 미흡과 프론트엔드의 무자비한 로컬스토리지 덮어쓰기라는 두 가지 파편이 절묘하게 만나서 '서버도 있고 DB도 있는데 브라우저가 화면을 덮어쓰는' 기막힌 콜라보를 만들어낸 셈이다.
로컬스토리지 덮어쓰기 로직을 걷어내고 최신 서버 데이터를 바로 보게 고치고 나니 비로소 선명하게 41이 뜬다.
AI랑 호흡 맞춰서 빠르게 기능 찍어내는 건 좋은데, 사실상 개발하는 사람이 전체 내용을 모르고 그냥 돌리면 이런 파편들을 인지도 못하고 지나치기 쉬운데 제때 치우고 가야지 안 그러면 나중에 진짜 기괴한 방식으로 뒤통수를 맞는다.이게 사실 막 설치하고는 테스트하기도 어렵기도 하거니와 그냥 전부 AI에게 맡겨서 코딩을 하고 나면 모든게 정상이면 다행인데 문제 발생했을 때 진짜 난감해질수 있다는 걸 새삼 느꼈다.
적당히 안정화되면 디자인 에디터 쪽이나 손보려고 했었는데, 그 '적당히' 수준까지가 꽤나 걸릴거 같은 불길한 예감이 든다.
그냥 AI발달의 가속화를 기다려야하나...바이브 코딩은 이미 대세가 된데다 한 번 경험하면 되돌아가지 못하는 심각한 부작용도 있다.
거기다가 현재는 전체 조율을 할 개발자가 필요하겠지만 궁극적으로는 그냥 '이거 만들어' 하면 알아서 다 조율해서 나오게 될 날이 진짜 며칠 안남았다는 걸 안다.
이런걸 체감할 때마다 기분이 참 묘하다.
Read in:
댓글 0개
댓글을 작성하려면 로그인이 필요합니다.