Skip to content

RPC 카탈로그

스냅샷 문서

이 문서는 2026-08-20 기준 supabase/schema.sql에서 추출한 스냅샷입니다. 정본은 언제나 supabase/schema.sql이며, 이 문서와 어긋나면 schema.sql이 우선합니다.

  • create or replace function 정의문: 359개 (같은 함수의 버전 갱신 포함)
  • 유니크 함수 이름: 230개 — 이 중 31개는 이후 마이그레이션에서 drop되어 최종 상태에는 199개가 존재
  • 클라이언트(웹앱)에서 호출하는 RPC: 47개 (src/react/types/supabase.tsSupabaseRpcName 타입맵 + get_admin_mapping_page)
  • Edge Function 전용 RPC: 6개

2026-08-20 20260820120000(RPC 표면 위생)이 아래 7종을 추가로 drop했습니다 — cheer_session, save_onboarding_progress, repair_calendar_read_models, check_calendar_read_model_integrity, refresh_all_user_exercise_stats, refresh_user_exercise_stats, refresh_session_exercise_stats. 아래 표·목록에는 회수됨 표기로 남겨 두었습니다.

2026-08-21 정정: 20260821010000(P3 replay 기계 해체)이 materialize_wodup_unmatched_user_customs_v1 · exercise_identity_for_wodup_user_custom_v1 · exercise_identity_for_external 3종을, 20260821010200~010400(5.1 양파 평탄화)이 화면 읽기 체인 내부 층 8종(get_session_detail_v{2,3}_core·_v4_engine, get_calendar_day_summary_v{2,3}_core·_v4_engine, get_calendar_month_summary_v{2,3}_core)을 drop했습니다 — 공개 표면 3종의 이름·인자·계약 버전은 불변(§1 행 유효). 최종 함수 수는 199 − 11 = 188개입니다.

모든 화면 RPC는 auth.uid() 기준으로 현재 로그인 유저의 데이터만 반환하며, user id를 파라미터로 받지 않습니다(예외 = 팔로우 게이트 profile_feed_can_view_v1 뒤의 get_following_*_v1 친구 읽기 RPC — 대상 p_user_id를 받되 팔로우하지 않으면 42501). 화면 RPC 응답은 최상위 contract_version 정수를 포함하고, 프론트는 callScreenRpc(...)(src/react/services/barbelicRepository.ts)의 strict adapter를 거쳐서만 소비합니다. 응답 계약의 상세(행 상한·바이트 예산·버전 규칙)는 app-screen-rpc-contract.md를 참고하세요.

§1 화면 읽기 RPC (read model)

반환은 전부 jsonb이며 괄호 안은 현재 output contract version입니다.

