2026-09-12 ServiceOn Blog 작업일지입니다. 오늘은 25건의 작업을 진행했습니다.

공개 웹 (시작 시 최종 매거진 일자)

현상/기능

  • 시작하면 무조건 오늘 날짜로 가지 말고 최종 매거진 일자가 오픈
  • 어제 매거진이 안나온다

작업

  • 운영 홈이 KST 오늘(2026-09-13 새벽)을 열어 9/12 일간호가 비고, 주간 띠(13–19)에 어제도 없음
  • `PostListPage` — 초기일을 `dates_in_range` 최종 DATE로 고름 (list_by_date와 동일)
  • `pickLatestDateKey`
  • mock — 2026-09-12 AI 매거진·카드

공개 웹 (홈 보드 행 정렬)

현상/기능

  • 홈 IT·AI / 프로젝트 / Working 날짜를 우측 끝으로
  • 4개가 박스를 넘어가지 않게

작업

  • `HomeBoard` CompactPostLink — 제목 왼쪽·날짜 오른쪽 한 줄
  • 각 칸 목록을 높이 4등분, overflow hidden

공개 웹 (홈 2×2 보드)

현상/기능

  • 홈 각 영역 5개 높이 → 4개로 맞추기
  • 4건은 날짜와 관계없이 최신 4건
  • 프로젝트 부제는 제목 옆 1줄
  • 프로젝트 제목 좌측 이미지 복구

작업

  • `PostListPage` — 홈 IT·AI 카드 최신 4건 SSR (`initialLatestCardPosts`)
  • `HomeBoard` — 칸 높이 4행, publishedAt 최신 4건, 프로젝트 제목+부제 한 줄, 좌측 썸네일 항상 표시
  • `admin-url` — 로컬 관리자 origin을 3001로 맞춤 (썸네일 경로)

공개 웹 (홈 프로젝트 칸)

현상/기능

  • 홈 화면 프로젝트 이미지가 깨진다. 부제목도 같이 나오게

작업

  • `HomeBoard` CompactPostLink — 프로젝트 썸네일 object-cover, 부제(summary) 한 줄 표시

공개 웹 (프로젝트 문의)

현상/기능

  • 프로젝트 공개페이지 맨아래 문의를 우측끝으로

작업

  • `PortfolioContact` — 우측 정렬, 「문의 :」 제거, 복사 아이콘으로 메일 주소 복사

관리자 (포스팅 에디터)

현상/기능

  • 관리자 모든 페이지에서 내용·설명 입력에 에디터로 글꼴을 변경할 수 있게

작업

  • `RichTextEditor` — 글꼴·크기·굵게·기울임·밑줄·색·목록
  • 포스트 본문, 프로젝트 소개/흐름/기능 설명, 공유링크 설명에 적용
  • 공개 공유링크 목록은 설명 HTML 표시

관리자 / 공개 웹 (기능 배치·이미지 fit)

현상/기능

  • 이미지 가로/세로 선택(기본 가로, 세로는 이미지 좌·설명 우)
  • 모든 공개 페이지 이미지는 fit
  • 프로젝트 페이지 이미지 클릭 시 크게 보기

작업

  • 관리자 기능 편집: 세로 배치 체크
  • 공개 상세: 가로는 이미지 위·설명 아래, 세로는 이미지 1장일 때만 좌·설명 우. 이미지 2장은 항상 가로
  • 프로젝트 목록/상세 클릭 확대
  • 공개 카드·행·매거진·본문 이미지 object-contain

관리자 (프로젝트 기능 영역)

현상/기능

  • 추가 시 페이지가 내려가지 않게 하고, 기능 영역 안에서만 스크롤. 각 기능은 제목 아래로 접기

작업

  • `PortfolioSectionsEditor` — 기능 목록 max-h 영역 스크롤, 제목 클릭으로 내용 접기/펼치기, 추가 시 해당 항목만 펼치고 영역 안으로 스크롤

관리자 / 공개 웹 (프로젝트 기능 편집)

현상/기능

  • 상세/수정에서 저장·삭제·취소 항상 하단 고정, 기능 순서 변경, 기능 이미지 2장(공개는 나란히)

작업

  • 저장/삭제/취소 하단 고정
  • `PortfolioSectionsEditor` — 위·아래 순서, 이미지 1·2
  • `PortfolioDetailView` — 이미지 2장이면 2열 나란히

