You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4.8 KiB
4.8 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
slack-notifier
Gitea/Notion webhook 알림을 담당자에게 Slack 개인 DM으로 중계하는 Go(Gin) 서버. 워크스페이스 규칙은 상위 ../CLAUDE.md 참고.
스택 / 실행
- Go 1.26 (Gin) — 버전은 mise로 관리(
mise use go@1.26) - 관리 UI: 표준
html/template+ HTMX (Node 빌드 불필요), 템플릿은go:embed로 바이너리에 포함 - 명령은
Makefile에 정리되어 있음(환경은 명령어로 분기,APP_ENV에 의존 안 함):make run-dev/make run-prod—go run . -env {dev,prod}(dev=text·debug·콘솔, prod=JSON·info·logs/app.log)make test(go test ./...) ·make vet·make fmt(gofmt -w .)make build(현재 OS) ·make build-linux ARCH=arm64|amd64(EC2 배포용 정적 바이너리, 기본 arm64/Graviton)
- 단일 테스트:
go test ./internal/gitea -run TestName -v(테스트는 현재internal/gitea에만 있음) - 헬스체크
GET /health, 관리 페이지http://localhost:8000/admin/mappings - 배포:
docker compose up --build(distroless, host:6000→컨테이너:8000) 또는deploy/의 systemd+Caddy. 외부 접근은 HTTPS 필요.
구조
main.go # 조립: config → mapping/slack/notion → server.Run
internal/
config/ config.go # env 설정 (.env, godotenv) + 환경/로그 기본값
logging/ logging.go # log/slog 환경별 설정 + Gin 액세스로그 미들웨어
security/ security.go # HMAC-SHA256 서명 검증 (Gitea/Notion 공용)
slack/ slack.go # users.lookupByEmail + chat.postMessage(DM), email 캐시
notify/ notify.go # Notification 모델 + Block Kit 헬퍼
mapping/ mapping.go # 수동 매핑 스토어 (data/mappings.json, thread-safe)
gitea/ gitea.go(+test)# Gitea 이벤트 → 담당자 이메일/로그인 + 메시지
notion/ notion.go # Notion 이벤트 → 페이지 People 속성 → 이메일
server/ server.go # Gin 엔진, 라우트, deliver()
webhooks.go # POST /webhooks/{gitea,notion}
admin.go # /admin/mappings (GET/POST/DELETE, HTMX)
templates/ # mappings.html (embed)
data/mappings.json # 런타임 매핑 데이터 (gitignore)
deploy/ # 비-Docker 배포: slack-notifier.service(systemd) + Caddyfile(HTTPS 리버스 프록시) + run.sh
핵심 동작
- 담당자 해석 순서: 수동 매핑(이메일→, 로그인→) 우선, 없으면 원래 이메일 그대로 → Slack 조회.
- 못 찾으면
DEFAULT_SLACK_CHANNELfallback, 그것도 없으면 skip(로그만).
- 못 찾으면
- 모든 webhook은 raw body 기준 HMAC-SHA256 검증. secret 미설정 시 검증 skip(개발용, WARN 로그).
- Notion은 최초 구독 시 받은
verification_token을 로그에서 확인해.env에 넣어야 정상 검증됨. - 관리 페이지에서 추가/삭제한 매핑은 즉시
data/mappings.json에 저장. - 환경은 실행 명령어
-env플래그로 분기(go run . -env prod). 값은dev|prod(긴 형태 development/production도 정규화됨). 미지정 시APP_ENV→dev순 fallback.- 환경별
.env로드:.env.{env}.local→.env.{env}→.env(앞이 우선). 예:.env.dev,.env.prod.
- 환경별
- 로깅은
log/slog표준 라이브러리. 환경별로 결정:dev→ text 포맷 + debug 레벨 + Gin debug 모드, 콘솔(IDE)만 출력prod→ JSON 포맷 + info 레벨 + Gin release 모드,logs/app.log파일로 추출(+ stdout)LOG_LEVEL/LOG_FORMAT/LOG_FILE로 개별 오버라이드. 코드에선slog.Info/Warn/Error사용(표준log금지).LOG_FILE지정 시 부모 디렉터리는 자동 생성, stdout과 파일에 동시 기록. dev 기본값은 빈 값(콘솔만).- 파일은 날짜별로 회전됨:
LOG_FILE=logs/app.log→ 실제 기록은logs/app-YYYY-MM-DD.log. 날짜가 바뀌면 새 파일 생성,LOG_RETENTION_DAYS(기본 7)일치만 보존하고 초과분 자동 삭제. 구현은internal/logging/rotate.go(표준 라이브러리만, 외부 회전 의존성 없음).
작업 시 주의
- 이벤트별 "담당자" 로직은 제품 정책에 가까움. 새 이벤트/대상 규칙은
internal/gitea·internal/notion의BuildNotifications에 추가하고, 가능하면 테스트(*_test.go)도 같이. - 메시지는 한국어 + Block Kit(
notify.SimpleBlocks). - 비밀값(
SLACK_BOT_TOKEN, secret, Notion 토큰)은.env로만 관리, 커밋 금지(.gitignore확인). - 저사양 타겟이므로 무거운 의존성 추가 자제. 라우터는 Gin, 그 외는 표준 라이브러리 위주.