Skip to content

About

음성 아카이브 백엔드와 변환 파이프라인

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

soriham-api

소리함 — 음성 녹음 아카이브(로컬 STT, 화자분리, AI 요약, 검색) — 의 백엔드입니다. 녹음 폴더를 스캔·감시해 데이터베이스에 등록하고, 변환·요약 파이프라인을 진행하는 워커와 검색·재생용 REST API를 제공합니다.

스택: Python 3.12+, FastAPI, PostgreSQL(alembic 마이그레이션, pg_trgm 검색).

실행

cp .env.example .env   # 값 채우기
docker compose up -d   # postgres
uv sync
uv run alembic upgrade head

uv run soriham-api bootstrap --email you@example.com --name 이름 \
  --workspace-slug mine --workspace-name 내 보관함    # 최초 1회, 첫 운영자
uv run soriham-api scan     # 녹음 폴더 스캔 등록
uv run soriham-api watch    # 새 파일 감시 등록
uv run soriham-api worker   # 변환 파이프라인 워커 (stt 러너 필요)
                            # 제목/요약/태그는 기본 Ollama(qwen3), ENRICH_BACKEND로 교체
uv run soriham-api serve    # REST API (기본 8200 포트)

워커 복구

워커는 한 프로세스로 운용합니다. 중단된 작업은 마지막 갱신으로부터 5분이 지나면 다시 확인합니다. 러너 요청 ID를 DB에 먼저 저장하므로 워커만 재시작해도 같은 잡을 재사용합니다. 러너도 요청 ID를 지원하는 버전이어야 합니다. 갱신 시 워커를 멈추고 alembic upgrade head를 적용한 뒤 러너와 워커 순서로 기동합니다.

전사 결과와 성공 사용량은 함께 커밋합니다. 요약 실패 시 전사는 보존하며, 워커를 다시 시작하면 요약만 이어갑니다. 러너가 재시작되거나 완료 결과 보관 시간(기본 1시간)이 지나면 전사 계산을 다시 할 수 있습니다.

REST API

가입은 누구나 할 수 있고 관리자 승인을 받아야 쓸 수 있습니다. 로그인 세션은 httpOnly 쿠키이며, 안전하지 않은 메서드는 X-CSRF-Token 헤더를 함께 요구합니다.

메서드·경로 역할
POST /api/auth/signup · login · logout 가입·로그인·로그아웃
GET /api/auth/me 내 계정, 워크스페이스 목록, 화면이 그릴 것들
POST /api/auth/password 비밀번호 변경 (다른 자리의 세션은 폐기)
GET /api/admin/users?status= 상태로 거른 계정 목록
PUT /api/admin/users/{id}/status 승인·거절·중지·재개
POST /api/workspaces 워크스페이스 생성 (서비스 관리자만)
GET /api/workspaces/{ws}/recordings 목록 (q, status, tag 필터, 페이지네이션)
POST /api/workspaces/{ws}/recordings 업로드
GET /api/workspaces/{ws}/tags 태그 목록
GET /api/workspaces/{ws}/search?q= 검색 (세그먼트·파일명·제목·요약)
GET /api/workspaces/{ws}/stats 상태별 집계, 처리 배속, ETA, 최근 에러
GET /api/workspaces/{ws}/usage 사용량과 한도 (전사 시간 30일 롤링, 저장 용량)
GET·PUT·DELETE /api/workspaces/{ws}/members… 구성원 목록과 역할 변경, 내보내기
GET·POST·DELETE /api/workspaces/{ws}/invites… 초대 발급·목록·철회
GET·POST /api/invites/{token}… 초대 미리보기와 수락
GET /api/recordings/{id} 상세 (세그먼트, 화자 이름, 태그)
PATCH /api/recordings/{id} 제목 수정
DELETE /api/recordings/{id} 삭제 (업로드본은 원본 파일까지, 스캔본은 등록만)
POST /api/recordings/{id}/retry 실패한 녹음을 다시 큐에 (남은 산출물부터 재개)
PUT /api/recordings/{id}/speakers/{key} 화자 표시 이름 수정
GET /api/recordings/{id}/audio 오디오 스트리밍 (Range 지원)
POST·DELETE /api/recordings/{id}/tags… 태그 추가·제거
GET·POST·DELETE /api/recordings/{id}/shares… 사람 지정 공유 (열람·편집)
POST·DELETE /api/recordings/{id}/links… 공유 링크 발급·철회
GET /api/shared-with-me 나에게 공유된 녹음
GET /api/shared/{token} · /audio 로그인 없는 링크 열람과 재생
POST /api/shared/{token}/unlock 비밀번호가 걸린 링크 열기

id는 전부 uuid(공개 식별자)입니다. 스캔·감시로 들어온 원본 오디오는 제자리 인덱싱하며 이동·복사하지 않고, 업로드본만 보관 폴더의 워크스페이스별 하위 경로에 저장합니다.

녹음은 워크스페이스 하나에 속합니다. 태그와 중복 판정도 워크스페이스 안에서만 이뤄집니다.

워크스페이스마다 전사 시간과 저장 용량 한도를 둘 수 있습니다. 한도를 비우면 무제한입니다. 한도를 넘긴 녹음은 quota_blocked로 서 있다가, 기간이 지나거나 한도가 오르면 워커가 다시 큐에 넣습니다.

전체 아키텍처

[녹음 폴더] ──스캔·감시──▶ [soriham-api: 인제스트 + PostgreSQL]
                                     │
                                     ▼
                            [soriham-api: 워커] ──HTTP 잡 API──▶ [soriham-stt: 변환 러너]
                                     │                            (whisper + 화자분리)
                                     ▼
[브라우저] ◀──▶ [soriham-console 웹 UI] ──REST──▶ [soriham-api: FastAPI]
레포지토리 역할
soriham-api FastAPI 백엔드와 처리 워커 (Python, PostgreSQL)
soriham-console 웹 콘솔 (React, TypeScript)
soriham-stt 음성 변환 러너 (whisper 계열, pyannote)

스캔 파일이 바뀌었을 때

같은 경로의 내용이 바뀌면 새 녹음으로 등록합니다. 이전 녹취록과 편집 정보, 공유는 이전 녹음에 보존하며 그 링크로 새 오디오를 내보내지 않습니다. 원래 내용이 다시 발견되면 이전 녹음 ID와 산출물을 되찾습니다.

새 코드를 기동하기 전에 마이그레이션을 적용합니다. 교체 전후의 기록이 같은 경로에 남아 있으면 이전 스키마로의 downgrade는 데이터를 보존하며 거부합니다.

감시는 5초 이상 쓰기가 잠잠해진 파일을 등록하고 실패한 등록은 재시도합니다. 긴 일시정지 복사는 완료와 구분할 수 없으므로 완성한 파일을 rename으로 넣는 것이 가장 확실합니다. 감시 중단 후 누락 확인에는 scan을 사용합니다.

About

음성 아카이브 백엔드와 변환 파이프라인

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages