Commit Graph

24 Commits

Author SHA1 Message Date
king 8ed1263bef feat(project): 관리자 페이지 접근 토글 + 멤버 배정 등록사용자 자동목록
- project 를 MODULE_KEYS 에 추가 → 관리자 페이지에 '프로젝트 관리' 토글
  자동 생성. 직원별 접근 권한 부여(admin 자동, 일반은 기본 OFF).
- 모듈 진입을 has_module('project') 로 게이트(기존 전원허용 철회).
- 멤버 배정 모달: GET /project/api/assignable-users 로 project 권한 보유
  등록 사용자를 드롭다운 자동 목록화(타이핑 제거). 이미 배정된 사람 제외.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 12:08:57 +09:00
king c192d61c71 feat(project): 아사나식 프로젝트 관리 모듈 추가
- project_db 신규(projects/members/stages/tasks/comments/activity, project_app CRUD)
- 프로젝트/서브프로젝트(self-FK), 업무·진행단계(칸반), 멤버 배정
- 메인 뷰 달력(FullCalendar)/타임라인(vis-timeline) 토글 + 보드/리스트
- 진입은 로그인 회사 직원 전원, 생성/배정은 관리자 전용
- 업무 배정·완료 시 관리자 메일 알림(app/mail.py, SMTP_* env, 미설정 시 skip)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 11:22:05 +09:00
king 1c14c748dd feat(dispatch): Order ID 강조 + 송장번호 배송조회 딥링크
- Order ID 를 카드에서 가장 크게(22px bold) 표시 — 가장 자주 보는 값
- Tracking 번호 클릭 시 배송사 조회 페이지로 송장번호 채워 새 탭 이동
  (store.courier_tracking_url + Jinja 필터 courier_track)
- Ninja Van/J&T 등 말레이시아 주요 배송사 URL 매핑(미매핑은 텍스트 폴백)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 19:02:44 +09:00
king a65ca65a8b feat(dispatch): 배송사 배지를 로고 이미지로 표시
- store.courier_logo_url: 배송사명(부분 일치) → 로고 SVG URL, 없으면 텍스트 폴백
- Jinja 필터 courier_logo 등록(main.py)
- Ninja Van / J&T Express 내장 SVG 로고 추가(static/dispatch/courier/)
- 출고 작업 카드 + Kagayaku 전달 요약에 로고 렌더

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:54:23 +09:00
king 99eea01fc1 feat(dispatch): 말레이시아 TikTok 출고관리 모듈 추가
03_TikTok_Order_Export.xlsx 업로드 → 1박스=1카드 출고 작업 리스트,
SKU 피킹 요약, Kagayaku 전달표(A4 인쇄)를 자동 생성.

- 1박스 묶음 기준: Package ID > Tracking ID > Order ID, 같은 박스 같은 SKU 합산
- 작업 상태 5단계 토글(AJAX 즉시 저장) + dispatch_logs 기록
- 고객 이름/주소/전화 미저장(파싱 시 폐기, 스키마에 컬럼 없음)
- 엑셀은 openpyxl 파싱(pandas 미사용), DB는 dispatch_db 전용
- 인증은 기존 Google OAuth + 신규 권한키 dispatch 재사용
- scripts/sql/dispatch_db_init.sql, docs/DISPATCH_MODULE.md 동봉

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 15:11:43 +09:00
king 03929ff517 feat(malaysia): 메뉴명 '말레이시아 재고관리'로 변경 + 사이드바/헤더 영문 토글
- 메인 메뉴/라벨 '말레이시아 재고' → '말레이시아 재고관리'
- EN 토글 시 사이드바 활성 항목(말레이시아만)·상단 페이지 제목/부제 부분치환 번역
  (다른 메뉴는 그대로)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 18:49:46 +09:00
king 6b43d9926d feat(malaysia): 세트 BOM을 itemcode_db에서 읽고 입력을 그리드 일괄로 전환
- 세트구성(set_bom) 수동 관리 메뉴/라우트/API/템플릿 제거
- 세트 BOM은 itemcode_db set_components(set_code/single_code/quantity)에서
  읽음 (MalaysiaItemcodeReader, ITEMCODE_DB_URL 재사용)