공개 웹 (프로젝트 상세 레이아웃)

현상/기능

  • 3000/project/[id] 에서 사이트 및 유틸 문구 삭제, 제목-부제-대표이미지 배치, 제목 우측 사이트 열기, 대표이미지 강조, 기능 이미지는 타이틀 아래

작업

  • `PortfolioDetailView` — 헤더 순서 제목/부제/대표이미지, 사이트 열기는 제목 라인 우측
  • 섹션 제목: 소개 / 흐름 요약 / 기능
  • 대표이미지는 액자+배지+캡션, 기능 이미지는 기능명 아래

관리자 / 공개 웹 (프로젝트 본문 항목)

현상/기능

  • 프로젝트를 제목, 부제, 사이트 및 유틸 소개글, 사이트/유틸의 흐름 요약, 사이트 및 유틸 기능, 사용기술을 등록할 수 있도록 수정

작업

  • 관리자 `/projects`: 제목·부제·소개글·흐름 요약·기능·사용기술 입력 (`ProjectTechEditor`)
  • 기능은 기존 섹션 테이블, 사용기술은 `tech_stack` JSON
  • 공개 상세: 소개 / 흐름 요약 / 기능 / 사용기술 칩. 개발정보 표는 폼에서 제외

관리자 (프로젝트·포트폴리오 통합)

현상/기능

  • 프로젝트와 포트폴리오를 하나로 묶는다. 3001/portfolio 와 3001/projects 를 하나로 만들어 프로젝트로 포스팅

작업

  • 관리자 메뉴: 포트폴리오 항목 제거. `/projects` 가 통합 포스팅
  • `/portfolio` → `/projects` 리다이렉트
  • `POST/DELETE /api/project-posts` — Working 프로젝트 + 공개 카드를 한 번에 저장/삭제
  • `ProjectPostsClient` — 이름/슬러그/소개/이미지/영역/개발정보/Working 표시/공개
  • 공개 `/project`·Working 칩은 기존 테이블 연결 유지. 포스트 작성의 프로젝트 선택은 그대로
  • dbId: RFC variant가 아닌 기존 프로젝트 UUID도 그대로 전달 (저장 시 no row 방지)

공개 웹 (/project Project List)

현상/기능

  • /project 페이지에 타이틀을 Project List 로 변경하고 분류는 뺀다. 목록 카드 날짜는 Working 최종 수정 날짜

작업

  • `project/` — 제목 Project List, CategoryFilter 제거
  • `latestWorkingAtByProjectId` — 프로젝트별 Working 최신 publishedAt
  • `PortfolioCard`/`PortfolioGrid` — 목록 날짜는 Working 일자(KST). 없으면 카드 publishedAt
  • 헤더 메뉴·홈 보드·관리자·상세는 미변경

공개 웹 (Working 프로젝트 카드 구분)

현상/기능

  • working 메뉴에서 프로젝트를 선택하면 나오는 상단의 프로젝트 카드는 아래 working 리스트와 UI 적으로 구별

작업

  • `PortfolioCard` — `variant="spotlight"` 추가. 앰버 패널·큰 제목·썸네일. 기본 `row`는 /project 유지
  • `HistoryClient` — 선택 시 spotlight + 작업 일지 구분선/제목. 날짜 제목은 h3

공개 웹 (공유링크 등록 팝업 취소)

현상/기능

  • 공유링크에서 + 해서 팝업이 뜨는데 취소버튼 추가 하고 그 버튼을 눌러야 팝업이 사라지게

작업

  • `ShareLinkCompose` — 하단 취소 버튼 추가. 바깥 클릭·Esc·X로 닫지 않음
  • 등록/저장 성공 시에만 기존처럼 닫힘. ShareLinkBoard API 미변경

공개 웹 (PC에서 설치 배너 숨김)

현상/기능

  • 홈 메뉴 추가 배너는 pc 에서는 안보이게 가능한가

작업

  • `PwaInstallBanner` — 폰·태블릿만 표시. PC(데스크톱) 숨김
  • iPhone/iPad는 데스크톱 사이트 요청이어도 표시. standalone은 기존처럼 숨김
  • PC에서는 beforeinstallprompt preventDefault 하지 않음. layout·Header 미변경

공개 웹 (Working 상세 원문 보기)

