solution.crowny.org 백엔드 — 개발명세 A2~A8 구현
개요
crowny-solution(solution.crowny.org:9735)에 개발명세 A2~A8(진단 상태기계·계약 사다리·구독원장 3분할·편성엔진 5+5·감사로그·A6 API)를 구현. 정본 판정 로직은 한선씨(솔루션앱.한선), server.js는 1:1 파리티 JS(lib/솔루션앱.js)로 이중 구현.
무엇을 했는지
- 솔루션앱.한선 — 함수 정의만(top-level 기동문 없음): 진단 상태기계 전이표, AI 모의 스코어(규칙기반), undo 보상전이, 계약 사다리+게이트(4→5 수료≥2), 구독원장 3분할(절단나눗셈 헬퍼로 자연반올림 VM 함정 회피), SLA 감면크레딧, edu 크레딧 12개월 환급 판정, 편성엔진(광고금지·연속2일제한·계약대체·하드캡, 배열은 카운트만 반환해 VM 함수재호출 배열함정 회피), 감사로그 레코드/undoable 판정.
- 솔루션앱검증.한선 — 66 assert 케이스(전이표 전체 14, AI스코어 4, undo왕복 7, 사다리게이트 10, 3분할 11, SLA감면 2, 크레딧환급 5, 편성엔진 12, FeedBasis 1) — CROWNY_STRICT=1 컴파일 경고 0, 66/66 PASS.
- lib/솔루션앱.js — 위 로직 JS 파리티 포트. /tmp 파리티 스크립트로 22개 대표케이스(3분할·게이트·전이·환급·편성캡) 한선씨↔JS 결과 일치 확인.
- server.js — data/solapp.json(시설4·계약3[stage1/3/5]·라이브3·릴리즈2026Q3·SLA티켓2) + data/solapp-audit.log(append-only 줄단위 JSON) 영속 추가. A6 API 전체 배선: /api/feed, /api/diagnosis(+decision/undo), /api/contracts(+ledger/visit), /api/credits/:id/redeem, /api/academy/lives(+enroll), /api/completions, /api/releases, /api/proposals, /api/sla/tickets, /api/audit. 계약 stage4→edu방문 2회 시 게이트 통과→stage5 자동전이+SubscriptionLedger 자동생성 라이브 확인.
- SPA 셸 라우팅(/app /feed /catalog /contract /academy /upgrade /ops) — web/app.html 없으면 index.html 폴백 대신 200 "준비중" 텍스트로 응답(web/app.html은 별도 에이전트 작업물, 미충돌 확인).
검증 결과
- 한선씨: 66/66 PASS, STRICT 경고 0
- 파리티: 22/22 PASS
- curl 종단: 진단접수→ai_screened(score=90)→decision approve→undo×2(received까지 롤백, 감사 5건)→ CON-3 ledger 3분할 합계=F(59000) 검증 → CON-2 stage4 edu방문 완료 시 stage5 자동승격+원장생성(감사 contract.stage_changed 기록) → credits/redeem 성공 → academy enroll 201 → audit 총 22+건 누적
- 기존 라우트 회귀: GET / 200, /api/solutions 200, /api/categories 200, /rental.html 200, /docs/disaster.html 200, crew login 401(정상) — 전부 무변경
관련 파일
- /Users/ef/crowny-solution/솔루션앱.한선 (정본)
- /Users/ef/crowny-solution/솔루션앱검증.한선 (셀프테스트)
- /Users/ef/crowny-solution/lib/솔루션앱.js (JS 파리티)
- /Users/ef/crowny-solution/server.js (A6 라우트 배선, .bak-solapp 백업 보관)
- /Users/ef/crowny-solution/data/solapp.json, data/solapp-audit.log (영속)
잔여 이슈
- web/app.html 미존재 — 다른 에이전트 작업 완료 후 SPA 셸 라우팅이 자동으로 해당 파일을 서빙(코드 변경 불필요, 존재검사만 함).
- 데모 시드 SOL-102 가격 문자열("1.2억~(시군구)")의 숫자 파싱이 단순 정규식이라 월구독료로는 부정확(자동 stage5 승격 시 monthlyFee=12로 계산됨) — 실제 스키마에 정식 monthlyFee 필드가 생기면 대체 필요.
- /api/contracts/:id (단건 상세, ledger 제외) 엔드포인트는 A6 명세에 없어 미구현 — 목록(?facility=)과 ledger 하위경로만 제공.