尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗2026-10-26: 안내·등록 키오스크의 도움 버튼과 입구 안내로봇의 이동지원 접수를 통합 요청에 연결했다. 직원 첫 화면도 통합 요청이며, 예전 데이터는 /staff/legacy에서 확인한다. 탑승권 없이도 입구에서 접수할 수 있다.
2026-10-25 DX 통합 요청 1차 구현: 기존 사전등록을 유지하면서, 현장 요청 → 직원 배정 → 도착·지원 → 종료를 별도 흐름으로 추가했다. 미등록 여객도 항공편·서류 없이 /help에서 요청하고, 사전등록 여객은 내 등록의 「지금 도움 요청」에서 내용을 불러온다. 직원은 /staff/requests에서 처리한다.
구현 범위, 알림 설정, 추가 DB 스키마와 배포 순서는 docs/dx-integration.md에 있다. 키오스크·안내로봇의 새 접수는 통합 요청으로 연결한다. 기존 호출·이동지원 기록은 이전 요청 화면에서 확인하며 자동 합산하지 않는다. 모든 위치와 서비스 처리는 시연용이며 실제 로봇·차량 출동과 연결되지 않는다.
다음은 유지 중인 사전등록·탑승권 시연 흐름이다.
여객이 항공권 예매 완료 화면의 링크로 들어와 필요한 도움과 증빙을 한 번 등록하면, 체크인할 때 전자토큰이 탑승권에 저장된다. 출국 당일 교통약자 우대출구에서는 서류 없이 탑승권만으로 확인받고, 공항의 안내 키오스크도 탑승권을 읽어 화면과 길 안내를 그 여객에게 맞춘다. 증빙서류는 공항이 아닌 별도 서버가 보관한다는 구조다. 시제품은 파일을 기기 밖으로 보내지 않고 "냈다"만 받는다. 체크인은 모의 체크인으로 흉내 낸다(2026-10-24, 팀 제안서 「예약 완료 후 연결형 정보입력」). 이름·연락처는 받지 않는다. 받는 것은 항공편과 고른 항목, 증빙 확인 여부뿐이고 출발 후 지운다. 증빙서류(여권 MRZ, 복지카드, 산모수첩, 가족관계증명서)는 휴대전화나 키오스크 안에서 글자 인식(tesseract.js)으로 종류와 나이를 판정하고, 사진과 읽은 글자는 어디에도 보내지 않는다. 공항 입구 안내로봇에서는 등록하지 않은 여객도 탑승권을 찍고 그 자리에서 등록하며, 이동지원(전동차)을 청하고 접수 상태를 본다.
설계는 docs/spec.md 에 있다. docs/plans/2026-10-05-webapp-prototype.md 는 예전 구조를 만들 때의 계획이라 지금 구조와 맞지 않는다.
지금은 모의 데이터 전용이다. 실제 여객 정보는 기관의 개인정보 검토가 끝난 뒤에만 받는다. 길과 시설 위치도 시연용 모의 자료다.
| 주소 | 누가 | 무엇을 |
|---|---|---|
/help | 여객 | 위치와 서비스·필요한 지원을 확인해 현장 요청. 사전등록·항공편·증빙 선택 없이 이용 가능 |
/p/{token}/help | 사전등록 여객 | 저장한 지원 선택과 인원을 불러온 뒤 현장 요청 |
/staff/requests | 직원 | 통합 요청 처리와 당일 집계, 선택적 기기 알림 |
/staff/requests/new | 안내데스크 | 여객 대신 통합 요청 접수 |
/ | 여객 | 서비스 소개, 등록 시작, 예매 완료 화면 시연. 오른쪽 위에서 영어로 바꾼다(/?lang=en) |
/demo/booking | 시연 | 시연용 모의 예매 완료 화면. Journey Support Pass 링크(/register?via=booking)와 대체 접점(예약 확인 문자) |
/register | 여객 (휴대전화) | 「공항 이용 도움 체크리스트」대로 묻는다. 어떤 점이 불편하세요?(여덟 가지) → 동의 → 고른 불편의 가지만 하나씩 → 함께 가는 분 → 도움 받는 방식 → 들를 곳 → 항공편 → 서류 → 더 하고 싶은 말씀 → 확인 |
/p/{token} | 여객 (휴대전화) | 내 등록. 준비 상황(등록, 증빙 확인, 체크인), 「모의 체크인 하기」, 체크인 뒤 모바일 탑승권(항공사 탑승권 바코드와 번호 여섯 자리), 내 항공편, 고른 안내, 「내 등록 지우기」. 여객이 보여 줄 서비스 전용 QR 은 없다 |
/staff/exit | 직원 (우대출구) | 탑승권 QR 을 찍으면 우대 대상 확인됨 / 체크인 카운터로 안내, 필요한 지원만 나온다 |
/kiosk/entry | 여객 (공항 입구 안내로봇) | 탑승권을 찍으면 로봇이 깨어난다. 미리 등록한 여객은 고른 도움을 확인하고, 아니면 그 자리에서 불편 다섯 가지를 고르고 서류를 인식시켜 등록한다. 맞춤 안내, 이동지원 요청, 접수 상태 확인 |
/demo/boarding | 시연 | 미리 등록하지 않은 여객의 모의 탑승권(QR 에 편과 탑승권 번호만) |
/staff/assist | 직원 | 통합 전 이동지원 기록과 남은 요청 처리 |
/kiosk | 직원 | 키오스크 설치. 설치 코드와 놓을 자리를 넣으면 그 기기가 키오스크가 된다 |
/kiosk/register | 여객 (등록 키오스크, 예비) | 주 흐름에서 뺐다. /kiosk?reserve=1 로 설치할 때만 쓴다. 현장 등록과 QR 스티커 인쇄 |
/kiosk/guide | 여객 (안내 키오스크) | 탑승권을 대거나 번호를 누르면 미리 등록한 내용을 먼저 보여 주고 「고치기」로 그 자리에서 고친다. 그 뒤 고른 방식대로 항공편, 탑승구 가는 길, 가까운 시설을 보여준다. 「직원 부르기」, 만족도 한 문항 |
/check | 직원·시연하는 사람 | 기기 점검. 그 기기에서 인터넷, 카메라 QR 읽기, 소리(한국어·영어 목소리), 화면 크기, 인터넷 없이 열기, 화면 꺼짐 막기를 본다. 서버에 아무것도 남기지 않는다 |
/staff/login | 직원 | 접속 코드로 로그인 |
/staff/zone | 현장 직원 | 근무 구역 고르기·바꾸기 |
/staff | 직원 | 통합 요청으로 이동 |
/staff/legacy | 직원 | 통합 전 호출·이동지원 확인 |
/staff/legacy/calls | 직원 | 기존 직원 호출 배정·종료 |
/staff/desk | 안내데스크 | 여객 대신 등록하기, QR이나 번호로 패스 찾기(우대 확인·체크인 여부 보기, 등록 지우기) |
/staff/desk/register | 안내데스크 | 예매 링크를 못 본 여객 대신 등록하기. 스티커 대신 여객 휴대전화로 QR 을 찍게 한다 |
/staff/desk/stats | 안내데스크 | 오늘 현황. 건수와 가운데값만 |
키오스크로 설치한 기기는 직원 화면을 열 수 없고, 직원 코드로는 키오스크를 설치할 수 없다.
계정이나 외부 서비스 없이 이 컴퓨터 안에서 돈다. DB는 .data/pglite 폴더에 저장된다.
npm install
npm run seed -- --mock-flights
npm run dev
http://localhost:3000 을 연다.
seed 는 개발 서버를 끈 상태에서 실행한다. 직원 구역과 지금 시각 기준의 모의 운항을 넣고, 시범용 접속 코드를 화면에 출력한다. 같은 코드가 db/seed-zones.json 에도 있다. 아래 세 개만 알면 된다.
| 코드 | 어디에 쓰는가 |
|---|---|
100100 | 안내데스크 로그인 (/staff/login) |
200200 | 현장 직원 공통 로그인 (/staff/login). 들어가서 근무 구역을 고른다 |
300300 | 키오스크 설치 (/kiosk) |
이 코드는 모의 데이터 전용이다. 저장소에 공개된 값이라 배포된 곳에는 넣지 않는다. 구역마다 따로 있는 코드도 같은 파일에 있으며, 그 코드로 들어가면 그 구역으로 바로 들어가고 구역을 바꿀 수 없다.
모의 운항 편명은 MK101, MK102, MK111, MK112, MK127, MK221, MK250(지연), MK900(탑승구 미정), MK300, MC830(공동운항, 실제 운항 편은 MK300), MK401(탑승중), MK402(탑승마감), MK403(결항), MK501(제1여객터미널), MK601(괌, 한 글자 도시) 이다. 모의 운항은 seed 를 실행한 시각 기준으로 몇 분~몇 시간 뒤에 떠나게 들어가므로, 시간이 지나 편이 떠났으면 seed 를 다시 실행한다.
같은 곳으로 가는 편이 많은 장면(도착 도시에서 고르기 → 출발 시간대 → 항공사)을 볼 수 있게 오사카로 가는 편 열두 개(MK7xx, MQ7xx, MZ7xx)도 들어간다.
직원 로그인과 키오스크 설치는 한 브라우저에서 같은 자리(쿠키)를 쓴다. 그래서 키오스크와 직원 화면은 서로 다른 브라우저나 시크릿 창, 또는 다른 기기에서 연다.
/ 에서 「등록 시작하기」를 누른다. 안내받는 방식에서 「큰 글씨로 보여주세요」를 고르면 그 화면부터 글자가 커진다. 동의하고, 이동·찾는 시설·직원 도움을 고른다. 편명에 MK1 까지만 넣어도 후보가 뜬다. MK127 을 고르고 「등록하기」를 누른다. 패스 화면에 QR과 번호 여섯 자리가 나온다. 번호를 적어 둔다./kiosk 를 연다. 쓰임새는 「안내 키오스크」, 놓을 자리는 「탑승동 3층 중앙 (116번 탑승구 앞)」, 설치 코드는 300300 을 넣는다. 안내 키오스크의 처음 화면이 열린다./staff/login 에 200200 을 넣고 근무 구역으로 탑승동의 「중앙부」를 고른다(다른 구역을 골랐으면 「전체」를 눌러 본다). 방금 호출이 고른 항목, 항공편과 함께 보인다. 「가겠습니다」를 누르면 키오스크가 "직원이 오고 있습니다"로 바뀐다. 「도움 마침」을 누르면 끝난다.100100 으로 로그인해 「오늘 현황」을 열면 방금 한 일이 숫자로 보인다.등록 키오스크를 보려면 /kiosk 에서 쓰임새를 「등록 키오스크」로 골라 다시 설치한다.
장면마다 다른 안내가 나오도록 미리 골라 둔 패스 열 장을 만들고, QR을 한 장짜리 그림과 A4 PDF 로 뽑는다. 개발 서버를 켠 채로 실행한다.
npx tsx scripts/remote-demo.ts "저장할 폴더" --local
배포된 곳에 만들려면 --local 을 뺀다. 이때는 저장소에 올리지 않는 .env.deploy.local 의 값을 쓴다.
npx tsx scripts/remote-demo.ts "저장할 폴더"
시연용_패스QR.png 와 시연용_패스QR.pdf 가 생긴다. 화면에는 번호와 장면 이름만 출력한다.npm test
업무 규칙(등록, 패스, 직원 호출, 삭제, 측정값, 접속 코드와 잠금, 길 계산, 운항 수집, QR 인식)을 메모리 DB 로 검사한다.
화면은 실제 브라우저로 처음부터 끝까지 눌러 본다. 이 컴퓨터의 개발 서버에만 쓴다. 설치된 Chrome(없으면 Edge)을 새 프로필로 띄우므로 평소 쓰는 브라우저에는 영향이 없다.
# 1) 개발 서버를 끄고 (처음 한 번. 구역과 접속 코드를 넣는다)
npm run seed
# 2) 개발 서버를 켜고
npx tsx scripts/e2e.ts
.e2e-shots/ 에 번호 순으로 저장된다(SHOTS_DIR 로 바꿀 수 있다)..data/pglite 폴더를 지우고 시작한다.숫자는 모두 src/lib/config.ts 한 곳에 있다. 기업탐방에서 기관 기준을 확인하면 여기만 고친다.
| 값 | 기본 |
|---|---|
| 탑승 마감 추정 | 출발 10분 전 |
| 출발 후 삭제 | 30분 뒤 (그 뒤에 받은 운항 정보로 늦어지지 않은 것이 확인될 때. 수집이 멈추면 최대 135분 더 기다림) |
| 삭제 안전장치 | 예정 출발 24시간 뒤 |
| 건수·호출·조회 기록 보관 | 90일 |
| 직원 로그인 유지 | 12시간 |
| 키오스크 설치 유지 | 30일 |
| 접속 코드·설치 코드 입력 실패 차단 | 같은 기기 5번 또는 같은 접속 주소 20번 틀리면 10분 |
| 고유 일련 번호 입력 실패 차단 | 같은 설치(키오스크 설치 또는 안내데스크 로그인 한 번) 10번 또는 같은 접속 주소 40번 틀리면 10분 |
| 휴대전화 등록 한도 | 같은 접속 주소 20건, 모든 주소를 합해 300건(10분마다) |
| 휴대전화 등록 제한 | 같은 접속 주소에서 10분에 20건 |
| 계속 이용 확인 | 90초 건드리지 않으면 묻고, 30초 답이 없으면 처음 화면 |
| 직원 화면이 호출을 다시 읽는 간격 | 5초 |
| 안내 화면이 탑승구를 다시 읽는 간격 | 30초 |
| 운항 수집 간격 | 60분. vercel.json 의 예약과 맞춘 값이며 "운항 정보가 늦어지고 있습니다" 기준(수집 간격의 두 배 + 15분)이 여기서 나온다 |
걷는 속도, 엘리베이터 시간, 시설 위치 같은 길 안내의 값은 src/lib/airport.ts 에 있다. 모두 모의 자료다.
환경 변수는 .env.example 참고.
| 이름 | 용도 |
|---|---|
DATABASE_URL | 비우면 로컬 내장 DB. 없으면 POSTGRES_URL 을 쓴다 (Vercel 의 Supabase 연동이 넣어 주는 이름) |
SESSION_SECRET | 로그인 쿠키 서명. 배포 시 32자 이상 무작위 값 |
CRON_SECRET | 예약 실행 경로와 운영자 통로 호출용 |
ICN_API_KEY | 공공데이터포털 여객기 운항 현황 상세 조회 서비스 디코딩 키 |
DATA_MODE | mock(기본) 또는 live. live 는 기관 검토가 끝난 뒤에만 |
BASE_URL | 배포 주소. 시연용 패스의 QR 주소를 만들 때 쓴다 |
주소: https://journey-support-pass.vercel.app (모의 데이터 전용)
| 무엇 | 어디 |
|---|---|
| 화면과 서버 | Vercel 프로젝트 journey-support-pass, 서울 리전(icn1) |
| DB | Vercel Storage 로 만든 Supabase, 서울 리전. 연결 주소는 Vercel 이 POSTGRES_URL 로 넣어 준다 |
| 코드와 배포 | GitHub 비공개 저장소 rkdals0121/journey-support-pass. main 에 push 하면 자동으로 배포된다 |
DB 연결 값은 Vercel 에서 잠겨 있어 꺼내 볼 수 없다. 그래서 이 컴퓨터에서 DB 에 직접 접속하지 않고, 배포된 서버의 초기 설정 통로(/api/admin/setup)를 불러 서버가 직접 넣게 한다.
npx tsx scripts/remote-setup.ts
db/zone-codes.local.json 에서 배포용 코드를 읽는다. 켜져 있는 모든 자리의 코드가 있어야 하고, 이번에 kiosk 자리가 새로 생겼다. kiosk 의 코드가 없으면 "접속 코드가 없는 구역: kiosk" 로 끝나고 아무것도 넣지 않는다.이 명령은 저장소에 올리지 않는 파일 두 개를 읽는다. 다른 컴퓨터에서 실행하려면 이 파일을 옮겨야 한다.
| 파일 | 내용 |
|---|---|
.env.deploy.local | BASE_URL(배포 주소), CRON_SECRET(Vercel 에 넣은 것과 같은 값) |
db/zone-codes.local.json | 배포용 접속 코드. { "자리 id": "코드" } 모양이다. 자리 id 는 db/seed-zones.json 의 id 와 같다. 배포된 곳의 직원 로그인과 키오스크 설치에 쓰는 코드는 여기서 확인한다 |
db/seed-zones.json 에 적힌 코드(100100 등)는 저장소에 공개된 값이라 배포 DB 에는 넣지 않는다. 이 컴퓨터의 localhost:3000 에서만 쓴다.
배포된 곳은 실제 운항 정보를 받는다. 정해진 장면을 보여줘야 하는 시연 때는 위의 시연용 패스 명령을 쓴다(모의 운항도 함께 넣는다). 모의 운항만 넣거나 지우려면 아래를 쓴다.
npx tsx scripts/remote-setup.ts --mock-flights
npx tsx scripts/remote-setup.ts --clear-mock
npx tsx scripts/remote-metrics.ts
배포된 곳의 최근 14일 측정값을 화면에 요약해 보여주고 out/summary.json 에 저장한다. 끝에 숫자를 붙이면 그 일수만큼 받는다. 제안서의 기대 효과 세 가지에 해당하는 건수와 가운데값뿐이며, 항공편이나 여객이 고른 항목은 들어 있지 않다(명세 5.3).
| 작업 | 지금 | 정식 운영 전에 |
|---|---|---|
운항 수집 (/api/cron/poll-flights) | 한 시간에 한 번 (Vercel Cron) | 5분 간격으로 (인증키의 일일 호출 한도 확인 후) |
삭제 (/api/cron/purge) | 한 시간에 한 번 (Vercel Cron) | 10분 간격으로 |
Vercel 무료 요금제는 예약 하나가 하루 한 번까지만 돈다. 그래서 vercel.json 에 시각이 다른 예약을 24개씩 넣어 한 시간 간격을 만들었다. 무료 요금제의 예약은 정해진 분에 정확히 돌지 않고 그 시간대 안의 아무 때나 돈다. 한 시간 간격이면 공공데이터 호출은 하루 약 310회다.
한 시간 간격인 동안에는 탑승구 변경이 최대 한 시간 늦게 반영된다. 무료 요금제의 예약은 그 시간대 안의 아무 때나 돌아 정상일 때도 두 수집 사이가 두 시간 가까이 벌어질 수 있다. 그래서 마지막 수집 성공이 135분(수집 간격의 두 배 + 15분)보다 오래되면 안내 화면과 패스 화면에 "운항 정보가 늦어지고 있습니다. 탑승구는 전광판에서 한 번 더 확인해 주세요"가 뜬다. 시범에 쓰려면 아래 방법으로 간격을 줄이고 src/lib/config.ts 의 pollMin 도 함께 바꾼다.
간격을 줄이려면 Supabase SQL 편집기에서 pg_cron 과 pg_net 확장을 켜고 아래를 실행한다. CRON_SECRET값 자리에는 Vercel 에 넣은 값을 넣는다.
select cron.schedule('poll-flights', '*/5 * * * *', $$
select net.http_get(
url := 'https://journey-support-pass.vercel.app/api/cron/poll-flights',
headers := '{"Authorization": "Bearer CRON_SECRET값"}'::jsonb,
timeout_milliseconds := 280000
);
$$);
select cron.schedule('purge', '*/10 * * * *', $$
select net.http_get(
url := 'https://journey-support-pass.vercel.app/api/cron/purge',
headers := '{"Authorization": "Bearer CRON_SECRET값"}'::jsonb
);
$$);
운항 정보를 하루 동안 따로 받아 기록해 본다.
ICN_API_KEY="디코딩 키" npx tsx scripts/probe-poll.ts
5분마다 받아 out/probe-YYYYMMDD.jsonl 에 한 줄씩 남긴다. 한 번만 받아 보려면 끝에 --once 를 붙인다. 이 기록으로 하루 호출 횟수가 인증키 한도 안에 드는지, 탑승구 변경이 하루 몇 건 잡히는지, 실패하거나 늦는 회차의 비율을 본다. 2026-10-05 에 한 회 받아 본 결과는 명세 7.5 에 있다.
pgOptions). 실제 여객 정보를 받기 전에 Supabase 인증 기관 인증서를 넣어 검증을 켜야 한다.db/schema.sql 테이블 정의
db/seed-zones.json 직원 구역, 탑승구 범위, 시범용 접속 코드
src/lib/ 업무 규칙. 모두 Db 와 now 를 인자로 받아 검사에서 바꿔 끼운다
catalog.ts 선택 항목. 제안서의 표와 문구·순서가 같아야 한다
i18n.ts 여객 화면의 문구 (한국어, 영어, 각각의 쉬운 말)
airport.ts 키오스크 자리, 시설 위치, 길 계산. 위치 값은 모의 자료
guide.ts 안내 화면의 내용 만들기 (항공편, 길, 시설, 시간이 넉넉한지)
journey.ts 등록과 그 항공편. 여정이 끝났는지의 기준
registrations.ts 등록 받기
passes.ts, pass-format.ts 패스 만들기, QR 값과 번호의 모양
calls.ts 직원 호출
metrics.ts 건수 기록과 기대 효과 세 가지의 집계
purge.ts 출발 후 삭제, 여객이 지우기
auth.ts 접속 코드, 로그인 정보, 입력 차단
timing.ts 탑승 마감 추정, 운항 정보가 늦는지
flights/ 운항 수집, 탑승구 변경 추적, 편명 검색
demo.ts, setup.ts 시연용 패스, 초기 설정과 모의 운항
api/ 화면이 부르는 경로의 본체 (public 여객, kiosk 키오스크, staff 직원)
src/app/ 화면과 얇은 경로 처리기
components/ 여객 화면의 틀, 등록 질문, 직원 부르기, 계속 이용 확인, 카메라, QR
register/, p/[token]/ 휴대전화 등록, 패스
kiosk/ 키오스크 설치, 등록 키오스크, 안내 키오스크
staff/ 직원 로그인, 구역 고르기, 호출 목록, 안내데스크
scripts/seed.ts 이 컴퓨터의 내장 DB 에 구역과 모의 운항 넣기
scripts/remote-setup.ts 배포 DB 초기 설정, 모의 운항 넣기·지우기
scripts/remote-demo.ts 시연용 패스 만들고 QR 을 그림과 PDF 로 뽑기 (demo-sheet.ts 를 쓴다)
scripts/remote-metrics.ts 배포된 곳의 측정값 내려받기
scripts/probe-poll.ts 운항 API 실측
scripts/e2e.ts 화면을 실제 브라우저로 처음부터 끝까지 눌러 보는 점검
tests/ 단위 검사
docs/spec.md 개발 명세
docs/scenario-checklist.md 화면 점검 결과. e2e.ts 가 실행할 때마다 다시 적는다
DATA_MODE=mock 이며 모든 화면 위에 "시범 운영 · TRIAL" 띠가 뜬다.사람이 직접 확인해야 하는 것은 명세 11장에 모았다.