- db.py: create_set_out/compute_result/finalize_stocktake 에 bom_map 주입식
- 입출고: 낱개 전체 그리드 일괄 등록 + 세트 출고 그리드(BOM 분해)
- 일일 재고조사: 낱개+세트 전체 그리드에 수량만 키인 → 일괄 저장
- malaysia_stock_db.set_bom 테이블은 레거시(미사용)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 15:35:42 +09:00
king f137f2a6a6 feat(malaysia): 말레이시아 창고 재고관리 모듈 추가
- 신규 모듈 app/modules/malaysia (prefix /malaysia, 권한키 malaysia)
- malaysia_stock_db: warehouses/malaysia_items/set_bom/stock_movement/
  daily_stocktake/daily_stocktake_line (멱등 init SQL)
- 낱개(MT/MX/MZ) 입출고·조정 movement, 세트(MY) BOM 관리, 세트 출고 BOM 분해
- 일일 재고조사: 세트→낱개 자동 분해(direct+from_set=total), 확정 시 차이만 STOCKTAKE
- prefix 검증 이중화(DB CHECK + store.py 순수함수), MD- 전면 제외
- 상품명은 itemcode_db 읽기 전용 재사용(중복 마스터 없음)
- 화면 4종 + JSON API, 순수로직 테스트 14건, README/docs 갱신

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:34:31 +09:00
king 0b04a05b26 feat(expense): 관리자 분류 설정 메뉴 추가 (동적 분류)
- CategoryStore: 분류 항목 JSON 저장소(DATA_DIR/expense_categories.json)
- 관리자 설정 페이지(/expense/settings) + 분류 CRUD API
- _normalize 분류 고정목록 검증 제거 — 추가 분류 즉시 등록 폼/집계 반영
- index/reports 분류를 동적 목록으로 교체

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 17:22:01 +09:00
king 8c6539d6cb ui(sidebar): 아이콘/글자 크기 확대 + 운영·관리 그룹 묶음 정렬
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 08:29:28 +09:00
king 269e779129 feat(vacation): 휴가 관리 모듈 — 월간 달력 bar/연차·반차 신청/승인 워크플로/공휴일·연차 설정
- vacation_db 전용 저장소(VacationDBStore), VACATION_DB_URL 미설정 시 '설정 필요' 안내
- 월간 달력: 구글식 휴가 bar(주 단위 lane 배정), 일/공휴일 빨강·토요일 파랑
- 신청 폼: 종류/기간/시작·종료 구분(종일/오전/오후)/사유 + 예상 일수 미리보기
- 일수 계산은 서버(compute_days)에서 주말+공휴일(is_red) 제외 재계산
- 워크플로: 작성중/반려→제출→승인|반려, 취소 soft delete, 본인만 수정(작성중/반려)
- 권한: vacation(접근)/vacation_approver(승인), admin 통과. 설정은 admin 전용
- 공휴일(vacation_holidays) DB 기반 provider + settings CRUD, 연차잔여(vacation_balances)
- 엑셀 내보내기(openpyxl), scripts/sql/vacation_db_init.sql(멱등, 2026 공휴일 seed)
- main.py 등록, 메뉴 ready 전환, docs/.env.example/CLAUDE.md 갱신

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 08:20:20 +09:00
king 9e707be5ac feat(cupang): 쿠팡 밀크런 모듈 추가 (출고 달력/박스계산/입고센터)
- app/modules/cupang: router/db/store/itemcode + 템플릿 5종
- cupang_db 전용(JSON 폴백 없음). CUPANG_DB_URL 미설정 시 안내 페이지
- 월간 달력 + 출고 묶음(헤더+라인), 박스 입수량 자동계산(서버 재계산)
- 입고센터 관리(사용중 soft delete), 박스규칙 upsert, 엑셀 내보내기
- 상품 검색은 itemcode_db 읽기 전용(미설정 시 수동 입력)
- MODULE_KEYS/메뉴/아이콘/라벨 동기화, scripts/sql/cupang_db_init.sql(멱등)
- app/data/ gitignore 추가(PII)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 20:47:32 +09:00
king 550867ba0c feat(expense+admin): 결재 워크플로 + 첨부 + 집계 + 엑셀 + 사용자 직접 등록
[admin]
- POST /api/users 사용자 직접 등록 (이메일만으로). UserStore.create_user 추가
- admin.html: 등록 폼 + 삭제 버튼 + 한글 라벨 + 신규 권한 표시
- 신규 권한 키: expense_approver, vacation_approver (APPROVER_KEYS)
- is_approver(user_rec, kind) 헬퍼

[expense 워크플로]
- 상태 전이: 작성중 → 제출 → 승인/반려 → 정산완료
- API: /api/items/{id}/{submit,revert,approve,reject,settle}
- 권한: submit/revert=owner, approve/reject/settle=expense_approver 또는 admin
- expense_items 컬럼: approver_email, decided_at, reject_reason
- 작성중/반려 상태에서만 수정/삭제/첨부 가능

