feat(solution): 발행 워커·버전 관리와 예약·미리보기 정리

상시 프리렌더와 중복 예약 안내를 없애고, 검수된 발행 버전을 보존한다. 미리보기는 실제 렌더 완료까지 스피너를 표시한다.

사이트 81건, 발행·롤백·서치콘솔 45건, 프로세스 수명 3건 통과. 빌더·사이트 빌드 및 compose 설정 검증 통과.
This commit is contained in:
Mina Choi 2026-09-15 16:10:12 +09:00
parent 0f7d22750f
commit f2087aad5e
207 changed files with 8424 additions and 4429 deletions

View File

@ -1,5 +1,8 @@
# AGENTS.md — 이 레포에서 작업하기 전에
> 2026-09-15 발행 버전 전환: [docs/PUBLISH_VERSION.md](docs/PUBLISH_VERSION.md)가
> 아래의 상시 프리렌더·재굽기·자산 주소 교체 절차를 대체한다. 목업은 변경하지 않는다.
에이전트와 신규 합류자가 **먼저 읽는 파일**이다. 여기에는 *밟기 쉬운 함정*과 *규약*만 둔다.
설명은 각 문서가 단일 출처다 — 여기로 복사하지 말고 링크한다.

141
deploy.sh
View File

@ -1,127 +1,40 @@
#!/usr/bin/env bash
# 배포 — 코드를 당기고, 지정한 서비스만 다시 빌드해 갈아끼운다.
#
# ./deploy.sh 전체
# ./deploy.sh solution-backend 그 서비스만
# ./deploy.sh solution-backend solution-worker 여럿
#
# 서비스명 대신 컨테이너명(o2o-web4ai-solution-backend)으로 불러도 받는다.
# 서버 변경과 꺼진 admin을 보존한다. 렌더러 배포도 기존 사이트를 재굽지 않는다.
set -euo pipefail
cd "$(dirname "$0")"
PREFIX=o2o-web4ai
# api·worker·api-admin 은 이미지 한 벌(o2o-web4ai-backend)을 나눠 쓴다.
BACKEND_SVCS=(solution-backend solution-worker admin-backend)
BRANCH=${DEPLOY_BRANCH:-main}
PULL=1
ONLY=0
TARGETS=()
usage() {
cat <<'USAGE'
사용법: ./deploy.sh [옵션] [서비스...]
옵션
--no-pull 코드를 당기지 않는다(디스크에 있는 코드 그대로 빌드)
--only 백엔드 형제 서비스를 함께 갈아끼우지 않는다 (아래 ★ 참고)
-h, --help
환경변수
DEPLOY_BRANCH 기본 main. 다른 브랜치를 배포할 때만 쓴다
서비스: solution-backend · solution-worker · solution-prerender · solution-site
admin-backend · admin-frontend (프로필 admin, 기본 기동에서 빠져 있다)
solution-frontend (프로필 dev, 로컬 HMR 전용 — 운영에서 띄우지 않는다)
o2o-web4ai-solution-backend 처럼 컨테이너명으로 적어도 된다
★ solution-backend·solution-worker·admin-backend 는 이미지가 한 벌이다. 하나를 빌드하면 나머지도 새 이미지로
갈아끼워야 한다 — 안 그러면 옛 코드로 도는 컨테이너가 남는데, 셋 다 "살아 있음" 이라
화면상으로는 배포가 끝난 것처럼 보인다. --only 는 그걸 알고 건너뛸 때만 쓴다.
USAGE
}
while [ $# -gt 0 ]; do
case "$1" in
for arg in "$@"; do
case "$arg" in
--no-pull) PULL=0 ;;
--only) ONLY=1 ;;
-h|--help) usage; exit 0 ;;
-*) echo "모르는 옵션: $1" >&2; usage >&2; exit 2 ;;
*) TARGETS+=("${1#"$PREFIX"-}") ;; # 컨테이너명으로 불러도 받는다
--only) ONLY=1 ;;
-h|--help) echo "사용법: ./deploy.sh [--no-pull] [--only] [서비스...]"; exit 0 ;;
-*) echo "모르는 옵션: $arg" >&2; exit 2 ;;
*) TARGETS+=("${arg#o2o-web4ai-}") ;;
esac
shift
done
ALL_SVCS=$(docker compose config --services)
for t in ${TARGETS+"${TARGETS[@]}"}; do
grep -qx "$t" <<<"$ALL_SVCS" || {
echo "그런 서비스가 없다: $t" >&2
echo "있는 것: $(tr '\n' ' ' <<<"$ALL_SVCS")" >&2
exit 2
}
done
# ── 코드 ────────────────────────────────────────────────────────────
# 배포 서버의 작업트리는 main 의 **사본**이지 작업 공간이 아니다. 그래서 머지(pull)가 아니라
# origin/$BRANCH 로 하드 리셋한다 — 밖에서 force-push 가 나도 --ff-only 로 막히지 않고,
# 서버에서 누가 손댄 흔적이 다음 배포까지 살아남지 않는다.
#
# ★ fetch 가 실패하면 **리셋하지 않는다.** 이 서버엔 gitea 자격증명이 없어 fetch 가 죽는데,
# 그 상태의 origin/$BRANCH 는 마지막으로 fetch 된 낡은 ref 다.
# 실측(2026-09-01 킹서버): HEAD=9b4fe40 인데 origin/main=4871e50 — 믿고 리셋하면 한 커밋
# 롤백된다. 그러고도 빌드는 성공하고 컨테이너는 뜬다. 조용히 틀리는 종류다.
#
# ★ git clean 은 하지 않는다. .env 와 nginx/site.conf 는 추적되지 않는 파일이고 서버마다
# 다르다 — reset --hard 는 이 둘을 건드리지 않지만 clean 은 지운다.
if [ "$PULL" = 1 ]; then
echo "▶ git fetch origin $BRANCH"
if git fetch --prune origin "$BRANCH" 2>&1; then
DIRTY=$(git status --porcelain)
if [ -n "$DIRTY" ]; then
echo " ! 작업트리 변경을 버린다:"
sed 's/^/ /' <<<"$DIRTY"
fi
echo "▶ git reset --hard origin/$BRANCH"
git reset --hard "origin/$BRANCH"
else
echo " ! fetch 실패 — 리셋을 건너뛰고 디스크에 있는 코드 그대로 간다." >&2
echo " origin/$BRANCH 가 낡았을 수 있어 그걸로 리셋하면 배포가 조용히 롤백된다." >&2
echo " (밖에서 밀어넣었으면 이대로 두면 되고, 자동화하려면 gitea 배포키를 건다)" >&2
fi
git diff --quiet && git diff --cached --quiet || { echo "서버 변경을 먼저 정리하세요" >&2; exit 1; }
git pull --ff-only origin "${DEPLOY_BRANCH:-main}"
fi
echo "▶ 지금 코드: $(git log --oneline -1)"
# ── 대상 정하기 ─────────────────────────────────────────────────────
if [ ${#TARGETS[@]} -eq 0 ]; then
SVCS=() # 빈 인자 = compose 가 전부로 해석한다
echo "▶ 대상: 전체"
else
SVCS=("${TARGETS[@]}")
# 백엔드 하나를 건드리면 같은 이미지를 쓰는 형제도 함께 갈아끼운다.
if [ "$ONLY" = 0 ]; then
for t in "${TARGETS[@]}"; do
for b in "${BACKEND_SVCS[@]}"; do [ "$t" = "$b" ] || continue
for sib in "${BACKEND_SVCS[@]}"; do
printf '%s\n' "${SVCS[@]}" | grep -qx "$sib" || {
SVCS+=("$sib")
echo " + $sib — 같은 이미지를 쓴다(옛 코드로 남지 않게 함께 간다)"
}
done
done
done
fi
echo "▶ 대상: ${SVCS[*]}"
[ ${#TARGETS[@]} -gt 0 ] || TARGETS=(solution-backend solution-worker solution-site)
RUNNING=$(docker compose ps --services --status running)
if [ "$ONLY" = 0 ]; then
case " ${TARGETS[*]} " in
*" solution-backend "*|*" solution-worker "*)
TARGETS+=(solution-backend solution-worker)
if grep -qx admin-backend <<<"$RUNNING"; then TARGETS+=(admin-backend); fi ;;
esac
fi
# ── 빌드 · 교체 ─────────────────────────────────────────────────────
# build 절이 없는 서비스(node:24-alpine · nginx:alpine)는 build 가 조용히 건너뛴다.
echo "▶ build"
docker compose build ${SVCS+"${SVCS[@]}"}
echo "▶ up -d"
docker compose up -d --force-recreate ${SVCS+"${SVCS[@]}"}
echo
SERVICES=()
for target in "${TARGETS[@]}"; do
case " ${SERVICES[*]-} " in *" $target "*) ;; *) SERVICES+=("$target");; esac
done
# site의 렌더러도 worker 이미지에 들어간다.
case " ${SERVICES[*]} " in
*" solution-site "*) case " ${SERVICES[*]} " in *" solution-worker "*) ;; *) SERVICES+=(solution-worker);; esac ;;
esac
docker compose build "${SERVICES[@]}"
docker compose up -d --no-deps --force-recreate "${SERVICES[@]}"
docker compose ps
echo
echo "로그: ./log.sh"

View File

@ -28,8 +28,12 @@ x-common-env: &common-env
# ★ 기본값은 localhost 다. 운영 도메인을 기본으로 두면 .env 를 안 채운 로컬 빌드가
# 조용히 운영 주소를 번들에 굽는다(실측 2026-09-03: 로컬 링크가 킹서버로 갔다).
SITE_PUBLIC_HOST: ${SITE_PUBLIC_HOST:-localhost}
SITE_PAYLOAD_DIR: /app/out/payloads
SITE_OUTPUT_DIR: /app/out/sites
# ★ 렌더러(solution/site/scripts/prerender.ts)가 songs·out 디렉토리를 **자기 파일 위치
# 기준 상대경로**로 찾는다(SITE_ROOT = dist/prerender/../..) — 워커 컨테이너 안에서 그
# 렌더러를 직접 띄우므로(render_service.py) 세 디렉토리가 실제 설치 자리
# (/app/solution/site/) 아래 나란히 있어야 한다. 아래 볼륨 마운트와 짝이 맞아야 한다.
SITE_PAYLOAD_DIR: /app/solution/site/payloads
SITE_OUTPUT_DIR: /app/solution/site/out
# ★ 프리렌더와 같은 값이어야 한다. 어긋나면 색인 통보가 403 이다.
INDEXNOW_KEY: ${INDEXNOW_KEY:-}
@ -48,10 +52,10 @@ services:
# ★ 크론은 이 컨테이너에서만 돈다. 프로세스가 여럿이면 같은 시각에 중복 실행된다.
SCHEDULER_ENABLED: "1"
volumes:
- ./solution/site/payloads:/app/out/payloads
# 노래 파일. payload 와 나란히 둔다 — 백엔드가 mp3 를 여기 떨구면 프리렌더가
# 사이트 디렉토리로 복사한다(services/song_service · site/scripts/prerender.ts).
- ./solution/site/songs:/app/out/songs
- ./solution/site/payloads:/app/solution/site/payloads
# 노래 파일. payload 와 나란히 둔다 — 백엔드가 mp3 를 여기 떨구면 워커가 렌더러를
# 돌릴 때 사이트 디렉토리로 복사된다(services/song_service · site/scripts/prerender.ts).
- ./solution/site/songs:/app/solution/site/songs
# ★ 스키마 마이그레이션 SQL. 이미지에 굽지 않고 마운트한다 — 파일이 자주 늘고,
# 이미 세운 DB 를 따라오게 하는 것이 목적이라 코드 배포와 별개로 돌 수 있어야 한다.
- ./postgres-init:/app/postgres-init:ro
@ -64,13 +68,17 @@ services:
driver: json-file
options: { max-size: "10m", max-file: "5" }
# ★ BUILD·ROLLBACK 잡이 렌더러(solution/site)를 subprocess 로 직접 돌린다
# (services/render_service.py) — 예전에 solution-prerender 컨테이너가 하던 일이다.
# 그래서 이 서비스만 **다른 이미지**(Dockerfile.worker, Node 런타임 + 컴파일된 렌더러
# 포함)를 쓴다. solution-backend·admin-backend 는 그 Node 를 쓸 일이 없다.
solution-worker:
build:
context: .
dockerfile: solution/backend/Dockerfile
image: o2o-web4ai-backend
dockerfile: solution/backend/Dockerfile.worker
image: o2o-web4ai-worker
container_name: o2o-web4ai-solution-worker
command: ["python", "worker_main.py"]
command: ["sh", "-c", "node /app/solution/site/dist/prerender/prerender.js --seed-assets --out=/app/solution/site/out && exec python worker_main.py"]
env_file:
- .env
environment:
@ -79,15 +87,20 @@ services:
WORKER_CONCURRENCY: ${WORKER_CONCURRENCY:-1}
JOB_DEADLINE_SEC: ${JOB_DEADLINE_SEC:-900}
JOB_LEASE_SEC: ${JOB_LEASE_SEC:-120}
# 렌더러 subprocess 가 굽는 동안 기다리는 시간(사진 내려받기 포함). BUILD 의
# job_deadline_sec 보다 짧아야 한다 — 안 그러면 잡 전체가 먼저 타임아웃된다.
RENDER_TIMEOUT_SEC: ${RENDER_TIMEOUT_SEC:-180}
# 이미지의 HEALTHCHECK 는 API 용(HTTP :9800)이다. 워커는 포트가 없어 그대로 두면 늘 unhealthy 다.
healthcheck:
disable: true
volumes:
- ./solution/site/payloads:/app/out/payloads
# 노래 파일. payload 와 나란히 둔다 — 백엔드가 mp3 를 여기 떨구면 프리렌더가
- ./solution/site/payloads:/app/solution/site/payloads
# 노래 파일. payload 와 나란히 둔다 — 백엔드가 mp3 를 여기 떨구면 렌더
# 사이트 디렉토리로 복사한다(services/song_service · site/scripts/prerender.ts).
- ./solution/site/songs:/app/out/songs
- site-out:/app/out/sites:ro
- ./solution/site/songs:/app/solution/site/songs
# ★ 이제 이 컨테이너가 굽는 쪽이다 — 읽기전용이 아니다(예전 solution-prerender 가
# 쓰던 자리를 그대로 이어받는다).
- site-out:/app/solution/site/out
extra_hosts:
- "host.docker.internal:host-gateway"
stop_grace_period: 300s
@ -124,10 +137,10 @@ services:
start_period: 20s
retries: 3
volumes:
- ./solution/site/payloads:/app/out/payloads
- ./solution/site/payloads:/app/solution/site/payloads
# 노래 파일. payload 와 나란히 둔다 — 백엔드가 mp3 를 여기 떨구면 프리렌더가
# 사이트 디렉토리로 복사한다(services/song_service · site/scripts/prerender.ts).
- ./solution/site/songs:/app/out/songs
- ./solution/site/songs:/app/solution/site/songs
ports:
# ★ 내부망에만 연다. 0.0.0.0 으로 열면 API 를 가른 의미가 없다.
- "${ADMIN_API_BIND:-127.0.0.1}:${ADMIN_API_PORT_PUBLIC:-9801}:9801"
@ -140,48 +153,6 @@ services:
driver: json-file
options: { max-size: "10m", max-file: "5" }
# 발행 사이트를 굽는다. **굽기만 한다** — 서빙은 solution-site(nginx)가 맡는다.
#
# ★ 사장님 앱 dev 서버는 여기서 빠졌다. 운영에 `vite dev` 를 띄우면 요청마다 트랜스파일하고
# 기동이 npm install 네트워크에 의존하고 /src 원본이 그대로 나간다. 번들은 solution-site
# 이미지가 굽는다(nginx/Dockerfile). 로컬에서 HMR 이 필요하면 `--profile dev`.
solution-prerender:
image: node:24-alpine
container_name: o2o-web4ai-solution-prerender
working_dir: /app
command:
- sh
- -c
- |
cd /app
# ★ `-d node_modules` 로 판단하면 안 된다. 익명 볼륨은 빈 디렉토리로 이미 존재해서
# 설치를 건너뛰고 `vite: not found`(exit 127)로 죽는다.
[ -x node_modules/.bin/vite ] || npm install
exec node solution/site/scripts/watch-payloads.mjs
environment:
INDEXNOW_KEY: ${INDEXNOW_KEY:-}
# ★ 발행 호스트를 프론트 .env 에 따로 적지 않는다 — 루트 .env 의 SITE_PUBLIC_HOST 를
# 그대로 흘려보낸다. 두 곳에 적으면 canonical 과 화면 주소가 조용히 갈라진다.
VITE_PUBLISH_HOST: ${SITE_PUBLIC_HOST:-localhost}
volumes:
- ./package.json:/app/package.json
- ./package-lock.json:/app/package-lock.json
- ./tsconfig.base.json:/app/tsconfig.base.json
- ./solution:/app/solution
- ./admin:/app/admin
# ★ node_modules 는 컨테이너 것을 쓴다. 호스트가 macOS(arm64-darwin)라 그 안의
# rollup·esbuild 네이티브 바이너리를 리눅스 컨테이너가 못 쓴다.
- /app/node_modules
- /app/solution/site/node_modules
- /app/solution/frontend/node_modules
- /app/admin/frontend/node_modules
# ★ 산출물은 named volume. 호스트 경로면 재배포로 코드를 갈아엎는 순간 전 사이트가 404 다.
- site-out:/app/solution/site/out
restart: unless-stopped
logging:
driver: json-file
options: { max-size: "10m", max-file: "5" }
# 사장님 앱 dev 서버 + 발행본 정적서버(:3001). **로컬 전용**이다 — `--profile dev`.
# 운영에서 이게 뜨면 안 된다(위 solution-prerender 주석).
solution-frontend:
@ -294,7 +265,7 @@ services:
# 앞단 프록시를 세울 거면 여기서 포트만 옮기고 프록시가 이쪽을 가리키게 한다.
- "${SITE_HTTP_BIND:-0.0.0.0}:${SITE_HTTP_PORT:-80}:80"
depends_on:
- solution-prerender
- solution-backend
restart: unless-stopped
logging:
driver: json-file

View File

@ -1,5 +1,8 @@
# ARCHITECTURE
> 2026-09-15: 현재 발행 실행·산출물 버전·배포는 [PUBLISH_VERSION.md](PUBLISH_VERSION.md).
> 아래의 별도 프리렌더 컨테이너·폴링·전체 재굽기 설명은 이전 구조다.
제품 판단은 [PRODUCT.md](PRODUCT.md), 배포 절차는 [DEPLOY.md](DEPLOY.md),
에이전트가 밟기 쉬운 함정 목록은 [AGENTS.md](../AGENTS.md). 여기는 **구조와 경계**만 다룬다.

View File

@ -1,5 +1,8 @@
# 배포 · 스토리지
> 2026-09-15 이후 절차는 [PUBLISH_VERSION.md](PUBLISH_VERSION.md)를 따른다.
> 기존 사이트 전체 재굽기는 하지 않는다. 최초 전환 때 구 프리렌더를 중지한다.
> **현재 결정 (2026-08-31): 발행 사이트는 서버 안에서 nginx 가 정적 서빙한다.**
> Azure Blob 은 코드에 있으나 **켜지 않는다**(`AZURE_STORAGE_CONNECTION_STRING` 비움).
> 클라우드는 고도화 때 붙인다 — 근거는 [ARCHITECTURE.md 3절](ARCHITECTURE.md).

View File

@ -1,5 +1,15 @@
# 개발 일지
## 2026-09-15 — 워커 렌더·발행 버전·예약 안내·미리보기 대기
- 상시 프리렌더를 제거하고 워커가 컴파일된 Node 렌더러를 실행한다.
- 버전별 HTML을 보존하고 게이트 통과 뒤 공개 링크를 전환한다. 재시도는 저장된 성공본을 사용한다.
- 예약 전 확인을 이용안내에 통합하고 iframe 렌더 완료까지 스피너를 표시한다.
- 배포는 기존 HTML과 목업을 재굽지 않는다. 상세: [PUBLISH_VERSION.md](PUBLISH_VERSION.md).
- 읽기 생성 토큰 상한을 늘리고 추첨 배열을 고정해 반복 렌더를 방지한다.
- 편집기 주소는 /builder?placeId=…로 통일한다. 옛 step=editor 주소는 ID 복원 후 정정한다.
- 검증: 사이트 81건, 백엔드 발행·롤백·서치콘솔 45건 통과. 빌더·사이트 빌드 통과.
무엇을 왜 바꿨는지 날짜순으로 남긴다. 새 항목을 **위에** 추가한다.
결론과 배경은 각 문서가 단일 출처다 — 여기에는 요약과 링크만 둔다.

32
docs/PUBLISH_VERSION.md Normal file
View File

@ -0,0 +1,32 @@
# 발행 버전과 워커 (2026-09-15)
이 문서가 이전 문서의 프리렌더 상시 기동·전체 재굽기 절차를 대체한다.
`BUILD → snapshot → payload → Node 렌더 → 결과 게이트 → 공개 링크 전환 → DB 기록`
- Python은 HTML을 만들지 않는다. 미리 컴파일된 Node를 실행하고 JSON 보고서만 읽는다.
- 워커 이미지에 Node와 렌더러를 포함한다. 실행 중 npm 설치·번들 빌드는 없다.
- 공유 볼륨의 파일 잠금으로 렌더·공개 전환을 직렬화한다. 수집 등 다른 잡은 동시 실행한다.
- `out/versions/<slug>/<version>`에 성공한 HTML과 렌더 보고서를 보존한다.
- `out/s/<slug>`는 공개 버전의 상대 심볼릭 링크다. 게이트 통과 후 전환한다.
- 성공한 버전은 재시도·롤백 때 다시 쓰지 않는다. 기존 일반 디렉토리는 첫 재발행 때 legacy로 보존한다.
- 배포 시 HTML·기존 HTML의 자산 주소를 수정하지 않는다. 공용 자산과 미리보기 셸만 준비한다.
- 목업과 보관 버전의 참조 자산도 삭제 대상에서 제외한다. versions는 Azure 공용 업로드에서 제외한다.
- 롤백 API: `POST /v1/place/{place_id}/site/version/rollback`, `target_version`. 소유권 검사와 BUILD 중복 방지 키를 공유한다.
- 로컬 공개 전환과 DB/Azure는 단일 트랜잭션이 아니다. 외부 저장소·DB 실패 시 재시도 및 운영 확인이 필요하다.
- 최초 일반 디렉토리→링크 전환은 두 rename 사이 짧은 공백이 가능하다. 이후 링크 교체는 원자적이다.
## 배포
1. 진행 중 잡·서버 변경·목업 및 참조 자산 해시를 확인하고 site-out을 백업한다.
2. backend·worker·site 이미지를 빌드한다. admin은 기본 대상이 아니다.
3. 기존 worker와 solution-prerender를 중지한 뒤 새 worker를 기동한다. 두 렌더러를 동시에 실행하지 않는다.
4. API·미리보기·테스트 발행을 확인하고 목업 해시를 대조한다. 전체 재굽기·republish_all은 실행하지 않는다.
워커 경로: `SITE_PAYLOAD_DIR=/app/solution/site/payloads`, `SITE_OUTPUT_DIR=/app/solution/site/out`.
DB 테이블 추가는 없다. 기존 버전·잡·발행 로그를 사용한다.
## UI
예약 전 확인과 요약을 이용안내 및 예약에 통합한다. 별도 요약 섹션과 예약 카드의 중복 규정은 제거한다.
빌더 미리보기는 iframe 내부 렌더 완료 신호까지 스피너를 표시한다. 출처·iframe을 확인하고 12초 상한을 둔다.

View File

