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.ts의SupabaseRpcName타입맵 +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_dashboard | p_today date | jsonb (v3) | 홈 대시보드 패키지(이번 달 세션·계획, 주간 활동, 최근 세션·최근 PR) — current_month.plans는 session 테이블의 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.syncExerciseCatalogData → exerciseCatalogStore.ts(IndexedDB) |
get_exercise_catalog_changes | p_since_seq bigint, p_limit int | jsonb (v1) | 기기 순번 이후 바뀐 종목만(시스템 + 본인 커스텀, 종목마다 마지막 1건, 페이지 ≤1,000, 삭제·보관은 deleted, 보존 기간 밖이면 full_resync_required) — 이슈 #1238 Phase 3 | 홈 힌트 catalog_version > 기기 순번일 때·커스텀 종목 쓰기 직후 / catalogDomain.syncExerciseCatalogData |
get_home_year_activity | p_year int, p_as_of date | jsonb (v1) | 연간 활동 히트맵(홈 지연 로드 프래그먼트) | 홈 / callScreenRpc |
get_user_exercise_favorites | (없음) | jsonb (v1) | 종목 즐겨찾기 목록 + revision | 로그 테이블·종목 즐겨찾기 UI |
get_calendar_month_summary | p_from date, p_to date | jsonb (v4) | 월 캘린더 요약(일별 완료/계획 카드, materialized 읽기 모델) — 응답 키 planned_sessions(계획 카드; 키 이름은 유지, 이슈 #1215, 2026-09-04부터 session 테이블의 status = planned 행에서 읽음)·days[].planned_session_count·source_version 포함. 20260821490000이 섞던 반영 계획(plan_owner·adopted)은 계획 반영 폐기로 사라졌다 | 캘린더 월 뷰 |
get_calendar_day_summary | p_date date | jsonb (v5) | 선택일 요약(완료 세션의 크기 제한된 표시용 세트 + set-free 계획 카드) — summary.planned_session_count 포함(반영 계획 카드는 계획 반영 폐기로 사라짐, 이슈 #1215, 2026-09-04) | 캘린더 선택일 |
get_calendar_range_summary | p_from date, p_to date | jsonb (v1) | 주/월 같은 날짜 범위 합계(일 요약 테이블 가산, 세션 배열 없음, 최대 93일) — 통계 중앙화 Phase 4-1 | 주/월 드로어·모달 |
get_session_detail | p_session_id uuid | jsonb (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_detail | p_planned_session_id uuid | jsonb (v2) | 계획 세션 편집용 상세(편집 가능한 전체 세트) — 20260821490000부터 팔로우한 사람의 계획도 읽힘(planned_session_visible_v1; 비소유자 응답은 plan_owner·editable:false, adopted는 계획 반영 폐기(이슈 #1215, 2026-09-04) 뒤 항상 false, 그 밖은 P0002). 계획 행은 session(status = planned)에서 조립 | 계획 편집기 · 친구 계획 상세/운동 시작 |
get_log_table_month | p_from date, p_to date, p_exercise_ids uuid[] | jsonb (v3) | 데스크톱 기록표 월 데이터(일×즐겨찾기 종목 격자) | 데스크톱 기록표 |
get_log_table_cell_detail | p_date date, p_exercise_id uuid | jsonb (v2) | 기록표 셀(일×종목) 표시용 세트 토큰 | 데스크톱 기록표 셀 |
get_profile_feed | p_before_date, p_before_created_at, p_before_id, p_limit | jsonb (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_v1 | p_user_id uuid, p_from date, p_to date | jsonb (v1) | 팔로우한 사람의 달력 한 달(≤42일): 일별 완료/계획 카운트, 완료 세션 lite ≤64, set-free 계획 카드 ≤64(plan_owner + 호출자의 adopted) — 비팔로우 42501 (20260821490000, 계획 반영 v1) | 친구 달력(클라이언트 데이터층 planAdoptionStore, UI 미배선) |
get_following_volume_overview_v1 | p_user_id uuid, p_as_of date | jsonb (v4, get_volume_overview 페이로드 그대로) | 친구 리포트(20260821520000): 팔로우한 사람의 볼륨 개요 — 게이트 통과 후 같은 트랜잭션 로컬로 JWT sub 클레임을 대상으로 바꿔 get_volume_overview(p_as_of, 4) 체인을 그대로 호출(체인 정의 무접촉)하고 원복. 비팔로우 42501·null 22023 | 피드 친구 아이디/아바타 탭 → 친구 리포트 페이지(friendReportStore) |
get_session_search | p_limit int, p_before_date date, p_before_created_at timestamptz, p_before_id uuid | jsonb (v3) | 세션 검색 인덱스 — 페이지당 ≤120 세션 표시 카드, keyset 커서 페이지네이션(has_more/next_cursor, 20260830140000 이슈 #938 D5) | 세션 검색 |
get_pr_overview | p_as_of date | jsonb (v3) | PR 개요(추적 종목 요약 ≤128 + 최근 PR ≤24, 스냅샷 투영 기반) | PR 대시보드 |
get_volume_overview | p_as_of date 또는 p_as_of date, p_contract_version int | jsonb (v4, 구버전 v2 오버로드 병존) | 볼륨/기간 버킷·연간 집계 리포트 | 리포트(볼륨) 화면 |
get_exercise_pr_detail | p_exercise_id uuid, p_as_of date | jsonb (v4) | 종목 PR 상세 초기 페인트(NRM 상태 + 12주 버킷) | 종목 PR 상세 |
get_exercise_pr_detail_year | p_exercise_id, p_year, p_as_of | jsonb (v4) | 종목 연간 상세(일별 활동·근력 포인트·월 집계) | 종목 PR 상세(연도) |
get_exercise_pr_records | p_exercise_id, p_before_*, p_limit, p_as_of | jsonb (v5) | 종목 PR 기록 keyset 페이지(≤64행) | 종목 PR 기록 목록 |
get_exercise_pr_history | p_exercise_id, p_year, p_before_*, p_limit, p_as_of | jsonb (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_v5 | p_payload jsonb, p_client_mutation_id uuid, p_request_hash text | jsonb (session mutation receipt v2) | 완료 기록·계획·그룹 운동 계획의 신규 저장·수정·계획→완료 전이 한 문(멱등; payload contract_version: 5, status는 completed 또는 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_v5 | p_session_id uuid, p_expected_revision bigint, p_client_mutation_id uuid, p_request_hash text | jsonb (receipt v2, mutation_kind delete_session) | 완료 기록·계획 삭제(주인만, 그룹 계획은 작성자; server_revision 낙관 잠금) — 이슈 #1215, 2026-09-04 | 세션 상세·계획 편집기 |
save_workout_v4 | payload jsonb, p_client_mutation_id uuid, p_request_hash text | jsonb | 폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 호출하면 아무것도 쓰지 않고 SQLSTATE LG426(앱은 "앱 업데이트가 필요해요…" 안내). 옛 용도: 완료 운동 신규 저장 → save_session_v5 | (호출자 없음) |
update_completed_session_v4 | p_session_id uuid, payload jsonb, p_expected_revision bigint, p_client_mutation_id uuid, p_request_hash text | jsonb | 폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 옛 용도: 완료 세션 수정 → save_session_v5(id + expected_revision) | (호출자 없음) |
delete_completed_session_v4 | p_session_id uuid, p_expected_user_id uuid, p_expected_revision bigint, p_client_mutation_id uuid, p_request_hash text | jsonb | 폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 옛 용도: 완료 세션 삭제 → delete_session_v5 | (호출자 없음) |
save_plan_v3 | payload jsonb, p_client_mutation_id uuid, p_request_hash text | jsonb | 폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 옛 용도: 계획 생성·수정 → save_session_v5(status: planned) | (호출자 없음) |
delete_planned_session_v2 | p_planned_session_id uuid, p_expected_user_id uuid, p_expected_updated_at timestamptz, p_client_mutation_id uuid, p_request_hash text | jsonb | 폐기(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_pr | payload jsonb | jsonb | 수동 PR 저장 | PR 화면 / 온보딩 초기 1RM |
delete_manual_pr | p_id uuid | jsonb | 수동 PR 삭제 | PR 화면 |
save_manual_record_metric_v1 | payload jsonb | jsonb | 종목별 핵심 기록 지표(최대 반복수·최대 버티기·유산소 거리+시간) 직접 입력 저장 — 서버가 종목 기록 방식으로 지표 판정, id 동반 시 수정 (이슈 #1194) | 내 1RM 기록 관리 / 데스크톱 PR 보드 |
delete_manual_record_metric_v1 | p_id uuid | jsonb | 직접 입력 기록 지표 삭제 (이슈 #1194) | 내 1RM 기록 관리 |
replace_user_exercise_favorites | p_exercise_ids uuid[], p_expected_revision int | jsonb (v1) | 즐겨찾기 전체 교체(revision 검사) | 즐겨찾기 편집 |
set_user_exercise_favorite | p_exercise_id uuid, p_favorite boolean, p_expected_revision int | jsonb (v1) | 즐겨찾기 단건 토글 | 즐겨찾기 편집 |
ensure_user_profile | (없음) | profiles 행 | 로그인 직후 최소 프로필 행 보장(생성 or 반환) | 부팅/auth 경로 |
get_onboarding_state | (없음) | jsonb | 온보딩 상태 + 동의 요건 + 닉네임 정책 반환 | 온보딩 |
save_onboarding_progress | — | — | 회수됨 (20260820120000) — 온보딩은 중단하면 처음부터 다시 한다(오너 결정 2026-08-20). draft 병합은 complete_onboarding이 내부 헬퍼로 계속 수행 | — |
complete_onboarding | payload jsonb default '{}' | jsonb | 온보딩 완료 래퍼 — 내부에서 complete_onboarding_v4로 위임하고 one_rms 항목은 save_manual_pr로 저장 | 온보딩 |
withdraw_user_consent | p_consent_type text, p_document_version text | jsonb | 동의 철회(append-preserving 이력, 필수 동의 철회 시 온보딩 재진입) | 프로필/설정 |
get_profile_workspace | (없음) | jsonb | 프로필 워크스페이스(신체 지표 등) 읽기 | 프로필 |
save_profile_body_metric | payload jsonb | jsonb | 신체 지표(체중 등) 단건 저장 | 프로필 |
import_inbody_body_metrics | p_batch_id uuid, p_rows jsonb | jsonb | 인바디 신체 지표 배치 인입 | 프로필 |
create_custom_exercise | payload jsonb | jsonb (exercise 행 형태) | 본인 커스텀 종목 생성. load_multiplier(1 또는 2, 없으면 1 — 이슈 #1202 Phase 5 D11: 등록 화면 "덤벨·케틀벨 2개" 선택지) | 종목 추가 |
set_own_custom_exercise_active | p_exercise_id uuid, p_is_active boolean | jsonb (exercise 행 형태) | 본인 커스텀 종목 보관/복원 | 종목 관리 |
set_profile_handle_v1 | p_handle text | jsonb {user_id, handle} | 본인 아이디(@handle) 설정/변경(20260821470000) — 정규화(선두 @·공백 제거·소문자) 후 ^[a-z0-9_]{3,20}$(22023), 다른 프로필이 쓰면 23505. complete_onboarding(payload.handle)도 내부에서 이 함수를 부른다 | 내 정보 탭 아이디 카드 / 온보딩 |
search_user_profiles_v1 | p_query text, p_limit int | setof (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_v1 | p_user_id uuid | jsonb {user_id, display_name, followed_at} | 팔로우(멱등; 자기 자신 22023·없는/미완료 프로필 P0002 거부) | 피드 친구 추가 시트 |
unfollow_user_v1 | p_user_id uuid | boolean | 언팔로우(행이 있었으면 true) | 피드 친구 추가 시트 |
list_following_v1 | p_limit int | setof (user_id, display_name, handle, avatar_path, avatar_url, followed_at) | 내가 팔로우한 프로필, 최근순 ≤500(컬럼 확장 20260821470000) | 피드 탭 진입 시 1회 |
adopt_planned_session_v1 | p_planned_session_id uuid | jsonb | 폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 계획 반영 기능 자체가 폐기됐다(저장소 planned_session_adoptions 삭제). 옛 용도: 팔로우한 사람의 계획을 내 달력에 링크로 반영(20260821490000) | (호출자 없음) |
unadopt_planned_session_v1 | p_planned_session_id uuid | boolean | 폐기(LG426 스텁) — 이슈 #1215, 2026-09-04. 옛 용도: 반영 취소 | (호출자 없음) |
set_session_like_v1 | p_session_id uuid, p_liked boolean | jsonb {session_id, owner_user_id, liked, like_count, comment_count} | 완료 세션 좋아요/취소(멱등, 20260821530000) — 대상은 본인 또는 팔로우한 사람의 완료 세션(없음/미완료 P0002·비팔로우 42501) | 피드·홈 포스트 하트 / feedSocialStore.ts |
add_session_comment_v1 | p_session_id uuid, p_body text | jsonb {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_v1 | p_comment_id uuid | jsonb {deleted, session_id, like_count, comment_count, liked_by_me} | 댓글 삭제 — 작성자 본인 또는 세션 소유자(없음 P0002·그 밖 42501) | 댓글 시트 |
list_session_comments_v1 | p_session_id uuid, p_limit int | jsonb {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_v1 | p_user_id uuid | jsonb {user_id, display_name, blocked_at} | 차단(멱등, 20260821740000 D1) — 양방향 팔로우 즉시 삭제(해제해도 미복구), 자기 자신 22023·없는 프로필 P0002 | 피드 ⋯ 메뉴 차단 확인 / moderationStore.ts |
unblock_user_v1 | p_user_id uuid | boolean | 차단 해제(행이 있었으면 true) — 팔로우는 복구되지 않는다 | 내 정보 차단 목록 시트 |
list_blocked_users_v1 | p_limit int | setof (user_id, display_name, handle, avatar_path, avatar_url, blocked_at) | 내가 차단한 프로필, 최근순 ≤500 — 팔로잉 행 모양 + blocked_at | 내 정보 차단 목록 시트 |
report_content_v1 | p_target_type text, p_target_id uuid, p_reason_code text, p_detail text | jsonb {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_user | p_user_id uuid, p_limit int, p_validate_integrity boolean, p_lock_owner text | jsonb | 저장 직후 본인 통계 리프레시 큐 즉시 드레인(실패 시 cron이 재시도) | 저장 후 백그라운드 |
record_client_error_event | p_event jsonb | jsonb | 클라이언트 오류 이벤트 서버 기록 | appErrorTransport.ts |
§3 관리자/운영 RPC
| 함수명 | 주요 인자 | 반환 | 용도 | 호출 화면/서비스 |
|---|---|---|---|---|
get_admin_operations_checklist | p_stale_after interval, p_stats_stale_after interval, p_rpc_response_warning_bytes int, p_rpc_response_samples jsonb | jsonb | 관리자 운영 체크리스트 — DB 헬스 리포트에 Edge Function 배포 프로브·마이그레이션 이력 검사를 얹은 상위 리포트 | 관리자 화면 / barbelicRepository |
get_admin_health_report | (위와 동일 인자) | jsonb | 하위 수준 DB/인입/통계 헬스 리포트. 관리자 UI는 checklist를 쓰고, 이 함수는 SQL 직접 실행용으로 유지 | 운영 SQL |
get_admin_content_reports_v1 | p_status text, p_limit int | jsonb {items[], counts{pending, actioned, dismissed}} | UGC 신고 큐(20260821740000, 관리자 게이트 42501) — 상태 필터(pending/actioned/dismissed/all)·최신순 ≤200, 행에 신고자/대상 카드·미리보기·내려짐/정지 상태 | 관리자 신고 큐 탭 |
admin_resolve_content_report_v1 | p_report_id uuid, p_action text, p_note text | jsonb {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_v1 | p_user_id uuid, p_suspended boolean, p_note text | jsonb {user_id, suspended} | 신고 밖 정지/해제 토글(자기 자신 22023) — 해제는 lifted_at 스탬프 | 관리자 신고 큐 탭 |
get_admin_mapping_page | p_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 boolean | jsonb | 외부 종목 매핑 관리 페이지(검색·상태 필터·keyset 커서) | adminMappingPageRepository.ts |
create_catalog_exercise | payload jsonb | jsonb (exercise 행 형태) | 정식 카탈로그 종목 생성(관리자) | 관리자 화면 |
admin_create_catalog_exercise_with_mapping | payload jsonb, mapping_payload jsonb default null | jsonb | 카탈로그 종목 + 외부 매핑 동시 생성 | 관리자 화면 |
admin_rename_performance_detail | p_exercise_ids uuid[], p_current_detail text, p_next_detail text | jsonb | performance detail 라벨 일괄 개명 | 관리자 화면 |
admin_delete_performance_detail | p_exercise_ids uuid[], p_detail text | jsonb | performance detail 라벨 일괄 삭제 | 관리자 화면 |
admin_search_users_v1 | p_query text default '', p_limit int default 20 | table(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_v1 | p_provider text, p_user_id uuid | jsonb | 특정 유저의 외부 인입 데이터 전량 제거 프리미티브(2026-08-20, PR #461) | 운영 SQL |
import_motra_workouts_v1 | p_payload jsonb, p_user_id uuid default null | jsonb | 모트라 인입 v1(2026-08-24, 20260821620000 — Motra 트랙 Phase 4 쓰기 경로) — 변환기(scripts/motra-import) 산출물 행을 source='motra' 세션·엔트리·세트로 한 번에 기입. 판정 매니페스트 의미론(map/new slug=카탈로그 직결·custom=대상 유저 실체화)·유산소 시간 단독 세트·entry_review(D2)·one-shot 게이트(import_already_applied)·p_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_batch | p_batch_id uuid, p_operation_id text default '' | wodup_import_batches 행 | 업로드된 배치를 queued로 전이(중복 호출 안전, last_operation_id 갱신) | wodup-start-import |
start_wodup_import_batch | p_batch_id uuid, p_file_sha256 text, p_file_size bigint | wodup_import_batches 행 | 워커의 배치 클레임 — uploaded/queued 상태만 잡을 수 있어 중복 워커를 차단 | wodup-process-import-jobs (_shared/wodup-import-worker.ts) |
stage_wodup_import_batch | p_batch_id uuid, p_rows jsonb, p_reset boolean default true | jsonb | 정규화된 JSONL 행을 스테이징 테이블에 적재 | wodup-process-import-jobs |
import_wodup_batch_to_canonical | p_batch_id uuid | jsonb | 스테이징 행을 정식 세션·세트 테이블로 반영하고 영향 범위를 통계 리프레시 큐에 enqueue; 후처리로 세션 타이밍 백필과 체중 소급(backfill_wodup_bodyweight_snapshot_v1 — 인입 종목 카탈로그 체중계수·세션 체중 스냅샷, 20260821510000)을 실행 | wodup-process-import-jobs |
enqueue_stale_user_exercise_stats_refresh_jobs | p_limit int default 50 | jsonb | 오래된(stale) 유저 통계를 리프레시 큐에 보충 | stats-process-refresh-jobs |
process_user_exercise_stats_refresh_jobs | p_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_dashboard가 profile_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_v1은 uuid를 돌려준다)
온보딩·프로필 내부 계열 (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.sql에 create 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 문만 남아 있는 이름입니다(정의문은 과거 마이그레이션에만 존재).