[expense 첨부]
- 영수증/기타 (kind: receipt|other). 최대 20MB, 확장자 화이트리스트
- 저장: DATA_DIR/uploads/expense/{item_id}/{att_id}_{filename}
- expense_attachments 테이블 (CASCADE on item delete)
- API: 업로드/목록/다운로드/삭제

[expense 집계]
- /expense/reports: 연도별 월×카테고리 피벗 표

[expense 엑셀]
- GET /expense/api/export.xlsx?from&to&scope=mine|all
- scope=all 은 승인자/관리자만

[DDL]
- expense_db_init.sql: 신규 컬럼/테이블 포함 (멱등)
- expense_db_002_workflow_attachments.sql: 운영 DB 마이그레이션용

[deps]
- openpyxl>=3.1, python-multipart>=0.0.20

[docs]
- DATABASES.md: 워크플로 다이어그램, attachments 테이블, 마이그레이션
- PROJECT_OVERVIEW.md: 권한 키 표
- DEPLOYMENT.md: DATA_DIR/uploads 안내
2026-05-29 02:52:44 +09:00
king 9c58b022e2 feat(expense): 개인경비 모듈 + ERP 좌측메뉴 셸 + expense_db 연결
- ERP 셸: 좌측 사이드바 + 상단 헤더 + 콘텐츠 영역(erp_base.html)
- 분기: 슈퍼관리자 → 업무모듈 카드, 일반사용자 → ERP 메인(erp_home.html)
- 신규 라우트: /modules (슈퍼관리자 모듈 카드 재진입)
- 개인경비 모듈: app/modules/expense/ (라우터/저장소/템플릿)
  - JSON 저장소(ExpenseStore) + PostgreSQL 저장소(ExpenseDBStore)
  - 팩토리: EXPENSE_DB_URL 있으면 DB, 없으면 JSON 폴백
- DB: scripts/sql/expense_db_init.sql (멱등 DDL, postgres-db 컨테이너)
  - expense_db, 역할 expense_app, 테이블 expense_items, 인덱스/트리거
- 마이그레이션: scripts/migrate_expense_json_to_db.py (멱등, --dry-run)
- 의존성: psycopg[binary,pool]>=3.2
- 환경변수: EXPENSE_DB_URL 추가
- 문서: CLAUDE.md 작업 기준 + docs/{PROJECT_OVERVIEW,SERVER_ARCHITECTURE,DATABASES,DEPLOYMENT}.md
  - main-app 배포 경로 /opt/www/main 고정 명시
  - 위험 명령(DROP/TRUNCATE/rm -rf/volume 삭제) 사용자 승인 정책
2026-05-29 02:21:03 +09:00
king 316e3fe8d1 feat(erp): ERP 대시보드 + 관리자 권한 시스템 도입
- 로그인: dbxcorp.co.kr 도메인 화이트리스트만 사용. ALLOWED_EMAILS 게이트 제거
- king@dbxcorp.co.kr 슈퍼관리자 자동 부여 (강등/삭제 불가)
- 신규 로그인 사용자는 JSON 저장소에 자동 등록 (기본 모듈 권한 0)
- 관리자 페이지(/admin): 역할/모듈별 토글로 직원 권한 수정
- 메인 대시보드를 ERP 시스템(monochromatic shadcn)으로 재설계
  · 모듈: CORM, Order, 개인경비(준비중), 휴가(준비중)
  · 권한 없는 모듈은 '권한 없음' 배지 + 클릭 불가
- DESIGN.md 토큰 기반 styles → app/static/erp.css
- docker-compose: dbx-main-data 볼륨 마운트 (DATA_DIR=/data)
  으로 권한 JSON 영구 보관

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 23:36:51 +09:00
king c16bc905ed feat(ui): 메인 포털 홈 화면 카드명 수정 및 로그인/메인 화면 로고/헤더 레이아웃 스타일 개선
- 메인 홈 화면 카드 수정: 'CS 발주 업무' -> 'CS, 발주, 반품, 코드관리' (설명 문구도 이에 맞춤) / '고객 주문리스트 프로그램' -> '고객 주문 데이터베이스' (설명 문구도 이에 맞춤)