현상/기능

  • working 메뉴에 페이지를 열면 하단에 원문보기 버튼은 필요가 없다

작업

  • `CardArticle` — Working(dev_history)은 `SourceActionRow`에 sourceUrl 미전달. 원문 보기·출처 숨김
  • IT·AI 소식 상세·덱 모달은 원문 보기 유지. SourceActionRow 내부 로직 미변경

공개 웹 (브랜드명 ON Briefing → On Blog)

현상/기능

  • ON Briefing 을 On Blog 로 변경

작업

  • OG/RSS · 페이지 title — 사이트명 On Blog
  • n8n `SO-블로그 구독 메일` (`7p6KtUGdcYAOnJfv`) — 제목·본문 h1·Gmail 발신인 On Blog
  • 워드마크 SERVICEON | BLOG 는 그대로

공개 웹 (설치 배너 항상 표시)

현상/기능

  • 예전에 닫기(X)를 누른 경우인것 같다. 홈화면 아이콘으로 연 경우가 아니면 무조건 팝업이 나오게

작업

  • `PwaInstallBanner` — localStorage 닫기 기록·X 버튼 제거. standalone만 숨김
  • 브라우저(사파리 포함)에서는 새로고침해도 항상 표시

공개 웹 (사파리 달력)

현상/기능

  • 사파리로 열었는데 달력이 안된다

작업

  • `DatePickerButton` — 달력을 overlay 자식으로 배치(사파리 sibling fixed 터치). 연 직후 450ms 닫힘 방지
  • `DateCalendar`·`DateStrip` — pointerup으로 선택(사파리 click 누락)

공개 웹 (iOS Safari 설치 배너)

현상/기능

  • 아이폰, 사파리이다. 홈화면에 추가 베너가 안나온다

작업

  • `PwaInstallBanner` — iPhone/iPad는 폭 조건·`sm:hidden` 제거. 가로·데스크톱 사이트 요청에도 표시
  • iOS UA + Macintosh+터치 감지. localStorage 예외 시에도 표시
  • 안내 문구: 하단 공유(□↑) → 홈 화면에 추가. standalone이면 숨김

공개 웹 (PWA 달력 선택)

현상/기능

  • pwa 번전일때 달력이 선택이 안된다

작업

  • `DatePickerButton` — 달력을 body 포털+fixed. 하단 탭·화면 밖과 겹치면 위로 배치
  • 바깥 닫기는 backdrop pointerdown (iOS/PWA mousedown 오동작 방지)
  • `DateCalendar`·날짜띠 `touch-action: manipulation`
  • Header·MobileTabBar·admin 미변경

공개 웹 (PWA 설치 안내 배너)

현상/기능

  • 설치 안내 배너 추가

작업

  • `PwaInstallBanner` — 모바일 브라우저만, Header 아래. standalone·닫기 시 숨김 (`so-blog-pwa-install-v1`)
  • Android `beforeinstallprompt` 있으면 설치 버튼(좁은 화면에서만 preventDefault). iOS는 공유 → 홈 화면에 추가 안내
  • layout에만 연결. Header·MobileTabBar·admin 미변경

공개 웹 (모바일 앱 셸 + PWA)

현상/기능

  • blog 전체를 모바일에서 PWA 형태로 / 모바일만 앱처럼 만들어 PWA UI·UX를 자연스럽게 / 진행

작업

  • `apps/web`만. admin 미변경
  • `lib/` · `lib/` — 메뉴 항목·활성·글 상세 포커스 공용
  • `MobileTabBar` — sm 미만 하단 5탭(홈/소식/프로젝트/Working/링크)
  • `Header` — 모바일은 워드마크+검색+테마+관리자, 메뉴는 데스크톱만
  • PWA: `app/`, `public/icons` 192/512/maskable, viewport themeColor·viewportFit, appleWebApp
  • `scripts/generate-pwa-icons.ps1` — 아이콘 재생성

페이지 (공유 링크 + 등록)

현상/기능

  • links 페이지의 + 했을때 아이디/비번을 @/@@ 를 치면 내부에서 자동으로 admin@serviceon.local / admin1234 이걸로 매칭

작업

  • `POST /api/share-links`: 아이디 `@` + 비번 `@@` 이면 admin@serviceon.local / admin1234 로 검증
  • 화면 입력값은 `@` / `@@` 그대로. 매칭은 서버에서만