korace — 규칙 · 함정
프로젝트 폴더 =
C:\dev\korace· 계획서 전문 =C:\dev\korace\PLAN.md· 상태 =handoff.md. 여기엔 다시 밟으면 안 되는 것만 둔다.
앱 운영
- 앱 =
http://127.0.0.1:8815/· 상주 = 창 없는pythonw(예약작업korace_app+ HKCU Run). 127.0.0.1 전용 — 밖에서 봐야 하면 Tailscale, 포트를 열지 않는다. - 회귀는 한 줄 =
PYTHONUTF8=1 python tools/check_all.py(브라우저 검사 빼려면--fast). 새 화면을 만들면check_hub.py의SCREENS에 한 줄 추가까지가 한 작업이다. - 검사는 만든 데이터를 끝에서 전부 지운다(원상복구까지가 검증). 병렬로 돌리지 마라 — 에이전트 여럿이 공유
catalog.db에 동시에 쓰고 지우면 서로 것을 날린다(26.8.7 실측). Playwright 도 공유 프로필(C:\dev\pw-chrome-profile)을 쓰지 말고 격리 인스턴스로 띄운다.
설계 · 핀 데이터
- 모르면 만들지 마라. 추측 치수·핀은 최악이다 — 화면이 「등록됨」으로 보여주고 사람이 믿고 배선한다. 없으면 「핀 미등록」으로 두고 핀 단위 배선을 막는다.
- CC-BY-SA 자산 금지(Fritzing·SparkFun·pinout.xyz·KiCad 공식 라이브러리). korace 는 나중에 팔 수도 있다(페페 26.8.8) → MIT/Apache/BSD/공개 데이터시트만.
- 전원 핀은 전압이 필수다. 전압 없는 전원 핀은 저장이 거부된다 — 24V 를 5V 입력에 물리는 사고를 그 값으로 잡는다.
- 결선표·검사·견적 금액은 서버가 만든다. 화면에서 다시 만들면 언젠가 갈린다.
- 설계 → BOM 은 제안이다. 사람이 손으로 고친 수량·단가를 덮지 않는다.
🆕 신규 (26.8.8 — 실물 사진·근거 표시)
- 사진은
tools/fetch_photo.py로만 넣는다. 손으로 두면 출처가 빠지고, 출처 없는 사진은 나중에 통째로 버려야 한다. 확장자는 URL 이 아니라 바이트로 판정(로그인 페이지 HTML 이 .jpg 로 내려온다) · 4KB 미만은 placeholder 다. - 크레딧은 부품당 파일 하나. 공용 목록 1개면 병렬 수집이 동시에 쓰다 깨진다.
- 🔴병렬 수집 최대 사고 = 옆 부품 사진(26.8.8 실제 3건: 일반 클론↔SparkFun 정품 · 보드 대신 칩 단품 클로즈업 · 제조사 로고 이미지). 사람이 107장을 볼 수 없으니 지문(sha256) 중복 검사를 감사에 넣었다 — 같은 이미지가 두 부품에 붙으면 둘 중 하나는 남의 것이다. 수집 지시문엔 "실크스크린 글자로 같은 모델인지 확인"을 반드시 넣어라.
- 🔴cody-vision 을 「이게 그 부품이 맞나」에 쓰지 마라. 로고 이미지를 놓고 「MAX485·XLR·핀헤더가 보인다」고 좌표까지 붙여 환각했다. 무엇이 보이나(판독)는 시키되, 물건 동일성 판정은 사람이 눈으로 한 번 더 본다.
- 사진으로 그린 데이터는 데이터시트와 같은 무게가 아니다 →
evidence(photo/mixed) +photo_note(무엇을 읽고 무엇을 추정했나) 없으면 저장 거부. 표시는 목록 배지·캔버스 점선·결선표 경고문 세 곳(현장에 나가는 종이까지 가야 뜻이 있다). - 검사가 남의 데이터를 지우면 안 된다.
check_design.py는 미등록 부품에 핀 파일을 만들었다 지우는데, 그 사이 수집이 같은 부품을 등록하면 그걸 날린다 → 「우리가 만든 것일 때만」 지운다. - innerText 는 SVG 글자를 안 담는다. 캔버스 이름표를 검사하려면
textContent로 읽어라. - 저장 후 목록 배지가 안 바뀌면 캐시를 안 갱신한 것이다 — 화면이 처음 받아온
evidence맵을 저장 결과로 갱신해야 한다. - 사진·핀 데이터가 없는 부품이 남는 건 정상이다(26.8.8 기준 미등록 8). 핀맵 미공개·CC-BY-SA 뿐 · 골드핑거/SO-DIMM 이라 접점이 없다 · 리비전마다 다르다 → 그럴 땐 안 만든다.
🆕 신규 (26.8.8 — P1 화면)
- 저장하면서 모르는 필드를 날리지 마라. 핀 문서를 화면이 새로 조립해 POST 하면 화면이 안 쓰는 값(
desc323건·블록label14건)이 통째로 사라진다 → 읽어온 문서를 펼쳐 실어 보내고 아는 필드만 덮어쓴다. 숫자칸을 비웠을 땐 0 이 아니라 필드째 뺀다(header:0= 0번 헤더,x:0= 왼쪽 끝 = 전혀 다른 뜻). - 표 줄 클릭과 줄 안 버튼 클릭은 겹친다.
util.table의onRow가 있는 표에서 셀 안 버튼을 누르면 핸들러가 둘 다 돈다(편집기가 두 번 열려 저장 버튼이 2개가 됐다) → 줄 안 버튼은e.stopPropagation(). - SVG 글자에 「13px 미만 금지」를 그대로 재면 뜻이 없다. SVG font-size 는 px 가 아니라 사용자 단위라
getComputedStyle값이 화면 크기가 아니다 → hub 검사는svg안을 빼고, viewBox 배율(rect.width/viewBox.width)을 곱해 실제 화면 px 로 재라. 반대로 그리는 쪽은 글자 크기를 배율의 역수로 줘야 확대·축소해도 13px 을 지킨다. - 회전축은 부품 중심이다. 좌상단을 축으로 돌리면 90° 를 누를 때마다 부품이 화면 밖으로 달아난다.
- 작은 도형은 투명한 큰 히트영역을 겹쳐야 눌린다(핀 점 0.6mm). 그 히트영역이
pointerdown전파를 끊어야 드래그(부품 이동)와 안 부딪힌다. - PNG 은 크기만 보면 백지도 통과한다. 내려받아 픽셀을 세라(
expect_download→ PIL 로 흰색 아닌 표본 수). SVG→PNG 는 외부 참조가 없어야 캔버스가 안 더러워진다 → 스타일은 CSS 클래스 말고 표현 속성으로 준다. - 상주 프로세스는 서버 코드가 바뀌어도 안 바뀐다. 8815 에 떠 있던
pythonw가 전날 밤 기동분이라 그날 추가한 API 가 통째로 404 였다(화면 JS 는 디스크에서 매번 읽혀 멀쩡해 보인다) → 서버 파일을 고친 날은 기동시각부터 본다(psutil.Process(pid).create_time()), 재시작은subprocess.Popen(..., creationflags=DETACHED_PROCESS|CREATE_NO_WINDOW)(git-bash 의cmd //c start는 콘솔을 물고 멈춘다).