@ -93,7 +93,7 @@ CREATE TABLE IF NOT EXISTS public.users (
-- ============================================================
CREATE TABLE IF NOT EXISTS public.jobs (
job_id uuid PRIMARY KEY DEFAULT gen_random_uuid(), -- ★ 이 표만 server_default 가 꼭 필요하다 — 큐 전이가 raw SQL(RETURNING)이라 ORM 의 파이썬 default 가 안 먹는다
job_type SMALLINT NOT NULL, -- JobType: 1=collect 2=vision 3=copy 4=build 5=local_sync 6=ai_check
job_type SMALLINT NOT NULL, -- JobType: 1=collect 2=vision 3=copy 4=build 5=local_sync 6=ai_check 7=song 8=rollback
status SMALLINT NOT NULL DEFAULT 1, -- JobStatus: 1=pending 2=running 3=done 4=dead
priority SMALLINT NOT NULL DEFAULT 100, -- 낮을수록 우선
payload JSONB NOT NULL DEFAULT '{}'::jsonb,

View File

@ -0,0 +1,70 @@
# 워커 전용 이미지 — solution-backend(:9800)·admin-backend(:9801) 와 **다른 이미지**다.
#
# ★ 왜 갈랐나 (프리렌더를 워커 실행으로 통합, 2026-09-15)
# BUILD·ROLLBACK 잡은 이제 컴파일된 Node 렌더러(solution/site)를 subprocess 로 직접
# 돌린다(services/render_service.py) — 예전에 별도 컨테이너(solution-prerender)가 하던
# 일이다. 그 렌더러가 필요한 건 **워커뿐**이다. Dockerfile(api/admin 겸용)에 Node 를
# 같이 넣으면 API 를 여는 요청만 받는 컨테이너에도 쓰지 않는 Node 런타임과 렌더러
# 번들이 실려 나간다 — 이미지가 커지고 공격 표면도 는다.
#
# ★ 기동·잡 실행 중에 npm install 을 하지 않는다. site-builder 스테이지가 이미지 빌드
# 시점에 한 번 굽고, 최종 이미지는 컴파일된 산출물만 COPY 한다.
# ★ node_modules 는 안 들어간다 — solution/site/vite.config.ts 가 SSR 번들에
# `ssr.noExternal: true` 로 react 등 의존성까지 전부 접어 넣는다(실측: node_modules 를
# 지우고 실행해도 그대로 돈다, dist/prerender/prerender.js 단일 파일 1.8MB).
#
# ★ 빌드 컨텍스트는 solution-backend 와 같은 **레포 루트**다 — solution/site 와
# solution/backend 를 한 이미지에 담아야 한다.
# ── 1단계: 렌더러 컴파일 (Node) ──────────────────────────────────────────────
FROM node:24-bookworm AS site-builder
WORKDIR /app
COPY package.json package-lock.json tsconfig.base.json ./
COPY solution/shared/package.json solution/shared/
COPY solution/frontend/package.json solution/frontend/
COPY solution/site/package.json solution/site/
COPY admin/frontend/package.json admin/frontend/
# ★ npm workspaces 는 루트 package.json 의 workspaces 목록에 있는 자리마다 package.json 을
# 요구한다 — site 만 빌드해도 4개를 전부 COPY 해야 npm ci 가 성공한다(nginx/Dockerfile 과 같다).
RUN npm ci
COPY solution/shared ./solution/shared
COPY solution/site ./solution/site
RUN npm run build:client -w @o2o/site \
&& npm run build:prerender -w @o2o/site
# ── 2단계: Node 런타임만 (바이너리를 뽑아 쓴다) ──────────────────────────────
# ★ python:3.12-slim 과 같은 계열(Debian bookworm)의 태그를 써야 한다 — glibc ABI 가
# 어긋나면 바이너리만 복사해서는 못 돈다("cannot execute binary file" 류로 죽는다).
FROM node:24-bookworm-slim AS node-runtime
# ── 3단계: 최종 워커 이미지 ───────────────────────────────────────────────
FROM python:3.12-slim-bookworm
WORKDIR /app
COPY solution/backend/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# ★ yanolja_adapter.py 가 Playwright 로 페이지를 렌더링한다(수집 파이프라인, 워커 전용 경로) —
# 패키지(pip)만으로는 브라우저 실행 파일이 없다. --with-deps 가 Chromium 이 필요로 하는
# 시스템 라이브러리(libnss3 등)까지 apt 로 같이 깐다.
RUN playwright install --with-deps chromium
# Node 바이너리만 옮겨 온다 — npm·corepack 은 쓰지 않는다(빌드는 site-builder 스테이지가
# 이미 끝냈다). /usr/local/bin/node 하나로 `node dist/prerender/prerender.js` 를 돌리는
# 데 충분하다(실측: 아래 COPY 만으로 `node --version` 과 렌더 스모크 테스트가 통과한다).
COPY --from=node-runtime /usr/local/bin/node /usr/local/bin/node
COPY solution/backend ./solution/backend
# ★ SITE_ROOT(solution/site/scripts/prerender.ts)가 자기 파일 위치 기준 상대경로로
# payloads·songs·out 을 찾는다 — dist·public 이 이 자리(/app/solution/site/)에 있어야
# 워커가 컨테이너 안에서 렌더러를 그대로 실행할 수 있다.
COPY --from=site-builder /app/solution/site/dist ./solution/site/dist
COPY --from=site-builder /app/solution/site/public ./solution/site/public
ENV APP_ENV=local
ENV PYTHONPATH=/app/solution/backend
WORKDIR /app/solution/backend
# 워커는 포트가 없다 — 이미지 공통 HEALTHCHECK 를 두지 않는다(compose 가 disable 한다).
CMD ["python", "worker_main.py"]

View File

@ -389,6 +389,7 @@ class PublishAction(CodeEnum):
REBUILD = 3
SUSPEND = 4
RESUME = 5
ROLLBACK = 6 # 예전 버전으로 공개 주소를 되돌림 — services/rollback_service.py
class PublishResult(CodeEnum):
@ -434,6 +435,7 @@ class JobType(CodeEnum):
LOCAL_SYNC = 5 # 지역 정보 갱신 — 행정구역 코드 단위(같은 지역 사이트 50개여도 1회)
AI_CHECK = 6 # AI 검색 노출 점검
SONG = 7 # 이 숙소의 노래 한 곡 (가사 Gemini → 작곡 Suno). 발행이 이 잡을 건다
ROLLBACK = 8 # 예전 버전 스냅샷으로 다시 굽고 공개 주소를 그 버전으로 되돌림
class JobStatus(CodeEnum):

View File

@ -166,7 +166,7 @@ def fake_renderer(monkeypatch, tmp_path_factory):
필요한가
발행 게이트는 이제 **실제로 나갈 HTML** 보고 판정한다. HTML Node 렌더러가
굽고, BUILD 잡은 결과 보고서를 기다린다(services/render_report.wait_for).
굽고, BUILD 잡은 렌더러 subprocess 직접 돌린다(services/render_service.render_site).
파이썬 테스트 환경에는 Node 렌더러가 없으므로, payload 읽어 보고서를 만들어 주는
대역을 끼운다 여기서 검사하려는 **백엔드가 보고서를 어떻게 처리하는가** .
@ -175,8 +175,9 @@ def fake_renderer(monkeypatch, tmp_path_factory):
벌로 두면 어긋나고, 어긋난 아무도 모르는 원래 문제였다.
"""
import json
from pathlib import Path
from services import render_report, site_payload
from services import render_report, render_service, site_payload
payload_dir = tmp_path_factory.mktemp("payloads")
monkeypatch.setattr(site_payload, "payload_dir", lambda: payload_dir)
@ -229,13 +230,16 @@ def fake_renderer(monkeypatch, tmp_path_factory):
count += sum(1 for m in payload.get("media") or [] if long(m.get("alt")))
return count
async def _wait_for(slug, site_version, timeout_sec, poll_sec=1.0):
path = payload_dir / f"{slug}.json"
async def _render_site(payload_path, site_version, timeout_sec):
path = Path(payload_path)
slug = path.stem
if not path.is_file():
return None
raise render_service.RenderFailed(f"payload 파일이 없다: {payload_path}")
payload = json.loads(path.read_text(encoding="utf-8"))
if payload["site"]["version"] != site_version:
return None
raise render_service.RenderFailed(
f"버전이 다르다(payload={payload['site']['version']} 요청={site_version})"
)
place = payload.get("place") or {}
count = _count(payload)
# ★ 고유 콘텐츠 0건이면 렌더러는 **페이지를 쓰지 않는다**
@ -276,5 +280,8 @@ def fake_renderer(monkeypatch, tmp_path_factory):
"error": None,
}
monkeypatch.setattr(render_report, "wait_for", _wait_for)
monkeypatch.setattr(render_service, "render_site", _render_site)
async def _activate_site(slug, site_version):
return None
monkeypatch.setattr(render_service, "activate_site", _activate_site)
return payload_dir

View File

@ -45,6 +45,10 @@ class ISiteCRUD(ABC):
async def get_version(self, cdb: AsyncSession, site_id, site_version_id) -> Tuple[ErrorType, site_versions]:
pass
@abstractmethod
async def get_version_by_number(self, cdb: AsyncSession, site_id, version: int) -> Tuple[ErrorType, site_versions]:
pass
@abstractmethod
async def finish_version(self, cdb: AsyncSession, site_version_id, data: dict) -> Tuple[ErrorType, int]:
pass
@ -189,6 +193,31 @@ class SiteCRUD(ISiteCRUD):
LOG.e_no_callstack(ex)
return ErrorType.DB_RUN_FAILED, None
async def get_version_by_number(self, cdb: AsyncSession, site_id, version: int) -> Tuple[ErrorType, site_versions]:
"""롤백 대상 조회 — site_versions.version(사람이 보는 번호) 로 찾는다.
site_version_id(uuid) 아니다. 화면·API 버전 번호로 고르는 자연스럽고,
번호가 out/versions/<slug>/<version>/ 디렉토리 이름이다(prerender.ts)."""
try:
query = (
select(site_versions)
.where(
site_versions.site_id == site_id,
site_versions.version == version,
site_versions.deleted == False, # noqa: E712
)
.limit(1)
)
err_type, rows = await DB_SESSION_MNG.execute(cdb, query)
if err_type != ErrorType.SUCCESS:
return err_type, None
if len(rows) != 1:
return ErrorType.DB_INVALID_KEY, None
return ErrorType.SUCCESS, rows[0]
except Exception as ex:
LOG.e_no_callstack(ex)
return ErrorType.DB_RUN_FAILED, None
async def finish_version(self, cdb: AsyncSession, site_version_id, data: dict) -> Tuple[ErrorType, int]:
"""빌드 결과를 버전에 기록한다(BUILT 또는 FAILED)."""
try:

View File

@ -36,6 +36,17 @@ class Res_StartBuild(Res_WebPacketProtocol):
created: bool = True
class Req_Rollback(SiteProtocol):
"""예전 버전으로 공개 주소를 되돌린다.
재굽기가 아니다 대상 버전이 디스크에 아직 있으면 심볼릭 링크만 돌린다. 지워졌으면
(보관 정책, prerender.ts pruneOldVersions) site_versions.snapshot 으로 다시 굽고 나서
돌린다. 어느 경우든 게이트를 다시 통과해야 한다(사장님이 이미 확인한 값이라 대개는
그대로 통과한다)."""
target_version: int
class SiteVersionData(WebPacketProtocol):
model_config = ConfigDict(from_attributes=True)

View File

@ -7,6 +7,7 @@ from common.models.gmodel import PageParams, UserInfo
from router.v1.validator.dependencies import IsValidAccessToken, RemoveNoneResponse
from services.site_service import SiteService
from .protocol import (
Req_Rollback,
Req_SiteSlug,
Req_SiteStatus,
Req_SiteTemplate,
@ -178,6 +179,20 @@ async def site_preview(
return JSONResponse(content=payload)
@router.post(
path="/version/rollback",
response_model=Res_StartBuild,
summary="예전 버전으로 되돌리기(비동기)",
description="target_version 을 다시 공개 주소로 내보낸다. 재수집·재생성을 하지 않는다 — "
"그 버전이 발행될 때 박제된 snapshot 을 그대로 다시 굽는다. 렌더러가 그 사이 "
"바뀌었을 수 있어 게이트는 다시 통과해야 한다. 실패하면 지금 공개된 버전은 그대로다.",
)
async def rollback_version(
place_id: UUID, req: Req_Rollback, service: SiteService = Depends(), user_info: UserInfo = Depends(IsValidAccessToken)
):
return RemoveNoneResponse(await service.start_rollback(user_info, str(place_id), req))
@router.get(path="/version/list", response_model=Res_SiteVersions, summary="빌드 버전 목록")
async def list_versions(place_id: UUID, service: SiteService = Depends(), user_info: UserInfo = Depends(IsValidAccessToken)):
return RemoveNoneResponse(await service.list_versions(user_info, str(place_id)))

View File

@ -22,7 +22,7 @@ def is_configured() -> bool:
def output_dir() -> Path:
return Path(os.environ.get("SITE_OUTPUT_DIR", "/app/out/sites"))
return Path(os.environ.get("SITE_OUTPUT_DIR", "/app/solution/site/out"))
def _content_type(path: Path) -> str:
@ -104,7 +104,7 @@ def _upload_shared(container, root: Path, prefix: str) -> set[str]:
for entry in sorted(root.iterdir()):
# `s/` 는 사이트별 디렉터리다 — 발행한 사이트 하나만 따로 올린다.
# (여기서 함께 올리면 한 명이 발행할 때마다 전체 사이트를 다시 올리게 된다.)
if entry.name.startswith(".") or entry.name == SITE_ROOT_DIR:
if entry.name.startswith(".") or entry.name in {SITE_ROOT_DIR, "versions"}:
continue
if entry.is_dir():
uploaded |= _upload_tree(container, root, entry.name, prefix)

View File

@ -33,7 +33,7 @@ from services import (
azure_static,
indexnow,
publish_gate,
render_report,
render_service,
seo_keywords,
site_payload,
site_thumbnail,
@ -46,9 +46,9 @@ from services.snapshot import build_snapshot
_site_crud = SiteCRUD()
_place_crud = PlaceCRUD()
# 렌더러가 이 버전을 굽고 보고서를 돌려줄 때까지 기다리는 시간.
# ★ 넉넉해야 한다. 짧으면 멀쩡한 발행이 "렌더 대기 초과"로 실패한다 —
# 렌더러는 payload 를 2초 주기로 보고, 사이트 하나 굽는 데 1초 남짓 걸린다.
# 렌더러 subprocess 가 끝나기를 기다리는 시간(사진 내려받기 포함).
# ★ 넉넉해야 한다. 짧으면 멀쩡한 발행이 "렌더 시간 초과"로 실패한다 — 처음 보는 사진을
# 내려받는 발행은 몇 초가 더 걸린다(mirrorMedia, prerender.ts).
RENDER_TIMEOUT_SEC = float(os.environ.get("RENDER_TIMEOUT_SEC") or 180)
@ -73,10 +73,13 @@ async def ensure_site(place_id: str) -> "sites":
return row
async def _load_links(place_id: str) -> list:
async def load_channel_links(place_id: str) -> list:
"""채널 링크(야놀자·네이버 플레이스·인스타…).
스냅샷에 담기지 않는 유일한 발행 재료라 여기서 읽어 payload 넘긴다.
스냅샷에 담기지 않는 유일한 발행 재료라 여기서 읽어 payload 넘긴다 재빌드(run_build)
롤백(rollback_service.run_rollback) 같은 함수를 쓴다. **스냅샷에는 싣는다**
롤백이 스냅샷으로 다시 구워도 링크는 항상 지금 확정된 것을 보여줘야 한다(끊긴 링크를
버전째 되살리면 된다).
실패해도 목록으로 진행한다 링크가 없다고 발행을 막을 이유가 없다."""
err, rows = await DB_SESSION_MNG.execute_lambda(
place_channels.DBType(),
@ -249,24 +252,25 @@ async def run_build(job: dict) -> dict:
site.status = SiteStatus.PUBLISHED.value
site.published_at = site.published_at or now
links = await _load_links(place_id)
payload_path = await emit_payload(place, snapshot, site, version, links)
links = await load_channel_links(place_id)
payload_path = await emit_payload(place, snapshot, site, version, links, publish=want_publish)
if not payload_path:
return await _fail("payload 를 쓰지 못했다 — 렌더러에 넘길 입력이 없다")
result["payload_path"] = payload_path
slug = site_payload.publish_slug(place, site)
# ---- 렌더 결과를 기다린다 ----
# ---- 렌더러를 직접 돌린다 ----
# ★ 게이트는 **실제로 나갈 HTML** 을 보고 판정해야 한다. 렌더러가 자기 산출물을 대조해
# 구조화 데이터 불일치와 고유 콘텐츠 수를 보고서로 돌려준다.
report = await render_report.wait_for(slug, version_no, RENDER_TIMEOUT_SEC)
if report is None:
# ★ payload=False(미발행)면 렌더러는 `out/versions/<slug>/<version>/` 에만 굽고 공개
# 주소(`out/s/<slug>`)는 건드리지 않는다 — emit_payload 에 실은 publish 플래그가 정한다.
try:
report = await render_service.render_site(payload_path, version_no, RENDER_TIMEOUT_SEC)
except render_service.RenderFailed as ex:
# ★ 발행하지 않는다. 페이지가 있는지 확인하지 못한 채 "발행됨"으로 남기면
# 사장님은 [사이트 열기] 를 눌러야 404 로 알게 된다.
return await _fail(
f"렌더 결과를 {RENDER_TIMEOUT_SEC}초 안에 받지 못했다 — 렌더러가 도는지 확인이 필요하다"
)
return await _fail(str(ex))
mismatches = list(report.get("mismatches") or [])
# ★ None(재지 못했다)과 0(재 봤더니 0건)을 뭉개지 않는다. 게이트는 raw 를 보고,
@ -308,8 +312,9 @@ async def run_build(job: dict) -> dict:
thumbnail_url = None
if want_publish:
try:
await render_service.activate_site(slug, version_no)
azure_result = await azure_static.publish(slug)
except azure_static.AzurePublishError as ex:
except (azure_static.AzurePublishError, render_service.RenderFailed) as ex:
return await _fail(str(ex), None, stamp)
if azure_result:
result["azure"] = azure_result
@ -383,4 +388,3 @@ async def run_build(job: dict) -> dict:
version.build_status = BuildStatus.BUILT.value
version.built_at = now
return result

View File

@ -44,7 +44,7 @@ def is_configured() -> bool:
def output_dir() -> Path:
return Path(os.environ.get("SITE_OUTPUT_DIR", "/app/out/sites"))
return Path(os.environ.get("SITE_OUTPUT_DIR", "/app/solution/site/out"))
def site_urls(slug: str) -> list[str]:

View File

@ -1,22 +1,18 @@
"""렌더 보고서 — SSG 가 실제로 페이지를 구웠는지 확인하는 창구.
필요한가
발행 잡은 payload JSON 쓰는 것까지가 끝이고, 방문자가 HTML 프론트의 SSG 굽는다.
사이가 끊겨 있었다. 프리렌더가 깨져도 DB 에는 "발행됨"으로 남고, 페이지는 없는데
아무도 그걸 모른다 사장님이 [사이트 열기] 눌러야 404 발견된다.
BUILD 잡은 payload JSON 쓰고 렌더러를 직접 돌린다(services/render_service). 렌더러는
굽는 동안 있었던 (성공/실패, 구조화 데이터 대조, 고유 콘텐츠 ) 사이트마다
`<payload_dir>/.status/<slug>.json` 남긴다 백엔드에 마운트된 디렉토리가 payload
디렉토리뿐이라 보고서도 안에 둔다.
이제 프리렌더가 사이트마다 결과를 `<payload_dir>/.status/<slug>.json` 쓴다.
백엔드에 마운트된 디렉토리가 payload 디렉토리뿐이라 보고서도 안에 둔다.
여기서 하는 가지
1. 렌더 상태 구워졌는가, 언제, 실패했으면 (사이트 조회 API 그대로 내보낸다)
2. 발행 대기 BUILD 잡이 버전의 보고서를 기다렸다가, 결과로 발행 여부를 정한다
(wait_for). 게이트는 **실제로 나갈 HTML** 보고 판정해야 한다.
여기서 하는 보고서를 읽는다.
render_service 렌더러 subprocess 기다린 **직후** 읽어 발행 여부를 정하고,
사이트 조회 API(render_status) 아무 때나 다시 읽어 "지금 이 버전이 구워져 있나" 보여준다.
읽기 전용이다. 보고서가 없거나 깨져 있어도 예외를 밖으로 내보내지 않는다
사이트 조회가 부수 산출물 때문에 실패하면 된다.
"""
import asyncio
import json
from pathlib import Path
@ -58,29 +54,6 @@ def read_report(slug: str) -> dict | None:
return report
async def wait_for(slug: str, site_version: int, timeout_sec: float, poll_sec: float = 1.0) -> dict | None:
"""이 버전의 렌더 보고서가 나올 때까지 기다린다. 시간 안에 안 나오면 None.
기다리나
발행 게이트는 **실제로 나갈 HTML** 보고 판정해야 한다. HTML 프론트 렌더러가
굽고, 렌더러는 payload 파일을 보고 도는 별도 프로세스다. 그래서 잡이 payload
보고서가 때까지 기다렸다가, 결과로 발행 여부를 정한다.
버전이 맞는 보고서만 받는다. 직전 버전 보고서를 보고 통과시키면 이번에 바뀐 값은
아무도 검사하지 않은 채로 발행된다.
BUILD 잡은 heartbeat lease 갱신하므로 여기서 기다려도 reaper 회수되지 않는다."""
deadline = asyncio.get_running_loop().time() + timeout_sec
while True:
report = read_report(slug)
if report is not None and report.get("siteVersion") == site_version:
return report
if asyncio.get_running_loop().time() >= deadline:
LOG.w(f"[render] 보고서 대기 시간 초과 slug={slug} v{site_version} ({timeout_sec}초)")
return None
await asyncio.sleep(poll_sec)
def render_status(slug: str, site_version: int | None = None) -> dict:
"""사이트 조회 API 가 그대로 내보내는 렌더 상태.

View File

@ -0,0 +1,153 @@
"""렌더러 실행 — Python 워커가 미리 컴파일된 Node 렌더러를 subprocess 로 직접 돌린다.
(프리렌더를 워커 실행으로 통합, 2026-09-15)
예전에는 `solution-prerender` 라는 별도 상시 컨테이너가 payloads/ 디렉토리를 2초마다
폴링하며 바뀐 파일을 구웠고, BUILD 잡은 `.status/<slug>.json` 나타나기를 폴링했다
(render_report.wait_for). 컨테이너 하나·폴링 겹이 전부 "굽는 걸 어떻게 아느냐"
같은 문제를 풀고 있었다 워커가 굽기를 직접 돌리면 필요 없다: subprocess
끝나는 순간이 "구워졌다" 신호다.
파일은 payload 렌더러 실행 구조화된 결과, 경계만 다룬다.
Python 여전히 HTML 만들지 않는다(ARCHITECTURE 1) 여기서 하는 일은 미리 빌드된
JS 파일 하나를 `node` 실행하고 결과 보고서(.status/<slug>.json, prerender.ts 쓴다)
읽어 돌려주는 것뿐이다. 렌더러 코드 자체는 solution/site 소유 그대로다.
워커 이미지에는 컴파일된 렌더러(`dist/client` · `dist/prerender/prerender.js`) `public/`
있으면 된다 node_modules 필요 없다(vite.config.ts `ssr.noExternal: true`, 실측:
node_modules 지우고 실행해도 그대로 돈다). 기동· 실행 중에 npm install 하지 않는다.
"""
import asyncio
import fcntl
import os
from pathlib import Path
from common.logger import LOG
from services import render_report
# 컴파일된 렌더러 진입점. Dockerfile 의 site-builder 스테이지가 여기에 굽는다.
RENDERER_ENTRY_ENV = "RENDERER_ENTRY"
DEFAULT_RENDERER_ENTRY = "/app/solution/site/dist/prerender/prerender.js"
NODE_BIN_ENV = "NODE_BIN"
DEFAULT_NODE_BIN = "node"
# 렌더러가 굽는 산출물 루트(out/). services/azure_static·indexnow 와 **같은 env** 를 본다 —
# 렌더러가 쓴 자리와 백엔드가 훑는 자리가 어긋나면 "구웠는데 없다"는 조용한 실패가 난다.
OUTPUT_DIR_ENV = "SITE_OUTPUT_DIR"
DEFAULT_OUTPUT_DIR = "/app/solution/site/out"
class RenderFailed(RuntimeError):
"""렌더러 프로세스 자체가 죽었거나(비정상 종료) 보고서를 남기지 못했다.
게이트 반려(구조화 데이터 불일치·고유 콘텐츠 0) 여기 걸린다 그건 exit code
1 이어도 보고서가 정상적으로 남으므로 호출측이 report.ok 판단한다. 예외는
"무슨 일이 있었는지조차 모른다" 경우만 위한 것이다."""
def renderer_entry() -> str:
return os.environ.get(RENDERER_ENTRY_ENV) or DEFAULT_RENDERER_ENTRY
def output_dir() -> str:
return os.environ.get(OUTPUT_DIR_ENV) or DEFAULT_OUTPUT_DIR
async def _run_subprocess(args: list[str], timeout_sec: float) -> tuple[int | None, str]:
"""같은 볼륨의 자산 대장·사이트맵은 한 프로세스만 갱신한다."""
root = Path(output_dir())
root.mkdir(parents=True, exist_ok=True)
with (root / ".render.lock").open("a") as lock:
try:
async with asyncio.timeout(timeout_sec):
while True:
try:
fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
break
except BlockingIOError:
await asyncio.sleep(0.1)
return await _run_unlocked(args, timeout_sec)
except TimeoutError:
return None, "렌더 대기 또는 실행 시간 초과"
finally:
fcntl.flock(lock, fcntl.LOCK_UN)
async def _run_unlocked(args: list[str], timeout_sec: float) -> tuple[int | None, str]:
"""렌더러 프로세스를 돌리고 (exit_code, stderr 일부) 를 돌려준다.
타임아웃이면 프로세스를 죽이고 회수한다 좀비로 남겨 워커 컨테이너의 프로세스 표를
채우면 된다. exit_code None 으로 남아 "시간 안에 안 끝났다" 구분한다."""
proc = await asyncio.create_subprocess_exec(
*args,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
try:
_stdout, stderr = await asyncio.wait_for(proc.communicate(), timeout=timeout_sec)
except (asyncio.TimeoutError, TimeoutError):
proc.kill()
# kill 후에도 반드시 wait 한다 — 안 하면 좀비 프로세스로 남는다.
await proc.wait()
return None, f"{timeout_sec:.0f}초 안에 끝나지 않아 강제 종료했다"
except asyncio.CancelledError:
if proc.returncode is None:
proc.kill()
await proc.wait()
raise
# 사유는 앞부분에 나온다(watch-payloads.mjs 의 run() 과 같은 규칙) — 스택 전체를 들 이유가 없다.
return proc.returncode, stderr.decode("utf-8", errors="replace")[:4000]
async def render_site(payload_path: str, site_version: int, timeout_sec: float) -> dict:
"""payload 파일 하나를 굽는다. 끝나면 렌더 보고서(dict)를 돌려준다.
게이트 판정은 여기서 하지 않는다 반환된 보고서의 `ok`·`mismatches`·
`uniqueContentCount` build_service.run_build 그대로 판단한다(예전과 같은 계약,
render_report.wait_for 폴링해서 얻던 것과 같은 모양이다).
멱등이다 같은 payload 파일로 다시 부르면 같은 결과가 나온다(재시도 안전). 렌더러
자신이 사이트별로 실패를 격리하므로, 이미 성공한 사이트를 다시 구워도 결과는 같다."""
slug = Path(payload_path).stem
# 재시도에서 같은 버전의 옛 성공 보고서를 이번 실행 결과로 읽지 않는다.
render_report.report_path(slug).unlink(missing_ok=True)
args = [
os.environ.get(NODE_BIN_ENV) or DEFAULT_NODE_BIN,
renderer_entry(),
f"--payload={payload_path}",
f"--out={output_dir()}",
"--stage-only",
]
try:
code, stderr = await _run_subprocess(args, timeout_sec)
except OSError as ex:
raise RenderFailed(f"렌더러 실행 실패: {type(ex).__name__}") from ex
report = render_report.read_report(slug)
if code in (0, 1) and report is not None and report.get("siteVersion") == site_version:
return report
# ★ 프로세스가 죽거나 시간 초과였는데 보고서도 없으면(사이트를 하나도 돌기 전에 죽은 경우)
# 대신 실패로 남긴다 — 안 그러면 build_service 가 "렌더 결과를 못 받았다" 는 것만 알고
# 진짜 사유(모듈 누락·OOM 등)는 워커 로그에만 남는다.
reason = (
f"렌더러가 {timeout_sec:.0f}초 안에 끝나지 않았다"
if code is None
else f"렌더러가 비정상 종료했다(exit {code})" if code != 0 else "보고서를 남기지 못했다(버전 불일치 포함)"
)
detail = f"{reason}" + (f"{stderr.strip()}" if stderr.strip() else "")
LOG.w(f"[render] {slug} v{site_version}: {detail}")
raise RenderFailed(detail)
async def activate_site(slug: str, site_version: int) -> None:
"""두 게이트를 통과한 뒤 Node가 공개 링크만 전환한다."""
args = [
os.environ.get(NODE_BIN_ENV) or DEFAULT_NODE_BIN,
renderer_entry(), f"--out={output_dir()}", f"--activate={slug}:{site_version}",
]
try:
code, _stderr = await _run_subprocess(args, 30)
except OSError as ex:
raise RenderFailed(f"공개 전환 실행 실패: {type(ex).__name__}") from ex
if code != 0:
raise RenderFailed("공개 버전 전환 실패")

View File

@ -0,0 +1,158 @@
"""예전 버전으로 되돌리기 — ROLLBACK 잡이 하는 일.
대상 버전 스냅샷 로드 payload 재조립 렌더 게이트 공개 주소 전환
재수집·재생성을 하지 않는다. run_build 다른 점이 이것 하나다 대상 버전이
박제해 snapshot(site_versions.snapshot) **그대로** 다시 payload 옮길 뿐이다.
사장님이 그때 이미 확인하고 발행했던 값이므로, 지금 fact 상태가 바뀌었어도 롤백은
시점의 값을 그대로 복원한다 "롤백했는데 최신 수정이 섞여 있다" 막는다.
그래도 게이트는 다시 돈다. 스냅샷은 그대로지만 **렌더러는 그때와 다를 있다**
( 사이 배포됐을 있다) 렌더러가 스냅샷을 어떻게 굽는지는 다시 확인해야 한다.
재굽기가 필요 없을 수도 있다 대상 버전 디렉토리가 보관 기간 안에 아직 디스크에 있으면
렌더러가 사실을 알아서 이용한다(prerender.ts publishVersion 렌더 자체는 매번 다시
하지만, 결과가 같으면 파일 내용도 같다 멱등이다). 디스크에서 지워졌어도 문제없다
snapshot 있으니 처음부터 다시 굽는다.
실패하면 지금 공개된 버전은 그대로다. render_service.render_site 실패를 던지거나
report.ok=False 심볼릭 링크를 아예 돌린다(prerender.ts publishVersion 성공한
렌더 결과에만 닿는다) 발행 파이프라인과 같은 원자성 보장이다.
"""
import os
import uuid
from common.database.db_session_manager import DB_SESSION_MNG
from common.database.model.models import places, site_publish_logs, site_versions, sites
from common.enums import (
BuildStatus,
DBWRType,
ErrorType,
PlaceCategory,
PublishAction,
PublishResult,
SiteStatus,
)
from common.logger import LOG
from common.utils.gtime import GTime
from crud.place_crud import PlaceCRUD
from crud.site_crud import SiteCRUD
from services import azure_static, indexnow, publish_gate, render_service, site_payload
from services.build_service import ensure_site, load_channel_links
_site_crud = SiteCRUD()
_place_crud = PlaceCRUD()
RENDER_TIMEOUT_SEC_ENV = "RENDER_TIMEOUT_SEC"
class RollbackAborted(RuntimeError):
"""재시도해도 소용없는 중단 — 잡의 last_error 로 남는다."""
async def _log(site_id, version_id, result: PublishResult, gate=None, actor=None):
row = site_publish_logs(
site_id=site_id,
site_version_id=version_id,
action=PublishAction.ROLLBACK.value,
result=result.value,
reject_reason=(gate.reason.value if gate is not None and gate.reason else None),
detail=(gate.as_log() if gate is not None and not gate.passed else None),
actor_user_id=uuid.UUID(actor) if actor else None,
)
await DB_SESSION_MNG.execute_lambda_run([site_publish_logs.DBType()], [lambda s: _site_crud.add_log(s, row)])
async def run_rollback(job: dict) -> dict:
"""ROLLBACK 잡 핸들러. payload: {place_id, owner_user_id, target_version, requested_by?}"""
payload = job["payload"]
place_id = payload["place_id"]
owner_user_id = payload["owner_user_id"]
target_version = int(payload["target_version"])
render_timeout_sec = float(os.environ.get(RENDER_TIMEOUT_SEC_ENV) or 180)
err, place = await DB_SESSION_MNG.execute_lambda(
places.DBType(),
DBWRType.DB_READ.value,
lambda s: _place_crud.get_place(s, uuid.UUID(owner_user_id), uuid.UUID(place_id)),
)
if err != ErrorType.SUCCESS or place is None:
raise RollbackAborted(f"사업장을 찾을 수 없다: {place_id}")
site = await ensure_site(place_id)
v_err, version = await DB_SESSION_MNG.execute_lambda(
site_versions.DBType(),
DBWRType.DB_READ.value,
lambda s: _site_crud.get_version_by_number(s, site.site_id, target_version),
)
if v_err != ErrorType.SUCCESS or version is None:
raise RollbackAborted(f"버전 {target_version} 을 찾을 수 없다")
if version.build_status != BuildStatus.BUILT.value or not version.snapshot:
raise RollbackAborted(f"버전 {target_version} 은 성공적으로 빌드된 적이 없어 되돌릴 수 없다")
if site.current_version_id == version.site_version_id:
raise RollbackAborted(f"이미 지금 공개 중인 버전이다(v{target_version})")
result = {
"place_id": place_id, "site_id": str(site.site_id),
"target_version": target_version, "site_version_id": str(version.site_version_id),
}
async def _fail(reason: str, gate: publish_gate.GateResult | None = None):
await _log(site.site_id, version.site_version_id, PublishResult.REJECTED if gate else PublishResult.FAILED,
gate, payload.get("requested_by"))
result["rolled_back"] = False
result["error"] = reason
LOG.w(f"[rollback] place={place_id} v{target_version} 실패: {reason}")
return result
# ★ snapshot 을 그대로 옮긴다 — 재수집하지 않는다(파일 머리주석 참조).
links = await load_channel_links(place_id)
payload_dict = await site_payload.prepare_site_payload(
place, version.snapshot, site, version, links, publish=True
)
payload_path = site_payload.write_payload(payload_dict)
result["payload_path"] = payload_path
try:
report = await render_service.render_site(payload_path, target_version, render_timeout_sec)
except render_service.RenderFailed as ex:
return await _fail(str(ex))
mismatches = list(report.get("mismatches") or [])
unique_count_raw = report.get("uniqueContentCount")
# ★ 렌더러가 그때와 달라졌을 수 있으므로 게이트를 다시 돈다(파일 머리주석 참조) —
# fact 검증 게이트(1차)는 건너뛴다. snapshot 은 이미 확인된 값만 담아 발행했던 것이라
# 다시 물을 것이 없다 — 여기서 또 물으면 "그때는 됐는데 지금은 안 된다"는 모순이 난다.
gate = publish_gate.evaluate(
PlaceCategory(place.category), version.snapshot.get("facts") or [], unique_count_raw, mismatches
)
result["gate"] = {"passed": gate.passed, **gate.as_log()}
if not gate.passed:
return await _fail(f"{gate.reason.name}: {gate.as_log()}", gate)
if not report.get("ok"):
return await _fail(str(report.get("error") or "렌더 실패"))
slug = site_payload.publish_slug(place, site)
try:
await render_service.activate_site(slug, target_version)
await azure_static.publish(slug)
except (render_service.RenderFailed, azure_static.AzurePublishError) as ex:
return await _fail(str(ex))
await indexnow.submit(slug)
now = GTime.UTC()
site_update = {
"status": SiteStatus.PUBLISHED.value,
"current_version_id": version.site_version_id,
"published_at": now,
}
await DB_SESSION_MNG.execute_lambda_claim(
sites.DBType(), lambda s: _site_crud.update_site(s, site.site_id, site_update)
)
await _log(site.site_id, version.site_version_id, PublishResult.SUCCESS, None, payload.get("requested_by"))
result["rolled_back"] = True
LOG.i(f"[rollback] place={place_id} v{target_version} 로 되돌림")
return result

View File

@ -39,8 +39,13 @@ from services.stay_guide import nol_stay_guide
SCHEMA_VERSION = 1
# 출력 디렉토리. 컨테이너 밖(볼륨·오브젝트 스토리지)으로 빼기 쉬우라고 env 로 둔다.
# ★ 기본값이 `solution/site/payloads` 아래인 이유 — 렌더러(prerender.ts)가 songs·out 디렉토리를
# **자기 파일 위치 기준 상대경로**로 찾는다(SITE_ROOT = dist/prerender/../..). 워커가 그
# 렌더러를 subprocess 로 직접 띄우면서(render_service.py) 세 디렉토리(payloads·songs·out)가
# 그 렌더러가 실제로 설치된 자리(`/app/solution/site/`) 아래에 나란히 있어야 한다 —
# 어긋나면 워커는 payload 를 잘 쓰는데 렌더러는 다른 곳에서 songs 를 찾다가 못 찾는다.
PAYLOAD_DIR_ENV = "SITE_PAYLOAD_DIR"
DEFAULT_PAYLOAD_DIR = "/app/out/payloads"
DEFAULT_PAYLOAD_DIR = "/app/solution/site/payloads"
# 커스텀 도메인이 없을 때 쓰는 기본 호스트. sites.domain 이 채워지면 그 값이 이긴다.
#
@ -780,11 +785,15 @@ def region_label(*addresses: str | None) -> str | None:
# ── payload 조립 ──────────────────────────────────────────────────────────
def to_site_payload(place, snapshot: dict, site, version, links) -> dict:
def to_site_payload(place, snapshot: dict, site, version, links, publish: bool = False) -> dict:
"""스냅샷 + 사이트/버전 행 + 채널 링크 → SitePayload(dict).
순수 변환 함수다. DB 파일도 건드리지 않는다 그래야 테스트가 쉽고,
같은 입력이면 언제나 같은 payload 나온다."""
같은 입력이면 언제나 같은 payload 나온다.
`publish` 렌더러(prerender.ts publishVersion)에게 "이 버전으로 공개 주소를
넘겨도 되는가"를 알리는 신호다. False(미리보기·게이트 통과 전 재빌드)면 렌더러가
`out/versions/<slug>/<version>/` 에만 굽고 `out/s/<slug>` 심볼릭 링크는 그대로 둔다."""
snapshot = snapshot or {}
snap_place = snapshot.get("place") or {}
place_id = str(_get(place, "place_id"))
@ -929,6 +938,7 @@ def to_site_payload(place, snapshot: dict, site, version, links) -> dict:
"publishedAt": published_at or updated_at,
"updatedAt": updated_at,
"version": int(_get(version, "version") or 1),
"publish": bool(publish),
},
"place": {
"name": name,
@ -1037,9 +1047,9 @@ def write_payload(payload: dict) -> str:
return str(path)
async def prepare_site_payload(place, snapshot: dict, site, version, links) -> dict:
async def prepare_site_payload(place, snapshot: dict, site, version, links, publish: bool = False) -> dict:
"""미리보기·발행 공통 보강. 요약은 DB 스냅샷이 아니라 응답/산출물에만 싣는다."""
payload = to_site_payload(place, snapshot, site, version, links)
payload = to_site_payload(place, snapshot, site, version, links, publish)
for fact in payload["facts"]:
if fact["key"] != "intro" or fact["status"] not in {s.value for s in PUBLISHABLE_FACT_STATUSES}:
continue
@ -1054,14 +1064,14 @@ async def prepare_site_payload(place, snapshot: dict, site, version, links) -> d
return payload
async def emit_payload(place, snapshot: dict, site, version, links) -> str | None:
async def emit_payload(place, snapshot: dict, site, version, links, publish: bool = False) -> str | None:
"""payload 조립 + 파일 쓰기. 실패해도 예외를 밖으로 내보내지 않는다.
발행 자체를 실패시키면 된다 게이트를 통과해 DB 남은 발행 기록은 이미 정확하고,
payload 그것을 화면으로 옮기는 부수 산출물이다. 디스크가 없거나 권한이 없어서
발행이 되돌려지는 나쁘다. 대신 경고 로그로 반드시 드러낸다."""
try:
payload = await prepare_site_payload(place, snapshot, site, version, links)
payload = await prepare_site_payload(place, snapshot, site, version, links, publish)
path = write_payload(payload)
LOG.i(
f"[payload] {payload['site']['slug']}{path} "

View File

@ -29,6 +29,7 @@ from router.v1.site.protocol import (
Req_SiteStatus,
Req_SiteTemplate,
Req_SiteTheme,
Req_Rollback,
Req_StartBuild,
Res_MySites,
Res_PublishLogs,
@ -166,7 +167,7 @@ class SiteService:
(`snapshot.build_snapshot` `site_payload.prepare_site_payload`) 그대로 거치므로,
여기서 갈릴 자리가 없다. 버전은 아직 없으니 0 으로 넘긴다 화면에 쓰인다.
"""
from services.build_service import ensure_site, _load_links
from services.build_service import ensure_site, load_channel_links
from services.site_payload import prepare_site_payload
from services.snapshot import build_snapshot
@ -175,7 +176,7 @@ class SiteService:
return None
site = await ensure_site(place_id)
links = await _load_links(place_id)
links = await load_channel_links(place_id)
snapshot = await build_snapshot(place)
# ★ version 은 None 이다. 발행 전이라 버전 행이 없고, payload 의 site.version 은
# 캐시 무효화 키라 미리보기에서는 뜻이 없다(to_site_payload 가 0 으로 떨어뜨린다).
@ -570,6 +571,35 @@ class SiteService:
res.created = created
return res
async def start_rollback(self, user_info: UserInfo, place_id: str, req: Req_Rollback) -> Res_StartBuild:
"""예전 버전으로 공개 주소를 되돌리는 잡을 큐에 넣는다.
dedupe_key 빌드와 **같은 **(`build:{place_id}`) 쓴다 롤백 도중에 발행이
끼어들거나 반대가 되면 어느 쪽이 이겼는지 없는 상태가 된다. 사이트의
공개 주소를 바꾸는 작업은 항상 하나만 활성화된다."""
res = Res_StartBuild()
err_type, _place = await self._load_place(user_info, place_id)
if err_type != ErrorType.SUCCESS:
res.result.SetResult(err_type)
return res
job_id, created = await enqueue_job(
self.queue, JobType.ROLLBACK,
{
"place_id": place_id, "owner_user_id": user_info.user_id,
"target_version": req.target_version, "requested_by": user_info.user_id,
},
dedupe_key=f"build:{place_id}",
)
if job_id is None:
res.result.SetResult(ErrorType.COLLECT_ALREADY_RUNNING)
return res
res.job_id = uuid.UUID(job_id)
res.status = JobStatus.PENDING
res.created = created
return res
async def list_versions(self, user_info: UserInfo, place_id: str) -> Res_SiteVersions:
from sqlalchemy import select

View File

@ -64,7 +64,7 @@ async def _generate_kind(client: httpx.AsyncClient, kind: str, region_label: str
{"role": "system", "content": prompts.SYSTEM_PROMPT},
{"role": "user", "content": prompts.build_prompt(kind, region_label)},
],
"max_tokens": perplexity.DEFAULT_MAX_TOKENS,
"max_tokens": _MAX_TOKENS.get(kind, perplexity.DEFAULT_MAX_TOKENS),
}
try:
payload = await perplexity.call(body, client=client)
@ -80,6 +80,15 @@ async def _generate_kind(client: httpx.AsyncClient, kind: str, region_label: str
return items, dropped
# 종류별 응답 토큰 상한. 기본(2048)으로 모자란 종류만 적는다.
#
# ★ 왜 (실측 2026-09-15) `reading` 은 30~34꼭지 × 서너 문장이라 다른 종류의 서너 배다.
# 2048 로 부르면 응답이 **문장 한가운데서 잘려** 오고, 파서는 그걸 "JSON 이 아니다" 로
# 통째로 버린다 — 여섯 지역 전부 0건이었다. 잘린 것은 재시도해도 같은 자리에서 잘린다.
# ★ 상한만 올린다. 꼭지 수를 줄이면 화면이 매번 5~6개만 뽑는 의미가 없어진다
# (`site/sections/items/ReadingSection.tsx`).
_MAX_TOKENS = {"reading": 8000}
# 사진을 무엇으로 찾을지. 종류마다 출처가 다르다.
#
# chronicle · postcard 공공데이터(TourAPI) — 장소·시설 사진. 공공누리 Type1/Type3 만

View File

@ -100,10 +100,10 @@ async def test_unverified_fact_blocks_publish(auth_headers, client, db_engine):
(필수 항목 누락은 2026-08-27 부터 막지 않는다. 그래서 여기서 걸리는 사유가 바뀌었다.)"""
h = await auth_headers("u1")
pid = await _place(client, h, "미검증펜션")
# 크롤링으로만 들어온 값 = 후보 상태
# 크롤링은 바로 노출되는 정책이다. 실제 미검증 상태를 만드는 API 출처로 검사한다.
for k, v in REQUIRED.items():
await client.post(f"/v1/place/{pid}/fact", headers=h, json={
"key": k, "value": v, "source_type": SourceType.CRAWL.value, "source_url": "https://ota.test/1"})
"key": k, "value": v, "source_type": SourceType.API.value, "source_url": "https://api.test/1"})
job_id = (await client.post(f"/v1/place/{pid}/site/build", headers=h, json={"publish": True})).json()["job_id"]
await _run()
@ -292,17 +292,17 @@ async def _build(client, h, pid, publish=True):
async def test_렌더가_실패하면_발행하지_않는다(auth_headers, client, db_engine, monkeypatch):
"""검증: 렌더러가 페이지를 굽지 못했다고 보고한다.
기대결과: FAILED. 페이지가 없는데 "발행됨"으로 남으면 사장님은 404 눌러야 안다."""
from services import render_report
from services import render_service
async def _broken(slug, site_version, timeout_sec, poll_sec=1.0):
return {"schemaVersion": 1, "slug": slug, "siteId": "", "placeId": "",
async def _broken(payload_path, site_version, timeout_sec):
return {"schemaVersion": 1, "slug": "t", "siteId": "", "placeId": "",
"siteVersion": site_version, "ok": False, "renderedAt": "2026-01-01T00:00:00Z",
"routes": 0, "bundle": "t.js", "uniqueContentCount": 5, "jsonld": [],
"mismatches": [], "error": "번들이 없다"}
h = await auth_headers("u1")
pid = await _built_place(client, h, db_engine)
monkeypatch.setattr(render_report, "wait_for", _broken)
monkeypatch.setattr(render_service, "render_site", _broken)
r = await _build(client, h, pid)
assert r["build_status"] == "FAILED"
@ -316,10 +316,10 @@ async def test_렌더가_실패하면_발행하지_않는다(auth_headers, clien
async def test_구조화데이터가_화면과_다르면_발행하지_않는다(auth_headers, client, db_engine, monkeypatch):
"""검증: 렌더러가 JSON-LD 불일치를 보고한다.
기대결과: JSONLD_MISMATCH 검색엔진에만 다른 말을 하는 페이지는 나가면 된다."""
from services import render_report
from services import render_service
async def _mismatch(slug, site_version, timeout_sec, poll_sec=1.0):
return {"schemaVersion": 1, "slug": slug, "siteId": "", "placeId": "",
async def _mismatch(payload_path, site_version, timeout_sec):
return {"schemaVersion": 1, "slug": "t", "siteId": "", "placeId": "",
"siteVersion": site_version, "ok": False, "renderedAt": "2026-01-01T00:00:00Z",
"routes": 0, "bundle": "t.js", "uniqueContentCount": 5, "jsonld": [],
"mismatches": ["telephone: '02-0000-0000' 이 화면에 없다"],
@ -327,7 +327,7 @@ async def test_구조화데이터가_화면과_다르면_발행하지_않는다(
h = await auth_headers("u1")
pid = await _built_place(client, h, db_engine)
monkeypatch.setattr(render_report, "wait_for", _mismatch)
monkeypatch.setattr(render_service, "render_site", _mismatch)
r = await _build(client, h, pid)
assert r["build_status"] == "FAILED"
@ -339,14 +339,14 @@ async def test_구조화데이터가_화면과_다르면_발행하지_않는다(
async def test_렌더_결과가_안_오면_발행하지_않는다(auth_headers, client, db_engine, monkeypatch):
"""검증: 렌더러가 죽어 보고서가 오지 않는다(타임아웃).
기대결과: FAILED. 확인하지 못한 것을 발행됨으로 남기지 않는다."""
from services import render_report
from services import render_service
async def _timeout(slug, site_version, timeout_sec, poll_sec=1.0):
return None
async def _timeout(payload_path, site_version, timeout_sec):
raise render_service.RenderFailed("렌더 결과를 받지 못했다 — 렌더러가 도는지 확인이 필요하다")
h = await auth_headers("u1")
pid = await _built_place(client, h, db_engine)
monkeypatch.setattr(render_report, "wait_for", _timeout)
monkeypatch.setattr(render_service, "render_site", _timeout)
r = await _build(client, h, pid)
assert r["build_status"] == "FAILED"

View File

@ -0,0 +1,38 @@
import asyncio
import sys
import pytest
from services import render_service
@pytest.fixture(autouse=True)
def fake_renderer(monkeypatch, tmp_path):
# 이 파일은 conftest의 렌더 대역 대신 실제 자식 프로세스 수명만 검사한다.
monkeypatch.setenv("SITE_OUTPUT_DIR", str(tmp_path))
async def test_process_success():
code, _ = await render_service._run_subprocess([sys.executable, "-c", "print(1)"], 2)
assert code == 0
async def test_timeout_releases_lock():
code, _ = await render_service._run_subprocess(
[sys.executable, "-c", "import time;time.sleep(5)"], 0.1
)
assert code is None
code, _ = await render_service._run_subprocess([sys.executable, "-c", "print(1)"], 2)
assert code == 0
async def test_cancel_releases_lock():
task = asyncio.create_task(render_service._run_subprocess(
[sys.executable, "-c", "import time;time.sleep(5)"], 10
))
await asyncio.sleep(0.1)
task.cancel()
with pytest.raises(asyncio.CancelledError):
await task
code, _ = await render_service._run_subprocess([sys.executable, "-c", "print(1)"], 2)
assert code == 0

View File

@ -0,0 +1,131 @@
"""롤백 — 예전 버전으로 공개 주소를 되돌린다.
경로가 절대 하면 되는 :
- 재수집·재생성으로 스냅샷을 새로 만드는 ( 버전이 발행됐던 그대로여야 한다)
- 실패했는데 site.current_version_id 바꾸는 (직전 공개본이 그대로 있어야 한다)
- 지금 공개 중인 버전으로 "롤백" 허용하는 (의미 없는 잡을 만든다)
"""
import uuid
from common.enums import BuildStatus, JobStatus, SiteStatus
from crud.job_crud import JobQueue
from worker.handlers import build_handler
from worker.runner import Worker
from tests.test_build_publish import _approved_media, _place, _verified_facts
async def _run():
assert await Worker("w", JobQueue(), build_handler(), job_deadline_sec=60).process_one() is True
async def _publish(client, h, pid, intro="하조대 해변 도보 3분 거리의 펜션입니다."):
await _verified_facts(client, h, pid, {"intro": intro})
job_id = (await client.post(f"/v1/place/{pid}/site/build", headers=h, json={"publish": True})).json()["job_id"]
await _run()
return (await client.get(f"/v1/job/{job_id}", headers=h)).json()["job"]["result"]
async def test_rollback_to_earlier_version(auth_headers, client, db_engine):
"""검증: v1 발행 → v2 발행 → v1 로 롤백.
기대결과: 공개 버전이 다시 v1 된다. 롤백은 site_versions 행을 만들지 않는다."""
h = await auth_headers("u1")
pid = await _place(client, h)
await _approved_media(db_engine, pid)
r1 = await _publish(client, h, pid, "v1 소개 — 하조대 해변 도보 3분 거리의 펜션입니다.")
assert r1["published"] is True
r2 = await _publish(client, h, pid, "v2 소개 — 리모델링을 마친 하조대 앞 오션뷰 펜션입니다.")
assert r2["published"] is True
assert r2["version"] == r1["version"] + 1
job_id = (await client.post(
f"/v1/place/{pid}/site/version/rollback", headers=h, json={"target_version": r1["version"]}
)).json()["job_id"]
await _run()
job = (await client.get(f"/v1/job/{job_id}", headers=h)).json()["job"]
assert job["status"] == JobStatus.DONE.value, job.get("last_error")
result = job["result"]
assert result["rolled_back"] is True, result.get("error")
assert result["target_version"] == r1["version"]
site = (await client.get(f"/v1/place/{pid}/site", headers=h)).json()
assert site["site"]["status"] == SiteStatus.PUBLISHED.value
assert site["current_version"]["version"] == r1["version"]
assert site["current_version"]["build_status"] == BuildStatus.BUILT.value
versions = (await client.get(f"/v1/place/{pid}/site/version/list", headers=h)).json()["versions"]
# ★ 롤백은 새 버전을 만들지 않는다 — v1·v2 두 개뿐이어야 한다.
assert len(versions) == 2
async def test_rollback_rejects_current_version(auth_headers, client, db_engine):
"""검증: 지금 공개 중인 버전으로 롤백을 시도한다.
기대결과: 성공으로 끝나지 않는다(last_error) 의미 없는 재굽기를 하지 않는다.
(BuildAborted 같은 패턴 재시도해도 소용없는 중단이라 PENDING(백오프)으로 남고,
소진되면 DEAD 된다. 여기서 보는 "그래도 site 상태는 안 바뀐다" 것이다.)"""
h = await auth_headers("u1")
pid = await _place(client, h)
await _approved_media(db_engine, pid)
r1 = await _publish(client, h, pid)
job_id = (await client.post(
f"/v1/place/{pid}/site/version/rollback", headers=h, json={"target_version": r1["version"]}
)).json()["job_id"]
await _run()
job = (await client.get(f"/v1/job/{job_id}", headers=h)).json()["job"]
assert job["status"] != JobStatus.DONE.value
assert "이미" in (job.get("last_error") or "")
site = (await client.get(f"/v1/place/{pid}/site", headers=h)).json()
assert site["current_version"]["version"] == r1["version"]
async def test_rollback_rejects_unknown_version(auth_headers, client, db_engine):
"""검증: 존재하지 않는 버전 번호로 롤백을 시도한다.
기대결과: 잡이 성공으로 끝나지 않는다 공개 상태는 그대로다."""
h = await auth_headers("u1")
pid = await _place(client, h)
await _approved_media(db_engine, pid)
r1 = await _publish(client, h, pid)
job_id = (await client.post(
f"/v1/place/{pid}/site/version/rollback", headers=h, json={"target_version": 999}
)).json()["job_id"]
await _run()
job = (await client.get(f"/v1/job/{job_id}", headers=h)).json()["job"]
assert job["status"] != JobStatus.DONE.value
site = (await client.get(f"/v1/place/{pid}/site", headers=h)).json()
assert site["site"]["status"] == SiteStatus.PUBLISHED.value
assert site["current_version"]["version"] == r1["version"]
async def test_failed_rollback_keeps_current_published_version(auth_headers, client, db_engine, monkeypatch):
"""검증: 롤백 대상 렌더가 실패한다(구조화 데이터 불일치로 시뮬레이션).
기대결과: site.current_version_id 바뀌지 않는다 직전 공개본이 그대로 서비스된다."""
from services import render_service
h = await auth_headers("u1")
pid = await _place(client, h)
await _approved_media(db_engine, pid)
r1 = await _publish(client, h, pid, "v1 소개 — 하조대 해변 도보 3분 거리의 펜션입니다.")
r2 = await _publish(client, h, pid, "v2 소개 — 리모델링을 마친 하조대 앞 오션뷰 펜션입니다.")
site_before = (await client.get(f"/v1/place/{pid}/site", headers=h)).json()
assert site_before["current_version"]["version"] == r2["version"]
async def _broken(payload_path, site_version, timeout_sec):
raise render_service.RenderFailed("렌더러가 죽었다(시뮬레이션)")
monkeypatch.setattr(render_service, "render_site", _broken)
job_id = (await client.post(
f"/v1/place/{pid}/site/version/rollback", headers=h, json={"target_version": r1["version"]}
)).json()["job_id"]
await _run()
job = (await client.get(f"/v1/job/{job_id}", headers=h)).json()["job"]
assert job["status"] == JobStatus.DONE.value
assert job["result"]["rolled_back"] is False
site_after = (await client.get(f"/v1/place/{pid}/site", headers=h)).json()
assert site_after["current_version"]["version"] == r2["version"], "실패했는데 공개 버전이 바뀌었다"

View File

@ -16,6 +16,7 @@
JobType.BUILD services/build_service.run_build 정적 빌드 + 발행 검수 게이트
JobType.LOCAL_SYNC services/story_service.run_local_sync 지역 이야기 생성(지역당 1)
JobType.SONG services/song_service.run_song 숙소의 노래 (가사 Gemini 작곡 Suno)
JobType.ROLLBACK services/rollback_service.run_rollback 예전 버전으로 공개 주소를 되돌림
JobType.AI_CHECK reports 모듈이 붙을
"""
@ -82,6 +83,7 @@ def _register_builtin():
from services.copy_service import run_copy
from services.story_service import run_local_sync
from services.song_service import run_song
from services.rollback_service import run_rollback
from services.vision_service import run_vision
if JobType.COLLECT.value not in HANDLERS:
@ -96,6 +98,8 @@ def _register_builtin():
HANDLERS[JobType.LOCAL_SYNC.value] = run_local_sync
if JobType.SONG.value not in HANDLERS:
HANDLERS[JobType.SONG.value] = run_song
if JobType.ROLLBACK.value not in HANDLERS:
HANDLERS[JobType.ROLLBACK.value] = run_rollback
_register_builtin()

View File

@ -4,10 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import {
useMutation,
useQuery
} from '@tanstack/react-query';
import { useMutation, useQuery } from "@tanstack/react-query";
import type {
DataTag,
DefinedInitialDataOptions,
@ -20,8 +17,8 @@ import type {
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult
} from '@tanstack/react-query';
UseQueryResult,
} from "@tanstack/react-query";
import type {
HTTPValidationError,
@ -31,429 +28,576 @@ import type {
ReqUpdateMe,
ResLogin,
ResMe,
ResRefreshToken
} from '.././model';
import { customFetch } from '../../mutator/custom-fetch';
ResRefreshToken,
} from ".././model";
import { customFetch } from "../../mutator/custom-fetch";
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
/**
* id/pw JWT .
* @summary
*/
export const login = (
reqLogin: ReqLogin,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
reqLogin: ReqLogin,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResLogin>(
{url: `/v1/auth/login`, method: 'POST',
headers: {'Content-Type': 'application/json', },
data: reqLogin, signal
return customFetch<ResLogin>(
{
url: `/v1/auth/login`,
method: "POST",
headers: { "Content-Type": "application/json" },
data: reqLogin,
signal,
},
options);
}
options,
);
};
export const getLoginMutationOptions = <
TError = void | HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof login>>,
TError,
{ data: ReqLogin },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof login>>,
TError,
{ data: ReqLogin },
TContext
> => {
const mutationKey = ["login"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export const getLoginMutationOptions = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof login>>, TError,{data: ReqLogin}, TContext>, request?: SecondParameter<typeof customFetch>}
): UseMutationOptions<Awaited<ReturnType<typeof login>>, TError,{data: ReqLogin}, TContext> => {
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof login>>,
{ data: ReqLogin }
> = (props) => {
const { data } = props ?? {};
const mutationKey = ['login'];
const {mutation: mutationOptions, request: requestOptions} = options ?
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
options
: {...options, mutation: {...options.mutation, mutationKey}}
: {mutation: { mutationKey, }, request: undefined};
return login(data, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type LoginMutationResult = NonNullable<
Awaited<ReturnType<typeof login>>
>;
export type LoginMutationBody = ReqLogin;
export type LoginMutationError = void | HTTPValidationError;
const mutationFn: MutationFunction<Awaited<ReturnType<typeof login>>, {data: ReqLogin}> = (props) => {
const {data} = props ?? {};
return login(data,requestOptions)
}
return { mutationFn, ...mutationOptions }}
export type LoginMutationResult = NonNullable<Awaited<ReturnType<typeof login>>>
export type LoginMutationBody = ReqLogin
export type LoginMutationError = void | HTTPValidationError
/**
/**
* @summary
*/
export const useLogin = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof login>>, TError,{data: ReqLogin}, TContext>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient): UseMutationResult<
Awaited<ReturnType<typeof login>>,
TError,
{data: ReqLogin},
TContext
> => {
export const useLogin = <
TError = void | HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof login>>,
TError,
{ data: ReqLogin },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof login>>,
TError,
{ data: ReqLogin },
TContext
> => {
const mutationOptions = getLoginMutationOptions(options);
const mutationOptions = getLoginMutationOptions(options);
return useMutation(mutationOptions, queryClient);
}
/**
return useMutation(mutationOptions, queryClient);
};
/**
* id/pw . () 1 , .
* @summary
*/
export const signup = (
reqSignup: ReqSignup,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
reqSignup: ReqSignup,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResLogin>(
{url: `/v1/auth/signup`, method: 'POST',
headers: {'Content-Type': 'application/json', },
data: reqSignup, signal
return customFetch<ResLogin>(
{
url: `/v1/auth/signup`,
method: "POST",
headers: { "Content-Type": "application/json" },
data: reqSignup,
signal,
},
options);
}
options,
);
};
export const getSignupMutationOptions = <
TError = void | HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof signup>>,
TError,
{ data: ReqSignup },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof signup>>,
TError,
{ data: ReqSignup },
TContext
> => {
const mutationKey = ["signup"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export const getSignupMutationOptions = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof signup>>, TError,{data: ReqSignup}, TContext>, request?: SecondParameter<typeof customFetch>}
): UseMutationOptions<Awaited<ReturnType<typeof signup>>, TError,{data: ReqSignup}, TContext> => {
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof signup>>,
{ data: ReqSignup }
> = (props) => {
const { data } = props ?? {};
const mutationKey = ['signup'];
const {mutation: mutationOptions, request: requestOptions} = options ?
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
options
: {...options, mutation: {...options.mutation, mutationKey}}
: {mutation: { mutationKey, }, request: undefined};
return signup(data, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type SignupMutationResult = NonNullable<
Awaited<ReturnType<typeof signup>>
>;
export type SignupMutationBody = ReqSignup;
export type SignupMutationError = void | HTTPValidationError;
const mutationFn: MutationFunction<Awaited<ReturnType<typeof signup>>, {data: ReqSignup}> = (props) => {
const {data} = props ?? {};
return signup(data,requestOptions)
}
return { mutationFn, ...mutationOptions }}
export type SignupMutationResult = NonNullable<Awaited<ReturnType<typeof signup>>>
export type SignupMutationBody = ReqSignup
export type SignupMutationError = void | HTTPValidationError
/**
/**
* @summary
*/
export const useSignup = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof signup>>, TError,{data: ReqSignup}, TContext>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient): UseMutationResult<
Awaited<ReturnType<typeof signup>>,
TError,
{data: ReqSignup},
TContext
> => {
export const useSignup = <
TError = void | HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof signup>>,
TError,
{ data: ReqSignup },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof signup>>,
TError,
{ data: ReqSignup },
TContext
> => {
const mutationOptions = getSignupMutationOptions(options);
const mutationOptions = getSignupMutationOptions(options);
return useMutation(mutationOptions, queryClient);
}
/**
return useMutation(mutationOptions, queryClient);
};
/**
* ID (GIS credential) JWT . .
* @summary
*/
export const googleLogin = (
reqGoogleLogin: ReqGoogleLogin,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
reqGoogleLogin: ReqGoogleLogin,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResLogin>(
{url: `/v1/auth/google`, method: 'POST',
headers: {'Content-Type': 'application/json', },
data: reqGoogleLogin, signal
return customFetch<ResLogin>(
{
url: `/v1/auth/google`,
method: "POST",
headers: { "Content-Type": "application/json" },
data: reqGoogleLogin,
signal,
},
options);
}
options,
);
};
export const getGoogleLoginMutationOptions = <
TError = void | HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof googleLogin>>,
TError,
{ data: ReqGoogleLogin },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof googleLogin>>,
TError,
{ data: ReqGoogleLogin },
TContext
> => {
const mutationKey = ["googleLogin"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export const getGoogleLoginMutationOptions = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof googleLogin>>, TError,{data: ReqGoogleLogin}, TContext>, request?: SecondParameter<typeof customFetch>}
): UseMutationOptions<Awaited<ReturnType<typeof googleLogin>>, TError,{data: ReqGoogleLogin}, TContext> => {
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof googleLogin>>,
{ data: ReqGoogleLogin }
> = (props) => {
const { data } = props ?? {};
const mutationKey = ['googleLogin'];
const {mutation: mutationOptions, request: requestOptions} = options ?
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
options
: {...options, mutation: {...options.mutation, mutationKey}}
: {mutation: { mutationKey, }, request: undefined};
return googleLogin(data, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type GoogleLoginMutationResult = NonNullable<
Awaited<ReturnType<typeof googleLogin>>
>;
export type GoogleLoginMutationBody = ReqGoogleLogin;
export type GoogleLoginMutationError = void | HTTPValidationError;
const mutationFn: MutationFunction<Awaited<ReturnType<typeof googleLogin>>, {data: ReqGoogleLogin}> = (props) => {
const {data} = props ?? {};
return googleLogin(data,requestOptions)
}
return { mutationFn, ...mutationOptions }}
export type GoogleLoginMutationResult = NonNullable<Awaited<ReturnType<typeof googleLogin>>>
export type GoogleLoginMutationBody = ReqGoogleLogin
export type GoogleLoginMutationError = void | HTTPValidationError
/**
/**
* @summary
*/
export const useGoogleLogin = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof googleLogin>>, TError,{data: ReqGoogleLogin}, TContext>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient): UseMutationResult<
Awaited<ReturnType<typeof googleLogin>>,
TError,
{data: ReqGoogleLogin},
TContext
> => {
export const useGoogleLogin = <
TError = void | HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof googleLogin>>,
TError,
{ data: ReqGoogleLogin },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof googleLogin>>,
TError,
{ data: ReqGoogleLogin },
TContext
> => {
const mutationOptions = getGoogleLoginMutationOptions(options);
const mutationOptions = getGoogleLoginMutationOptions(options);
return useMutation(mutationOptions, queryClient);
}
/**
return useMutation(mutationOptions, queryClient);
};
/**
* refresh access .
* @summary
*/
export const refreshToken = (
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResRefreshToken>(
{url: `/v1/auth/refresh_token`, method: 'POST', signal
},
options);
}
return customFetch<ResRefreshToken>(
{ url: `/v1/auth/refresh_token`, method: "POST", signal },
options,
);
};
export const getRefreshTokenMutationOptions = <
TError = void,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof refreshToken>>,
TError,
void,
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof refreshToken>>,
TError,
void,
TContext
> => {
const mutationKey = ["refreshToken"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export const getRefreshTokenMutationOptions = <TError = void,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof refreshToken>>, TError,void, TContext>, request?: SecondParameter<typeof customFetch>}
): UseMutationOptions<Awaited<ReturnType<typeof refreshToken>>, TError,void, TContext> => {
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof refreshToken>>,
void
> = () => {
return refreshToken(requestOptions);
};
const mutationKey = ['refreshToken'];
const {mutation: mutationOptions, request: requestOptions} = options ?
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
options
: {...options, mutation: {...options.mutation, mutationKey}}
: {mutation: { mutationKey, }, request: undefined};
return { mutationFn, ...mutationOptions };
};
export type RefreshTokenMutationResult = NonNullable<
Awaited<ReturnType<typeof refreshToken>>
>;
export type RefreshTokenMutationError = void;
const mutationFn: MutationFunction<Awaited<ReturnType<typeof refreshToken>>, void> = () => {
return refreshToken(requestOptions)
}
return { mutationFn, ...mutationOptions }}
export type RefreshTokenMutationResult = NonNullable<Awaited<ReturnType<typeof refreshToken>>>
export type RefreshTokenMutationError = void
/**
/**
* @summary
*/
export const useRefreshToken = <TError = void,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof refreshToken>>, TError,void, TContext>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient): UseMutationResult<
Awaited<ReturnType<typeof refreshToken>>,
TError,
void,
TContext
> => {
export const useRefreshToken = <TError = void, TContext = unknown>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof refreshToken>>,
TError,
void,
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof refreshToken>>,
TError,
void,
TContext
> => {
const mutationOptions = getRefreshTokenMutationOptions(options);
const mutationOptions = getRefreshTokenMutationOptions(options);
return useMutation(mutationOptions, queryClient);
}
/**
return useMutation(mutationOptions, queryClient);
};
/**
* access . + .
* @summary
*/
export const me = (
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResMe>(
{url: `/v1/auth/me`, method: 'GET', signal
},
options);
}
return customFetch<ResMe>(
{ url: `/v1/auth/me`, method: "GET", signal },
options,
);
};
export const getMeQueryKey = () => {
return [
`/v1/auth/me`
] as const;
}
return [`/v1/auth/me`] as const;
};
export const getMeQueryOptions = <TData = Awaited<ReturnType<typeof me>>, TError = void>( options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
) => {
export const getMeQueryOptions = <
TData = Awaited<ReturnType<typeof me>>,
TError = void,
>(options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
}) => {
const { query: queryOptions, request: requestOptions } = options ?? {};
const {query: queryOptions, request: requestOptions} = options ?? {};
const queryKey = queryOptions?.queryKey ?? getMeQueryKey();
const queryKey = queryOptions?.queryKey ?? getMeQueryKey();
const queryFn: QueryFunction<Awaited<ReturnType<typeof me>>> = ({ signal }) =>
me(requestOptions, signal);
const queryFn: QueryFunction<Awaited<ReturnType<typeof me>>> = ({ signal }) => me(requestOptions, signal);
return { queryKey, queryFn, ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
}
export type MeQueryResult = NonNullable<Awaited<ReturnType<typeof me>>>
export type MeQueryError = void
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof me>>,
TError,
TData
> & { queryKey: DataTag<QueryKey, TData, TError> };
};
export type MeQueryResult = NonNullable<Awaited<ReturnType<typeof me>>>;
export type MeQueryError = void;
export function useMe<TData = Awaited<ReturnType<typeof me>>, TError = void>(
options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>> & Pick<
options: {
query: Partial<
UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>
> &
Pick<
DefinedInitialDataOptions<
Awaited<ReturnType<typeof me>>,
TError,
Awaited<ReturnType<typeof me>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useMe<TData = Awaited<ReturnType<typeof me>>, TError = void>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>> & Pick<
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>
> &
Pick<
UndefinedInitialDataOptions<
Awaited<ReturnType<typeof me>>,
TError,
Awaited<ReturnType<typeof me>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useMe<TData = Awaited<ReturnType<typeof me>>, TError = void>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
/**
* @summary
*/
export function useMe<TData = Awaited<ReturnType<typeof me>>, TError = void>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof me>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions = getMeQueryOptions(options);
const queryOptions = getMeQueryOptions(options)
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
TData,
TError
> & { queryKey: DataTag<QueryKey, TData, TError> };
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
query.queryKey = queryOptions.queryKey ;
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* /// (··ID ).
* @summary
*/
export const updateMe = (
reqUpdateMe: ReqUpdateMe,
options?: SecondParameter<typeof customFetch>,) => {
return customFetch<ResMe>(
{url: `/v1/auth/me`, method: 'PATCH',
headers: {'Content-Type': 'application/json', },
data: reqUpdateMe
reqUpdateMe: ReqUpdateMe,
options?: SecondParameter<typeof customFetch>,
) => {
return customFetch<ResMe>(
{
url: `/v1/auth/me`,
method: "PATCH",
headers: { "Content-Type": "application/json" },
data: reqUpdateMe,
},
options);
}
options,
);
};
export const getUpdateMeMutationOptions = <
TError = void | HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateMe>>,
TError,
{ data: ReqUpdateMe },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateMe>>,
TError,
{ data: ReqUpdateMe },
TContext
> => {
const mutationKey = ["updateMe"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export const getUpdateMeMutationOptions = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof updateMe>>, TError,{data: ReqUpdateMe}, TContext>, request?: SecondParameter<typeof customFetch>}
): UseMutationOptions<Awaited<ReturnType<typeof updateMe>>, TError,{data: ReqUpdateMe}, TContext> => {
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updateMe>>,
{ data: ReqUpdateMe }
> = (props) => {
const { data } = props ?? {};
const mutationKey = ['updateMe'];
const {mutation: mutationOptions, request: requestOptions} = options ?
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
options
: {...options, mutation: {...options.mutation, mutationKey}}
: {mutation: { mutationKey, }, request: undefined};
return updateMe(data, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type UpdateMeMutationResult = NonNullable<
Awaited<ReturnType<typeof updateMe>>
>;
export type UpdateMeMutationBody = ReqUpdateMe;
export type UpdateMeMutationError = void | HTTPValidationError;
const mutationFn: MutationFunction<Awaited<ReturnType<typeof updateMe>>, {data: ReqUpdateMe}> = (props) => {
const {data} = props ?? {};
return updateMe(data,requestOptions)
}
return { mutationFn, ...mutationOptions }}
export type UpdateMeMutationResult = NonNullable<Awaited<ReturnType<typeof updateMe>>>
export type UpdateMeMutationBody = ReqUpdateMe
export type UpdateMeMutationError = void | HTTPValidationError
/**
/**
* @summary
*/
export const useUpdateMe = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof updateMe>>, TError,{data: ReqUpdateMe}, TContext>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient): UseMutationResult<
Awaited<ReturnType<typeof updateMe>>,
TError,
{data: ReqUpdateMe},
TContext
> => {
export const useUpdateMe = <
TError = void | HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateMe>>,
TError,
{ data: ReqUpdateMe },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof updateMe>>,
TError,
{ data: ReqUpdateMe },
TContext
> => {
const mutationOptions = getUpdateMeMutationOptions(options);
const mutationOptions = getUpdateMeMutationOptions(options);
return useMutation(mutationOptions, queryClient);
}
return useMutation(mutationOptions, queryClient);
};

View File

@ -4,9 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import {
useQuery
} from '@tanstack/react-query';
import { useQuery } from "@tanstack/react-query";
import type {
DataTag,
DefinedInitialDataOptions,
@ -16,105 +14,163 @@ import type {
QueryKey,
UndefinedInitialDataOptions,
UseQueryOptions,
UseQueryResult
} from '@tanstack/react-query';
import { customFetch } from '../../mutator/custom-fetch';
UseQueryResult,
} from "@tanstack/react-query";
import { customFetch } from "../../mutator/custom-fetch";
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
/**
* @summary Healthz
*/
export const healthzHealthzGet = (
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<unknown>(
{url: `/healthz`, method: 'GET', signal
},
options);
}
return customFetch<unknown>(
{ url: `/healthz`, method: "GET", signal },
options,
);
};
export const getHealthzHealthzGetQueryKey = () => {
return [
`/healthz`
] as const;
}
return [`/healthz`] as const;
};
export const getHealthzHealthzGetQueryOptions = <TData = Awaited<ReturnType<typeof healthzHealthzGet>>, TError = void>( options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
) => {
export const getHealthzHealthzGetQueryOptions = <
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
TError = void,
>(options?: {
query?: Partial<
UseQueryOptions<
Awaited<ReturnType<typeof healthzHealthzGet>>,
TError,
TData
>
>;
request?: SecondParameter<typeof customFetch>;
}) => {
const { query: queryOptions, request: requestOptions } = options ?? {};
const {query: queryOptions, request: requestOptions} = options ?? {};
const queryKey = queryOptions?.queryKey ?? getHealthzHealthzGetQueryKey();
const queryKey = queryOptions?.queryKey ?? getHealthzHealthzGetQueryKey();
const queryFn: QueryFunction<
Awaited<ReturnType<typeof healthzHealthzGet>>
> = ({ signal }) => healthzHealthzGet(requestOptions, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof healthzHealthzGet>>,
TError,
TData
> & { queryKey: DataTag<QueryKey, TData, TError> };
};
const queryFn: QueryFunction<Awaited<ReturnType<typeof healthzHealthzGet>>> = ({ signal }) => healthzHealthzGet(requestOptions, signal);
export type HealthzHealthzGetQueryResult = NonNullable<
Awaited<ReturnType<typeof healthzHealthzGet>>
>;
export type HealthzHealthzGetQueryError = void;
return { queryKey, queryFn, ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
}
export type HealthzHealthzGetQueryResult = NonNullable<Awaited<ReturnType<typeof healthzHealthzGet>>>
export type HealthzHealthzGetQueryError = void
export function useHealthzHealthzGet<TData = Awaited<ReturnType<typeof healthzHealthzGet>>, TError = void>(
options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData>> & Pick<
export function useHealthzHealthzGet<
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
TError = void,
>(
options: {
query: Partial<
UseQueryOptions<
Awaited<ReturnType<typeof healthzHealthzGet>>,
TError,
TData
>
> &
Pick<
DefinedInitialDataOptions<
Awaited<ReturnType<typeof healthzHealthzGet>>,
TError,
Awaited<ReturnType<typeof healthzHealthzGet>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useHealthzHealthzGet<TData = Awaited<ReturnType<typeof healthzHealthzGet>>, TError = void>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData>> & Pick<
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useHealthzHealthzGet<
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
TError = void,
>(
options?: {
query?: Partial<
UseQueryOptions<
Awaited<ReturnType<typeof healthzHealthzGet>>,
TError,
TData
>
> &
Pick<
UndefinedInitialDataOptions<
Awaited<ReturnType<typeof healthzHealthzGet>>,
TError,
Awaited<ReturnType<typeof healthzHealthzGet>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useHealthzHealthzGet<TData = Awaited<ReturnType<typeof healthzHealthzGet>>, TError = void>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useHealthzHealthzGet<
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
TError = void,
>(
options?: {
query?: Partial<
UseQueryOptions<
Awaited<ReturnType<typeof healthzHealthzGet>>,
TError,
TData
>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
/**
* @summary Healthz
*/
export function useHealthzHealthzGet<TData = Awaited<ReturnType<typeof healthzHealthzGet>>, TError = void>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof healthzHealthzGet>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
export function useHealthzHealthzGet<
TData = Awaited<ReturnType<typeof healthzHealthzGet>>,
TError = void,
>(
options?: {
query?: Partial<
UseQueryOptions<
Awaited<ReturnType<typeof healthzHealthzGet>>,
TError,
TData
>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions = getHealthzHealthzGetQueryOptions(options);
const queryOptions = getHealthzHealthzGetQueryOptions(options)
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
TData,
TError
> & { queryKey: DataTag<QueryKey, TData, TError> };
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
query.queryKey = queryOptions.queryKey ;
query.queryKey = queryOptions.queryKey;
return query;
}

View File

@ -4,10 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import {
useMutation,
useQuery
} from '@tanstack/react-query';
import { useMutation, useQuery } from "@tanstack/react-query";
import type {
DataTag,
DefinedInitialDataOptions,
@ -20,8 +17,8 @@ import type {
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult
} from '@tanstack/react-query';
UseQueryResult,
} from "@tanstack/react-query";
import type {
HTTPValidationError,
@ -32,407 +29,595 @@ import type {
ResCategorySchema,
ResExtractFacts,
ResFact,
ResFactList
} from '.././model';
import { customFetch } from '../../mutator/custom-fetch';
ResFactList,
} from ".././model";
import { customFetch } from "../../mutator/custom-fetch";
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
/**
* fact . .
* @summary fact
*/
export const getSchema = (
placeId: string,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
placeId: string,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResCategorySchema>(
{url: `/v1/place/${placeId}/fact/schema`, method: 'GET', signal
},
options);
}
return customFetch<ResCategorySchema>(
{ url: `/v1/place/${placeId}/fact/schema`, method: "GET", signal },
options,
);
};
export const getGetSchemaQueryKey = (placeId?: string) => {
return [`/v1/place/${placeId}/fact/schema`] as const;
};
export const getGetSchemaQueryKey = (placeId?: string,) => {
return [
`/v1/place/${placeId}/fact/schema`
] as const;
}
export const getGetSchemaQueryOptions = <TData = Awaited<ReturnType<typeof getSchema>>, TError = void | HTTPValidationError>(placeId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
export const getGetSchemaQueryOptions = <
TData = Awaited<ReturnType<typeof getSchema>>,
TError = void | HTTPValidationError,
>(
placeId: string,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
) => {
const { query: queryOptions, request: requestOptions } = options ?? {};
const {query: queryOptions, request: requestOptions} = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetSchemaQueryKey(placeId);
const queryKey = queryOptions?.queryKey ?? getGetSchemaQueryKey(placeId);
const queryFn: QueryFunction<Awaited<ReturnType<typeof getSchema>>> = ({
signal,
}) => getSchema(placeId, requestOptions, signal);
return {
queryKey,
queryFn,
enabled: !!placeId,
...queryOptions,
} as UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
};
const queryFn: QueryFunction<Awaited<ReturnType<typeof getSchema>>> = ({ signal }) => getSchema(placeId, requestOptions, signal);
export type GetSchemaQueryResult = NonNullable<
Awaited<ReturnType<typeof getSchema>>
>;
export type GetSchemaQueryError = void | HTTPValidationError;
return { queryKey, queryFn, enabled: !!(placeId), ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
}
export type GetSchemaQueryResult = NonNullable<Awaited<ReturnType<typeof getSchema>>>
export type GetSchemaQueryError = void | HTTPValidationError
export function useGetSchema<TData = Awaited<ReturnType<typeof getSchema>>, TError = void | HTTPValidationError>(
placeId: string, options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData>> & Pick<
export function useGetSchema<
TData = Awaited<ReturnType<typeof getSchema>>,
TError = void | HTTPValidationError,
>(
placeId: string,
options: {
query: Partial<
UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData>
> &
Pick<
DefinedInitialDataOptions<
Awaited<ReturnType<typeof getSchema>>,
TError,
Awaited<ReturnType<typeof getSchema>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useGetSchema<TData = Awaited<ReturnType<typeof getSchema>>, TError = void | HTTPValidationError>(
placeId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData>> & Pick<
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useGetSchema<
TData = Awaited<ReturnType<typeof getSchema>>,
TError = void | HTTPValidationError,
>(
placeId: string,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData>
> &
Pick<
UndefinedInitialDataOptions<
Awaited<ReturnType<typeof getSchema>>,
TError,
Awaited<ReturnType<typeof getSchema>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useGetSchema<TData = Awaited<ReturnType<typeof getSchema>>, TError = void | HTTPValidationError>(
placeId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useGetSchema<
TData = Awaited<ReturnType<typeof getSchema>>,
TError = void | HTTPValidationError,
>(
placeId: string,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
/**
* @summary fact
*/
export function useGetSchema<TData = Awaited<ReturnType<typeof getSchema>>, TError = void | HTTPValidationError>(
placeId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
export function useGetSchema<
TData = Awaited<ReturnType<typeof getSchema>>,
TError = void | HTTPValidationError,
>(
placeId: string,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof getSchema>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions = getGetSchemaQueryOptions(placeId, options);
const queryOptions = getGetSchemaQueryOptions(placeId,options)
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
TData,
TError
> & { queryKey: DataTag<QueryKey, TData, TError> };
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
query.queryKey = queryOptions.queryKey ;
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* publishable_only=true (VERIFIED·CORRECTED).
* @summary fact
*/
export const listFacts = (
placeId: string,
params?: ListFactsParams,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
placeId: string,
params?: ListFactsParams,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResFactList>(
{url: `/v1/place/${placeId}/fact/list`, method: 'GET',
params, signal
},
options);
}
return customFetch<ResFactList>(
{ url: `/v1/place/${placeId}/fact/list`, method: "GET", params, signal },
options,
);
};
export const getListFactsQueryKey = (placeId?: string,
params?: ListFactsParams,) => {
return [
`/v1/place/${placeId}/fact/list`, ...(params ? [params]: [])
] as const;
}
export const getListFactsQueryOptions = <TData = Awaited<ReturnType<typeof listFacts>>, TError = void | HTTPValidationError>(placeId: string,
params?: ListFactsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
export const getListFactsQueryKey = (
placeId?: string,
params?: ListFactsParams,
) => {
return [
`/v1/place/${placeId}/fact/list`,
...(params ? [params] : []),
] as const;
};
const {query: queryOptions, request: requestOptions} = options ?? {};
export const getListFactsQueryOptions = <
TData = Awaited<ReturnType<typeof listFacts>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListFactsParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
) => {
const { query: queryOptions, request: requestOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getListFactsQueryKey(placeId,params);
const queryKey =
queryOptions?.queryKey ?? getListFactsQueryKey(placeId, params);
const queryFn: QueryFunction<Awaited<ReturnType<typeof listFacts>>> = ({
signal,
}) => listFacts(placeId, params, requestOptions, signal);
const queryFn: QueryFunction<Awaited<ReturnType<typeof listFacts>>> = ({ signal }) => listFacts(placeId,params, requestOptions, signal);
return {
queryKey,
queryFn,
enabled: !!placeId,
...queryOptions,
} as UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
};
export type ListFactsQueryResult = NonNullable<
Awaited<ReturnType<typeof listFacts>>
>;
export type ListFactsQueryError = void | HTTPValidationError;
return { queryKey, queryFn, enabled: !!(placeId), ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
}
export type ListFactsQueryResult = NonNullable<Awaited<ReturnType<typeof listFacts>>>
export type ListFactsQueryError = void | HTTPValidationError
export function useListFacts<TData = Awaited<ReturnType<typeof listFacts>>, TError = void | HTTPValidationError>(
placeId: string,
params: undefined | ListFactsParams, options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData>> & Pick<
export function useListFacts<
TData = Awaited<ReturnType<typeof listFacts>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params: undefined | ListFactsParams,
options: {
query: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData>
> &
Pick<
DefinedInitialDataOptions<
Awaited<ReturnType<typeof listFacts>>,
TError,
Awaited<ReturnType<typeof listFacts>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useListFacts<TData = Awaited<ReturnType<typeof listFacts>>, TError = void | HTTPValidationError>(
placeId: string,
params?: ListFactsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData>> & Pick<
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useListFacts<
TData = Awaited<ReturnType<typeof listFacts>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListFactsParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData>
> &
Pick<
UndefinedInitialDataOptions<
Awaited<ReturnType<typeof listFacts>>,
TError,
Awaited<ReturnType<typeof listFacts>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useListFacts<TData = Awaited<ReturnType<typeof listFacts>>, TError = void | HTTPValidationError>(
placeId: string,
params?: ListFactsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useListFacts<
TData = Awaited<ReturnType<typeof listFacts>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListFactsParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
/**
* @summary fact
*/
export function useListFacts<TData = Awaited<ReturnType<typeof listFacts>>, TError = void | HTTPValidationError>(
placeId: string,
params?: ListFactsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
export function useListFacts<
TData = Awaited<ReturnType<typeof listFacts>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListFactsParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listFacts>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions = getListFactsQueryOptions(placeId, params, options);
const queryOptions = getListFactsQueryOptions(placeId,params,options)
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
TData,
TError
> & { queryKey: DataTag<QueryKey, TData, TError> };
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
query.queryKey = queryOptions.queryKey ;
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* key fact EXPIRED ( ). (api/crawl/llm) (CORRECTED) .
* @summary fact
*/
export const upsertFact = (
placeId: string,
reqUpsertFact: ReqUpsertFact,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
placeId: string,
reqUpsertFact: ReqUpsertFact,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResFact>(
{url: `/v1/place/${placeId}/fact`, method: 'POST',
headers: {'Content-Type': 'application/json', },
data: reqUpsertFact, signal
return customFetch<ResFact>(
{
url: `/v1/place/${placeId}/fact`,
method: "POST",
headers: { "Content-Type": "application/json" },
data: reqUpsertFact,
signal,
},
options);
}
options,
);
};
export const getUpsertFactMutationOptions = <
TError = void | HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof upsertFact>>,
TError,
{ placeId: string; data: ReqUpsertFact },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof upsertFact>>,
TError,
{ placeId: string; data: ReqUpsertFact },
TContext
> => {
const mutationKey = ["upsertFact"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export const getUpsertFactMutationOptions = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof upsertFact>>, TError,{placeId: string;data: ReqUpsertFact}, TContext>, request?: SecondParameter<typeof customFetch>}
): UseMutationOptions<Awaited<ReturnType<typeof upsertFact>>, TError,{placeId: string;data: ReqUpsertFact}, TContext> => {
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof upsertFact>>,
{ placeId: string; data: ReqUpsertFact }
> = (props) => {
const { placeId, data } = props ?? {};
const mutationKey = ['upsertFact'];
const {mutation: mutationOptions, request: requestOptions} = options ?
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
options
: {...options, mutation: {...options.mutation, mutationKey}}
: {mutation: { mutationKey, }, request: undefined};
return upsertFact(placeId, data, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type UpsertFactMutationResult = NonNullable<
Awaited<ReturnType<typeof upsertFact>>
>;
export type UpsertFactMutationBody = ReqUpsertFact;
export type UpsertFactMutationError = void | HTTPValidationError;
const mutationFn: MutationFunction<Awaited<ReturnType<typeof upsertFact>>, {placeId: string;data: ReqUpsertFact}> = (props) => {
const {placeId,data} = props ?? {};
return upsertFact(placeId,data,requestOptions)
}
return { mutationFn, ...mutationOptions }}
export type UpsertFactMutationResult = NonNullable<Awaited<ReturnType<typeof upsertFact>>>
export type UpsertFactMutationBody = ReqUpsertFact
export type UpsertFactMutationError = void | HTTPValidationError
/**
/**
* @summary fact
*/
export const useUpsertFact = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof upsertFact>>, TError,{placeId: string;data: ReqUpsertFact}, TContext>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient): UseMutationResult<
Awaited<ReturnType<typeof upsertFact>>,
TError,
{placeId: string;data: ReqUpsertFact},
TContext
> => {
export const useUpsertFact = <
TError = void | HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof upsertFact>>,
TError,
{ placeId: string; data: ReqUpsertFact },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof upsertFact>>,
TError,
{ placeId: string; data: ReqUpsertFact },
TContext
> => {
const mutationOptions = getUpsertFactMutationOptions(options);
const mutationOptions = getUpsertFactMutationOptions(options);
return useMutation(mutationOptions, queryClient);
}
/**
return useMutation(mutationOptions, queryClient);
};
/**
* (FACT_STATUS_TRANSITIONS). CORRECTED value .
* @summary
*/
export const transitionFact = (
placeId: string,
factId: string,
reqTransitionFact: ReqTransitionFact,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
placeId: string,
factId: string,
reqTransitionFact: ReqTransitionFact,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResFact>(
{url: `/v1/place/${placeId}/fact/${factId}/transition`, method: 'POST',
headers: {'Content-Type': 'application/json', },
data: reqTransitionFact, signal
return customFetch<ResFact>(
{
url: `/v1/place/${placeId}/fact/${factId}/transition`,
method: "POST",
headers: { "Content-Type": "application/json" },
data: reqTransitionFact,
signal,
},
options);
}
options,
);
};
export const getTransitionFactMutationOptions = <
TError = void | HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof transitionFact>>,
TError,
{ placeId: string; factId: string; data: ReqTransitionFact },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof transitionFact>>,
TError,
{ placeId: string; factId: string; data: ReqTransitionFact },
TContext
> => {
const mutationKey = ["transitionFact"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export const getTransitionFactMutationOptions = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof transitionFact>>, TError,{placeId: string;factId: string;data: ReqTransitionFact}, TContext>, request?: SecondParameter<typeof customFetch>}
): UseMutationOptions<Awaited<ReturnType<typeof transitionFact>>, TError,{placeId: string;factId: string;data: ReqTransitionFact}, TContext> => {
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof transitionFact>>,
{ placeId: string; factId: string; data: ReqTransitionFact }
> = (props) => {
const { placeId, factId, data } = props ?? {};
const mutationKey = ['transitionFact'];
const {mutation: mutationOptions, request: requestOptions} = options ?
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
options
: {...options, mutation: {...options.mutation, mutationKey}}
: {mutation: { mutationKey, }, request: undefined};
return transitionFact(placeId, factId, data, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type TransitionFactMutationResult = NonNullable<
Awaited<ReturnType<typeof transitionFact>>
>;
export type TransitionFactMutationBody = ReqTransitionFact;
export type TransitionFactMutationError = void | HTTPValidationError;
const mutationFn: MutationFunction<Awaited<ReturnType<typeof transitionFact>>, {placeId: string;factId: string;data: ReqTransitionFact}> = (props) => {
const {placeId,factId,data} = props ?? {};
return transitionFact(placeId,factId,data,requestOptions)
}
return { mutationFn, ...mutationOptions }}
export type TransitionFactMutationResult = NonNullable<Awaited<ReturnType<typeof transitionFact>>>
export type TransitionFactMutationBody = ReqTransitionFact
export type TransitionFactMutationError = void | HTTPValidationError
/**
/**
* @summary
*/
export const useTransitionFact = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof transitionFact>>, TError,{placeId: string;factId: string;data: ReqTransitionFact}, TContext>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient): UseMutationResult<
Awaited<ReturnType<typeof transitionFact>>,
TError,
{placeId: string;factId: string;data: ReqTransitionFact},
TContext
> => {
export const useTransitionFact = <
TError = void | HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof transitionFact>>,
TError,
{ placeId: string; factId: string; data: ReqTransitionFact },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof transitionFact>>,
TError,
{ placeId: string; factId: string; data: ReqTransitionFact },
TContext
> => {
const mutationOptions = getTransitionFactMutationOptions(options);
const mutationOptions = getTransitionFactMutationOptions(options);
return useMutation(mutationOptions, queryClient);
}
/**
return useMutation(mutationOptions, queryClient);
};
/**
* · fact . ** ** . (UNVERIFIED) . .
* @summary fact
*/
export const extractFactsFromText = (
placeId: string,
reqExtractFacts: ReqExtractFacts,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
placeId: string,
reqExtractFacts: ReqExtractFacts,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResExtractFacts>(
{url: `/v1/place/${placeId}/fact/extract`, method: 'POST',
headers: {'Content-Type': 'application/json', },
data: reqExtractFacts, signal
return customFetch<ResExtractFacts>(
{
url: `/v1/place/${placeId}/fact/extract`,
method: "POST",
headers: { "Content-Type": "application/json" },
data: reqExtractFacts,
signal,
},
options);
}
options,
);
};
export const getExtractFactsFromTextMutationOptions = <
TError = void | HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof extractFactsFromText>>,
TError,
{ placeId: string; data: ReqExtractFacts },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof extractFactsFromText>>,
TError,
{ placeId: string; data: ReqExtractFacts },
TContext
> => {
const mutationKey = ["extractFactsFromText"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export const getExtractFactsFromTextMutationOptions = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof extractFactsFromText>>, TError,{placeId: string;data: ReqExtractFacts}, TContext>, request?: SecondParameter<typeof customFetch>}
): UseMutationOptions<Awaited<ReturnType<typeof extractFactsFromText>>, TError,{placeId: string;data: ReqExtractFacts}, TContext> => {
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof extractFactsFromText>>,
{ placeId: string; data: ReqExtractFacts }
> = (props) => {
const { placeId, data } = props ?? {};
const mutationKey = ['extractFactsFromText'];
const {mutation: mutationOptions, request: requestOptions} = options ?
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
options
: {...options, mutation: {...options.mutation, mutationKey}}
: {mutation: { mutationKey, }, request: undefined};
return extractFactsFromText(placeId, data, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type ExtractFactsFromTextMutationResult = NonNullable<
Awaited<ReturnType<typeof extractFactsFromText>>
>;
export type ExtractFactsFromTextMutationBody = ReqExtractFacts;
export type ExtractFactsFromTextMutationError = void | HTTPValidationError;
const mutationFn: MutationFunction<Awaited<ReturnType<typeof extractFactsFromText>>, {placeId: string;data: ReqExtractFacts}> = (props) => {
const {placeId,data} = props ?? {};
return extractFactsFromText(placeId,data,requestOptions)
}
return { mutationFn, ...mutationOptions }}
export type ExtractFactsFromTextMutationResult = NonNullable<Awaited<ReturnType<typeof extractFactsFromText>>>
export type ExtractFactsFromTextMutationBody = ReqExtractFacts
export type ExtractFactsFromTextMutationError = void | HTTPValidationError
/**
/**
* @summary fact
*/
export const useExtractFactsFromText = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof extractFactsFromText>>, TError,{placeId: string;data: ReqExtractFacts}, TContext>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient): UseMutationResult<
Awaited<ReturnType<typeof extractFactsFromText>>,
TError,
{placeId: string;data: ReqExtractFacts},
TContext
> => {
export const useExtractFactsFromText = <
TError = void | HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof extractFactsFromText>>,
TError,
{ placeId: string; data: ReqExtractFacts },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof extractFactsFromText>>,
TError,
{ placeId: string; data: ReqExtractFacts },
TContext
> => {
const mutationOptions = getExtractFactsFromTextMutationOptions(options);
const mutationOptions = getExtractFactsFromTextMutationOptions(options);
return useMutation(mutationOptions, queryClient);
}
return useMutation(mutationOptions, queryClient);
};

View File

@ -4,10 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import {
useMutation,
useQuery
} from '@tanstack/react-query';
import { useMutation, useQuery } from "@tanstack/react-query";
import type {
DataTag,
DefinedInitialDataOptions,
@ -20,8 +17,8 @@ import type {
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult
} from '@tanstack/react-query';
UseQueryResult,
} from "@tanstack/react-query";
import type {
HTTPValidationError,
@ -29,248 +26,356 @@ import type {
ReqCreateFaq,
ReqTransitionFaq,
ResFaq,
ResFaqList
} from '.././model';
import { customFetch } from '../../mutator/custom-fetch';
ResFaqList,
} from ".././model";
import { customFetch } from "../../mutator/custom-fetch";
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
/**
* publishable_only=true (VERIFIED·CORRECTED). (UNVERIFIED) .
* @summary FAQ
*/
export const listFaqs = (
placeId: string,
params?: ListFaqsParams,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
placeId: string,
params?: ListFaqsParams,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResFaqList>(
{url: `/v1/place/${placeId}/faq/list`, method: 'GET',
params, signal
},
options);
}
return customFetch<ResFaqList>(
{ url: `/v1/place/${placeId}/faq/list`, method: "GET", params, signal },
options,
);
};
export const getListFaqsQueryKey = (placeId?: string,
params?: ListFaqsParams,) => {
return [
`/v1/place/${placeId}/faq/list`, ...(params ? [params]: [])
] as const;
}
export const getListFaqsQueryOptions = <TData = Awaited<ReturnType<typeof listFaqs>>, TError = void | HTTPValidationError>(placeId: string,
params?: ListFaqsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
export const getListFaqsQueryKey = (
placeId?: string,
params?: ListFaqsParams,
) => {
return [
`/v1/place/${placeId}/faq/list`,
...(params ? [params] : []),
] as const;
};
const {query: queryOptions, request: requestOptions} = options ?? {};
export const getListFaqsQueryOptions = <
TData = Awaited<ReturnType<typeof listFaqs>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListFaqsParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
) => {
const { query: queryOptions, request: requestOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getListFaqsQueryKey(placeId,params);
const queryKey =
queryOptions?.queryKey ?? getListFaqsQueryKey(placeId, params);
const queryFn: QueryFunction<Awaited<ReturnType<typeof listFaqs>>> = ({
signal,
}) => listFaqs(placeId, params, requestOptions, signal);
const queryFn: QueryFunction<Awaited<ReturnType<typeof listFaqs>>> = ({ signal }) => listFaqs(placeId,params, requestOptions, signal);
return {
queryKey,
queryFn,
enabled: !!placeId,
...queryOptions,
} as UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
};
export type ListFaqsQueryResult = NonNullable<
Awaited<ReturnType<typeof listFaqs>>
>;
export type ListFaqsQueryError = void | HTTPValidationError;
return { queryKey, queryFn, enabled: !!(placeId), ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
}
export type ListFaqsQueryResult = NonNullable<Awaited<ReturnType<typeof listFaqs>>>
export type ListFaqsQueryError = void | HTTPValidationError
export function useListFaqs<TData = Awaited<ReturnType<typeof listFaqs>>, TError = void | HTTPValidationError>(
placeId: string,
params: undefined | ListFaqsParams, options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData>> & Pick<
export function useListFaqs<
TData = Awaited<ReturnType<typeof listFaqs>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params: undefined | ListFaqsParams,
options: {
query: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData>
> &
Pick<
DefinedInitialDataOptions<
Awaited<ReturnType<typeof listFaqs>>,
TError,
Awaited<ReturnType<typeof listFaqs>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useListFaqs<TData = Awaited<ReturnType<typeof listFaqs>>, TError = void | HTTPValidationError>(
placeId: string,
params?: ListFaqsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData>> & Pick<
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useListFaqs<
TData = Awaited<ReturnType<typeof listFaqs>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListFaqsParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData>
> &
Pick<
UndefinedInitialDataOptions<
Awaited<ReturnType<typeof listFaqs>>,
TError,
Awaited<ReturnType<typeof listFaqs>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useListFaqs<TData = Awaited<ReturnType<typeof listFaqs>>, TError = void | HTTPValidationError>(
placeId: string,
params?: ListFaqsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useListFaqs<
TData = Awaited<ReturnType<typeof listFaqs>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListFaqsParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
/**
* @summary FAQ
*/
export function useListFaqs<TData = Awaited<ReturnType<typeof listFaqs>>, TError = void | HTTPValidationError>(
placeId: string,
params?: ListFaqsParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
export function useListFaqs<
TData = Awaited<ReturnType<typeof listFaqs>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListFaqsParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listFaqs>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions = getListFaqsQueryOptions(placeId, params, options);
const queryOptions = getListFaqsQueryOptions(placeId,params,options)
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
TData,
TError
> & { queryKey: DataTag<QueryKey, TData, TError> };
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
query.queryKey = queryOptions.queryKey ;
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* FAQ. fact owner (VERIFIED) . (generated_by) OWNER .
* @summary FAQ
*/
export const createFaq = (
placeId: string,
reqCreateFaq: ReqCreateFaq,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
placeId: string,
reqCreateFaq: ReqCreateFaq,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResFaq>(
{url: `/v1/place/${placeId}/faq`, method: 'POST',
headers: {'Content-Type': 'application/json', },
data: reqCreateFaq, signal
return customFetch<ResFaq>(
{
url: `/v1/place/${placeId}/faq`,
method: "POST",
headers: { "Content-Type": "application/json" },
data: reqCreateFaq,
signal,
},
options);
}
options,
);
};
export const getCreateFaqMutationOptions = <
TError = void | HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createFaq>>,
TError,
{ placeId: string; data: ReqCreateFaq },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createFaq>>,
TError,
{ placeId: string; data: ReqCreateFaq },
TContext
> => {
const mutationKey = ["createFaq"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export const getCreateFaqMutationOptions = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof createFaq>>, TError,{placeId: string;data: ReqCreateFaq}, TContext>, request?: SecondParameter<typeof customFetch>}
): UseMutationOptions<Awaited<ReturnType<typeof createFaq>>, TError,{placeId: string;data: ReqCreateFaq}, TContext> => {
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createFaq>>,
{ placeId: string; data: ReqCreateFaq }
> = (props) => {
const { placeId, data } = props ?? {};
const mutationKey = ['createFaq'];
const {mutation: mutationOptions, request: requestOptions} = options ?
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
options
: {...options, mutation: {...options.mutation, mutationKey}}
: {mutation: { mutationKey, }, request: undefined};
return createFaq(placeId, data, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type CreateFaqMutationResult = NonNullable<
Awaited<ReturnType<typeof createFaq>>
>;
export type CreateFaqMutationBody = ReqCreateFaq;
export type CreateFaqMutationError = void | HTTPValidationError;
const mutationFn: MutationFunction<Awaited<ReturnType<typeof createFaq>>, {placeId: string;data: ReqCreateFaq}> = (props) => {
const {placeId,data} = props ?? {};
return createFaq(placeId,data,requestOptions)
}
return { mutationFn, ...mutationOptions }}
export type CreateFaqMutationResult = NonNullable<Awaited<ReturnType<typeof createFaq>>>
export type CreateFaqMutationBody = ReqCreateFaq
export type CreateFaqMutationError = void | HTTPValidationError
/**
/**
* @summary FAQ
*/
export const useCreateFaq = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof createFaq>>, TError,{placeId: string;data: ReqCreateFaq}, TContext>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient): UseMutationResult<
Awaited<ReturnType<typeof createFaq>>,
TError,
{placeId: string;data: ReqCreateFaq},
TContext
> => {
export const useCreateFaq = <
TError = void | HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createFaq>>,
TError,
{ placeId: string; data: ReqCreateFaq },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof createFaq>>,
TError,
{ placeId: string; data: ReqCreateFaq },
TContext
> => {
const mutationOptions = getCreateFaqMutationOptions(options);
const mutationOptions = getCreateFaqMutationOptions(options);
return useMutation(mutationOptions, queryClient);
}
/**
return useMutation(mutationOptions, queryClient);
};
/**
* (FACT_STATUS_TRANSITIONS fact ). CORRECTED question/answer , .
* @summary (··)
*/
export const transitionFaq = (
placeId: string,
faqId: string,
reqTransitionFaq: ReqTransitionFaq,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
placeId: string,
faqId: string,
reqTransitionFaq: ReqTransitionFaq,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResFaq>(
{url: `/v1/place/${placeId}/faq/${faqId}/transition`, method: 'POST',
headers: {'Content-Type': 'application/json', },
data: reqTransitionFaq, signal
return customFetch<ResFaq>(
{
url: `/v1/place/${placeId}/faq/${faqId}/transition`,
method: "POST",
headers: { "Content-Type": "application/json" },
data: reqTransitionFaq,
signal,
},
options);
}
options,
);
};
export const getTransitionFaqMutationOptions = <
TError = void | HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof transitionFaq>>,
TError,
{ placeId: string; faqId: string; data: ReqTransitionFaq },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof transitionFaq>>,
TError,
{ placeId: string; faqId: string; data: ReqTransitionFaq },
TContext
> => {
const mutationKey = ["transitionFaq"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export const getTransitionFaqMutationOptions = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof transitionFaq>>, TError,{placeId: string;faqId: string;data: ReqTransitionFaq}, TContext>, request?: SecondParameter<typeof customFetch>}
): UseMutationOptions<Awaited<ReturnType<typeof transitionFaq>>, TError,{placeId: string;faqId: string;data: ReqTransitionFaq}, TContext> => {
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof transitionFaq>>,
{ placeId: string; faqId: string; data: ReqTransitionFaq }
> = (props) => {
const { placeId, faqId, data } = props ?? {};
const mutationKey = ['transitionFaq'];
const {mutation: mutationOptions, request: requestOptions} = options ?
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
options
: {...options, mutation: {...options.mutation, mutationKey}}
: {mutation: { mutationKey, }, request: undefined};
return transitionFaq(placeId, faqId, data, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type TransitionFaqMutationResult = NonNullable<
Awaited<ReturnType<typeof transitionFaq>>
>;
export type TransitionFaqMutationBody = ReqTransitionFaq;
export type TransitionFaqMutationError = void | HTTPValidationError;
const mutationFn: MutationFunction<Awaited<ReturnType<typeof transitionFaq>>, {placeId: string;faqId: string;data: ReqTransitionFaq}> = (props) => {
const {placeId,faqId,data} = props ?? {};
return transitionFaq(placeId,faqId,data,requestOptions)
}
return { mutationFn, ...mutationOptions }}
export type TransitionFaqMutationResult = NonNullable<Awaited<ReturnType<typeof transitionFaq>>>
export type TransitionFaqMutationBody = ReqTransitionFaq
export type TransitionFaqMutationError = void | HTTPValidationError
/**
/**
* @summary (··)
*/
export const useTransitionFaq = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof transitionFaq>>, TError,{placeId: string;faqId: string;data: ReqTransitionFaq}, TContext>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient): UseMutationResult<
Awaited<ReturnType<typeof transitionFaq>>,
TError,
{placeId: string;faqId: string;data: ReqTransitionFaq},
TContext
> => {
export const useTransitionFaq = <
TError = void | HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof transitionFaq>>,
TError,
{ placeId: string; faqId: string; data: ReqTransitionFaq },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof transitionFaq>>,
TError,
{ placeId: string; faqId: string; data: ReqTransitionFaq },
TContext
> => {
const mutationOptions = getTransitionFaqMutationOptions(options);
const mutationOptions = getTransitionFaqMutationOptions(options);
return useMutation(mutationOptions, queryClient);
}
return useMutation(mutationOptions, queryClient);
};

View File

@ -0,0 +1,166 @@
/**
* Generated by orval v7.21.0 🍺
* Do not edit manually.
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import { useQuery } from "@tanstack/react-query";
import type {
DataTag,
DefinedInitialDataOptions,
DefinedUseQueryResult,
QueryClient,
QueryFunction,
QueryKey,
UndefinedInitialDataOptions,
UseQueryOptions,
UseQueryResult,
} from "@tanstack/react-query";
import type { HTTPValidationError, RelayParams } from ".././model";
import { customFetch } from "../../mutator/custom-fetch";
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
/**
* . ,
** **(allowlist ).
* @summary
*/
export const relay = (
params: RelayParams,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<unknown>(
{ url: `/v1/image/relay`, method: "GET", params, signal },
options,
);
};
export const getRelayQueryKey = (params?: RelayParams) => {
return [`/v1/image/relay`, ...(params ? [params] : [])] as const;
};
export const getRelayQueryOptions = <
TData = Awaited<ReturnType<typeof relay>>,
TError = HTTPValidationError,
>(
params: RelayParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof relay>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
) => {
const { query: queryOptions, request: requestOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getRelayQueryKey(params);
const queryFn: QueryFunction<Awaited<ReturnType<typeof relay>>> = ({
signal,
}) => relay(params, requestOptions, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof relay>>,
TError,
TData
> & { queryKey: DataTag<QueryKey, TData, TError> };
};
export type RelayQueryResult = NonNullable<Awaited<ReturnType<typeof relay>>>;
export type RelayQueryError = HTTPValidationError;
export function useRelay<
TData = Awaited<ReturnType<typeof relay>>,
TError = HTTPValidationError,
>(
params: RelayParams,
options: {
query: Partial<
UseQueryOptions<Awaited<ReturnType<typeof relay>>, TError, TData>
> &
Pick<
DefinedInitialDataOptions<
Awaited<ReturnType<typeof relay>>,
TError,
Awaited<ReturnType<typeof relay>>
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useRelay<
TData = Awaited<ReturnType<typeof relay>>,
TError = HTTPValidationError,
>(
params: RelayParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof relay>>, TError, TData>
> &
Pick<
UndefinedInitialDataOptions<
Awaited<ReturnType<typeof relay>>,
TError,
Awaited<ReturnType<typeof relay>>
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useRelay<
TData = Awaited<ReturnType<typeof relay>>,
TError = HTTPValidationError,
>(
params: RelayParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof relay>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
/**
* @summary
*/
export function useRelay<
TData = Awaited<ReturnType<typeof relay>>,
TError = HTTPValidationError,
>(
params: RelayParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof relay>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions = getRelayQueryOptions(params, options);
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
TData,
TError
> & { queryKey: DataTag<QueryKey, TData, TError> };
query.queryKey = queryOptions.queryKey;
return query;
}

View File

@ -4,10 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import {
useMutation,
useQuery
} from '@tanstack/react-query';
import { useMutation, useQuery } from "@tanstack/react-query";
import type {
DataTag,
DefinedInitialDataOptions,
@ -20,268 +17,374 @@ import type {
UseMutationOptions,
UseMutationResult,
UseQueryOptions,
UseQueryResult
} from '@tanstack/react-query';
UseQueryResult,
} from "@tanstack/react-query";
import type {
HTTPValidationError,
ResJob,
ResJobOps
} from '.././model';
import { customFetch } from '../../mutator/custom-fetch';
import type { HTTPValidationError, ResJob, ResJobOps } from ".././model";
import { customFetch } from "../../mutator/custom-fetch";
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
/**
* + + 1 DEAD + (stuck). .
* @summary
*/
export const jobOps = (
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResJobOps>(
{url: `/v1/job/ops`, method: 'GET', signal
},
options);
}
return customFetch<ResJobOps>(
{ url: `/v1/job/ops`, method: "GET", signal },
options,
);
};
export const getJobOpsQueryKey = () => {
return [
`/v1/job/ops`
] as const;
}
return [`/v1/job/ops`] as const;
};
export const getJobOpsQueryOptions = <TData = Awaited<ReturnType<typeof jobOps>>, TError = void>( options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof jobOps>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
) => {
export const getJobOpsQueryOptions = <
TData = Awaited<ReturnType<typeof jobOps>>,
TError = void,
>(options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof jobOps>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
}) => {
const { query: queryOptions, request: requestOptions } = options ?? {};
const {query: queryOptions, request: requestOptions} = options ?? {};
const queryKey = queryOptions?.queryKey ?? getJobOpsQueryKey();
const queryKey = queryOptions?.queryKey ?? getJobOpsQueryKey();
const queryFn: QueryFunction<Awaited<ReturnType<typeof jobOps>>> = ({
signal,
}) => jobOps(requestOptions, signal);
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof jobOps>>,
TError,
TData
> & { queryKey: DataTag<QueryKey, TData, TError> };
};
const queryFn: QueryFunction<Awaited<ReturnType<typeof jobOps>>> = ({ signal }) => jobOps(requestOptions, signal);
export type JobOpsQueryResult = NonNullable<Awaited<ReturnType<typeof jobOps>>>;
export type JobOpsQueryError = void;
return { queryKey, queryFn, ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof jobOps>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
}
export type JobOpsQueryResult = NonNullable<Awaited<ReturnType<typeof jobOps>>>
export type JobOpsQueryError = void
export function useJobOps<TData = Awaited<ReturnType<typeof jobOps>>, TError = void>(
options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof jobOps>>, TError, TData>> & Pick<
export function useJobOps<
TData = Awaited<ReturnType<typeof jobOps>>,
TError = void,
>(
options: {
query: Partial<
UseQueryOptions<Awaited<ReturnType<typeof jobOps>>, TError, TData>
> &
Pick<
DefinedInitialDataOptions<
Awaited<ReturnType<typeof jobOps>>,
TError,
Awaited<ReturnType<typeof jobOps>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useJobOps<TData = Awaited<ReturnType<typeof jobOps>>, TError = void>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof jobOps>>, TError, TData>> & Pick<
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useJobOps<
TData = Awaited<ReturnType<typeof jobOps>>,
TError = void,
>(
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof jobOps>>, TError, TData>
> &
Pick<
UndefinedInitialDataOptions<
Awaited<ReturnType<typeof jobOps>>,
TError,
Awaited<ReturnType<typeof jobOps>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useJobOps<TData = Awaited<ReturnType<typeof jobOps>>, TError = void>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof jobOps>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useJobOps<
TData = Awaited<ReturnType<typeof jobOps>>,
TError = void,
>(
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof jobOps>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
/**
* @summary
*/
export function useJobOps<TData = Awaited<ReturnType<typeof jobOps>>, TError = void>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof jobOps>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
export function useJobOps<
TData = Awaited<ReturnType<typeof jobOps>>,
TError = void,
>(
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof jobOps>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions = getJobOpsQueryOptions(options);
const queryOptions = getJobOpsQueryOptions(options)
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
TData,
TError
> & { queryKey: DataTag<QueryKey, TData, TError> };
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
query.queryKey = queryOptions.queryKey ;
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* @summary ()
*/
export const getJob = (
jobId: string,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
jobId: string,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResJob>(
{url: `/v1/job/${jobId}`, method: 'GET', signal
},
options);
}
return customFetch<ResJob>(
{ url: `/v1/job/${jobId}`, method: "GET", signal },
options,
);
};
export const getGetJobQueryKey = (jobId?: string) => {
return [`/v1/job/${jobId}`] as const;
};
export const getGetJobQueryKey = (jobId?: string,) => {
return [
`/v1/job/${jobId}`
] as const;
}
export const getGetJobQueryOptions = <TData = Awaited<ReturnType<typeof getJob>>, TError = void | HTTPValidationError>(jobId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
export const getGetJobQueryOptions = <
TData = Awaited<ReturnType<typeof getJob>>,
TError = void | HTTPValidationError,
>(
jobId: string,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
) => {
const { query: queryOptions, request: requestOptions } = options ?? {};
const {query: queryOptions, request: requestOptions} = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetJobQueryKey(jobId);
const queryKey = queryOptions?.queryKey ?? getGetJobQueryKey(jobId);
const queryFn: QueryFunction<Awaited<ReturnType<typeof getJob>>> = ({
signal,
}) => getJob(jobId, requestOptions, signal);
return {
queryKey,
queryFn,
enabled: !!jobId,
...queryOptions,
} as UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
};
const queryFn: QueryFunction<Awaited<ReturnType<typeof getJob>>> = ({ signal }) => getJob(jobId, requestOptions, signal);
export type GetJobQueryResult = NonNullable<Awaited<ReturnType<typeof getJob>>>;
export type GetJobQueryError = void | HTTPValidationError;
return { queryKey, queryFn, enabled: !!(jobId), ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
}
export type GetJobQueryResult = NonNullable<Awaited<ReturnType<typeof getJob>>>
export type GetJobQueryError = void | HTTPValidationError
export function useGetJob<TData = Awaited<ReturnType<typeof getJob>>, TError = void | HTTPValidationError>(
jobId: string, options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData>> & Pick<
export function useGetJob<
TData = Awaited<ReturnType<typeof getJob>>,
TError = void | HTTPValidationError,
>(
jobId: string,
options: {
query: Partial<
UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData>
> &
Pick<
DefinedInitialDataOptions<
Awaited<ReturnType<typeof getJob>>,
TError,
Awaited<ReturnType<typeof getJob>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useGetJob<TData = Awaited<ReturnType<typeof getJob>>, TError = void | HTTPValidationError>(
jobId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData>> & Pick<
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useGetJob<
TData = Awaited<ReturnType<typeof getJob>>,
TError = void | HTTPValidationError,
>(
jobId: string,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData>
> &
Pick<
UndefinedInitialDataOptions<
Awaited<ReturnType<typeof getJob>>,
TError,
Awaited<ReturnType<typeof getJob>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useGetJob<TData = Awaited<ReturnType<typeof getJob>>, TError = void | HTTPValidationError>(
jobId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useGetJob<
TData = Awaited<ReturnType<typeof getJob>>,
TError = void | HTTPValidationError,
>(
jobId: string,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
/**
* @summary ()
*/
export function useGetJob<TData = Awaited<ReturnType<typeof getJob>>, TError = void | HTTPValidationError>(
jobId: string, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
export function useGetJob<
TData = Awaited<ReturnType<typeof getJob>>,
TError = void | HTTPValidationError,
>(
jobId: string,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof getJob>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions = getGetJobQueryOptions(jobId, options);
const queryOptions = getGetJobQueryOptions(jobId,options)
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
TData,
TError
> & { queryKey: DataTag<QueryKey, TData, TError> };
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
query.queryKey = queryOptions.queryKey ;
query.queryKey = queryOptions.queryKey;
return query;
}
/**
* max_attempts dead-letter . .
* @summary DEAD
*/
export const requeueJob = (
jobId: string,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
jobId: string,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResJob>(
{url: `/v1/job/${jobId}/requeue`, method: 'POST', signal
},
options);
}
return customFetch<ResJob>(
{ url: `/v1/job/${jobId}/requeue`, method: "POST", signal },
options,
);
};
export const getRequeueJobMutationOptions = <
TError = void | HTTPValidationError,
TContext = unknown,
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof requeueJob>>,
TError,
{ jobId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
}): UseMutationOptions<
Awaited<ReturnType<typeof requeueJob>>,
TError,
{ jobId: string },
TContext
> => {
const mutationKey = ["requeueJob"];
const { mutation: mutationOptions, request: requestOptions } = options
? options.mutation &&
"mutationKey" in options.mutation &&
options.mutation.mutationKey
? options
: { ...options, mutation: { ...options.mutation, mutationKey } }
: { mutation: { mutationKey }, request: undefined };
export const getRequeueJobMutationOptions = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof requeueJob>>, TError,{jobId: string}, TContext>, request?: SecondParameter<typeof customFetch>}
): UseMutationOptions<Awaited<ReturnType<typeof requeueJob>>, TError,{jobId: string}, TContext> => {
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof requeueJob>>,
{ jobId: string }
> = (props) => {
const { jobId } = props ?? {};
const mutationKey = ['requeueJob'];
const {mutation: mutationOptions, request: requestOptions} = options ?
options.mutation && 'mutationKey' in options.mutation && options.mutation.mutationKey ?
options
: {...options, mutation: {...options.mutation, mutationKey}}
: {mutation: { mutationKey, }, request: undefined};
return requeueJob(jobId, requestOptions);
};
return { mutationFn, ...mutationOptions };
};
export type RequeueJobMutationResult = NonNullable<
Awaited<ReturnType<typeof requeueJob>>
>;
const mutationFn: MutationFunction<Awaited<ReturnType<typeof requeueJob>>, {jobId: string}> = (props) => {
const {jobId} = props ?? {};
export type RequeueJobMutationError = void | HTTPValidationError;
return requeueJob(jobId,requestOptions)
}
return { mutationFn, ...mutationOptions }}
export type RequeueJobMutationResult = NonNullable<Awaited<ReturnType<typeof requeueJob>>>
export type RequeueJobMutationError = void | HTTPValidationError
/**
/**
* @summary DEAD
*/
export const useRequeueJob = <TError = void | HTTPValidationError,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof requeueJob>>, TError,{jobId: string}, TContext>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient): UseMutationResult<
Awaited<ReturnType<typeof requeueJob>>,
TError,
{jobId: string},
TContext
> => {
export const useRequeueJob = <
TError = void | HTTPValidationError,
TContext = unknown,
>(
options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof requeueJob>>,
TError,
{ jobId: string },
TContext
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseMutationResult<
Awaited<ReturnType<typeof requeueJob>>,
TError,
{ jobId: string },
TContext
> => {
const mutationOptions = getRequeueJobMutationOptions(options);
const mutationOptions = getRequeueJobMutationOptions(options);
return useMutation(mutationOptions, queryClient);
}
return useMutation(mutationOptions, queryClient);
};

View File

@ -4,9 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import {
useQuery
} from '@tanstack/react-query';
import { useQuery } from "@tanstack/react-query";
import type {
DataTag,
DefinedInitialDataOptions,
@ -16,120 +14,174 @@ import type {
QueryKey,
UndefinedInitialDataOptions,
UseQueryOptions,
UseQueryResult
} from '@tanstack/react-query';
UseQueryResult,
} from "@tanstack/react-query";
import type {
HTTPValidationError,
ListMediaParams,
ResMediaList
} from '.././model';
import { customFetch } from '../../mutator/custom-fetch';
ResMediaList,
} from ".././model";
import { customFetch } from "../../mutator/custom-fetch";
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
/**
* publishable_only=true ( + alt ) . unit_id · . source_type(owner/crawl) origin_url (docs/DECISIONS.md 1-2) CRAWL , .
* @summary
*/
export const listMedia = (
placeId: string,
params?: ListMediaParams,
options?: SecondParameter<typeof customFetch>,signal?: AbortSignal
placeId: string,
params?: ListMediaParams,
options?: SecondParameter<typeof customFetch>,
signal?: AbortSignal,
) => {
return customFetch<ResMediaList>(
{url: `/v1/place/${placeId}/media/list`, method: 'GET',
params, signal
},
options);
}
return customFetch<ResMediaList>(
{ url: `/v1/place/${placeId}/media/list`, method: "GET", params, signal },
options,
);
};
export const getListMediaQueryKey = (placeId?: string,
params?: ListMediaParams,) => {
return [
`/v1/place/${placeId}/media/list`, ...(params ? [params]: [])
] as const;
}
export const getListMediaQueryOptions = <TData = Awaited<ReturnType<typeof listMedia>>, TError = void | HTTPValidationError>(placeId: string,
params?: ListMediaParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
export const getListMediaQueryKey = (
placeId?: string,
params?: ListMediaParams,
) => {
return [
`/v1/place/${placeId}/media/list`,
...(params ? [params] : []),
] as const;
};
const {query: queryOptions, request: requestOptions} = options ?? {};
export const getListMediaQueryOptions = <
TData = Awaited<ReturnType<typeof listMedia>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListMediaParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
) => {
const { query: queryOptions, request: requestOptions } = options ?? {};
const queryKey = queryOptions?.queryKey ?? getListMediaQueryKey(placeId,params);
const queryKey =
queryOptions?.queryKey ?? getListMediaQueryKey(placeId, params);
const queryFn: QueryFunction<Awaited<ReturnType<typeof listMedia>>> = ({
signal,
}) => listMedia(placeId, params, requestOptions, signal);
const queryFn: QueryFunction<Awaited<ReturnType<typeof listMedia>>> = ({ signal }) => listMedia(placeId,params, requestOptions, signal);
return {
queryKey,
queryFn,
enabled: !!placeId,
...queryOptions,
} as UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
};
export type ListMediaQueryResult = NonNullable<
Awaited<ReturnType<typeof listMedia>>
>;
export type ListMediaQueryError = void | HTTPValidationError;
return { queryKey, queryFn, enabled: !!(placeId), ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
}
export type ListMediaQueryResult = NonNullable<Awaited<ReturnType<typeof listMedia>>>
export type ListMediaQueryError = void | HTTPValidationError
export function useListMedia<TData = Awaited<ReturnType<typeof listMedia>>, TError = void | HTTPValidationError>(
placeId: string,
params: undefined | ListMediaParams, options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData>> & Pick<
export function useListMedia<
TData = Awaited<ReturnType<typeof listMedia>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params: undefined | ListMediaParams,
options: {
query: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData>
> &
Pick<
DefinedInitialDataOptions<
Awaited<ReturnType<typeof listMedia>>,
TError,
Awaited<ReturnType<typeof listMedia>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useListMedia<TData = Awaited<ReturnType<typeof listMedia>>, TError = void | HTTPValidationError>(
placeId: string,
params?: ListMediaParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData>> & Pick<
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): DefinedUseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useListMedia<
TData = Awaited<ReturnType<typeof listMedia>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListMediaParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData>
> &
Pick<
UndefinedInitialDataOptions<
Awaited<ReturnType<typeof listMedia>>,
TError,
Awaited<ReturnType<typeof listMedia>>
> , 'initialData'
>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useListMedia<TData = Awaited<ReturnType<typeof listMedia>>, TError = void | HTTPValidationError>(
placeId: string,
params?: ListMediaParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
>,
"initialData"
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
export function useListMedia<
TData = Awaited<ReturnType<typeof listMedia>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListMediaParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
};
/**
* @summary
*/
export function useListMedia<TData = Awaited<ReturnType<typeof listMedia>>, TError = void | HTTPValidationError>(
placeId: string,
params?: ListMediaParams, options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData>>, request?: SecondParameter<typeof customFetch>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
export function useListMedia<
TData = Awaited<ReturnType<typeof listMedia>>,
TError = void | HTTPValidationError,
>(
placeId: string,
params?: ListMediaParams,
options?: {
query?: Partial<
UseQueryOptions<Awaited<ReturnType<typeof listMedia>>, TError, TData>
>;
request?: SecondParameter<typeof customFetch>;
},
queryClient?: QueryClient,
): UseQueryResult<TData, TError> & {
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions = getListMediaQueryOptions(placeId, params, options);
const queryOptions = getListMediaQueryOptions(placeId,params,options)
const query = useQuery(queryOptions, queryClient) as UseQueryResult<
TData,
TError
> & { queryKey: DataTag<QueryKey, TData, TError> };
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
query.queryKey = queryOptions.queryKey ;
query.queryKey = queryOptions.queryKey;
return query;
}

View File

@ -4,7 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { AuditCheckDataRecommendation } from './auditCheckDataRecommendation';
import type { AuditCheckDataRecommendation } from "./auditCheckDataRecommendation";
export interface AuditCheckData {
id: string;

View File

@ -12,8 +12,7 @@
"먼저 가입한 쪽의 소유" ,
( ). DECISIONS.md 1.
*/
export type AuthProvider = typeof AuthProvider[keyof typeof AuthProvider];
export type AuthProvider = (typeof AuthProvider)[keyof typeof AuthProvider];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const AuthProvider = {

View File

@ -8,8 +8,7 @@
/**
* site_versions.build_status . .
*/
export type BuildStatus = typeof BuildStatus[keyof typeof BuildStatus];
export type BuildStatus = (typeof BuildStatus)[keyof typeof BuildStatus];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const BuildStatus = {

View File

@ -6,8 +6,8 @@
*/
export type CheckSlugParams = {
/**
* (: doflo)
*/
slug: string;
/**
* (: doflo)
*/
slug: string;
};

View File

@ -4,9 +4,9 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { ErrorInfoSuccess } from './errorInfoSuccess';
import type { ErrorInfoCode } from './errorInfoCode';
import type { ErrorInfoDesc } from './errorInfoDesc';
import type { ErrorInfoSuccess } from "./errorInfoSuccess";
import type { ErrorInfoCode } from "./errorInfoCode";
import type { ErrorInfoDesc } from "./errorInfoDesc";
/**
* . result.success / code / desc .

View File

@ -11,8 +11,8 @@
place id .
id ( link ) + .
*/
export type ExternalPlaceSource = typeof ExternalPlaceSource[keyof typeof ExternalPlaceSource];
export type ExternalPlaceSource =
(typeof ExternalPlaceSource)[keyof typeof ExternalPlaceSource];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const ExternalPlaceSource = {

View File

@ -4,17 +4,17 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { FactDataUnitId } from './factDataUnitId';
import type { FactDataValue } from './factDataValue';
import type { FactDataSummary } from './factDataSummary';
import type { FactDataUnit } from './factDataUnit';
import type { SourceType } from './sourceType';
import type { FactDataSourceUrl } from './factDataSourceUrl';
import type { FactDataCollectedAt } from './factDataCollectedAt';
import type { FactDataVerifiedBy } from './factDataVerifiedBy';
import type { FactDataVerifiedAt } from './factDataVerifiedAt';
import type { FactStatus } from './factStatus';
import type { FactDataExpiresAt } from './factDataExpiresAt';
import type { FactDataUnitId } from "./factDataUnitId";
import type { FactDataValue } from "./factDataValue";
import type { FactDataSummary } from "./factDataSummary";
import type { FactDataUnit } from "./factDataUnit";
import type { SourceType } from "./sourceType";
import type { FactDataSourceUrl } from "./factDataSourceUrl";
import type { FactDataCollectedAt } from "./factDataCollectedAt";
import type { FactDataVerifiedBy } from "./factDataVerifiedBy";
import type { FactDataVerifiedAt } from "./factDataVerifiedAt";
import type { FactStatus } from "./factStatus";
import type { FactDataExpiresAt } from "./factDataExpiresAt";
export interface FactData {
fact_id: string;

View File

@ -9,8 +9,7 @@
* facts.status / faqs.status / routes.status .
VERIFIED CORRECTED (PUBLISHABLE_FACT_STATUSES).
*/
export type FactStatus = typeof FactStatus[keyof typeof FactStatus];
export type FactStatus = (typeof FactStatus)[keyof typeof FactStatus];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const FactStatus = {

View File

@ -9,8 +9,8 @@
* fact . ()
(PUBLISHED_REPLACED) .
*/
export type FactWriteOutcome = typeof FactWriteOutcome[keyof typeof FactWriteOutcome];
export type FactWriteOutcome =
(typeof FactWriteOutcome)[keyof typeof FactWriteOutcome];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const FactWriteOutcome = {

View File

@ -4,11 +4,11 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { FaqDataSourceFactIds } from './faqDataSourceFactIds';
import type { SourceType } from './sourceType';
import type { FactStatus } from './factStatus';
import type { FaqDataCreatedAt } from './faqDataCreatedAt';
import type { FaqDataUpdatedAt } from './faqDataUpdatedAt';
import type { FaqDataSourceFactIds } from "./faqDataSourceFactIds";
import type { SourceType } from "./sourceType";
import type { FactStatus } from "./factStatus";
import type { FaqDataCreatedAt } from "./faqDataCreatedAt";
import type { FaqDataUpdatedAt } from "./faqDataUpdatedAt";
export interface FaqData {
faq_id: string;

View File

@ -4,7 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { FieldSpecDataUnit } from './fieldSpecDataUnit';
import type { FieldSpecDataUnit } from "./fieldSpecDataUnit";
/**
* .

View File

@ -5,4 +5,6 @@
* OpenAPI spec version: 0.1.0
*/
export type ReqSyncFestivalsAreaCode = string | null;
export type GetGuideParams = {
place_id: string;
};

View File

@ -6,19 +6,19 @@
*/
export type GetWeatherParams = {
/**
* @minLength 1
* @maxLength 10
*/
region_code: string;
/**
* @minimum -90
* @maximum 90
*/
latitude: number;
/**
* @minimum -180
* @maximum 180
*/
longitude: number;
/**
* @minLength 1
* @maxLength 10
*/
region_code: string;
/**
* @minimum -90
* @maximum 90
*/
latitude: number;
/**
* @minimum -180
* @maximum 180
*/
longitude: number;
};

View File

@ -4,7 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { ValidationError } from './validationError';
import type { ValidationError } from "./validationError";
export interface HTTPValidationError {
detail?: ValidationError[];

View File

@ -5,318 +5,333 @@
* OpenAPI spec version: 0.1.0
*/
export * from './auditCheckData';
export * from './auditCheckDataRecommendation';
export * from './authProvider';
export * from './buildStatus';
export * from './checkSlugParams';
export * from './errorInfo';
export * from './errorInfoCode';
export * from './errorInfoDesc';
export * from './errorInfoSuccess';
export * from './externalPlaceSource';
export * from './factData';
export * from './factDataCollectedAt';
export * from './factDataExpiresAt';
export * from './factDataSourceUrl';
export * from './factDataSummary';
export * from './factDataUnit';
export * from './factDataUnitId';
export * from './factDataValue';
export * from './factDataVerifiedAt';
export * from './factDataVerifiedBy';
export * from './factStatus';
export * from './factWriteOutcome';
export * from './faqData';
export * from './faqDataCreatedAt';
export * from './faqDataSourceFactIds';
export * from './faqDataUpdatedAt';
export * from './fieldSpecData';
export * from './fieldSpecDataUnit';
export * from './getWeatherParams';
export * from './hTTPValidationError';
export * from './jobData';
export * from './jobDataCreatedAt';
export * from './jobDataLastError';
export * from './jobDataResult';
export * from './jobDataRunAfter';
export * from './jobDataRunStartedAt';
export * from './jobDataUpdatedAt';
export * from './jobStatus';
export * from './jobType';
export * from './linkChannel';
export * from './linkData';
export * from './linkDataConfirmedAt';
export * from './linkDataDiscoveredAt';
export * from './linkDataTitle';
export * from './listContentsParams';
export * from './listFactsParams';
export * from './listFaqsParams';
export * from './listLinksParams';
export * from './listMediaParams';
export * from './listMySitesParams';
export * from './listPlacesParams';
export * from './listShowcaseParams';
export * from './localContentData';
export * from './localContentDataBody';
export * from './localContentDataCollectedAt';
export * from './localContentDataDisplayEndAt';
export * from './localContentDataDisplayStartAt';
export * from './localContentDataExternalId';
export * from './localContentDataPublishedAt';
export * from './localContentDataTitle';
export * from './localContentStatus';
export * from './localContentType';
export * from './localSource';
export * from './mediaData';
export * from './mediaDataAltText';
export * from './mediaDataCreatedAt';
export * from './mediaDataHeight';
export * from './mediaDataLabel';
export * from './mediaDataOriginUrl';
export * from './mediaDataSourceUrl';
export * from './mediaDataUnitId';
export * from './mediaDataVisionConfidence';
export * from './mediaDataWidth';
export * from './mediaStatus';
export * from './mySiteData';
export * from './mySiteDataCreatedAt';
export * from './mySiteDataDomain';
export * from './mySiteDataPublishedAt';
export * from './mySiteDataThumbnailUrl';
export * from './mySiteDataRoadAddress';
export * from './mySiteDataSiteId';
export * from './mySiteDataStatus';
export * from './mySiteDataTemplateId';
export * from './placeCandidate';
export * from './placeCandidateAddress';
export * from './placeCandidateCategoryName';
export * from './placeCandidateExternalPlaceId';
export * from './placeCandidateLatitude';
export * from './placeCandidateLongitude';
export * from './placeCandidateNaverPlaceUrl';
export * from './placeCandidatePhone';
export * from './placeCandidatePlaceUrl';
export * from './placeCandidateRoadAddress';
export * from './placeCategory';
export * from './placeData';
export * from './placeDataAddress';
export * from './placeDataContentUpdatedAt';
export * from './placeDataCreatedAt';
export * from './placeDataExternalPlaceId';
export * from './placeDataExternalSource';
export * from './placeDataLatitude';
export * from './placeDataLongitude';
export * from './placeDataOwnerUserId';
export * from './placeDataPhone';
export * from './placeDataRegionCode';
export * from './placeDataRoadAddress';
export * from './placeDataVerifiedAt';
export * from './placeSearchItem';
export * from './placeSearchItemCategory';
export * from './placeSearchItemCategoryName';
export * from './placeSearchItemRoadAddress';
export * from './placeStatus';
export * from './publishAction';
export * from './publishLogData';
export * from './publishLogDataCreatedAt';
export * from './publishLogDataDetail';
export * from './publishLogDataRejectReason';
export * from './publishRejectReason';
export * from './publishResult';
export * from './renderStatusData';
export * from './renderStatusDataError';
export * from './renderStatusDataRenderedAt';
export * from './renderStatusDataRenderedVersion';
export * from './reqCreateFaq';
export * from './reqCreateFaqSortOrder';
export * from './reqCreateLink';
export * from './reqCreateLinkTitle';
export * from './reqCreatePlace';
export * from './reqCreatePlaceOwnerUserId';
export * from './reqCreateUnit';
export * from './reqExtractFacts';
export * from './reqGoogleLogin';
export * from './reqLogin';
export * from './reqPublishLocalContent';
export * from './reqSignup';
export * from './reqSignupName';
export * from './reqSiteSlug';
export * from './reqSiteStatus';
export * from './reqSiteTemplate';
export * from './reqSiteTheme';
export * from './reqSiteThemeTheme';
export * from './reqStartBuild';
export * from './reqStartCollect';
export * from './reqStartCopy';
export * from './reqStartVision';
export * from './reqSyncFestivals';
export * from './reqSyncFestivalsAreaCode';
export * from './reqSyncFestivalsStartDate';
export * from './reqTransitionFact';
export * from './reqTransitionFactValue';
export * from './reqTransitionFaq';
export * from './reqTransitionFaqAnswer';
export * from './reqTransitionFaqQuestion';
export * from './reqUpdateLocalContent';
export * from './reqUpdateLocalContentBody';
export * from './reqUpdateLocalContentBodyAnyOf';
export * from './reqUpdateLocalContentDisplayEndAt';
export * from './reqUpdateLocalContentDisplayStartAt';
export * from './reqUpdateLocalContentTitle';
export * from './reqUpdateMe';
export * from './reqUpdateMeContactNumber';
export * from './reqUpdateMeEmail';
export * from './reqUpdateMeName';
export * from './reqUpdateMePassword';
export * from './reqUpdatePlace';
export * from './reqUpdatePlaceName';
export * from './reqUpdatePlaceOwnerUserId';
export * from './reqUpdatePlaceStatus';
export * from './reqUpsertFact';
export * from './reqUpsertFactExpiresAt';
export * from './reqUpsertFactSourceUrl';
export * from './reqUpsertFactUnitId';
export * from './reqUpsertFactValue';
export * from './reqVerifyPlace';
export * from './reqVerifyPlaceAddress';
export * from './reqVerifyPlaceByUrl';
export * from './reqVerifyPlaceLatitude';
export * from './reqVerifyPlaceLongitude';
export * from './reqVerifyPlacePhone';
export * from './reqVerifyPlacePlaceUrl';
export * from './reqVerifyPlaceRegionCode';
export * from './reqVerifyPlaceRoadAddress';
export * from './resCategorySchema';
export * from './resCategorySchemaCategory';
export * from './resCategorySchemaLabel';
export * from './resCategorySchemaMsg';
export * from './resExtractFacts';
export * from './resExtractFactsMsg';
export * from './resExtractedFact';
export * from './resExtractedFactReason';
export * from './resExtractedFactUnitName';
export * from './resFact';
export * from './resFactFact';
export * from './resFactList';
export * from './resFactListMsg';
export * from './resFactMsg';
export * from './resFactOutcome';
export * from './resFaq';
export * from './resFaqFaq';
export * from './resFaqList';
export * from './resFaqListMsg';
export * from './resFaqMsg';
export * from './resJob';
export * from './resJobJob';
export * from './resJobMsg';
export * from './resJobOps';
export * from './resJobOpsMsg';
export * from './resLink';
export * from './resLinkLink';
export * from './resLinkList';
export * from './resLinkListMsg';
export * from './resLinkMsg';
export * from './resLocalContentList';
export * from './resLocalContentListMsg';
export * from './resLogin';
export * from './resLoginMsg';
export * from './resMe';
export * from './resMeContactNumber';
export * from './resMeEmail';
export * from './resMeMsg';
export * from './resMeName';
export * from './resMediaList';
export * from './resMediaListMsg';
export * from './resMySites';
export * from './resMySitesMsg';
export * from './resPlace';
export * from './resPlaceList';
export * from './resPlaceListMsg';
export * from './resPlaceMsg';
export * from './resPlacePlace';
export * from './resPlaceSearch';
export * from './resPlaceSearchMsg';
export * from './resPlaceSearchSource';
export * from './resPublishLogs';
export * from './resPublishLogsMsg';
export * from './resRefreshToken';
export * from './resRefreshTokenMsg';
export * from './resSeoAudit';
export * from './resSeoAuditMsg';
export * from './resSeoAuditSummary';
export * from './resSeoAuditVisibility';
export * from './resShowcase';
export * from './resShowcaseMsg';
export * from './resSite';
export * from './resSiteCurrentVersion';
export * from './resSiteMsg';
export * from './resSiteSite';
export * from './resSiteSlug';
export * from './resSiteSlugMsg';
export * from './resSiteSlugReason';
export * from './resSiteSlugSite';
export * from './resSiteSlugSuggestion';
export * from './resSiteVersions';
export * from './resSiteVersionsMsg';
export * from './resSlugCheck';
export * from './resSlugCheckMsg';
export * from './resSlugCheckReason';
export * from './resSlugCheckSuggestion';
export * from './resStartBuild';
export * from './resStartBuildJobId';
export * from './resStartBuildMsg';
export * from './resStartBuildStatus';
export * from './resStartCollect';
export * from './resStartCollectJobId';
export * from './resStartCollectMsg';
export * from './resStartCollectStatus';
export * from './resStartCopy';
export * from './resStartCopyJobId';
export * from './resStartCopyMsg';
export * from './resStartCopyStatus';
export * from './resStartVision';
export * from './resStartVisionJobId';
export * from './resStartVisionMsg';
export * from './resStartVisionStatus';
export * from './resSyncFestivals';
export * from './resSyncFestivalsMsg';
export * from './resUnit';
export * from './resUnitList';
export * from './resUnitListMsg';
export * from './resUnitMsg';
export * from './resUnitUnit';
export * from './resVerifyCandidates';
export * from './resVerifyCandidatesMsg';
export * from './resVerifyCandidatesReason';
export * from './resVerifyCandidatesSource';
export * from './resWeather';
export * from './resWeatherMsg';
export * from './resWeatherWeather';
export * from './searchPlacesPublicParams';
export * from './showcaseItem';
export * from './showcaseItemRegion';
export * from './showcaseItemThumbnailUrl';
export * from './siteData';
export * from './siteDataCurrentVersionId';
export * from './siteDataDomain';
export * from './siteDataPublishedAt';
export * from './siteDataTemplateId';
export * from './siteDataTheme';
export * from './siteDataThemeAnyOf';
export * from './siteDataThumbnailUrl';
export * from './siteStatus';
export * from './siteVersionData';
export * from './siteVersionDataBuildError';
export * from './siteVersionDataBuiltAt';
export * from './siteVersionDataCreatedAt';
export * from './sourceType';
export * from './unitData';
export * from './userRole';
export * from './validationError';
export * from './validationErrorCtx';
export * from './validationErrorLocItem';
export * from './verifyCandidatesParams';
export * from './weatherData';
export * from './weatherDataTimezone';
export * from './weatherDataWindSpeed';
export * from "./auditCheckData";
export * from "./auditCheckDataRecommendation";
export * from "./authProvider";
export * from "./buildStatus";
export * from "./checkSlugParams";
export * from "./errorInfo";
export * from "./errorInfoCode";
export * from "./errorInfoDesc";
export * from "./errorInfoSuccess";
export * from "./externalPlaceSource";
export * from "./factData";
export * from "./factDataCollectedAt";
export * from "./factDataExpiresAt";
export * from "./factDataSourceUrl";
export * from "./factDataSummary";
export * from "./factDataUnit";
export * from "./factDataUnitId";
export * from "./factDataValue";
export * from "./factDataVerifiedAt";
export * from "./factDataVerifiedBy";
export * from "./factStatus";
export * from "./factWriteOutcome";
export * from "./faqData";
export * from "./faqDataCreatedAt";
export * from "./faqDataSourceFactIds";
export * from "./faqDataUpdatedAt";
export * from "./fieldSpecData";
export * from "./fieldSpecDataUnit";
export * from "./getGuideParams";
export * from "./getWeatherParams";
export * from "./hTTPValidationError";
export * from "./jobData";
export * from "./jobDataCreatedAt";
export * from "./jobDataLastError";
export * from "./jobDataResult";
export * from "./jobDataRunAfter";
export * from "./jobDataRunStartedAt";
export * from "./jobDataUpdatedAt";
export * from "./jobStatus";
export * from "./jobType";
export * from "./linkChannel";
export * from "./linkData";
export * from "./linkDataConfirmedAt";
export * from "./linkDataDiscoveredAt";
export * from "./linkDataTitle";
export * from "./listContentsParams";
export * from "./listFactsParams";
export * from "./listFaqsParams";
export * from "./listLinksParams";
export * from "./listMediaParams";
export * from "./listMySitesParams";
export * from "./listPlacesParams";
export * from "./listShowcaseParams";
export * from "./localContentData";
export * from "./localContentDataBody";
export * from "./localContentDataCollectedAt";
export * from "./localContentDataDisplayEndAt";
export * from "./localContentDataDisplayStartAt";
export * from "./localContentDataExternalId";
export * from "./localContentDataPublishedAt";
export * from "./localContentDataTitle";
export * from "./localContentStatus";
export * from "./localContentType";
export * from "./localSource";
export * from "./mediaData";
export * from "./mediaDataAltText";
export * from "./mediaDataCreatedAt";
export * from "./mediaDataHeight";
export * from "./mediaDataLabel";
export * from "./mediaDataOriginUrl";
export * from "./mediaDataSourceUrl";
export * from "./mediaDataUnitId";
export * from "./mediaDataVisionConfidence";
export * from "./mediaDataWidth";
export * from "./mediaStatus";
export * from "./mySiteData";
export * from "./mySiteDataCreatedAt";
export * from "./mySiteDataDomain";
export * from "./mySiteDataPublishedAt";
export * from "./mySiteDataRoadAddress";
export * from "./mySiteDataSiteId";
export * from "./mySiteDataStatus";
export * from "./mySiteDataTemplateId";
export * from "./mySiteDataThumbnailUrl";
export * from "./placeCandidate";
export * from "./placeCandidateAddress";
export * from "./placeCandidateCategoryName";
export * from "./placeCandidateExternalPlaceId";
export * from "./placeCandidateLatitude";
export * from "./placeCandidateLongitude";
export * from "./placeCandidateNaverPlaceUrl";
export * from "./placeCandidatePhone";
export * from "./placeCandidatePlaceUrl";
export * from "./placeCandidateRoadAddress";
export * from "./placeCategory";
export * from "./placeContentData";
export * from "./placeContentDataBody";
export * from "./placeContentDataCollectedAt";
export * from "./placeContentDataDisplayEndAt";
export * from "./placeData";
export * from "./placeDataAddress";
export * from "./placeDataContentUpdatedAt";
export * from "./placeDataCreatedAt";
export * from "./placeDataExternalPlaceId";
export * from "./placeDataExternalSource";
export * from "./placeDataLatitude";
export * from "./placeDataLongitude";
export * from "./placeDataOwnerUserId";
export * from "./placeDataPhone";
export * from "./placeDataRegionCode";
export * from "./placeDataRoadAddress";
export * from "./placeDataVerifiedAt";
export * from "./placeSearchItem";
export * from "./placeSearchItemCategory";
export * from "./placeSearchItemCategoryName";
export * from "./placeSearchItemNaverPlaceUrl";
export * from "./placeSearchItemRoadAddress";
export * from "./placeStatus";
export * from "./publishAction";
export * from "./publishLogData";
export * from "./publishLogDataCreatedAt";
export * from "./publishLogDataDetail";
export * from "./publishLogDataRejectReason";
export * from "./publishRejectReason";
export * from "./publishResult";
export * from "./relayParams";
export * from "./renderStatusData";
export * from "./renderStatusDataError";
export * from "./renderStatusDataRenderedAt";
export * from "./renderStatusDataRenderedVersion";
export * from "./reqCreateFaq";
export * from "./reqCreateFaqSortOrder";
export * from "./reqCreateLink";
export * from "./reqCreateLinkTitle";
export * from "./reqCreatePlace";
export * from "./reqCreateUnit";
export * from "./reqExtractFacts";
export * from "./reqGoogleLogin";
export * from "./reqHidePlaceContent";
export * from "./reqLogin";
export * from "./reqPublishLocalContent";
export * from "./reqRollback";
export * from "./reqSignup";
export * from "./reqSignupName";
export * from "./reqSiteSlug";
export * from "./reqSiteStatus";
export * from "./reqSiteTemplate";
export * from "./reqSiteTheme";
export * from "./reqSiteThemeTheme";
export * from "./reqStartBuild";
export * from "./reqStartCollect";
export * from "./reqStartCopy";
export * from "./reqStartVision";
export * from "./reqTransitionFact";
export * from "./reqTransitionFactValue";
export * from "./reqTransitionFaq";
export * from "./reqTransitionFaqAnswer";
export * from "./reqTransitionFaqQuestion";
export * from "./reqUpdateLocalContent";
export * from "./reqUpdateLocalContentBody";
export * from "./reqUpdateLocalContentBodyAnyOf";
export * from "./reqUpdateLocalContentDisplayEndAt";
export * from "./reqUpdateLocalContentDisplayStartAt";
export * from "./reqUpdateLocalContentTitle";
export * from "./reqUpdateMe";
export * from "./reqUpdateMeContactNumber";
export * from "./reqUpdateMeEmail";
export * from "./reqUpdateMeName";
export * from "./reqUpdateMePassword";
export * from "./reqUpdatePlace";
export * from "./reqUpdatePlaceName";
export * from "./reqUpdatePlaceStatus";
export * from "./reqUpsertFact";
export * from "./reqUpsertFactExpiresAt";
export * from "./reqUpsertFactSourceUrl";
export * from "./reqUpsertFactUnitId";
export * from "./reqUpsertFactValue";
export * from "./reqVerifyPlace";
export * from "./reqVerifyPlaceAddress";
export * from "./reqVerifyPlaceByUrl";
export * from "./reqVerifyPlaceCategoryName";
export * from "./reqVerifyPlaceLatitude";
export * from "./reqVerifyPlaceLongitude";
export * from "./reqVerifyPlacePhone";
export * from "./reqVerifyPlacePlaceUrl";
export * from "./reqVerifyPlaceRegionCode";
export * from "./reqVerifyPlaceRoadAddress";
export * from "./resCategorySchema";
export * from "./resCategorySchemaCategory";
export * from "./resCategorySchemaLabel";
export * from "./resCategorySchemaMsg";
export * from "./resExtractFacts";
export * from "./resExtractFactsMsg";
export * from "./resExtractedFact";
export * from "./resExtractedFactReason";
export * from "./resExtractedFactUnitName";
export * from "./resFact";
export * from "./resFactFact";
export * from "./resFactList";
export * from "./resFactListMsg";
export * from "./resFactMsg";
export * from "./resFactOutcome";
export * from "./resFaq";
export * from "./resFaqFaq";
export * from "./resFaqList";
export * from "./resFaqListMsg";
export * from "./resFaqMsg";
export * from "./resJob";
export * from "./resJobJob";
export * from "./resJobMsg";
export * from "./resJobOps";
export * from "./resJobOpsMsg";
export * from "./resLink";
export * from "./resLinkLink";
export * from "./resLinkList";
export * from "./resLinkListMsg";
export * from "./resLinkMsg";
export * from "./resLocalContentList";
export * from "./resLocalContentListMsg";
export * from "./resLocalGuide";
export * from "./resLocalGuideAttractionsItem";
export * from "./resLocalGuideCoursesItem";
export * from "./resLocalGuideFestivalsItem";
export * from "./resLocalGuideItinerariesItem";
export * from "./resLocalGuideMsg";
export * from "./resLocalGuideRestaurantsItem";
export * from "./resLocalGuideSyncedAt";
export * from "./resLogin";
export * from "./resLoginMsg";
export * from "./resMe";
export * from "./resMeContactNumber";
export * from "./resMeEmail";
export * from "./resMeMsg";
export * from "./resMeName";
export * from "./resMediaList";
export * from "./resMediaListMsg";
export * from "./resMySites";
export * from "./resMySitesMsg";
export * from "./resPlace";
export * from "./resPlaceContentList";
export * from "./resPlaceContentListMsg";
export * from "./resPlaceList";
export * from "./resPlaceListMsg";
export * from "./resPlaceMsg";
export * from "./resPlacePlace";
export * from "./resPlaceSearch";
export * from "./resPlaceSearchMsg";
export * from "./resPlaceSearchSource";
export * from "./resPublishLogs";
export * from "./resPublishLogsMsg";
export * from "./resRefreshToken";
export * from "./resRefreshTokenMsg";
export * from "./resSeoAudit";
export * from "./resSeoAuditMsg";
export * from "./resSeoAuditSummary";
export * from "./resSeoAuditVisibility";
export * from "./resShowcase";
export * from "./resShowcaseMsg";
export * from "./resSite";
export * from "./resSiteCurrentVersion";
export * from "./resSiteMsg";
export * from "./resSiteSite";
export * from "./resSiteSlug";
export * from "./resSiteSlugMsg";
export * from "./resSiteSlugReason";
export * from "./resSiteSlugSite";
export * from "./resSiteSlugSuggestion";
export * from "./resSiteVersions";
export * from "./resSiteVersionsMsg";
export * from "./resSlugCheck";
export * from "./resSlugCheckMsg";
export * from "./resSlugCheckReason";
export * from "./resSlugCheckSuggestion";
export * from "./resStartBuild";
export * from "./resStartBuildJobId";
export * from "./resStartBuildMsg";
export * from "./resStartBuildStatus";
export * from "./resStartCollect";
export * from "./resStartCollectJobId";
export * from "./resStartCollectMsg";
export * from "./resStartCollectStatus";
export * from "./resStartCopy";
export * from "./resStartCopyJobId";
export * from "./resStartCopyMsg";
export * from "./resStartCopyStatus";
export * from "./resStartVision";
export * from "./resStartVisionJobId";
export * from "./resStartVisionMsg";
export * from "./resStartVisionStatus";
export * from "./resSyncPlace";
export * from "./resSyncPlaceMsg";
export * from "./resUnit";
export * from "./resUnitList";
export * from "./resUnitListMsg";
export * from "./resUnitMsg";
export * from "./resUnitUnit";
export * from "./resVerifyCandidates";
export * from "./resVerifyCandidatesMsg";
export * from "./resVerifyCandidatesReason";
export * from "./resVerifyCandidatesSource";
export * from "./resWeather";
export * from "./resWeatherMsg";
export * from "./resWeatherWeather";
export * from "./searchPlacesPublicParams";
export * from "./showcaseItem";
export * from "./showcaseItemRegion";
export * from "./showcaseItemThumbnailUrl";
export * from "./siteData";
export * from "./siteDataCurrentVersionId";
export * from "./siteDataDomain";
export * from "./siteDataPublishedAt";
export * from "./siteDataTemplateId";
export * from "./siteDataTheme";
export * from "./siteDataThemeAnyOf";
export * from "./siteDataThumbnailUrl";
export * from "./siteStatus";
export * from "./siteVersionData";
export * from "./siteVersionDataBuildError";
export * from "./siteVersionDataBuiltAt";
export * from "./siteVersionDataCreatedAt";
export * from "./sourceType";
export * from "./unitData";
export * from "./userRole";
export * from "./validationError";
export * from "./validationErrorCtx";
export * from "./validationErrorLocItem";
export * from "./verifyCandidatesParams";
export * from "./weatherData";
export * from "./weatherDataTimezone";
export * from "./weatherDataWindSpeed";

View File

@ -4,14 +4,14 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { JobType } from './jobType';
import type { JobStatus } from './jobStatus';
import type { JobDataResult } from './jobDataResult';
import type { JobDataLastError } from './jobDataLastError';
import type { JobDataRunAfter } from './jobDataRunAfter';
import type { JobDataRunStartedAt } from './jobDataRunStartedAt';
import type { JobDataCreatedAt } from './jobDataCreatedAt';
import type { JobDataUpdatedAt } from './jobDataUpdatedAt';
import type { JobType } from "./jobType";
import type { JobStatus } from "./jobStatus";
import type { JobDataResult } from "./jobDataResult";
import type { JobDataLastError } from "./jobDataLastError";
import type { JobDataRunAfter } from "./jobDataRunAfter";
import type { JobDataRunStartedAt } from "./jobDataRunStartedAt";
import type { JobDataCreatedAt } from "./jobDataCreatedAt";
import type { JobDataUpdatedAt } from "./jobDataUpdatedAt";
export interface JobData {
job_id: string;

View File

@ -11,8 +11,7 @@
UPDATE(CAS) .
PENDING(run_after=) , DEAD(dead-letter).
*/
export type JobStatus = typeof JobStatus[keyof typeof JobStatus];
export type JobStatus = (typeof JobStatus)[keyof typeof JobStatus];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const JobStatus = {

View File

@ -11,8 +11,7 @@
( ) (HTTP API )
.
*/
export type JobType = typeof JobType[keyof typeof JobType];
export type JobType = (typeof JobType)[keyof typeof JobType];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const JobType = {
@ -22,4 +21,6 @@ export const JobType = {
BUILD: 4,
LOCAL_SYNC: 5,
AI_CHECK: 6,
SONG: 7,
ROLLBACK: 8,
} as const;

View File

@ -6,10 +6,9 @@
*/
/**
* place_links.channel . Perplexity .
* place_channels.channel . Perplexity .
*/
export type LinkChannel = typeof LinkChannel[keyof typeof LinkChannel];
export type LinkChannel = (typeof LinkChannel)[keyof typeof LinkChannel];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const LinkChannel = {

View File

@ -4,11 +4,11 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { LinkChannel } from './linkChannel';
import type { LinkDataTitle } from './linkDataTitle';
import type { SourceType } from './sourceType';
import type { LinkDataDiscoveredAt } from './linkDataDiscoveredAt';
import type { LinkDataConfirmedAt } from './linkDataConfirmedAt';
import type { LinkChannel } from "./linkChannel";
import type { LinkDataTitle } from "./linkDataTitle";
import type { SourceType } from "./sourceType";
import type { LinkDataDiscoveredAt } from "./linkDataDiscoveredAt";
import type { LinkDataConfirmedAt } from "./linkDataConfirmedAt";
export interface LinkData {
link_id: string;

View File

@ -4,9 +4,9 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { LocalContentStatus } from './localContentStatus';
import type { LocalContentStatus } from "./localContentStatus";
export type ListContentsParams = {
status?: LocalContentStatus | null;
region_code?: string | null;
status?: LocalContentStatus | null;
region_code?: string | null;
};

View File

@ -6,9 +6,9 @@
*/
export type ListFactsParams = {
/**
* ·· fact
*/
unit_id?: string | null;
publishable_only?: boolean;
/**
* ·· fact
*/
unit_id?: string | null;
publishable_only?: boolean;
};

View File

@ -6,5 +6,5 @@
*/
export type ListFaqsParams = {
publishable_only?: boolean;
publishable_only?: boolean;
};

View File

@ -6,5 +6,5 @@
*/
export type ListLinksParams = {
confirmed_only?: boolean;
confirmed_only?: boolean;
};

View File

@ -6,9 +6,9 @@
*/
export type ListMediaParams = {
/**
* ·
*/
unit_id?: string | null;
publishable_only?: boolean;
/**
* ·
*/
unit_id?: string | null;
publishable_only?: boolean;
};

View File

@ -6,13 +6,13 @@
*/
export type ListMySitesParams = {
/**
* @minimum 1
*/
page?: number;
/**
* @minimum 1
* @maximum 100
*/
size?: number;
/**
* @minimum 1
*/
page?: number;
/**
* @minimum 1
* @maximum 100
*/
size?: number;
};

View File

@ -4,29 +4,29 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { PlaceCategory } from './placeCategory';
import type { PlaceStatus } from './placeStatus';
import type { PlaceCategory } from "./placeCategory";
import type { PlaceStatus } from "./placeStatus";
export type ListPlacesParams = {
/**
* ·
*/
search?: string | null;
/**
*
*/
category?: PlaceCategory | null;
/**
*
*/
status?: PlaceStatus | null;
/**
* @minimum 1
*/
page?: number;
/**
* @minimum 1
* @maximum 100
*/
size?: number;
/**
* ·
*/
search?: string | null;
/**
*
*/
category?: PlaceCategory | null;
/**
*
*/
status?: PlaceStatus | null;
/**
* @minimum 1
*/
page?: number;
/**
* @minimum 1
* @maximum 100
*/
size?: number;
};

View File

@ -6,10 +6,10 @@
*/
export type ListShowcaseParams = {
/**
*
* @minimum 1
* @maximum 48
*/
limit?: number;
/**
*
* @minimum 1
* @maximum 48
*/
limit?: number;
};

View File

@ -4,16 +4,16 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { LocalContentType } from './localContentType';
import type { LocalSource } from './localSource';
import type { LocalContentDataExternalId } from './localContentDataExternalId';
import type { LocalContentDataTitle } from './localContentDataTitle';
import type { LocalContentDataBody } from './localContentDataBody';
import type { LocalContentStatus } from './localContentStatus';
import type { LocalContentDataCollectedAt } from './localContentDataCollectedAt';
import type { LocalContentDataPublishedAt } from './localContentDataPublishedAt';
import type { LocalContentDataDisplayStartAt } from './localContentDataDisplayStartAt';
import type { LocalContentDataDisplayEndAt } from './localContentDataDisplayEndAt';
import type { LocalContentType } from "./localContentType";
import type { LocalSource } from "./localSource";
import type { LocalContentDataExternalId } from "./localContentDataExternalId";
import type { LocalContentDataTitle } from "./localContentDataTitle";
import type { LocalContentDataBody } from "./localContentDataBody";
import type { LocalContentStatus } from "./localContentStatus";
import type { LocalContentDataCollectedAt } from "./localContentDataCollectedAt";
import type { LocalContentDataPublishedAt } from "./localContentDataPublishedAt";
import type { LocalContentDataDisplayStartAt } from "./localContentDataDisplayStartAt";
import type { LocalContentDataDisplayEndAt } from "./localContentDataDisplayEndAt";
export interface LocalContentData {
local_content_id: string;

View File

@ -8,8 +8,8 @@
/**
* .
*/
export type LocalContentStatus = typeof LocalContentStatus[keyof typeof LocalContentStatus];
export type LocalContentStatus =
(typeof LocalContentStatus)[keyof typeof LocalContentStatus];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const LocalContentStatus = {

View File

@ -8,8 +8,8 @@
/**
* local_contents.content_type . .
*/
export type LocalContentType = typeof LocalContentType[keyof typeof LocalContentType];
export type LocalContentType =
(typeof LocalContentType)[keyof typeof LocalContentType];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const LocalContentType = {
@ -17,4 +17,6 @@ export const LocalContentType = {
FESTIVAL: 2,
ATTRACTION: 3,
RESTAURANT: 4,
COURSE: 5,
STORY: 6,
} as const;

View File

@ -8,8 +8,7 @@
/**
* local_contents.source . API .
*/
export type LocalSource = typeof LocalSource[keyof typeof LocalSource];
export type LocalSource = (typeof LocalSource)[keyof typeof LocalSource];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const LocalSource = {
@ -17,4 +16,6 @@ export const LocalSource = {
TOUR_API: 2,
KAKAO_LOCAL: 3,
OFFICIAL_WEB: 4,
LLM: 5,
NAVER_CRAWL: 6,
} as const;

View File

@ -4,17 +4,17 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { MediaDataUnitId } from './mediaDataUnitId';
import type { MediaDataOriginUrl } from './mediaDataOriginUrl';
import type { SourceType } from './sourceType';
import type { MediaDataSourceUrl } from './mediaDataSourceUrl';
import type { MediaDataLabel } from './mediaDataLabel';
import type { MediaDataAltText } from './mediaDataAltText';
import type { MediaDataVisionConfidence } from './mediaDataVisionConfidence';
import type { MediaStatus } from './mediaStatus';
import type { MediaDataWidth } from './mediaDataWidth';
import type { MediaDataHeight } from './mediaDataHeight';
import type { MediaDataCreatedAt } from './mediaDataCreatedAt';
import type { MediaDataUnitId } from "./mediaDataUnitId";
import type { MediaDataOriginUrl } from "./mediaDataOriginUrl";
import type { SourceType } from "./sourceType";
import type { MediaDataSourceUrl } from "./mediaDataSourceUrl";
import type { MediaDataLabel } from "./mediaDataLabel";
import type { MediaDataAltText } from "./mediaDataAltText";
import type { MediaDataVisionConfidence } from "./mediaDataVisionConfidence";
import type { MediaStatus } from "./mediaStatus";
import type { MediaDataWidth } from "./mediaDataWidth";
import type { MediaDataHeight } from "./mediaDataHeight";
import type { MediaDataCreatedAt } from "./mediaDataCreatedAt";
/**
* 1.

View File

@ -8,8 +8,7 @@
/**
* media.status . PENDING_REVIEW .
*/
export type MediaStatus = typeof MediaStatus[keyof typeof MediaStatus];
export type MediaStatus = (typeof MediaStatus)[keyof typeof MediaStatus];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const MediaStatus = {

View File

@ -4,16 +4,16 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { PlaceCategory } from './placeCategory';
import type { PlaceStatus } from './placeStatus';
import type { MySiteDataRoadAddress } from './mySiteDataRoadAddress';
import type { MySiteDataCreatedAt } from './mySiteDataCreatedAt';
import type { MySiteDataSiteId } from './mySiteDataSiteId';
import type { MySiteDataStatus } from './mySiteDataStatus';
import type { MySiteDataDomain } from './mySiteDataDomain';
import type { MySiteDataTemplateId } from './mySiteDataTemplateId';
import type { MySiteDataPublishedAt } from './mySiteDataPublishedAt';
import type { MySiteDataThumbnailUrl } from './mySiteDataThumbnailUrl';
import type { PlaceCategory } from "./placeCategory";
import type { PlaceStatus } from "./placeStatus";
import type { MySiteDataRoadAddress } from "./mySiteDataRoadAddress";
import type { MySiteDataCreatedAt } from "./mySiteDataCreatedAt";
import type { MySiteDataSiteId } from "./mySiteDataSiteId";
import type { MySiteDataStatus } from "./mySiteDataStatus";
import type { MySiteDataDomain } from "./mySiteDataDomain";
import type { MySiteDataTemplateId } from "./mySiteDataTemplateId";
import type { MySiteDataPublishedAt } from "./mySiteDataPublishedAt";
import type { MySiteDataThumbnailUrl } from "./mySiteDataThumbnailUrl";
/**
* (place) + (site).
@ -33,7 +33,6 @@ export interface MySiteData {
domain?: MySiteDataDomain;
template_id?: MySiteDataTemplateId;
published_at?: MySiteDataPublishedAt;
/** 목록 카드의 그림. 발행에 성공해야 채워지고, 발행마다 `?v=` 가 바뀐다(site_thumbnail.public_url). */
thumbnail_url?: MySiteDataThumbnailUrl;
needs_rebuild?: boolean;
}

View File

@ -4,6 +4,6 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { SiteStatus } from './siteStatus';
import type { SiteStatus } from "./siteStatus";
export type MySiteDataStatus = SiteStatus | null;

View File

@ -4,15 +4,15 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { PlaceCandidateExternalPlaceId } from './placeCandidateExternalPlaceId';
import type { PlaceCandidateRoadAddress } from './placeCandidateRoadAddress';
import type { PlaceCandidateAddress } from './placeCandidateAddress';
import type { PlaceCandidatePhone } from './placeCandidatePhone';
import type { PlaceCandidateLatitude } from './placeCandidateLatitude';
import type { PlaceCandidateLongitude } from './placeCandidateLongitude';
import type { PlaceCandidateCategoryName } from './placeCandidateCategoryName';
import type { PlaceCandidatePlaceUrl } from './placeCandidatePlaceUrl';
import type { PlaceCandidateNaverPlaceUrl } from './placeCandidateNaverPlaceUrl';
import type { PlaceCandidateExternalPlaceId } from "./placeCandidateExternalPlaceId";
import type { PlaceCandidateRoadAddress } from "./placeCandidateRoadAddress";
import type { PlaceCandidateAddress } from "./placeCandidateAddress";
import type { PlaceCandidatePhone } from "./placeCandidatePhone";
import type { PlaceCandidateLatitude } from "./placeCandidateLatitude";
import type { PlaceCandidateLongitude } from "./placeCandidateLongitude";
import type { PlaceCandidateCategoryName } from "./placeCandidateCategoryName";
import type { PlaceCandidatePlaceUrl } from "./placeCandidatePlaceUrl";
import type { PlaceCandidateNaverPlaceUrl } from "./placeCandidateNaverPlaceUrl";
/**
* DB 1. UI .

View File

@ -9,8 +9,7 @@
* places.category . (common/category_schema/resources/*.json) 1:1.
= + 1 .
*/
export type PlaceCategory = typeof PlaceCategory[keyof typeof PlaceCategory];
export type PlaceCategory = (typeof PlaceCategory)[keyof typeof PlaceCategory];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const PlaceCategory = {

View File

@ -0,0 +1,27 @@
/**
* Generated by orval v7.21.0 🍺
* Do not edit manually.
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { LocalContentType } from "./localContentType";
import type { PlaceContentDataBody } from "./placeContentDataBody";
import type { PlaceContentDataDisplayEndAt } from "./placeContentDataDisplayEndAt";
import type { PlaceContentDataCollectedAt } from "./placeContentDataCollectedAt";
/**
* 1(admin ).
*/
export interface PlaceContentData {
place_content_id: string;
place_id: string;
content_type: LocalContentType;
external_id: string;
title: string;
body: PlaceContentDataBody;
distance_m: number;
has_image: boolean;
hidden: boolean;
display_end_at?: PlaceContentDataDisplayEndAt;
collected_at?: PlaceContentDataCollectedAt;
}

View File

@ -0,0 +1,8 @@
/**
* Generated by orval v7.21.0 🍺
* Do not edit manually.
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
export type PlaceContentDataBody = { [key: string]: unknown };

View File

@ -0,0 +1,8 @@
/**
* Generated by orval v7.21.0 🍺
* Do not edit manually.
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
export type PlaceContentDataCollectedAt = string | null;

View File

@ -0,0 +1,8 @@
/**
* Generated by orval v7.21.0 🍺
* Do not edit manually.
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
export type PlaceContentDataDisplayEndAt = string | null;

View File

@ -4,20 +4,20 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { PlaceCategory } from './placeCategory';
import type { PlaceStatus } from './placeStatus';
import type { PlaceDataOwnerUserId } from './placeDataOwnerUserId';
import type { PlaceDataExternalSource } from './placeDataExternalSource';
import type { PlaceDataExternalPlaceId } from './placeDataExternalPlaceId';
import type { PlaceDataRoadAddress } from './placeDataRoadAddress';
import type { PlaceDataAddress } from './placeDataAddress';
import type { PlaceDataPhone } from './placeDataPhone';
import type { PlaceDataLatitude } from './placeDataLatitude';
import type { PlaceDataLongitude } from './placeDataLongitude';
import type { PlaceDataRegionCode } from './placeDataRegionCode';
import type { PlaceDataVerifiedAt } from './placeDataVerifiedAt';
import type { PlaceDataContentUpdatedAt } from './placeDataContentUpdatedAt';
import type { PlaceDataCreatedAt } from './placeDataCreatedAt';
import type { PlaceCategory } from "./placeCategory";
import type { PlaceStatus } from "./placeStatus";
import type { PlaceDataOwnerUserId } from "./placeDataOwnerUserId";
import type { PlaceDataExternalSource } from "./placeDataExternalSource";
import type { PlaceDataExternalPlaceId } from "./placeDataExternalPlaceId";
import type { PlaceDataRoadAddress } from "./placeDataRoadAddress";
import type { PlaceDataAddress } from "./placeDataAddress";
import type { PlaceDataPhone } from "./placeDataPhone";
import type { PlaceDataLatitude } from "./placeDataLatitude";
import type { PlaceDataLongitude } from "./placeDataLongitude";
import type { PlaceDataRegionCode } from "./placeDataRegionCode";
import type { PlaceDataVerifiedAt } from "./placeDataVerifiedAt";
import type { PlaceDataContentUpdatedAt } from "./placeDataContentUpdatedAt";
import type { PlaceDataCreatedAt } from "./placeDataCreatedAt";
export interface PlaceData {
place_id: string;

View File

@ -4,6 +4,6 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { ExternalPlaceSource } from './externalPlaceSource';
import type { ExternalPlaceSource } from "./externalPlaceSource";
export type PlaceDataExternalSource = ExternalPlaceSource | null;

View File

@ -4,9 +4,10 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { PlaceSearchItemRoadAddress } from './placeSearchItemRoadAddress';
import type { PlaceSearchItemCategoryName } from './placeSearchItemCategoryName';
import type { PlaceSearchItemCategory } from './placeSearchItemCategory';
import type { PlaceSearchItemRoadAddress } from "./placeSearchItemRoadAddress";
import type { PlaceSearchItemCategoryName } from "./placeSearchItemCategoryName";
import type { PlaceSearchItemCategory } from "./placeSearchItemCategory";
import type { PlaceSearchItemNaverPlaceUrl } from "./placeSearchItemNaverPlaceUrl";
/**
* 1.
@ -21,6 +22,5 @@ export interface PlaceSearchItem {
road_address?: PlaceSearchItemRoadAddress;
category_name?: PlaceSearchItemCategoryName;
category?: PlaceSearchItemCategory;
/** @nullable */
naver_place_url?: string | null;
naver_place_url?: PlaceSearchItemNaverPlaceUrl;
}

View File

@ -4,6 +4,6 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { PlaceCategory } from './placeCategory';
import type { PlaceCategory } from "./placeCategory";
export type PlaceSearchItemCategory = PlaceCategory | null;

View File

@ -9,8 +9,7 @@
* places.status . .
SUSPENDED ( 404 ).
*/
export type PlaceStatus = typeof PlaceStatus[keyof typeof PlaceStatus];
export type PlaceStatus = (typeof PlaceStatus)[keyof typeof PlaceStatus];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const PlaceStatus = {

View File

@ -8,8 +8,7 @@
/**
* publish_logs.action .
*/
export type PublishAction = typeof PublishAction[keyof typeof PublishAction];
export type PublishAction = (typeof PublishAction)[keyof typeof PublishAction];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const PublishAction = {
@ -18,4 +17,5 @@ export const PublishAction = {
REBUILD: 3,
SUSPEND: 4,
RESUME: 5,
ROLLBACK: 6,
} as const;

View File

@ -4,11 +4,11 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { PublishAction } from './publishAction';
import type { PublishResult } from './publishResult';
import type { PublishLogDataRejectReason } from './publishLogDataRejectReason';
import type { PublishLogDataDetail } from './publishLogDataDetail';
import type { PublishLogDataCreatedAt } from './publishLogDataCreatedAt';
import type { PublishAction } from "./publishAction";
import type { PublishResult } from "./publishResult";
import type { PublishLogDataRejectReason } from "./publishLogDataRejectReason";
import type { PublishLogDataDetail } from "./publishLogDataDetail";
import type { PublishLogDataCreatedAt } from "./publishLogDataCreatedAt";
export interface PublishLogData {
publish_log_id: string;

View File

@ -4,6 +4,6 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { PublishRejectReason } from './publishRejectReason';
import type { PublishRejectReason } from "./publishRejectReason";
export type PublishLogDataRejectReason = PublishRejectReason | null;

View File

@ -8,8 +8,8 @@
/**
* publish_logs.reject_reason . ( 1~3).
*/
export type PublishRejectReason = typeof PublishRejectReason[keyof typeof PublishRejectReason];
export type PublishRejectReason =
(typeof PublishRejectReason)[keyof typeof PublishRejectReason];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const PublishRejectReason = {

View File

@ -8,8 +8,7 @@
/**
* publish_logs.result .
*/
export type PublishResult = typeof PublishResult[keyof typeof PublishResult];
export type PublishResult = (typeof PublishResult)[keyof typeof PublishResult];
// eslint-disable-next-line @typescript-eslint/no-redeclare
export const PublishResult = {

View File

@ -0,0 +1,14 @@
/**
* Generated by orval v7.21.0 🍺
* Do not edit manually.
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
export type RelayParams = {
/**
* @minLength 8
* @maxLength 2000
*/
url: string;
};

View File

@ -4,9 +4,9 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { RenderStatusDataRenderedAt } from './renderStatusDataRenderedAt';
import type { RenderStatusDataRenderedVersion } from './renderStatusDataRenderedVersion';
import type { RenderStatusDataError } from './renderStatusDataError';
import type { RenderStatusDataRenderedAt } from "./renderStatusDataRenderedAt";
import type { RenderStatusDataRenderedVersion } from "./renderStatusDataRenderedVersion";
import type { RenderStatusDataError } from "./renderStatusDataError";
/**
* . .

View File

@ -4,7 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { ReqCreateFaqSortOrder } from './reqCreateFaqSortOrder';
import type { ReqCreateFaqSortOrder } from "./reqCreateFaqSortOrder";
/**
* FAQ.

View File

@ -4,9 +4,9 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { LinkChannel } from './linkChannel';
import type { ReqCreateLinkTitle } from './reqCreateLinkTitle';
import type { SourceType } from './sourceType';
import type { LinkChannel } from "./linkChannel";
import type { ReqCreateLinkTitle } from "./reqCreateLinkTitle";
import type { SourceType } from "./sourceType";
export interface ReqCreateLink {
channel?: LinkChannel;

View File

@ -4,11 +4,9 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { PlaceCategory } from './placeCategory';
import type { ReqCreatePlaceOwnerUserId } from './reqCreatePlaceOwnerUserId';
import type { PlaceCategory } from "./placeCategory";
export interface ReqCreatePlace {
name?: string;
category?: PlaceCategory;
owner_user_id?: ReqCreatePlaceOwnerUserId;
}

View File

@ -0,0 +1,10 @@
/**
* Generated by orval v7.21.0 🍺
* Do not edit manually.
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
export interface ReqHidePlaceContent {
hidden: boolean;
}

View File

@ -0,0 +1,18 @@
/**
* Generated by orval v7.21.0 🍺
* Do not edit manually.
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
/**
* .
.
( , prerender.ts pruneOldVersions) site_versions.snapshot
. (
).
*/
export interface ReqRollback {
target_version: number;
}

View File

@ -4,7 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { ReqSignupName } from './reqSignupName';
import type { ReqSignupName } from "./reqSignupName";
/**
* id/pw . = 1.

View File

@ -4,7 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { PublishAction } from './publishAction';
import type { PublishAction } from "./publishAction";
/**
* .

View File

@ -4,7 +4,7 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { ReqSiteThemeTheme } from './reqSiteThemeTheme';
import type { ReqSiteThemeTheme } from "./reqSiteThemeTheme";
/**
* (··) . [] .

View File

@ -10,4 +10,6 @@
fact . ( ).
*/
export interface ReqStartCopy { [key: string]: unknown }
export interface ReqStartCopy {
[key: string]: unknown;
}

View File

@ -1,18 +0,0 @@
/**
* Generated by orval v7.21.0 🍺
* Do not edit manually.
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { ReqSyncFestivalsAreaCode } from './reqSyncFestivalsAreaCode';
import type { ReqSyncFestivalsStartDate } from './reqSyncFestivalsStartDate';
export interface ReqSyncFestivals {
/**
* @minLength 1
* @maxLength 10
*/
region_code: string;
area_code?: ReqSyncFestivalsAreaCode;
start_date?: ReqSyncFestivalsStartDate;
}

View File

@ -4,8 +4,8 @@
* Web4Ai API
* OpenAPI spec version: 0.1.0
*/
import type { FactStatus } from './factStatus';
import type { ReqTransitionFactValue } from './reqTransitionFactValue';
import type { FactStatus } from "./factStatus";
import type { ReqTransitionFactValue } from "./reqTransitionFactValue";
/**
* . FACT_STATUS_TRANSITIONS .

Some files were not shown because too many files have changed in this diff Show More