iop/agent-task/edge_node_id/plan_local_G02_0.log
toki 6ec73e47d5 feat: edge config mapper, node id, router registry, writer injection 구현
- edge_config_mapper: 엣지 설정 매핑 기능 추가
- edge_node_id: 엣지 노드 ID 생성/관리 기능 추가
- node_router_registry: 노드 라우터 레지스트리 기능 추가
- node_writer_injection: 노드	writer 주입 기능 추가
- edge console 및 server 업데이트
- node bootstrap module 업데이트
2026-05-05 09:19:16 +09:00

123 lines
4.4 KiB
Text

<!-- task=edge_node_id plan=0 tag=REFACTOR -->
# EdgeNode ID 생성 방식 개선 — alias 기반에서 명시적 ID로
## 이 파일을 읽는 구현 에이전트에게
각 체크리스트 항목을 완료하고 중간 검증 명령을 실행한 뒤 출력을 `CODE_REVIEW-local-G02.md`의 검증 결과 섹션에 붙여 넣으세요.
`CODE_REVIEW-local-G02.md`의 "이 파일을 읽는 리뷰 에이전트에게" 섹션에 있는 아카이브·complete.log 생성 지시는 **리뷰 에이전트 전용**이므로 구현 에이전트는 실행하지 마세요.
## 배경
`apps/edge/internal/node/store.go:61`에서 NodeRecord ID를 `"node-" + d.Alias`로 만든다.
alias가 유일하므로 현재는 충돌이 없지만, alias 변경·재등록 시나리오나 control-plane 통합 시 예측 가능한 ID가 필요해진다.
`google/uuid`는 이미 go.mod indirect 의존성으로 존재하므로 추가 dep 없이 UUID를 사용할 수 있다.
설정 파일에 명시적 `id` 필드를 추가하고, 값이 없을 때만 UUID v4를 자동 생성하는 방식이 가장 유연하다.
---
### [REFACTOR-1] `config.NodeDefinition`에 `ID` 필드 추가
**문제**
`packages/config/` 내 NodeDefinition 구조체(정확한 파일·라인은 구현 전 확인)에 `ID` 필드가 없어서 edge 설정 파일에서 node ID를 지정할 수 없다.
**해결 방법**
```go
type NodeDefinition struct {
ID string `yaml:"id" mapstructure:"id"` // optional; UUID v4 auto-assigned if empty
Alias string `yaml:"alias" mapstructure:"alias"`
Token string `yaml:"token" mapstructure:"token"`
Adapters AdaptersConf `yaml:"adapters" mapstructure:"adapters"`
Runtime RuntimeConf `yaml:"runtime" mapstructure:"runtime"`
}
```
**수정 파일 및 체크리스트**
- [ ] `packages/config/` 내 NodeDefinition 정의 파일 — `ID` 필드 추가
- [ ] `configs/edge.yaml` (예시 파일) — `id:` 필드 주석으로 추가
**테스트 작성**: 스킵 — struct 필드 추가만이므로 REFACTOR-2 테스트로 검증 가능.
**중간 검증**
```
go build ./packages/config/...
```
기대 결과: 빌드 성공.
---
### [REFACTOR-2] `LoadFromConfig`에서 UUID 자동 생성
**문제**
`apps/edge/internal/node/store.go:61`
```go
ID: "node-" + d.Alias,
```
alias 기반 ID는 alias 변경 시 ID가 바뀌고, 외부 시스템과 연동 시 예측 불가하다.
**해결 방법**
설정에 `d.ID`가 있으면 그대로 사용하고, 없으면 UUID v4를 생성한다.
```go
import "github.com/google/uuid"
nodeID := d.ID
if nodeID == "" {
nodeID = uuid.NewString()
}
s.Add(&NodeRecord{
ID: nodeID,
Alias: d.Alias,
Token: d.Token,
Adapters: d.Adapters,
Runtime: d.Runtime,
})
```
주의: `uuid.NewString()`은 매 호출마다 새 UUID를 반환한다. 따라서 ID 없는 노드는 edge 재시작마다 새 ID를 받는다. 이는 현재 단계에서 허용 가능하며, 지속적 ID가 필요해지면 설정 파일에 `id:` 필드를 명시한다.
**수정 파일 및 체크리스트**
- [ ] `apps/edge/internal/node/store.go` — `LoadFromConfig` 내 ID 생성 로직 교체, `github.com/google/uuid` import 추가
- [ ] `go.mod` — `github.com/google/uuid`를 indirect → direct로 승격 (`go mod tidy`)
**테스트 작성**: `apps/edge/internal/node/store_test.go`에 추가.
- `TestLoadFromConfig_ExplicitID`: `d.ID`가 설정된 경우 해당 ID가 그대로 사용되는지 확인.
- `TestLoadFromConfig_AutoID`: `d.ID`가 비어 있을 때 생성된 ID가 비어 있지 않고 유효한 UUID 형식인지 확인.
- `TestLoadFromConfig_AutoIDUnique`: 두 노드 모두 `id` 없이 정의 시 서로 다른 ID가 할당되는지 확인.
**중간 검증**
```
go test ./apps/edge/internal/node/...
```
기대 결과: 신규 테스트 포함 PASS.
---
## 수정 파일 요약
| 파일 | 항목 |
|------|------|
| `packages/config/` NodeDefinition 파일 | REFACTOR-1 |
| `configs/edge.yaml` | REFACTOR-1 |
| `apps/edge/internal/node/store.go` | REFACTOR-2 |
| `apps/edge/internal/node/store_test.go` | REFACTOR-2 |
| `go.mod` / `go.sum` | REFACTOR-2 |
## 의존 관계 및 구현 순서
REFACTOR-1 → REFACTOR-2 순서. config struct 변경 후 store 수정.
## 최종 검증
```
go mod tidy
go build ./...
go test ./apps/edge/... ./packages/config/...
```
기대 결과: 빌드 성공, 모든 테스트 PASS, `store.go`에 `"node-" + d.Alias` 패턴 없음.