전체 작업

개인 운영 대시보드

흩어져 있던 서비스·봇·작업 도구의 상태를 스마트폰 홈 화면 같은 한 화면에서 확인하고 조작할 수 있게 만들었다.

작업 기록 14건

무엇을 만들었나

여러 곳에 흩어진 서비스와 도구를 아이콘과 위젯으로 모아 상태를 보고 일부는 바로 조작할 수 있게 한 개인용 대시보드다. 시스템이 살아 있는지 한 번에 판정하는 도구, 디스코드 챗봇 조작 화면, 음성 통화 서비스 접속 현황, 컴퓨터 자원 사용량 화면 등을 기능 단위로 계속 붙여 나갔다. 음성 통화 서비스 위젯과 위임 설정 교정 같은 변경은 운영 중인 서비스를 재시작하지 않고 임시 복사본이나 별도 서버에서 먼저 검증했다.

구현 방식과 보안 설계는 ‘기술 상세’에 있습니다.

구조와 설계

Next.js(App Router)·React·TypeScript 기반이며, 기능을 모듈로 나누고 각 모듈을 domain·application·infrastructure·presentation 4개 계층으로 구성한다. 데이터는 JSON 파일 저장소에 두고, 다른 프로세스(봇)와는 HTTP 대신 상태 파일 읽기와 제어 파일 쓰기로 통신한다. 제어 파일은 쓰기 큐·배타 잠금·임시파일 후 rename으로 원자적으로 쓰고, 봇이 아직 집어가지 않은 명령이 있으면 덮어쓰지 않고 409로 거절한다. 상태 화면은 폴링하되 숨긴 탭에서는 멈추고, 갱신이 90초를 넘은 상태는 정상으로 표시하지 않는다. 시스템 생존 확인 CLI는 launchctl·lsof·docker 조회를 시스템별이 아니라 전체 1회만 호출해 파싱·매칭하는 구조로 만들어 2초 예산 안(실측 0.38초)에 들어왔다.

사용 기술

Next.js 16 (App Router), React 19, TypeScript, CSS Modules, Node.js, JSON 파일 저장소, launchd, ResizeObserver

보안·안정성 설계

  • 다른 프로세스가 읽는 제어 파일을 쓰기 큐·배타 잠금·임시파일 후 rename으로 원자적으로 쓰고, 미처리 명령이 남아 있으면 덮어쓰지 않고 409로 거절했다.
  • 연동 대상 봇 저장소는 읽기 전용으로만 접근하고, 토큰·API 키 같은 비밀값은 읽지도 화면에 표시하지도 않았다.
  • 이미지 파일 API가 상대 경로와 실제 경로를 확인해 지정 폴더 밖 파일 접근을 거부한다(폴더 밖 요청에 HTTP 403 확인).
  • 시스템 정보 수집 명령을 셸 문자열이 아니라 인자 배열로 실행했다.
  • 설정 API가 지원하지 않는 값을 400(검증 실패)으로 거부하는 것을 별도 서버에서 확인했고, 페르소나 1500자·세계관 3000자·출연진 5명 상한을 화면에서도 검사한다.
  • 상태 파일 파서가 enum·0 이상 정수·범위를 검사하고, 값이 잘못되면 조용히 통과시키지 않고 전체 상태를 무효 처리한다. 필드가 없는 기존 파일은 기본값으로 계속 읽는다.
  • 상태 갱신이 90초를 넘으면 접속자 정보를 숨기고 '꺼져 있음'으로 표시하며, 통신 실패 시에도 마지막 데이터의 시각을 다시 판정한다. 파일 부재·손상은 '상태 없음'으로 따로 표시해 오래된 값을 정상으로 오인하지 않게 했다.
  • 수정 폼에서 비어 있는 칸은 payload에서 키를 생략해, 사용자가 일부만 바꿔도 기존 값이 지워지지 않게 했다.
  • 시스템의 폐기·운영 여부를 나타내는 lifecycle 필드는 사람만 적도록 하고 자동 추론·자동 기입을 하지 않았다.
  • 음성 통화 서비스 위젯을 추가할 때는 운영 서비스를 재시작하지 않고 임시 복사본·별도 서버에서 검증했으며, 운영 파일과 빌드 식별자의 해시가 작업 전후 동일함을 확인했다.
  • 에이전트 작업의 지시서·답·로그 본문은 같은 기기(루프백)에서 열 때만 내려 주고, 출처는 기동마다 새로 만드는 무작위 값과 소켓 주소를 함께 확인해 판정한다. 1차 검수에서 찾은 헤더 위조 우회를 이 방식으로 고쳤고, 검수용 인스턴스에서 위조 요청이 막히는 것을 재검수로 확인했다.
  • 에이전트 감시 API는 완료 전달용 식별자를 본문 공개 설정과 분리해, 서버가 검증한 루프백 요청에만 제공한다.

작업 기록

  1. 에이전트 실행 감시 모듈 보완

    여러 AI 에이전트 작업의 상태를 대시보드와 CLI에서 모아 보고, 정상 완료·실패·응답 대기·보고 없는 중단을 상태로 구분하고, 완료 대기 결과는 종료 코드로 알리게 했다. 러너가 결과를 남기기 전에 죽으면 계속 실행 중으로 보이던 문제를 생존 확인으로 고쳤고, 전체 테스트는 133개에서 153개로 늘어 모두 통과했다.

  2. 백그라운드 작업 상황판과 본문 보호

    백그라운드 에이전트 작업의 상태를 상세 화면과 홈 위젯으로 보여 주되, 지시서·답·로그 본문은 같은 기기에서 열 때만 내려 주게 했다. 1차 검수에서 발견된 우회 경로를 고친 뒤 재검수를 통과했다(테스트 76/76).

  3. 진행 중 작업 9건 정체 점검

    몇 주째 '재시작 필요' 등으로 남아 있던 작업 9건을 코드·커밋·운영 화면과 대조하는 읽기 전용 점검을 했다. 8건은 코드·커밋·운영 화면 기준으로 이미 반영된 것으로 확인했고(일부 실기기 시험은 하지 못했다) 1건은 다른 작업에 흡수돼, 재시작이 필요한 항목은 없다는 결론을 냈다.

  4. 포트폴리오 바로가기 아이콘 추가

    포트폴리오 사이트의 심볼을 대시보드 앱 아이콘 규칙에 맞춘 SVG로 옮기고, 아이콘 목록에 출처와 색상을 기록했다. 홈 화면 배치와 실제 화면 확인은 다음 단계로 남겼다.

  5. 자동화 작업 실행 통계 표시 추가

    자동화 작업이 새로 기록하는 상태 필드를 읽어 실패 횟수와 최근 실패 비율을 상세 화면과 홈 위젯에 표시했다. 필드가 없는 기존 파일도 그대로 읽히도록 호환성을 유지했다.

  6. Codex 위임 설정의 허용값 교정

    설정 화면에서 고를 수 있던 값 중 API가 거부하는 값을 빼고 새로 지원되는 값을 넣어, 실제 지원값 6개로 맞췄다. 잘못된 값이 400으로 거부되는지와 운영 티어 설정이 보존되는지를 별도 서버에서 확인했다.

  7. 저장소 .gitignore 정비

    여러 AI 에이전트가 동시에 고치는 저장소에서 백업·캐시·원자적 저장 임시 파일이 git 변경으로 잡히지 않게 했다. 임시 파일 이름을 짐작하지 않고 저장 코드를 읽어 확인한 뒤 규칙을 만들었다.

  8. 도트 작업실·리소스 TOP 모듈 추가

    픽셀아트 도구와 결과물을 모은 화면, 앱별 메모리·CPU와 스왑·GPU 상태를 보여주는 화면을 추가했다. 테스트 24개가 통과했고 폴더 밖 파일 요청은 403으로 거부된다.

  9. 루틴 앱에 주간 예약 작업 2개 등록

    주간 카탈로그에 예약 작업 2개를 추가하고 예정 시각·유예 경계와 기존 6개 루틴 판정이 유지되는지 검증했다. 테스트 격리를 위해 임시 폴더에 모듈 사본을 두고 설정 우선순위를 확인했다.

  10. 루틴 위젯 넘침 버그 수정

    루틴이 8개로 늘면서 위젯 목록이 타일 밖으로 넘치는 문제를 실제 높이 측정으로 해결했다. 들어가는 만큼만 보여주고 나머지는 '외 N개'로 표시하며, 실패·지연 항목을 먼저 노출한다.

  11. 디스코드 챗봇 조작 모듈과 홈 타일 추가

    디스코드 페르소나 챗봇의 상태를 보고 페르소나를 바꾸는 화면을 붙였다. 두 프로세스가 파일 2개로만 통신하므로 원자적 쓰기와 미처리 명령 보호(409)를 직접 구현했고, 폴링 중에도 편집 초안이 지워지지 않게 했다.

  12. 챗봇 확장(세계관·출연진)에 맞춰 화면 갱신

    봇에 세계관·출연진·강조색·단톡방 기능이 추가돼 화면을 따라 확장했다. 비어 있는 칸이 기존 값을 지우지 않도록 해당 키를 payload에서 빼는 규칙을 검증 스크립트로 고정했다.

  13. 음성 통화 서비스 아이콘과 상태 위젯 추가

    홈 화면에 외부 서비스로 이동하는 아이콘과 접속 현황 위젯을 추가했다. 정상 0명·꺼져 있음·상태 없음을 구분해 표시하고, 운영 서비스를 재시작하지 않은 채 임시 복사본에서 빌드와 화면을 검증했다.

  14. 시스템 생존 확인 CLI와 관리 화면 구현

    AI 에이전트가 작업 전에 시스템이 살아 있는지 명령 한 번으로 판정하는 CLI와 사람용 관리 화면을 만들었다. 등록 시스템 11개 전체 조회가 0.38초이며 결과는 exit code로 구분한다.

이 페이지는 작업 기록 문서 14건을 바탕으로 정리했습니다. 고객 정보, 접속 주소, 비밀값은 공개 전에 걸러 냅니다.