크라우니클린 P0 구축 (clean.crowny.org:9624)
- 일자: 2026-07-26 착수 / 2026-07-27 완료
- 산출:
/Users/ef/crowny-clean/— 순수 한선씨 서버 + 단일 앱.html - 사양 SSOT:
/Users/ef/Downloads/크라우니클린 패키지/README.md(5.10 P0 범위) - 디자인 SSOT:
크라우니캔버스 디자인 규칙.css+클린화면A–H·S·M.dc.html
개요
이사·입주 프리미엄 1:1 클리닝 서비스. 차별점은 청소 품질 주장이 아니라 전 과정 사진 기록이다. 접수 → 배정 스태프 공개 → 구역·머신별 작업 → before/after → 리포트를 고객이 모바일로 실시간 확인한다.
핵심 불변식(절대규칙 5)을 서버 라우트 수준에서 강제했다.
- 금액 발생·고객 공개·주소 노출 =
confirm=1없으면 409 + 감사 로그 append-only - 스태프는 촬영·보고만 — 분류·짝·공개·금액 라우트는 403
- 미분류(pending)·보류(held) 사진은 고객 응답에 절대 포함되지 않음
- CRD는 정수
crd_milli로만 저장, 0.05 배수 검증, 표기는 항상 소수 2자리
무엇을 했는지
1. 서버.한선 (1,580줄 · 포트 9624 · hanseonc_high 경고 0)
데이터 모델(5.1) 전부를 PSV append-log(latest-wins)로 영속화 — 재기동 시 복원 확인.
quote booking job zone photo report approval staff crew crd_ledger audit_log + staff_report review chat.
라우트 43개 전수 200/403/409/404 검증(아래 검증 절 참조).
| 군 | 라우트 |
|---|---|
| 공통 | GET /health GET / GET /fonts/PretendardVariable.woff2 |
| 1a | GET /home |
| B | POST /quotes/estimate POST /quotes GET /quotes POST /quotes/finalize(관리자) |
| C | GET /slots GET /staff GET /crews/assigned POST /bookings(confirm) GET /bookings POST /bookings/change |
| D | GET /jobs/:id GET /jobs/:id/photos(published만) GET /jobs/:id/timeline |
| E | POST /approvals(관리자) GET /approvals POST /approvals/decide(confirm+decision 명시) GET·POST /chat |
| F | GET /jobs/:id/report POST /reports/publish(관리자) POST /reviews(CRD 적립) GET /crd |
| S | POST /staff/photos(스태프) GET /staff/queue GET·POST /staff/report |
| M | GET /admin/inbox POST /admin/photos/classify POST /admin/zones/publish(confirm) POST /admin/zones/status GET /admin/audit |
| 뷰 배치 | GET /view/live /view/booking /view/report /view/staff /view/admin — 한 화면 = 한 요청 |
visibility=pending(고객 불가시) → 관리자 classify(교정 이력 감사 기록) →
관리자 zones/publish(확인 다이얼로그) → 그때서야 /jobs/:id/photos에 등장.2. 앱.html (단일 파일 · 고객 6 + 스태프 3 + 관리자 2 화면)
- 토큰은
크라우니캔버스 디자인 규칙.css값 무수정 복사, 다크는[data-theme="다크"]토큰 스왑만 - 딥링크
#역할/화면,?theme=다크(알림·공유 링크가 화면에 직결) - 확인 다이얼로그 공통 컴포넌트 — 제목·설명·기록 문구·실행 4요소 강제
- 웹폰트 자체 서빙(외부 CDN 미사용)
3. 앱.한선 — 프론트 뷰모델 정본 (한선씨 동반, 셀프테스트 33/33 PASS)
화면 라우팅·탭 모델·권한 매트릭스·골드 상한·CRD 표기·용어 게이트를 한선씨로 선언.
env RUN=1 crownyc run 앱.toau로 검증한다. JS는 이 규칙의 렌더 계층이다.
검증
- 컴파일:
hanseonc_high 서버.한선경고 0 (54,519 큐브) ·앱.한선경고 0 - 라우트: curl 43/43 PASS (권한 403 5건 · 확인 게이트 409 3건 · 404 1건 포함)
- 재기동 복원: kill 후 재기동 → CRD 잔액·견적·승인 상태 그대로 복원
- 브라우저 육안: 8화면 전부 렌더 확인(라이트/다크). 스크린샷
/tmp/clean_shots/ - 디자인이식 diff: 판정 옴 · 신규색 0 · 신규치수 0→3(토큰 var 참조 오탐)
- QA 체크리스트(5.9): 용어 혼용 0 · CRD 소수 2자리 · 골드 솔리드 화면당 ≤2(관리자 1) ·
이번에 확인한 함정 (다른 세션도 해당)
TCP쓰기는 부분쓰기 루프가 없는 단일write()(crownyc.c:12243).
파일소켓전송(856)으로 보낼 것. C레벨 부분쓰기 루프가 있다.
- Content-Length는 UTF-8 바이트수여야 한다. 생략하면 fetch가 EOF를 기다리며 멈춘다.
글자수()는 문자수 → 한글 본문에서 어긋난다. 바이트수 헬퍼 필수.
- 한선씨 문자열의
${...}는 변수 보간으로 파싱된다 — 체계()에 셸 변수를 넣을 때
${i}는 컴파일 에러(미정의 변수). "$n" 형태로 쓸 것.
- 브라우저는 한글 쿼리값을 %XX로 인코딩한다 — 서버에서
role=관리자문자열 비교가
- 응답 크기를 줄이는 것이 곧 안정성이다. 정적 UI 문구는 클라이언트 상수로, 목록은 커서 12건.
- 크라우니AI검증(WKWebView) 헤드리스는 +1초 수집 예산이라, 큰 fetch가 진행 중이면
--virtual-time-budget로 교차 확인할 것.관련 파일
/Users/ef/crowny-clean/서버.한선·서버.toau— 백엔드/Users/ef/crowny-clean/앱.html— 프론트(고객·스태프·관리자)/Users/ef/crowny-clean/앱.한선·앱.toau— 뷰모델 정본 + 셀프테스트 33/33/Users/ef/crowny-clean/data/*.psv— append-log 영속화/Users/ef/crowny-clean/fonts/PretendardVariable.woff2— 자체 서빙 웹폰트- 디자인 리포트:
/Users/ef/.claude/design-port/크라우니클린/리포트/
잔여 이슈
- P1: G군(소개·선물·결제) · H군(마이·설정) · S4(특이사항 제안) · M3(자동화 학습 제안 단계)
- P2: 반자동 승격(임계값 92%) · F5(A/S) · A6(검색). 현재 추론·규칙 승격은 미구현이며
- P3: 자동 단계 · 바타입 1080×360 · 태블릿 레일 64px
- 실시간은 폴링 없이 화면 진입 시 조회다. WS(
job.progress)·D5 동기화 실패 UI는 미구현. - 사진은 전부 스트라이프 플레이스홀더 — 실제 업로드 저장소·EXIF 제거 파이프라인 미구축
exif_stripped=1 플래그만 기록).
- 인증 없음. 역할은 쿼리 파라미터라 신뢰 경계가 없다 — 공개 전 세션·토큰 필수.
- A군(사례·후기 목록)은 홈의 대표 사례 2건만. 목록·상세·뷰어는 미구현.
운영 중 발견한 시스템 이슈 (다른 세션 확인 요망)
crowny-monitor/모니터판.toau(pid 4293)가 [ARRAY] OOM 무한 스핀으로
/tmp/모니터판.err에 136GB를 쌓아 루트 디스크를 100%로 채우고 있었다.
작업 진행이 불가해 해당 프로세스를 종료하고 로그를 비웠다(디스크 136GB 회수).
근본 원인(배열 힙 고갈 후 재시도 루프)은 해당 서비스 담당 세션이 봐야 한다.