함수명주요 인자반환용도호출 화면/서비스
get_home_dashboardp_today datejsonb (v3)홈 대시보드 패키지(이번 달 세션·계획, 주간 활동, 최근 세션·최근 PR) — current_month.planssession 테이블의 status = planned 행에서 읽는다(이슈 #1215, 2026-09-04). 20260821490000이 섞던 반영 계획 카드(plan_owner·adopted)는 계획 반영 폐기로 사라졌다홈 / callScreenRpc
get_exercise_catalog(없음)jsonb (v9)활성 종목 카탈로그 전체(UUID 정체성 + 표시·검색 메타 + 필수 입력 논리식 required_inputs(#947), ≤4,096행(#938 D8)) + latest_seq(호출자에게 보이는 변경 로그 최신 순번, 이슈 #1238 Phase 3). 기기 사본이 없거나 보존 기간 밖일 때만종목 선택 전반 / catalogDomain.syncExerciseCatalogDataexerciseCatalogStore.ts(IndexedDB)
get_exercise_catalog_changesp_since_seq bigint, p_limit intjsonb (v1)기기 순번 이후 바뀐 종목만(시스템 + 본인 커스텀, 종목마다 마지막 1건, 페이지 ≤1,000, 삭제·보관은 deleted, 보존 기간 밖이면 full_resync_required) — 이슈 #1238 Phase 3홈 힌트 catalog_version > 기기 순번일 때·커스텀 종목 쓰기 직후 / catalogDomain.syncExerciseCatalogData
get_home_year_activityp_year int, p_as_of datejsonb (v1)연간 활동 히트맵(홈 지연 로드 프래그먼트)홈 / callScreenRpc
get_user_exercise_favorites(없음)jsonb (v1)종목 즐겨찾기 목록 + revision로그 테이블·종목 즐겨찾기 UI
get_calendar_month_summaryp_from date, p_to datejsonb (v4)월 캘린더 요약(일별 완료/계획 카드, materialized 읽기 모델) — 응답 키 planned_sessions(계획 카드; 키 이름은 유지, 이슈 #1215, 2026-09-04부터 session 테이블의 status = planned 행에서 읽음)·days[].planned_session_count·source_version 포함. 20260821490000이 섞던 반영 계획(plan_owner·adopted)은 계획 반영 폐기로 사라졌다캘린더 월 뷰
get_calendar_day_summaryp_date datejsonb (v5)선택일 요약(완료 세션의 크기 제한된 표시용 세트 + set-free 계획 카드) — summary.planned_session_count 포함(반영 계획 카드는 계획 반영 폐기로 사라짐, 이슈 #1215, 2026-09-04)캘린더 선택일
get_calendar_range_summaryp_from date, p_to datejsonb (v1)주/월 같은 날짜 범위 합계(일 요약 테이블 가산, 세션 배열 없음, 최대 93일) — 통계 중앙화 Phase 4-1주/월 드로어·모달
get_session_detailp_session_id uuidjsonb (v6)완료 세션 상세 — raw table-shaped 행(응답 키 session_exercises·exercise_sets — 키 이름은 유지, 이슈 #1215, 2026-09-04부터 session_exercise_part·exercise_set_part 행)을 반환하는 유일한 경로. 20260821530000부터 소유자 외에 팔로워도 완료 세션을 읽을 수 있다(profile_feed_can_view_v1; 쓰기 RPC는 소유자 고정) — 피드 "자세히"세션 상세
get_planned_session_detailp_planned_session_id uuidjsonb (v2)계획 세션 편집용 상세(편집 가능한 전체 세트) — 20260821490000부터 팔로우한 사람의 계획도 읽힘(planned_session_visible_v1; 비소유자 응답은 plan_owner·editable:false, adopted는 계획 반영 폐기(이슈 #1215, 2026-09-04) 뒤 항상 false, 그 밖은 P0002). 계획 행은 session(status = planned)에서 조립계획 편집기 · 친구 계획 상세/운동 시작
get_log_table_monthp_from date, p_to date, p_exercise_ids uuid[]jsonb (v3)데스크톱 기록표 월 데이터(일×즐겨찾기 종목 격자)데스크톱 기록표
get_log_table_cell_detailp_date date, p_exercise_id uuidjsonb (v2)기록표 셀(일×종목) 표시용 세트 토큰데스크톱 기록표 셀
get_profile_feedp_before_date, p_before_created_at, p_before_id, p_limitjsonb (v3)프로필 피드 keyset 페이지(세션 ≤20/페이지) — 20260821480000부터 본인 + 팔로우한 사용자(user_follows)의 완료 세션을 한 정렬로 싣고, 친구 카드는 추가 키 author{id, display_name, handle, avatar_path, avatar_url}(본인 카드 null). 표시 함수 get_session_presentation_mains_json은 팔로워 읽기 허용(profile_feed_can_view_v1)프로필 피드
get_following_calendar_month_v1p_user_id uuid, p_from date, p_to datejsonb (v1)팔로우한 사람의 달력 한 달(≤42일): 일별 완료/계획 카운트, 완료 세션 lite ≤64, set-free 계획 카드 ≤64(plan_owner + 호출자의 adopted) — 비팔로우 42501 (20260821490000, 계획 반영 v1)친구 달력(클라이언트 데이터층 planAdoptionStore, UI 미배선)
get_following_volume_overview_v1p_user_id uuid, p_as_of datejsonb (v4, get_volume_overview 페이로드 그대로)친구 리포트(20260821520000): 팔로우한 사람의 볼륨 개요 — 게이트 통과 후 같은 트랜잭션 로컬로 JWT sub 클레임을 대상으로 바꿔 get_volume_overview(p_as_of, 4) 체인을 그대로 호출(체인 정의 무접촉)하고 원복. 비팔로우 42501·null 22023피드 친구 아이디/아바타 탭 → 친구 리포트 페이지(friendReportStore)
get_session_searchp_limit int, p_before_date date, p_before_created_at timestamptz, p_before_id uuidjsonb (v3)세션 검색 인덱스 — 페이지당 ≤120 세션 표시 카드, keyset 커서 페이지네이션(has_more/next_cursor, 20260830140000 이슈 #938 D5)세션 검색
get_pr_overviewp_as_of datejsonb (v3)PR 개요(추적 종목 요약 ≤128 + 최근 PR ≤24, 스냅샷 투영 기반)PR 대시보드
get_volume_overviewp_as_of date 또는 p_as_of date, p_contract_version intjsonb (v4, 구버전 v2 오버로드 병존)볼륨/기간 버킷·연간 집계 리포트리포트(볼륨) 화면
get_exercise_pr_detailp_exercise_id uuid, p_as_of datejsonb (v4)종목 PR 상세 초기 페인트(NRM 상태 + 12주 버킷)종목 PR 상세
get_exercise_pr_detail_yearp_exercise_id, p_year, p_as_ofjsonb (v4)종목 연간 상세(일별 활동·근력 포인트·월 집계)종목 PR 상세(연도)
get_exercise_pr_recordsp_exercise_id, p_before_*, p_limit, p_as_ofjsonb (v5)종목 PR 기록 keyset 페이지(≤64행)종목 PR 기록 목록
get_exercise_pr_historyp_exercise_id, p_year, p_before_*, p_limit, p_as_ofjsonb (v4)종목 연도 히스토리 keyset 페이지(≤60행)종목 PR 히스토리

§2 쓰기 RPC (운동 저장·수정·삭제, 온보딩, 프로필)

세션 쓰기 v5 한 쌍(save_session_v5·delete_session_v5, 이슈 #1215 — 옛 완료 v4·계획 v3·보드 v1 문은 폐기)은 client_mutation_id + request_hash 기반 멱등 영수증(mutation receipt)을 반환하고, workout_mutation_receipts 고유 제약이 중복 반영을 막습니다(상세: workout-write-path.md). 통계 재계산은 RPC 안에서 직접 하지 않고 리프레시 큐에 enqueue만 합니다. 클라이언트 대기열 규칙(저장·수정·삭제 한 갈래, 이슈 #1199): completed-workout-write-pipeline.md.

함수명주요 인자반환용도호출 화면/서비스
save_session_v5p_payload jsonb, p_client_mutation_id uuid, p_request_hash textjsonb (session mutation receipt v2)완료 기록·계획·그룹 운동 계획의 신규 저장·수정·계획→완료 전이 한 문(멱등; payload contract_version: 5, statuscompleted 또는 planned, group_id, exercises[] → parts[] → sets[] → parts[] 다섯 층 그대로; 수정은 expected_revision으로 server_revision 비교, 어긋나면 40001). 영수증 v2(contract_version 2, mutation_kind save_session, 층별 id, set_scores; 계획 저장은 stats_requested_version 0) — 이슈 #1215, 2026-09-04운동 저장 플로우·계획 편집기·그룹 보드 / barbelicRepository
delete_session_v5p_session_id uuid, p_expected_revision bigint, p_client_mutation_id uuid, p_request_hash textjsonb (receipt v2, mutation_kind delete_session)완료 기록·계획 삭제(주인만, 그룹 계획은 작성자; server_revision 낙관 잠금) — 이슈 #1215, 2026-09-04세션 상세·계획 편집기
save_workout_v4payload jsonb, p_client_mutation_id uuid, p_request_hash textjsonb폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 호출하면 아무것도 쓰지 않고 SQLSTATE LG426(앱은 "앱 업데이트가 필요해요…" 안내). 옛 용도: 완료 운동 신규 저장 → save_session_v5(호출자 없음)
update_completed_session_v4p_session_id uuid, payload jsonb, p_expected_revision bigint, p_client_mutation_id uuid, p_request_hash textjsonb폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 옛 용도: 완료 세션 수정 → save_session_v5(id + expected_revision)(호출자 없음)
delete_completed_session_v4p_session_id uuid, p_expected_user_id uuid, p_expected_revision bigint, p_client_mutation_id uuid, p_request_hash textjsonb폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 옛 용도: 완료 세션 삭제 → delete_session_v5(호출자 없음)
save_plan_v3payload jsonb, p_client_mutation_id uuid, p_request_hash textjsonb폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 옛 용도: 계획 생성·수정 → save_session_v5(status: planned)(호출자 없음)
delete_planned_session_v2p_planned_session_id uuid, p_expected_user_id uuid, p_expected_updated_at timestamptz, p_client_mutation_id uuid, p_request_hash textjsonb폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 옛 용도: 계획 삭제 → delete_session_v5(호출자 없음)
save_group_board_v1(옛 시그니처)jsonb폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 옛 용도: 그룹 보드 저장 → save_session_v5(status: planned + group_id)(호출자 없음)
save_manual_prpayload jsonbjsonb수동 PR 저장PR 화면 / 온보딩 초기 1RM
delete_manual_prp_id uuidjsonb수동 PR 삭제PR 화면
save_manual_record_metric_v1payload jsonbjsonb종목별 핵심 기록 지표(최대 반복수·최대 버티기·유산소 거리+시간) 직접 입력 저장 — 서버가 종목 기록 방식으로 지표 판정, id 동반 시 수정 (이슈 #1194)내 1RM 기록 관리 / 데스크톱 PR 보드
delete_manual_record_metric_v1p_id uuidjsonb직접 입력 기록 지표 삭제 (이슈 #1194)내 1RM 기록 관리
replace_user_exercise_favoritesp_exercise_ids uuid[], p_expected_revision intjsonb (v1)즐겨찾기 전체 교체(revision 검사)즐겨찾기 편집
set_user_exercise_favoritep_exercise_id uuid, p_favorite boolean, p_expected_revision intjsonb (v1)즐겨찾기 단건 토글즐겨찾기 편집
ensure_user_profile(없음)profiles로그인 직후 최소 프로필 행 보장(생성 or 반환)부팅/auth 경로
get_onboarding_state(없음)jsonb온보딩 상태 + 동의 요건 + 닉네임 정책 반환온보딩
save_onboarding_progress회수됨 (20260820120000) — 온보딩은 중단하면 처음부터 다시 한다(오너 결정 2026-08-20). draft 병합은 complete_onboarding이 내부 헬퍼로 계속 수행
complete_onboardingpayload jsonb default '{}'jsonb온보딩 완료 래퍼 — 내부에서 complete_onboarding_v4로 위임하고 one_rms 항목은 save_manual_pr로 저장온보딩
withdraw_user_consentp_consent_type text, p_document_version textjsonb동의 철회(append-preserving 이력, 필수 동의 철회 시 온보딩 재진입)프로필/설정
get_profile_workspace(없음)jsonb프로필 워크스페이스(신체 지표 등) 읽기프로필
save_profile_body_metricpayload jsonbjsonb신체 지표(체중 등) 단건 저장프로필
import_inbody_body_metricsp_batch_id uuid, p_rows jsonbjsonb인바디 신체 지표 배치 인입프로필
create_custom_exercisepayload jsonbjsonb (exercise 행 형태)본인 커스텀 종목 생성. load_multiplier(1 또는 2, 없으면 1 — 이슈 #1202 Phase 5 D11: 등록 화면 "덤벨·케틀벨 2개" 선택지)종목 추가
set_own_custom_exercise_activep_exercise_id uuid, p_is_active booleanjsonb (exercise 행 형태)본인 커스텀 종목 보관/복원종목 관리
set_profile_handle_v1p_handle textjsonb {user_id, handle}본인 아이디(@handle) 설정/변경(20260821470000) — 정규화(선두 @·공백 제거·소문자) 후 ^[a-z0-9_]{3,20}$(22023), 다른 프로필이 쓰면 23505. complete_onboarding(payload.handle)도 내부에서 이 함수를 부른다내 정보 탭 아이디 카드 / 온보딩
search_user_profiles_v1p_query text, p_limit intsetof (user_id, display_name, handle, avatar_path, avatar_url, is_following, followed_at)피드 친구 검색(20260821460000, 컬럼 확장 20260821470000) — 아이디·닉네임 부분일치·대소문자/선두 @ 무시, 정렬 아이디 정확→접두→닉네임 정확→접두, 본인·온보딩 미완료 제외, 빈 검색어는 0행, ≤50행. avatar_url은 http(s) 소셜 사진만피드 친구 추가 시트 / followingStore.ts
follow_user_v1p_user_id uuidjsonb {user_id, display_name, followed_at}팔로우(멱등; 자기 자신 22023·없는/미완료 프로필 P0002 거부)피드 친구 추가 시트
unfollow_user_v1p_user_id uuidboolean언팔로우(행이 있었으면 true)피드 친구 추가 시트
list_following_v1p_limit intsetof (user_id, display_name, handle, avatar_path, avatar_url, followed_at)내가 팔로우한 프로필, 최근순 ≤500(컬럼 확장 20260821470000)피드 탭 진입 시 1회
adopt_planned_session_v1p_planned_session_id uuidjsonb폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 계획 반영 기능 자체가 폐기됐다(저장소 planned_session_adoptions 삭제). 옛 용도: 팔로우한 사람의 계획을 내 달력에 링크로 반영(20260821490000)(호출자 없음)
unadopt_planned_session_v1p_planned_session_id uuidboolean폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 옛 용도: 반영 취소(호출자 없음)
set_session_like_v1p_session_id uuid, p_liked booleanjsonb {session_id, owner_user_id, liked, like_count, comment_count}완료 세션 좋아요/취소(멱등, 20260821530000) — 대상은 본인 또는 팔로우한 사람의 완료 세션(없음/미완료 P0002·비팔로우 42501)피드·홈 포스트 하트 / feedSocialStore.ts
add_session_comment_v1p_session_id uuid, p_body textjsonb {session_id, owner_user_id, comment{id, body, created_at, mine, can_delete, author}, like_count, comment_count, liked_by_me}댓글 추가(바깥 공백 제거 1~500자·≤2000 B, 위반 22023; 게이트는 좋아요와 동일). author = 피드 author 카드 모양댓글 시트
delete_session_comment_v1p_comment_id uuidjsonb {deleted, session_id, like_count, comment_count, liked_by_me}댓글 삭제 — 작성자 본인 또는 세션 소유자(없음 P0002·그 밖 42501)댓글 시트
list_session_comments_v1p_session_id uuid, p_limit intjsonb {session_id, owner_user_id, items[{id, body, created_at, mine, can_delete, author}], truncated, like_count, comment_count, liked_by_me}댓글 목록 오래된 순 ≤200(초과는 truncated), 게이트는 좋아요와 동일댓글 시트 열기
block_user_v1p_user_id uuidjsonb {user_id, display_name, blocked_at}차단(멱등, 20260821740000 D1) — 양방향 팔로우 즉시 삭제(해제해도 미복구), 자기 자신 22023·없는 프로필 P0002피드 ⋯ 메뉴 차단 확인 / moderationStore.ts
unblock_user_v1p_user_id uuidboolean차단 해제(행이 있었으면 true) — 팔로우는 복구되지 않는다내 정보 차단 목록 시트
list_blocked_users_v1p_limit intsetof (user_id, display_name, handle, avatar_path, avatar_url, blocked_at)내가 차단한 프로필, 최근순 ≤500 — 팔로잉 행 모양 + blocked_at내 정보 차단 목록 시트
report_content_v1p_target_type text, p_target_id uuid, p_reason_code text, p_detail textjsonb {report_id, status, already_reported, target_type, target_id}신고 접수(20260821740000 D2/D3) — 대상 session/comment/user, 사유 7종, 상세 ≤500자, (신고자, 대상) 멱등(already_reported), 본인 콘텐츠 22023, 비기각 신고는 신고자 화면에서 대상 숨김피드 ⋯ 메뉴·댓글 신고 시트
get_my_moderation_state_v1(없음)jsonb {suspended, suspended_at?, reason?}본인 정지 상태(D5 부팅 게이트) — 클라이언트는 fail-open부팅 시 1회 / moderationController.ts
process_user_exercise_stats_refresh_jobs_for_userp_user_id uuid, p_limit int, p_validate_integrity boolean, p_lock_owner textjsonb저장 직후 본인 통계 리프레시 큐 즉시 드레인(실패 시 cron이 재시도)저장 후 백그라운드
record_client_error_eventp_event jsonbjsonb클라이언트 오류 이벤트 서버 기록appErrorTransport.ts

§3 관리자/운영 RPC

함수명주요 인자반환용도호출 화면/서비스
get_admin_operations_checklistp_stale_after interval, p_stats_stale_after interval, p_rpc_response_warning_bytes int, p_rpc_response_samples jsonbjsonb관리자 운영 체크리스트 — DB 헬스 리포트에 Edge Function 배포 프로브·마이그레이션 이력 검사를 얹은 상위 리포트관리자 화면 / barbelicRepository
get_admin_health_report(위와 동일 인자)jsonb하위 수준 DB/인입/통계 헬스 리포트. 관리자 UI는 checklist를 쓰고, 이 함수는 SQL 직접 실행용으로 유지운영 SQL
get_admin_content_reports_v1p_status text, p_limit intjsonb {items[], counts{pending, actioned, dismissed}}UGC 신고 큐(20260821740000, 관리자 게이트 42501) — 상태 필터(pending/actioned/dismissed/all)·최신순 ≤200, 행에 신고자/대상 카드·미리보기·내려짐/정지 상태관리자 신고 큐 탭
admin_resolve_content_report_v1p_report_id uuid, p_action text, p_note textjsonb {report_id, status, action, target_user_suspended}신고 처리 1회(재처리 22023) — dismiss / remove_content(content_takedowns, 원본 불변 D4) / suspend_user(user_suspensions D5) / remove_and_suspend관리자 신고 큐 탭
admin_set_user_suspension_v1p_user_id uuid, p_suspended boolean, p_note textjsonb {user_id, suspended}신고 밖 정지/해제 토글(자기 자신 22023) — 해제는 lifted_at 스탬프관리자 신고 큐 탭
get_admin_mapping_pagep_primary_side text, p_query text, p_status text, p_local_exercise_id text, p_include_inactive boolean, p_cursor jsonb, p_limit int, p_include_counts booleanjsonb외부 종목 매핑 관리 페이지(검색·상태 필터·keyset 커서)adminMappingPageRepository.ts
create_catalog_exercisepayload jsonbjsonb (exercise 행 형태)정식 카탈로그 종목 생성(관리자)관리자 화면
admin_create_catalog_exercise_with_mappingpayload jsonb, mapping_payload jsonb default nulljsonb카탈로그 종목 + 외부 매핑 동시 생성관리자 화면
admin_rename_performance_detailp_exercise_ids uuid[], p_current_detail text, p_next_detail textjsonbperformance detail 라벨 일괄 개명관리자 화면
admin_delete_performance_detailp_exercise_ids uuid[], p_detail textjsonbperformance detail 라벨 일괄 삭제관리자 화면
admin_search_users_v1p_query text default '', p_limit int default 20table(user_id, email, display_name, created_at)Wodup 인입 대상 유저 검색(이메일·표시명 부분일치, 최대 50) — 관리자 대리 인입(2026-08-21). 비관리자 42501관리자 화면 / adminMappingPageRepository.ts
check_calendar_read_model_integrity회수됨 (20260820120000) — 호출자 0
repair_calendar_read_models회수됨 (20260820120000) — 드리프트 복구는 stats refresh 큐 경로로
remove_import_data_v1p_provider text, p_user_id uuidjsonb특정 유저의 외부 인입 데이터 전량 제거 프리미티브(2026-08-20, PR #461)운영 SQL
import_motra_workouts_v1p_payload jsonb, p_user_id uuid default nulljsonb모트라 인입 v1(2026-08-24, 20260821620000 — Motra 트랙 Phase 4 쓰기 경로) — 변환기(scripts/motra-import) 산출물 행을 source='motra' 세션·엔트리·세트로 한 번에 기입. 판정 매니페스트 의미론(map/new slug=카탈로그 직결·custom=대상 유저 실체화)·유산소 시간 단독 세트·entry_review(D2)·one-shot 게이트(import_already_appliedp_user_id 대리 인입(비관리자 42501)관리자 화면 (barbelicRepository.ts)

§4 Edge Function 전용/비동기 잡 RPC

wodup 인입은 wodup_import_batches 테이블을 잡 큐로 쓰는 비동기 파이프라인입니다(wodup-import-async-jobs.md). 통계 리프레시는 user_exercise_stats_refresh_jobs 큐를 워커가 소비합니다(stats-refresh-jobs.md).

함수명주요 인자반환용도호출 Edge Function
enqueue_wodup_import_batchp_batch_id uuid, p_operation_id text default ''wodup_import_batches업로드된 배치를 queued로 전이(중복 호출 안전, last_operation_id 갱신)wodup-start-import
start_wodup_import_batchp_batch_id uuid, p_file_sha256 text, p_file_size bigintwodup_import_batches워커의 배치 클레임 — uploaded/queued 상태만 잡을 수 있어 중복 워커를 차단wodup-process-import-jobs (_shared/wodup-import-worker.ts)
stage_wodup_import_batchp_batch_id uuid, p_rows jsonb, p_reset boolean default truejsonb정규화된 JSONL 행을 스테이징 테이블에 적재wodup-process-import-jobs
import_wodup_batch_to_canonicalp_batch_id uuidjsonb스테이징 행을 정식 세션·세트 테이블로 반영하고 영향 범위를 통계 리프레시 큐에 enqueue; 후처리로 세션 타이밍 백필과 체중 소급(backfill_wodup_bodyweight_snapshot_v1 — 인입 종목 카탈로그 체중계수·세션 체중 스냅샷, 20260821510000)을 실행wodup-process-import-jobs
enqueue_stale_user_exercise_stats_refresh_jobsp_limit int default 50jsonb오래된(stale) 유저 통계를 리프레시 큐에 보충stats-process-refresh-jobs
process_user_exercise_stats_refresh_jobsp_limit int default 10, p_validate_integrity boolean default true, p_lock_owner text default ''jsonb통계 리프레시 큐 워커 — pending 잡을 잠그고 materialized 통계를 재계산stats-process-refresh-jobs

§5 내부 함수 부록

클라이언트/Edge가 직접 호출하지 않는 내부 함수 전수 목록입니다(최종 상태 기준 144개, 은퇴 31개는 별도 절). SQL 내부 helper, 트리거, projection 갱신, cron 진입점이 섞여 있습니다.

통계 리프레시 큐·워커 계열 (19)

쓰기·인입이 남긴 dirty range를 큐에 병합하고, 워커/cron이 materialized 통계 테이블을 범위 재계산하는 계열.

enqueue_user_exercise_stats_refresh_job, enqueue_user_exercise_stats_refresh, refresh_user_exercise_stats_from_base, refresh_user_training_period_stats_from, refresh_user_exercise_main_reps_from, refresh_user_training_main_reps_from, refresh_user_exercise_best_reps_from, refresh_user_session_timing_stats_from, refresh_user_exercise_stats_from, validate_user_exercise_stats_integrity, process_user_exercise_stats_refresh_jobs_for_user_now, requeue_retryable_user_exercise_stats_refresh_jobs, run_user_exercise_stats_refresh_cron, sync_user_stats_refresh_state_from_job, get_user_stats_refresh_freshness, is_stats_refresh_statement_timeout_v1, set_user_stats_refresh_projection_context, guard_user_stats_refresh_projection_publication, enqueue_manual_pr_stats_refresh

PR/스냅샷 투영 계열 (12)

get_pr_overview 등이 읽는 PR 요약 스냅샷(세대 관리·롤오버 포함)과 PR 관련 JSON 조각 빌더.

bump_pr_overview_projection_catalog_version, build_user_pr_exercise_summary_rows, refresh_user_pr_overview_snapshot_window, get_user_pr_exercise_summaries_snapshot_json, prune_user_pr_overview_snapshot_generations, run_user_pr_overview_snapshot_rollover, initialize_user_pr_overview_snapshot, refresh_user_measured_pr_projection, get_user_pr_exercise_summaries_json, get_user_recent_prs_json, get_user_home_benchmark_prs_json, get_user_exercise_nrm_states_json

홈/화면 조립 JSON 빌더 계열 (5)

화면 RPC 내부에서 응답 조각을 조립하는 helper. volume_level_progress_v1은 볼륨 레벨/XP 정책(Lv.1~30 표·Lv.31 100,000kg·+500kg/레벨)의 DB 정본으로, get_home_dashboardprofile_summary.volume_level에 싣는다(통계 중앙화 Phase 4-2).

build_home_dashboard_core_v2, build_user_exercise_stats_json, get_session_presentation_mains_json, build_user_exercise_favorites_payload, volume_level_progress_v1

캘린더 읽기 모델 계열 (8)

일 요약 materialize와 dirty 마킹, 캘린더 응답 장식(decorate) helper.

mark_calendar_summary_dirty_date, calendar_day_summary_source, refresh_user_calendar_day_summaries, decorate_calendar_sessions_v1, decorate_calendar_planned_sessions_v1, decorate_calendar_day_atomic_sets_v1, calendar_strength_day_metrics_map_v1, calendar_strength_session_metrics_map_v1

완료 운동 쓰기 경로 내부 계열 (6)

v4 쓰기 RPC의 payload 검증·요청 hash·영수증 재생과 revision/tombstone 트리거. 공개 v4 문은 이슈 #1215(2026-09-04)로 폐기(LG426 스텁)되고 v4 엔진은 삭제됐다 — 현행 v5 쓰기의 검증·엔진·영수증은 validate_session_payload_v5_core·save_session_v5_engine·delete_session_v5_engine·write_session_children_v5·get_session_mutation_receipt_v2다.

validate_completed_workout_payload_v4, workout_mutation_request_hash_v1, get_workout_mutation_receipt_v1, stamp_completed_session_revision_v1, touch_completed_session_revision_from_child_v1, enforce_workout_source_tombstone_v1

계획(plan) 쓰기 경로 내부 계열 (6)

save_plan_v3/delete_planned_session_v2의 검증·hash·영수증과 revision 트리거(두 공개 문은 이슈 #1215로 폐기·LG426 스텁, 2026-09-04 — 계획도 save_session_v5/delete_session_v5로 쓰고, planned_sessions·planned_sets 테이블은 삭제됐다).

validate_plan_payload_v3, plan_mutation_request_hash_v1, get_plan_mutation_receipt_v1, stamp_planned_session_revision, stamp_planned_set_revision, touch_planned_session_revision_from_set

기록 정규화·원자값 계열 (15)

recording field 정본화, 단위(kg/lb)·outcome·거리·시간 정규화, 완료/계획 세트의 원자값 적용·재세척.

canonical_recording_fields_v1, measurement_type_from_recording_fields_v1, sort_recording_fields_v1, normalize_exercise_recording_fields_v1, normalize_session_exercise_recording_fields_v1, normalize_planned_set_recording_fields_v1, normalize_exercise_set_load_unit, normalize_exercise_set_outcome_v1, capture_exercise_set_load_lb, canonical_distance_meters_v1, canonical_duration_seconds_v1, apply_completed_atomic_values_v1, apply_plan_atomic_values_v1, rescrub_session_exercise_sets_v1, scrub_planned_set_atomic_values_v1

근력 추정·세트 목적·최대 반복 계열 (16)

1RM 추정 관측, 세트 목적(purpose) 분류, max-rep 관측과 각 projection 갱신·정합 검증.

strength_estimation_load_percent_v1, calculate_strength_observation_v1, refresh_user_strength_estimation_projection, strength_set_metrics_map_json, strength_display_frame_kg_v1(이슈 #1202: 유효 무게 프레임 → 추가 무게 프레임 환산), attach_strength_metrics_map_to_json_v1, attach_strength_metrics_to_json_v1, empty_strength_aggregate_json_v1, merge_strength_aggregate_array_v1, classify_set_purpose_v1, classify_set_purpose_v2, refresh_user_set_purpose_projection, validate_user_set_purpose_integrity, calculate_max_rep_observation_v1, max_rep_recording_profile_eligible_v1, refresh_user_max_rep_projection, validate_user_max_rep_integrity

wodup 인입 내부 계열 (18)

콤플렉스 이름 해석·정리(cleanup v1/v2), 정본 재매핑, 세션 타이밍 백필, 원자값 채움 등 인입 파이프라인 내부. (미매칭 커스텀 배치 실체화 2종 — materialize_wodup_unmatched_user_customs_v1 · exercise_identity_for_wodup_user_custom_v1 — 은 20260821010000 P3에서 회수됨: 1단계화가 즉시 실체화로 대체한 뒤 남은 고아)

normalize_wodup_complex_movement_name_v1, parse_wodup_complex_name_v1, refresh_wodup_complex_interpretations_v1, apply_wodup_training_complex_meta_v2, exclude_training_complex_strength_observation_v1, backfill_wodup_training_complexes_v1, retire_resolved_wodup_training_complex_catalog_v1, retire_resolved_wodup_training_complex_catalog_v2, guard_wodup_cleanup_observation_scope_v1, guard_wodup_cleanup_observation_scope_v2, finalize_wodup_training_complex_cleanup_v1, finalize_wodup_training_complex_cleanup_v2, rebase_wodup_training_complex_position_v2, wodup_session_timing_source_v1, backfill_wodup_session_timing_v1, body_weight_snapshot_for_date_v1, backfill_wodup_bodyweight_snapshot_v1, populate_wodup_atomic_set_values_v1 (wodup_provider_exercise_key_for_placeholder_v1·remap_wodup_user_customs_to_canonical_v1은 #1175 Phase 0에서 드롭 — 은퇴 목록)

종목 정체성·BRID 계열 (9)

종목 정체성(official/custom/external) 스코프 검증 트리거와 BRID(Barbelic Resource ID) 발급 문법·파생 함수(PR #460). 명세는 brid.md. (exercise_identity_for_external은 전역 placeholder 폐지로 고아가 되어 20260821010000 P3에서 회수됨)

enforce_exercise_identity_row, enforce_exercise_fact_identity, validate_exercise_identity_scope, brid_compact_name_key_v1, brid_uuid_v1, brid_for_official_exercise_v1, brid_for_user_custom_v1, brid_for_external_exercise_v1, brid_label_exercise_v2 (#1175: 라벨 공식 v2 — origin 인자 없이 source·소유자·uuid id로 결정; brid_uuid_v1uuid를 돌려준다)

온보딩·프로필 내부 계열 (11)

auth 신규 유저 프로필 생성 트리거, 동의 요건·닉네임 정규화, 온보딩 완료 버전 구현체, 신규 유저 기본 즐겨찾기 시드.

profile_display_name_from_auth_metadata, handle_new_auth_user_profile, onboarding_consent_requirements, normalize_onboarding_display_name, apply_onboarding_consents, apply_onboarding_progress, onboarding_state_for_user, complete_onboarding_v2, complete_onboarding_v3, complete_onboarding_v4, seed_new_user_default_exercise_favorites

트리거·가드 계열 (5)

행 수 상한·소유권 보존 트리거와 관리자 권한 가드.

is_lift_guild_admin, enforce_completed_session_exercise_limit, enforce_completed_exercise_set_limits, enforce_planned_session_set_limit, enforce_session_exercise_owner_on_user_change

레거시 잔존 계열 (3)

과거 계약의 잔존 함수 — 현재 앱 코드 호출 지점 없음.

training_effective_load(이슈 #1200부터 5인자: 든 무게·무게 배수·체중·체중계수·보조 무게), set_exercise_set_effective_load, refresh_session_effective_loads (구 effective-load 계산 계열 — 20260820120000에서 클라이언트 롤 실행 권한을 회수해 definer 내부 전용이 됐습니다). cheer_session은 같은 마이그레이션에서 drop됐습니다.

기타/유틸 계열 (5)

바이트 제한 문자열·배열 helper, UUID 후보 수집, 서울 기준 리포트 as-of 계산.

left_utf8_bytes, bounded_text_array_json, text_array_was_truncated, collect_json_uuid_candidates_v1, canonical_seoul_report_as_of_v1

은퇴(retired) 함수 (34)

schema.sqlcreate or replace function 정의 이력은 있으나 이후 마이그레이션에서 drop되어 최종 상태에는 존재하지 않는 이름입니다. 구 쓰기 계약(v1~v3)과 구 읽기 모델이 대부분입니다.

save_workout, save_workout_v2, save_workout_v3, update_completed_session, update_completed_session_v2, update_completed_session_v3, delete_completed_session, delete_completed_session_v2, delete_completed_session_v3, save_plan, save_plan_v2, delete_planned_session, get_calendar_month, get_home_summary, get_pr_dashboard, apply_workout_entry_metadata, merge_workout_raw_provenance_v1, preserve_completed_session_provenance_v1, update_completed_session_exact_children_v1, get_workout_mutation_canonical_states_v1, reconcile_legacy_workout_writes_v1, parse_legacy_liftguild_note_v1, prepare_workout_strength_semantics_v1, apply_strength_semantics_from_raw_payload_v1, apply_session_intent_from_raw_payload_v1, build_user_exercise_pr_metrics_json, normalize_exercise_pr_detail_aliases, merge_manual_pr_records, get_user_home_catalog_json, merge_exercise, resolve_exercise_external_placeholder, remap_wodup_user_customs_to_canonical_v1, wodup_provider_exercise_key_for_placeholder_v1, brid_label_exercise_v1

이 밖에 build_exercise_pr_detail_payload, calendar_day_summary_source_core, get_home_summary_without_manual_pr_v1, get_pr_dashboard_without_manual_pr_v1, get_session_presentation_mains_core_json 5개는 schema.sql에 drop 문만 남아 있는 이름입니다(정의문은 과거 마이그레이션에만 존재).