프로필의 세션 라이프사이클을 관리합니다.
각 테넌트는 어드민에서 세션 플로우(단계 순서)를 정의하며, READY와 CHAT은 예약어로 항상 플로우 앞쪽에 고정됩니다.
세션은 선형 단방향입니다 — 한 번 다음 단계로 전이하면 이전 단계로 돌아갈 수 없습니다.
CHAT 이후 다른 단계로 전이되는 순간 진행 중이던 스레드는 자동으로 종료됩니다.
입장 → READY → CHAT → SHOPPING → PAYMENT → COMPLETE → 종료
↑ ↑
채팅 가능 채팅 불가 (CHAT_ENDED)
채팅 허용 규칙
| 마지막 스탬프 | POST /v1/chat/{profile_id} 동작 |
|---|
| 활성 세션 없음 | 409 NO_ACTIVE_SESSION |
READY | 새 스레드 생성 + CHAT 스탬프 자동 기록 |
CHAT | 기존 활성 스레드에 이어서 대화 |
| 그 외 커스텀 단계 | 409 CHAT_ENDED — 세션 종료 후 재시작 필요 |
세션 시작
POST /v1/profile/{profile_id}/session/start
{
"success": true,
"data": {
"session_id": "a1b2c3d4-...",
"profile_id": "d28fd898-...",
"started_at": "2026-04-20T10:00:00Z"
}
}
프로필당 활성 세션은 1개만 허용됩니다. 이미 활성 세션이 있으면 409 SESSION_ACTIVE가 반환됩니다.
상태 스탬프 기록
POST /v1/profile/{profile_id}/session/stamp
{
"status": "SHOPPING",
"meta": {
"zone": "processed_food",
"cart_items": 3
}
}
| 필드 | 타입 | 필수 | 설명 |
|---|
status | string | O | 어드민에서 등록된 플로우 단계 중 하나 |
meta | object | X | 상태 관련 추가 데이터 |
{
"success": true,
"data": {
"session_id": "a1b2c3d4-...",
"status": "SHOPPING",
"timestamp": "2026-04-20T10:05:00Z"
}
}
전이 오류
| 코드 | 설명 |
|---|
INVALID_STAGE | 테넌트 플로우에 등록되지 않은 단계 |
STAGE_REGRESSION | 현재 단계보다 앞쪽으로 되돌리려는 시도 (역행 금지) |
CHAT에서 다른 단계로 전이되면 현재 활성 스레드는 자동으로 CLOSED 됩니다.
세션 종료
POST /v1/profile/{profile_id}/session/end
세션을 종료하고 전체 스탬프 이력을 반환합니다. 진행 중이던 스레드도 함께 종료됩니다.
{
"success": true,
"data": {
"session_id": "a1b2c3d4-...",
"profile_id": "d28fd898-...",
"started_at": "2026-04-20T10:00:00Z",
"ended_at": "2026-04-20T11:30:00Z",
"stamps": [
{ "status": "READY", "timestamp": "2026-04-20T10:00:00Z" },
{ "status": "CHAT", "timestamp": "2026-04-20T10:02:00Z" },
{ "status": "SHOPPING", "timestamp": "2026-04-20T10:15:00Z" },
{ "status": "PAYMENT", "timestamp": "2026-04-20T11:20:00Z" },
{ "status": "COMPLETE", "timestamp": "2026-04-20T11:25:00Z" }
]
}
}
현재 세션 조회
GET /v1/profile/{profile_id}/session
활성 세션과 현재 단계, 진행 중인 스레드 ID를 반환합니다.
앱이 비정상 종료된 뒤 재시작할 때 current_stage를 참조해 클라이언트 화면을 복원하세요.
{
"success": true,
"data": {
"session_id": "a1b2c3d4-...",
"profile_id": "d28fd898-...",
"is_active": true,
"started_at": "2026-04-20T10:00:00Z",
"current_stage": "CHAT",
"current_thread_id": "thr_a1b2c3d4e5f6",
"stamps": [
{ "status": "READY", "timestamp": "2026-04-20T10:00:00Z" },
{ "status": "CHAT", "timestamp": "2026-04-20T10:02:00Z" }
],
"query_results": {
"session": { "status": "CHAT", "back_list_status": "not_started", "last_error": null }
}
}
}
| 필드 | 설명 |
|---|
current_stage | 가장 최근 스탬프 (재진입 화면 매핑의 기준) |
current_thread_id | current_stage == "CHAT"일 때 활성 스레드 ID, 아니면 null |
query_results.session | 채팅 세션 생성(POST /v1/chat/{profile_id}) 이후에만 포함. llm-demo 쪽 최신 status / back_list_status / last_error 만 경량으로 담아 앱 복원 시 화면 분기에 사용. 전체 pipeline 은 GET /v1/chat/{profile_id}/recommend/{session_id} 폴링으로 받음 |
코드 예제
# 세션 시작
curl -X POST https://api.ones1ght.com/v1/profile/$PERSONA_ID/session/start \
-H "Authorization: Bearer $SDK_KEY"
# 상태 스탬프 (CHAT 이후 단계 전이)
curl -X POST https://api.ones1ght.com/v1/profile/$PERSONA_ID/session/stamp \
-H "Authorization: Bearer $SDK_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "SHOPPING", "meta": {"zone": "wine"}}'
# 현재 세션 조회 (재진입 지점 복원)
curl https://api.ones1ght.com/v1/profile/$PERSONA_ID/session \
-H "Authorization: Bearer $SDK_KEY"
# 세션 종료
curl -X POST https://api.ones1ght.com/v1/profile/$PERSONA_ID/session/end \
-H "Authorization: Bearer $SDK_KEY"