사람함께에이전트▾
사람 — 직접 정하고 책임지는 비즈니스 규칙과 흐름. 직접 읽어보세요.
함께 — 개념은 알아두고, 세부 규칙은 에이전트가 따릅니다.
에이전트 — 에이전트가 따르는 규칙과 레퍼런스. 필요할 때 찾아보세요.
일반▾
인터페이스▾
관측성▾
성능▾
네이티브▾
개발▾

스크립트

스크립트는 앱 서버를 띄워 작업 하나를 하고 끝나는 TypeScript 파일입니다. 프롬프트에서 치고 끝낼 일이 아니라 파일로 남길 일에 씁니다:
명령형태
↳ 잘 맞는 일
akan script검토하고 다시 돌릴 수 있는 script/ 속 파일
시드 데이터, 마이그레이션, 점검, 작은 유지보수 수정
akan console닫으면 사라지는 프롬프트
서비스 점검, 쿼리 시험, 작은 운영 명령 하나
  • 앱과 같은 구성. 앱이 이미 연결해 둔 서비스, 시그널, 어댑터를 그대로 씁니다.
  • 요청도 스케줄도 없음. 포트를 열지 않고, 앱의 init·interval·cron·queue 작업도 실행하지 않습니다.
  • 작게, 쓰고 버리게. 스크립트 하나에는 작업 하나만 담고, 작업이 끝나면 지웁니다.

만들고 실행하기

파일을 앱의 script/ 폴더 바로 아래에 두고, 그 이름을 akan script에 넘깁니다.
  1. apps/koyo/script/hello.ts를 만듭니다. 안에 들어갈 내용은 다음 섹션에 있습니다.
  2. 워크스페이스 루트에서 앱 이름과 파일 이름을 넘깁니다. 아래 명령은 apps/koyo/script/hello.ts를 실행합니다:
Terminal
인자
두 인자 모두 빼도 되며, 빼면 명령이 물어봅니다. 순서대로 받으므로 앱 이름이 먼저 옵니다:
appString선택
앱 이름이며, 파일 이름을 넘길 때는 꼭 적습니다. 빼면 목록에서 고르고, 앱이 하나뿐이면 그 앱을 씁니다.
filenameString선택
script/ 바로 아래 파일입니다. .ts는 붙여도 빼도 됩니다. 빼면 .ts 파일 목록에서 고릅니다.
  • 하위 폴더는 안 됩니다. /나 ..이 들어간 이름은 거부되므로, 스크립트는 모두 script/ 바로 아래에 둡니다.
  • 앱 폴더에서 실행됩니다. 작업 디렉터리가 apps/koyo/이므로 상대 경로는 거기서 시작합니다.

서버 시작과 종료

모든 스크립트의 뼈대는 같습니다. 서버를 시작하고, 작업하고, finally에서 서버를 멈춥니다. 가장 작은 스크립트는 이렇습니다:
apps/koyo/script/hello.ts
  • server는 앱의 것입니다. apps/koyo/server.ts에서 가져오므로, 스크립트는 앱과 똑같은 모듈로 부팅합니다.
  • start()는 앱을 조립하되 포트는 열지 않습니다. akan script에서는 데이터베이스를 연결하고 어댑터, 서비스, 시그널을 만드는 데서 멈춥니다.
  • stop()은 finally에 둡니다. 작업이 예외를 던져도 데이터베이스 연결, 타이머, 어댑터가 제대로 정리됩니다.

서비스로 작업하기

작업은 데이터베이스에 직접 쓰지 말고 서비스를 거쳐 합니다. 서비스는 도메인 규칙, 데이터베이스 접근, 다른 의존성을 이미 알고 있습니다.
다음 스크립트는 served 상태로 남은 아이스크림 주문을 모두 완료 처리합니다:
apps/koyo/script/finishServedOrders.ts
  • server.get(srv.IcecreamOrderService)는 클래스로 서비스를 찾으므로 모든 메서드에 타입이 붙습니다.
  • listByStatuses는 모델의 byStatuses 필터에서 나옵니다. 필터마다 서비스에 이런 list<Filter>가 생깁니다.
  • finishIcecreamOrder는 앱과 같은 상태 검사를 거치므로, served가 아닌 주문은 거부됩니다.

인스턴스 찾기

server.start()가 끝나면 server가 앱에 등록된 서비스, 시그널, 어댑터를 무엇이든 꺼내 줍니다. 이름 문자열은 타입 검사가 안 되므로 가능하면 클래스로 찾습니다.
찾는 기준호출
↳ 꺼내는 것
클래스server.get(srv.IcecreamOrderService)
서비스, 시그널, 어댑터 인스턴스를 타입과 함께 꺼냅니다.
역할server.get(StorageAdaptorRole)
구현과 상관없이 앱이 실제로 쓰는 스토리지 어댑터를 꺼냅니다.
refNameserver.getService("icecreamOrder")
서비스를 꺼냅니다.
refNameserver.getSignal("icecreamOrder")
시그널 로직을 실행해야 할 때 시그널을 꺼냅니다.
refNameserver.getAdaptor("blobStorage")
인프라 작업에 쓸 어댑터를 꺼냅니다.
  • refName은 모듈이 등록된 이름입니다. 서비스와 시그널은 icecreamOrder 같은 camelCase 모듈 이름이고, 어댑터는 adapt()에 넘긴 키입니다.
  • lib의 클래스는 lib 이름 아래에 있습니다. srv.shared.UserService처럼 씁니다.
  • StorageAdaptorRole은 akanjs/service에서 가져옵니다. 앱이 구현을 바꿔 끼워도 역할로는 그 어댑터를 찾을 수 있습니다.

데이터를 안전하게 바꾸기

데이터를 바꾸는 스크립트는 실제로 바꾸기 전에 무엇을 할지 먼저 보여 줘야 합니다. 세 가지 습관이면 대부분 해결됩니다:
  1. 대상 환경부터 출력합니다. getEnv().environment가 스크립트가 바꿀 환경을 알려 줍니다.
  2. 기본은 dry run으로 둡니다. 바꿀 대상을 보여 주기만 하는 실행입니다. APPLY=1 같은 환경 변수를 읽고, 이 값이 없으면 아무것도 바꾸지 않습니다.
  3. 쓰기는 서비스 메서드로 합니다. 그래야 도메인 규칙이 스크립트에 복사되지 않고 한곳에 남습니다.
위의 스크립트에 앞의 두 습관을 더하면 이렇습니다:
apps/koyo/script/finishServedOrders.ts
한 번 실행해 개수를 확인하고, 다시 실행해 적용합니다:
Terminal
  • 환경은 AKAN_PUBLIC_ENV가 정합니다. 서버는 그 값에 맞는 env/env.server.<env>.ts를 읽습니다. 새 워크스페이스의 .env에는 local로 들어 있습니다.
  • try 안의 return도 finally를 거칩니다. 그래서 dry run에서도 서버가 멈춥니다.

MIT 라이선스 하에 배포되었습니다.

내 AI에 이 문서 연결하기

MCPhttps://akanjs.com/mcp
Copyright © 2026 Akan.js 모든 권리 보유.시스템 관리자bassman