ProjectCard가 리스트에서도 description 필드를 마크다운 그대로 렌더링해서, 카드 하나가 화면 대부분을 차지했다 프로젝트 전용 상세 페이지(/projects/[slug])가 아예 없었다 — 조사해보니 "있다"고 착각했던 건 /log/[slug]와 혼동한 결과였다 홈페이지는 created_at 내림차순으로 최신 3개를 무조건 보여줬다. 어떤 프로젝트를 먼저 노출할지는 오직 "최근에 만들었는가"로만 결정됐다 카드에서 상세 정보로 이동할 방법 자체가 없었다 (있는 건 실제 서비스로 나가는 "바로가기" 외부 링크뿐)
개요
/projects 리스트에서 카드 하나가 "프로젝트 개요, 담당 역할, 주요 활동"까지 마크다운 본문 전체를 그대로 펼쳐서 보여주고 있었다. 프로젝트가 두세 개일 땐 문제가 안 보였는데, 늘어날수록 리스트가 스크롤 지옥이 될 게 뻔했다. 동시에 홈페이지의 "Projects" 섹션은 항상 최신순 3개만 기계적으로 보여주고 있어서, 어떤 프로젝트를 먼저 보여줄지 고를 방법이 없었다. 콘텐츠가 늘어나기 전에 구조를 먼저 정비하기로 했다.
카드 요약에 별도 필드(예: summary)를 새로 만들지 않고 기존 description을 텍스트로 변환해서 재사용했다. 지금 목표는 "카드가 너무 길다"는 문제 해결이지, 콘텐츠 구조 자체를 다시 설계하는 게 아니었다. 필요 이상으로 스키마를 건드리지 않는 것도 설계 판단이다. 카드 전체를 클릭 영역으로 만드는 방식은 <Link> 안에 <a>를 중첩시키는 실수를 하기 쉬운 지점이다. stopPropagation 이벤트 핸들러로 막는 방법도 있었지만, CSS 절대 위치 오버레이 패턴을 택해서 서버 컴포넌트를 그대로 유지하고 유효한 HTML 구조를 지켰다. 순서를 저장 버튼 없이 즉시 반영하는 방식도 고려했지만, 드래그는 실수로 순서가 흐트러지기 쉬운 조작이라 "저장을 눌러야 확정된다"는 한 단계를 의도적으로 남겼다. 되돌리기가 새로고침 한 번으로 가능해야 안심하고 조작할 수 있다. 홈에 노출할 프로젝트가 부족하면 시스템이 최신 글로 자동으로 채우는 방식도 검토했지만, 채택하지 않았다. 그렇게 하면 관리자가 의도하지 않은 프로젝트가 예고 없이 홈에 등장할 수 있다. 홈 구성은 관리자가 100% 의도한 대로만 채워지고, 비워두면 그냥 비어 보이는 쪽을 택했다. 예측 가능성이 자동 완성보다 우선이었다.
오버레이 링크 패턴은 "카드 전체 클릭 + 카드 안에 별도 액션 버튼"이 함께 필요한 모든 리스트 UI(상품 카드, 아티클 카드, 프로젝트 카드 등)에 그대로 재사용 가능하다. 핵심은 오버레이 링크와 액션 버튼의 z-index 순서 — 오버레이가 콘텐츠보다 위에, 액션 버튼만 오버레이보다 더 위에 있어야 둘 다 정상 작동한다. nullable 순서 컬럼으로 노출 여부와 순서를 동시에 표현하는 방식은 "노출 여부(boolean)"와 "순서(int)"를 각각 컬럼으로 나누는 것보다 단순하다. 컬럼 하나로 두 가지 상태를 표현하면서, 관리 UI도 "노출 중 리스트에 있는가"라는 하나의 질문으로 단순해진다. 드래그 순서 변경을 여러 개별 업데이트 쿼리 대신 하나의 트랜잭션(RPC 함수)으로 묶은 것도 재사용 가치가 있다. 순서처럼 "여러 row가 서로의 값에 의존하는 데이터"는 부분 실패가 곧 데이터 정합성 붕괴로 이어지기 때문에, 개별 update를 병렬 실행하는 방식은 지양하는 게 안전하다.
관련 프로젝트
프로젝트 개요 기획자(PM)로서 AI를 활용한 업무 자동화(AX) 사례를 문서화하는 개인 포트폴리오 사이트입니다. 국내 기업의 AX 기획자/AI PM 직군으로의 커리어 전환을 목표로, 사이트 자체가 채용 지원용 스토리텔링 자료로 실사용되고 있습니다. 핵심 패턴: 업무 병목 발견 → AI로 워크플로우 재설계 → Before/After·근거·재현 가능성 문서화 전체 서사는 '실행하지 않은 아이디어 나열'이 아니라, 하나의 검증된 자동화 패턴과 도메인별 확장 블루프린트를 갖춘 재사용 가능한 엔진을 보유하는 방향으로 수렴하고 있습니다. 기술 스택 Next.js 16, Tailwind CSS v4, TypeScript Supabase (개발/운영 환경 분리), Vercel, Resend Claude API 기반 기술 자문 및 프롬프트 설계 보안 아키텍처 관리자 CRUD는 세션 기반 인증과 RLS(Row Level Security)로 보호 공개 읽기 전용 경로는 별도의 익명 클라이언트로 분리 서비스 롤 키는 애플리케이션 코드에서 완전히 배제 권한 검증은 마이그레이션 파일 및 대시보드 검토를 통해서만 진행 작업 방식 (에이전틱 IDE 협업 워크플로우) AI 에이전트 기반 IDE가 파일/버전관리 작업을 담당하고, LLM은 기술 자문 및 프롬프트 작성 역할을 수행하는 협업 구조를 운영합니다. AI 자문 → 에이전트용 프롬프트 작성 → 실행자가 붙여넣기 → 계획 확인 → 자문 검토 → 실행 승인 → 로그 검토 → 직접 클릭 테스트 → 명시적 지시 시에만 커밋 통제 규칙 실행 전 계획 검토 필수 요약 보고가 아닌 직접 클릭 테스트로 검증 개발 환경 우선 적용 후 명시적 승인 하에 운영 환경 반영 커밋은 명시적 지시가 있을 때만 수행 DB 자격증명 직접 연결 및 범위 외 삭제 금지 브랜치 전략: 개발 브랜치에서 작업 후 운영 브랜치는 배포 전용으로 직접 커밋 금지, 병합 전 변경 범위 검증 현재 진행 상황 고객사 미팅 브리핑 자동화 사례: 1단계 완료, 개발/운영 환경 배포 및 실데이터 테스트 완료 범위 변경 감지 자동화 사례: 상태 확인 진행 중 리스크 조기 경보 자동화 사례: 운영 환경 배포 완료 보안 사고 관련 포스트: 'AI 리스크 거버넌스 사례'로 재구성 예정 AI 활용 관련 콘텐츠 시리즈 초안 작성 완료, 게시 미확정 핵심 학습 원칙 보고가 아닌 검증: 버그·보안 이슈는 항상 직접 로그/브라우저 검토를 통해서만 발견되며, 에이전트의 자체 결과 요약을 그대로 신뢰하지 않음 보안 사고의 콘텐츠화: 실제 발생한 권한 관련 이슈 사례를 케이스 스터디로 재구성하여 콘텐츠화 커밋 의미 분리: 기능 단위/변경 유형별로 항상 분리 커밋 자동화하지 않는 것도 스토리: 저사용 빈도 기능을 의도적으로 고도화하지 않은 결정 자체를 AX 스토리텔링 소재로 활용