Skip to content

feat(config): EAC 세션에서 사용자 정보 자동 탐지 + Edge/Brave 인증 지원#1

Open
zb-sj wants to merge 6 commits into
zigbang:mainfrom
zb-sj:feat/config-init-auto-discovery
Open

feat(config): EAC 세션에서 사용자 정보 자동 탐지 + Edge/Brave 인증 지원#1
zb-sj wants to merge 6 commits into
zigbang:mainfrom
zb-sj:feat/config-init-auto-discovery

Conversation

@zb-sj

@zb-sj zb-sj commented May 22, 2026

Copy link
Copy Markdown

요약

eac config init 이 한 사람(박영걸/ZB01135) 의 PERNR/KOSTL/결재선을 하드코드한 상태였음. 다른 직원이 그대로 실행하면 본인 명의가 아닌 누군가의 SAP 정보가 디스크에 박혀 voucher/corpcard 가 잘못된 사람 앞으로 만들어졌음. 이번 PR 은 그 하드코드를 제거하고 EAC 세션 정보만으로 본인 SAP 필드를 전부 자동 탐지하도록 바꿈.

겸사겸사 옆에 있던 두 이슈도 같이 정리:

  • (a) 쿠키 스토어 리더가 Chrome 만 보고 있어서 Edge/Brave 사용자는 JSESSIONID not found 로 죽고 있었음
  • (b) 하드코드된 webDataCacheBust 상수가 서버 측에서 회전돼서 모든 namedService 호출이 RequireBustMismatchException 으로 실패하고 있었음

변경 사항

eac config init 자동 탐지

  • /unidocu/view.do 응답의 staticProperties.user JSON 에서 PERNR / BUKRS / KOSTL / 이름 / 부서 / 이메일 / 직책 일괄 추출
  • 본인의 ZUNIEWF_2200 개인결재선 목록과 ITEM_PRESETSevikbText 를 매칭해서 wfLineSeq / wfLineLin1 자동 wire
  • 각 매칭된 결재선마다 결재자 체인 출력 (결재자: 1차 성민지 → 2차 장혜연) — opaque 한 SEQ/LIN1 코드를 사람 이름으로 검증 가능
  • 인터랙티브 prompt 는 식별자 3개(PERNR/BUKRS/KOSTL) 만 남기고, 각 prompt 에 canonical 텍스트 함께 표시:
    PERNR (사번) — Sejun Jeong (정세준) [ZB00743]:
    KOSTL (코스트 센터) — Frontend Hogangnono [343020]:
    

Slim disk schema

저장 필드를 식별자 only 로 축소:

{
  "user":  { "pernr": "...", "bukrs": "...", "kostl": "..." },
  "items": { "자기관리비": { "wfLineSeq": "...", "wfLineLin1": "..." } }
}
  • 표시 라벨 (pernrName/wfIdText/kostlText) 은 매 command 호출 시 view.do 에서 live 로 채워짐 → 부서 이동/직책 변경 시 즉시 반영
  • item 정책 필드 (hkont/evikb/*_Text) 는 코드의 ITEM_PRESETS 가 SSoT → 회계 계정 코드 변경 시 disk drift 없음
  • 디스크 사이즈 약 70% ↓

멀티 브라우저 인증

auth.ts 가 Chrome → Edge → Brave 순으로 cookie store 자동 탐지, 첫 번째 살아있는 세션 사용. 실패 시 다음 브라우저로 fallback. EAC_BROWSER=chrome|edge|brave 로 강제 지정 가능. 재로그인 안내 메시지도 탐지된 브라우저 이름으로 동적 치환.

기타

  • Cache-bust 자동 갱신ClientContextrequireBust/webDataCacheBust 를 view.do 에서 매번 받아서 사용. 더 이상 hardcode 안 함.
  • PERNR 불일치 hard-fail — 저장된 PERNR ≠ 라이브 세션 PERNR 인 경우 모든 command 가 명확한 에러 메시지로 종료. 옛 동작은 silent warning 이라 SAP 요청 body 에 PERNR=A + PERNR_TXT=B 같은 혼종이 갈 위험 있었음.
  • ITEM_PRESETS 확장 — 자기관리비 / 가족회식비 / 원격근무지원비 / 법인카드. (체력단련비는 flex 처리이므로 제외.) 같은 EVIKB 공유하는 item 들은 결재선 한 번 발견으로 셋 다 채움.
  • Dead field 제거UserProfile.wfDept / wfDeptText 는 ops.ts 에서 0회 사용 → 타입에서도 삭제.

하위 호환

  • 기존 fat config.json 그대로 동작 — 모르는 키는 silently ignored, 다음 init --force 때 slim 으로 재작성. 마이그레이션 불필요.
  • 깨지는 유일한 케이스: ITEM_PRESETS 에 없는 커스텀 item 키가 disk 에 있는 경우 → 친절한 메시지의 hard error ("ITEM_PRESETS 에 추가하고 재빌드하거나 config 에서 제거해라").

Test plan

  • bun src/index.ts config init --print --yes — 작성자 Edge 세션으로 live 검증: PERNR/BUKRS/KOSTL 자동탐지, 3개 item 이 같은 [개인]-장려지원금 결재선에 매핑되고 결재자 체인 1번만 출력 (dedupe 정상 동작)
  • bun src/index.ts config show — slim disk shape 출력 확인
  • bunx tsc --noEmit — 0 error (사전 존재 update-check.ts 에러는 별개)
  • loadCtx overlay 검증 — disk {pernr,bukrs,kostl} + ITEM_PRESETS merge 결과로 ops.ts 가 기대하는 풀셋 ReimbursementItem 생성
  • PERNR 불일치 hard-error — stale config.json 으로 cross-session 시도 시 정상 종료
  • 다른 직원들이 본인 EAC 세션으로 sanity-check 후 머지

🤖 Generated with Claude Code

zb-sj and others added 3 commits May 22, 2026 12:45
Walk a list of Chromium-family browsers (Chrome → Edge → Brave),
extracting JSESSIONID from the first one with a cookie present, and
fall back to the next on read failure. `EAC_BROWSER=chrome|edge|brave`
forces a single browser; all messaging (re-login prompt, error text)
substitutes the detected browser name.

The on-disk cookie format is identical across Chromium browsers
(v10 prefix + AES-128-CBC with PBKDF2-derived key from a per-browser
keychain entry), so only the paths and keychain service names differ.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces the hardcoded single-user DEFAULT_CONFIG with a session-driven
flow. `eac config init` now extracts PERNR/BUKRS/KOSTL (+ display
labels) from `view.do` `staticProperties.user`, then matches the user's
own ZUNIEWF_2200 personal-approval-lines against ITEM_PRESETS to
auto-wire wfLineSeq/wfLineLin1 — no per-user data is hardcoded.

What's stored on disk shrinks to identifiers only:
  user  → { pernr, bukrs, kostl }
  items → { [name]: { wfLineSeq, wfLineLin1 } }
Display labels (pernrName/wfIdText/kostlText) and policy fields
(hkont/evikb/*_Text) are re-derived every command run — labels from
view.do bootstrap, item policy from ITEM_PRESETS — so the on-disk
config never drifts when an employee changes department or when the
chart of accounts is updated.

Side fixes folded in:
- `client.ts` reads the rotating cache-bust from ctx (scraped from
  view.do `staticProperties.requireBust`) instead of a stale module
  constant — was tripping RequireBustMismatchException.
- `loadCtx` hard-fails when stored PERNR differs from the live session
  PERNR (previously a soft warning that left mixed PERNR + PERNR_TXT
  in SAP request bodies).
- Items presets expanded to 자기관리비/가족회식비/원격근무지원비/법인카드;
  체력단련비 stays in flex.
- Init shows the approver chain per detected line (`1차 X → 2차 Y`)
  so opaque SEQ/LIN1 IDs are humanly verifiable, and groups items
  that share the same approval line.
- Dead UserProfile fields (`wfDept`, `wfDeptText`) removed — ops.ts
  never read them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Authentication section now describes Chrome/Edge/Brave detection
instead of Chrome-only; `eac config` section documents the new
init flow (auto-discover from view.do, approver-chain verification,
PERNR-mismatch hard-fail) and the slimmer disk shape. Personal
values in the JSON example replaced with `<placeholder>` tokens.
Adds an ITEM_PRESETS reference table for the four built-in items.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zb-sj zb-sj changed the title feat(config): auto-discover identity from EAC session; multi-browser auth feat(config): EAC 세션에서 사용자 정보 자동 탐지 + Edge/Brave 인증 지원 May 22, 2026
zb-sj and others added 3 commits May 26, 2026 09:17
…atch

The CLI was hardcoding `BUPLA: "K100", GSBER: "K200"` in three voucher /
corpcard write paths. K200 is Zigbang's Business Area; users in other
business areas (e.g. Hogangnono = K300) got SAP rule ZFI1.213 rejection:
"Please input only the same 'Business Area'" — the credit line carried
K200 while the debit line's KOSTL implied a different GSBER.

Changes:
- `UserProfile` gains `bupla` and `gsber` as stored identifiers.
- `whoami.ts` pulls BUPLA/GSBER from `staticProperties.user`. BUPLA is
  reliably populated; GSBER is often empty (cost-center master doesn't
  push it back to the SPA bootstrap).
- `ops.ts` swaps the three hardcoded sites for `user.bupla` / `user.gsber`.
- `loadCtx` hard-fails when stored config is missing these — the SAP
  rejection it would otherwise trigger is opaque, so fail early with
  a remediation message.
- `config init` only prompts for GSBER (and only when view.do leaves
  it empty); the noisy PERNR/BUKRS/KOSTL/BUPLA confirmation prompts
  are gone since those are reliably auto-detected.
- New `--gsber <code>` flag lets non-interactive contexts (CI, scripted
  init) provide the value: `eac config init --force --gsber K300`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previous commit narrowed the prompt set to GSBER-only on the
assumption that auto-detected PERNR/BUKRS/KOSTL/BUPLA never need
human verification. That contradicted an earlier user decision to
keep per-field confirmation as a safety net. Restoring all five
prompts (PERNR/BUKRS/KOSTL/BUPLA/GSBER) — each with the auto-detected
value as default, Enter to accept.

GSBER's prompt label dynamically includes the K200/K300 hint only
when view.do left it empty, so the common case (already populated)
stays uncluttered. The `--gsber` flag remains for non-interactive
contexts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
K300 is Property, not Hogangnono — earlier guess was incorrect.
Hogangnono and other non-Zigbang/non-Property business units have
their own GSBER codes that vary, so any hardcoded mapping risks
misleading users into committing the wrong value.

Replace the mapping hint with a UI-lookup pointer: "EAC > 비용정산 >
EA전표작성 > 사업영역 드롭다운에서 default 값 확인". Code stays
agnostic to the company's specific business-area numbering.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant