6.4 KiB
Work Server
Fastify + Knex + PostgreSQL 기반의 범용 작업용 API 서버입니다.
추천 DB
PostgreSQL- 이유:
- Node 생태계에서 검증된 조합
Knex로 CRUD와 DDL을 함께 다루기 편함- 운영/확장/마이그레이션 측면에서 무난함
실행
docker compose up -d
docker compose logs -f work-server
work-server는 HMR/watch 없이 빌드 산출물(dist)을 실행합니다. 컨테이너 재기동은 docker compose up -d --build --force-recreate --no-deps work-server 기준으로 최신 소스를 다시 빌드한 뒤 새 컨테이너를 띄웁니다.
호스트 프로젝트 루트와 동일한 문맥으로 서버 재기동을 처리하려면 별도 host runner를 사용합니다. 이 runner는 별도 명시적 요청이 있을 때만 수동으로 켜거나 재기동합니다.
cd /home/how2ice/project/ai-code-app
npm run server-command:runner
환경 변수
기본 실행은 .env.example 값으로도 가능합니다.
로컬 환경에 맞는 값을 덮어쓰려면 .env.example를 참고해서 .env를 추가하면 됩니다.
주요 항목:
APP_TIME_ZONE: Node 서버 런타임 기준 시간대. 기본값Asia/SeoulDB_TIME_ZONE: 앱이 여는 DB 세션 시간대. 기본값Asia/SeoulDB_*: PostgreSQL 접속 정보PLAN_WORKER_ENABLED: Plan 자동화 worker 활성화 여부PLAN_WORKER_INTERVAL_MS: Plan polling 주기PLAN_GIT_REPO_PATH: 브랜치 생성/병합 대상 저장소 경로PLAN_MAIN_PROJECT_REPO_PATH: main 반영 후 pull 받을 메인 루트 프로젝트 경로. 비우면PLAN_GIT_REPO_PATH를 사용PLAN_RELEASE_BRANCH: 자동 merge 대상 release 브랜치명IOS_NOTIFICATION_ENABLED: iOS APNs 알림 활성화 여부APNS_*: Apple Push Notification 인증 키 정보SERVER_COMMAND_DOCKER_SOCKET: 서버 재기동 명령이 사용할 Docker Unix socket 경로. rootless Docker면 예:/run/user/1000/docker.sockSERVER_COMMAND_API_BASE_URL:work-server가 서버 재기동 요청을 위임할 host runner 주소SERVER_COMMAND_API_ACCESS_TOKEN: host runner 호출 토큰
서버 재기동 기능을 쓰려면 work-server 컨테이너가 Docker에 접근할 수 있어야 합니다. 기본값은 /var/run/docker.sock이며, rootless Docker 환경이면 .env에 SERVER_COMMAND_DOCKER_SOCKET 또는 DOCKER_HOST=unix:///run/user/<uid>/docker.sock를 맞춰 준 뒤 work-server를 다시 올려야 합니다.
기본 예시는 http://host.docker.internal:3211/api로 맞춰져 있어서, work-server 컨테이너가 아니라 호스트의 현재 프로젝트 루트에서 restart-*.sh를 실행합니다. 즉 Server > Command가 직접 CLI로 재기동한 것과 최대한 비슷한 문맥을 사용합니다.
Codex Live
Codex Live는 현재 프로젝트 환경에서 PLAN_MAIN_PROJECT_REPO_PATH로 지정된 main_project 저장소 루트를 기준으로 실행됩니다. 문서 예시와 기본 컨테이너 값은 PLAN_MAIN_PROJECT_REPO_PATH=/workspace/main-project이지만, 이것은 환경 변수 기본 예시일 뿐이며 실제 실행 루트는 현재 마운트된 프로젝트 경로를 따릅니다.
소스 수정이 필요하면 현재 실행 환경에서 실제로 연결된 main_project 저장소 루트의 AGENTS.md 규칙을 먼저 확인한 뒤, 그 작업 트리에서 바로 수정합니다.
현재 운영 기준에서는 Codex Live, 일반 채팅, 일반 작업메모 반영 요청은 현재 프로젝트 루트의 로컬 작업본을 직접 기준으로 처리합니다.
Codex Live와 Plan 자동화는 별개입니다. Codex Live는 채팅 유형 context를 최우선 기준으로 읽고, 현재 화면 및 최근 대화 문맥은 그 아래 보조 문맥으로 사용합니다. 자동화 유형 context는 기본 문맥으로 섞지 않습니다.
브라우저 기준 접속 확인, 화면 검증, 외부 도메인 테스트는 https://test.sm-home.cloud/를 기본 작업 도메인으로 사용합니다. 별도 요청이 없는 한 sm-home.cloud나 rel.sm-home.cloud는 기본 검증 대상으로 삼지 않습니다.
채팅에서 파일, 문서, 이미지, 코드 같은 리소스를 제공할 때의 기본 공개 경로는 public/.codex_chat/<chat-session-id>/resource/...입니다. Codex가 원본 파일 경로만 답해도 서버가 이 위치로 세션 전용 사본을 만들고, 채팅에는 공개 URL을 다시 적어 줍니다.
채팅 첨부 파일도 같은 기준을 사용하며 public/.codex_chat/<chat-session-id>/resource/uploads/... 아래에 저장됩니다.
Plan 자동화
Plan 게시판 항목을 작업 큐처럼 읽어 자동화할 수 있습니다.
현재 운영 기준에서 자동화 작업메모의 세부 Git 절차는 이 문서에 고정하지 않습니다. 상태 전이와 실제 처리 흐름은 worker 구현, 환경 변수, 현재 운영 정책을 함께 확인해야 합니다.
자동화 실행기는 선택된 자동화 유형의 description/context만 우선 참조합니다. Codex Live나 일반 채팅 문맥은 자동화 기본 context로 사용하지 않습니다.
안전 조건:
- Git worktree가 깨끗해야 동작
release브랜치가 실제로 존재해야 병합 가능- 실패 시 자동으로
이슈상태와 오류 메시지를 남김
주요 API
GET /healthGET /api/schema/tablesPOST /api/ddl/create-tablePOST /api/ddl/drop-tablePOST /api/ddl/add-columnPOST /api/ddl/drop-columnPOST /api/ddl/rawPOST /api/crud/:table/selectPOST /api/crud/:table/insertPATCH /api/crud/:table/updateDELETE /api/crud/:table/deleteGET /api/plan/statusesPOST /api/plan/setupGET /api/plan/itemsGET /api/plan/items/:idPOST /api/plan/itemsPATCH /api/plan/items/:idDELETE /api/plan/items/:idPOST /api/notifications/setupGET /api/notifications/tokensPUT /api/notifications/tokens/iosDELETE /api/notifications/tokens/iosPOST /api/notifications/send-test
iOS 알림 연동
- 프론트에서 알림
On시PUT /api/notifications/tokens/ios로 APNs 토큰을 등록합니다. - 프론트에서 알림
Off시 또는 토큰이 폐기되면DELETE /api/notifications/tokens/ios로 토큰을 제거합니다. - Plan worker가 브랜치 준비, 자동 작업 완료/실패, release 반영 완료/실패, main 반영 완료/실패 시 등록된 iOS 토큰으로 APNs 알림을 전송합니다.