- 디자인 레이아웃 스타일 개선: 로그인 화면의 좌측 상단 로고 이미지를 원본 이미지 크기로 정상 출력되도록 수정 (styles.css 내 brand-logo-img 수정) / 메인 대시보드 상단 헤더 높이를 기존 110px에서 55px로 단축하여 공간 효율화 / 메인 대시보드 내 로고 높이를 55px로 고정하고 가로 비율이 유지되도록 수정 / 로고 옆의 '업무 포털' 브랜드 텍스트 폰트 크기를 24px로 확대 및 볼드 처리하여 시인성 극대화
2026-05-25 21:12:49 +09:00
king 98ac452e7d feat(menu): CS 발주 업무 카드를 /corm/ 으로 연결
- 메뉴 카드 url 기본값을 /corm/ 로 (NPM 리버스 프록시 하위 경로)
- 헬스 배지가 가리킬 health_url 을 /corm/health/db 로 설정
- .env.example 의 CS_ORDER_URL 안내를 /corm/ 로 정리
2026-05-24 15:41:01 +09:00
king 844c796578 feat(sso): user_picture를 세션 top-level에 저장 — OMS 도 아바타 표시 가능
기존엔 'user' dict 안에만 picture 가 저장돼 OMS 가 못 읽었다.
이제 user_email/user_name 처럼 top-level 키로도 저장하여 OMS 가 동일하게 읽는다.
get_user() 도 top-level user_picture 를 인정.
2026-05-24 14:18:46 +09:00
king 7ddc765326 feat(sso): SESSION_SECRET_KEY 미설정 시 fail-fast + ALLOWED_EMAILS env화
- SESSION_SECRET_KEY 가 .env 에 없으면 컨테이너 기동 단계에서 RuntimeError.
  알려진 기본값(change-this-session-secret) 폴백 제거로
  운영 .env 누락 시 양쪽 secret 불일치로 SSO 가 조용히 깨지는 사고 방지.
- ALLOWED_EMAILS 를 환경변수(쉼표 구분)로 덮어쓸 수 있게 변경.
  env 미설정 시 기존 4명 기본 목록 유지 → 운영 호환.
- .env.example 갱신: SESSION_SECRET_KEY 안내 강화, ALLOWED_EMAILS 항목 추가.
2026-05-24 13:25:06 +09:00
king c274e50ee0 feat(sso): SESSION_MAX_AGE를 env로 노출 — OMS와 통일
- SessionMiddleware max_age 를 SESSION_MAX_AGE 환경변수에서 읽도록 변경
  (기본 28800초=8h, OMS .env.example 과 일치)
- .env.example 에 SESSION_MAX_AGE 항목 추가
- run-local.ps1 을 .gitignore 에 추가 (run-local.bat 와 동일 정책 — 로컬 전용)
2026-05-24 13:04:02 +09:00
king e33cc8686b feat: OMS(orderlist)와 SSO 호환되도록 세션 계약 정렬
- 세션 쿠키 이름을 SESSION_COOKIE_NAME env 로 OMS 와 통일
- 로그인 성공 시 top-level user_email / user_name 키도 함께 저장
- get_user() 가 OMS 가 만든 SSO 세션(top-level email만 있는 경우)도 인정
- /login 에 ?next= 지원 (open redirect 방지 위해 같은 호스트 절대경로만 허용)
2026-05-24 05:38:43 +09:00
king 023ce80d59 fix: env() helper가 빈 값일 때도 default로 폴백 2026-05-24 05:08:34 +09:00
king e8a85be36c feat: 주문리스트를 /orderlist/ 리버스 프록시 경로로 통합
- 메뉴 카드 새 탭 열기 + /orderlist/health/db 헬스 배지 (온라인/오프라인) 추가
- CUSTOMER_ORDER_LIST_URL 기본값을 /orderlist/ 로 (NPM 같은 도메인 하위 경로)
- orderlist 측 compose 정리 스크립트 추가 (ports 제거, npm_default 외부 네트워크 attach)
2026-05-24 05:04:29 +09:00
king c93e2be0a7 feat: 초기 커밋 — Pretendard 폰트 적용 및 Docker 배포 구성
- Pretendard Regular/Bold/Thin 폰트를 app/static/fonts/ 에 추가하고
  @font-face 로 등록하여 전체 페이지에 적용
- Dockerfile(python:3.12-slim + uvicorn --proxy-headers) 작성
- docker-compose.yml: NPM 뒤 운영 서버용 (포트 80)
- docker-compose.local.yml: 로컬 테스트용 (포트 8080)
- .env.local.example: 로컬 OAuth 설정 가이드 포함
- .dockerignore: 이미지 빌드 컨텍스트 최소화
- .gitignore: .env / .env.local 제외 명시
- README: Docker 빌드·배포·업데이트 절차 문서화

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-21 22:43:41 +09:00