# 구조

> 위젯은 조회를 하지 않습니다. 파일 하나를 읽어서 그립니다.

- 수치: 파일 1개
- 사람이 보는 화면: https://aitryed.com/ko/built/qa-widget/architecture/
- 반대 언어: https://aitryed.com/en/built/qa-widget/architecture/index.md
- 이 사이트 안내(AI용): https://aitryed.com/ko/llms.txt

---

**위젯은 «조회»를 하지 않습니다. 파일 하나를 읽어서 그립니다. 그리고 그 파일을 쓰는 건 «다른» 프로그램입니다.**

## 구조가 두 덩어리입니다

| 누가 | 하는 일 |
|---|---|
| **수집 프로그램** | 표와 이슈 목록을 훑어서 **파일 하나에 씀** |
| **위젯** | **그 파일을 읽어서 그림** |

**위젯은 원격 조회를 절대 안 합니다.**

## 갈라 놓은 이유 하나 — 「멈추면 사람이 닫습니다」

원격 조회는 **몇 초씩** 걸립니다. 서버가 느리면 더 걸립니다.

만약 위젯이 직접 조회하면, **그동안 창이 굳습니다.** 드래그도 안 되고 버튼도 안 눌립니다.

그리고 **굳는 창은 사람이 닫습니다.** 한 번 닫으면 다시 안 엽니다.

이 위젯의 존재 이유가 <strong>「항상 떠 있는 것」</strong>인데, **닫히면 존재 이유가 없어집니다.**

> **항상 떠 있어야 하는 물건은, 절대 굳으면 안 됩니다.**

## 갈라 놓은 이유 둘 — 「실패해도 직전 값이 남습니다」

이게 더 중요합니다.

| | 위젯이 직접 조회하면 | 파일을 읽으면 |
|---|---|---|
| 조회 성공 | 새 값 | 새 값 |
| **조회 실패** | **빈 화면 / 오류** | **직전 값이 그대로** |

「직전 값」이 왜 좋냐면 — **어제 값이라도 없는 것보다 낫기** 때문입니다.

그리고 **빈 화면은 두 가지를 구분 못 합니다.**

- 아직 데이터가 없는 상태
- **데이터가 있는데 못 가져온 상태**

직전 값이 남아 있으면 **「갱신 시각」을 보고 판단**할 수 있습니다. 「어? 3시간째 그대로네」 하고 알아챕니다.

## 설정을 코드에서 뺐습니다

이 프로젝트는 **차수가 바뀔 때마다** 같은 일을 반복합니다. 그때 **고칠 게 없어야** 했습니다.

그래서 차수마다 달라지는 걸 **전부 설정 파일 항목으로** 뺐습니다.

| 설정으로 뺀 것 |
|---|
| 어느 표를 볼지 |
| 리포트 주소 |
| 차수 이름 |
| 알림 보낼 곳 |
| 배포 폴더 |
| 서식 파일 위치 |

이렇게 해 두면 **새 차수를 시작할 때 코드를 안 열어도** 됩니다. 설정 파일 몇 줄만 고칩니다.

왜 중요하냐면 — **코드를 열면 다른 것도 건드리게** 되고, 그러면 **지난 차수에 잘 되던 게 깨집니다.** 그리고 그 사고는 **한참 뒤에** 드러납니다.

> **주기적으로 반복되는 일은, 반복할 때 «코드를 안 여는 것»이 목표입니다.**

## 여기부터는 자세한 기록입니다

이게 구조의 핵심이다. 위젯은 **파일 하나를 읽어서 그린다.** 시트와 이슈 트래커를 훑어 그 파일을 쓰는 건 별도 스크립트다.

## UI가 멈추면 사람이 닫는다

갈라 놓은 첫 번째 이유다. 원격 조회는 몇 초씩 걸리는데, 그동안 창이 굳으면 **사람은 그 위젯을 닫는다.**

그래서 갱신은 비동기로 던지고 **타이머가 완료를 확인**한다. 창은 계속 움직이고, 값이 늦게 도착하면 늦게 바뀐다.

이건 성능 최적화가 아니라 **생존 문제**다. 이 도구의 유일한 가치가 "계속 떠 있다"인데, 굳는 순간 사람이 닫아 버리면 가치가 0이 된다. 5초 멈춤이 기능 하나를 없애는 것과 같다.

## 실패해도 직전 값이 남는다

갈라 놓은 두 번째 이유. 조회 스크립트가 실패해도 위젯은 **직전 값을 그대로 들고 있다.**

빈 화면이나 0이 뜨는 것보다, 조금 낡은 숫자가 남아 있는 쪽이 낫다. 0은 **거짓말**이고 낡은 숫자는 **낡은 진실**이다.

이게 되는 이유는 위젯이 조회를 안 하기 때문이다. 위젯이 직접 API를 부르는 구조였으면 실패는 곧 화면 붕괴다. 파일을 읽는 구조라, 파일이 갱신 안 됐을 뿐이면 어제 값이 그대로 보인다.

다만 그러면 **"이게 언제 값인지"가 중요해진다.** 그래서 갱신 시각이 화면에 있다.

## 마일스톤은 코드가 아니라 설정이다

차수가 바뀔 때마다 고칠 게 없어야 했다. 그래서 마일스톤마다 다른 건 전부 설정 파일 키로 뺐다 — 시트 식별자, 리포트 주소, 스프린트 이름, 알림 채널, 배포 폴더, 템플릿 경로.

새 차수를 여는 건 **템플릿을 복사해서 값을 채우는 일**이고, 바탕화면에는 차수별 바로가기가 따로 생긴다. 코드는 한 벌이다.

여기서 한 가지가 중요했다. **차수를 코드 안 상수로 두면 이전 차수를 못 본다.** 프로젝트가 끝나도 지난 차수 결과를 다시 볼 일이 계속 생기는데, 상수였으면 그때마다 코드를 되돌려야 한다. 지금은 바로가기를 더블클릭하면 된다.
