Supabase Type Strategy
Barbelic 앱은 장기적으로 Supabase generated database type을 사용합니다. 다만 TypeScript 전면 이전 초기 단계에서는 운영 DB와 네트워크에 의존하지 않고 진행해야 하므로, 프론트가 직접 읽는 row와 RPC부터 수동 최소 타입으로 고정합니다.
Current Manual Baseline
- 기준 파일:
src/react/types/supabase.ts - 화면 RPC 응답 타입:
src/react/types/screenRpc.ts - 직접 table select row 타입:
SupabaseTableRowMap - 직접 RPC 호출 타입:
SupabaseRpcArgsMap,SupabaseRpcReturnMap - generated type 호환 껍데기:
SupabaseDatabaseManual
현재 수동 row 타입은 프론트 repository가 직접 접근하는 테이블만 포함합니다.
profiles
user_consents
exercise_archetypes
exercises
wodup_exercises
exercise_external_mappings
session
session_exercise
session_exercise_part
exercise_set
exercise_set_part
user_manual_pr_records
daily_conditions
user_exercise_stats
user_exercise_records
user_exercise_pr_states
user_exercise_pr_events
user_exercise_period_stats
user_training_period_stats
user_calendar_day_summaries
user_exercise_session_rollups
wodup_import_batchesuser_exercise_estimated_1rm_records는 정책 v1 migration이 비우고 더 이상 화면에서 읽지 않는 legacy projection이므로 수동 frontend table map에서도 제거한다. e1RM은 user_exercise_strength_observations, user_exercise_strength_daily, user_exercise_strength_states에 정책/곡선 버전과 함께 저장하지만 프론트가 이 원시 테이블을 직접 읽지는 않는다. 실제 수행 1..20RM은 기존 PR state/event에만 저장하며, 화면은 버전이 고정된 RPC payload를 사용한다.
화면 RPC payload는 table row 그대로가 아니라 화면 계약입니다. 그래서 get_home_dashboard, get_calendar_month_summary, get_calendar_day_summary, get_session_detail, get_planned_session_detail, get_pr_overview, get_volume_overview는 ScreenRpcPayloadMap과 adapter output 타입으로 따로 관리합니다.
The session frontend write contract exposes only save_session_v5 (create/update of completed records, plans and group plans) and delete_session_v5 (issue #1215, 2026-09-04; the v4 completed writers and v3 plan writers are retired LG426 stubs). Their owner binding is required in the typed payload. rpc() accepts only the active literal union; there is no generic string escape hatch or retired-name production union.
Future Generated Types
운영 DB 접근과 Supabase CLI 기준이 안정되면 아래 명령으로 generated type을 만듭니다.
supabase gen types typescript --project-id kobxeylancdimqhfkbnl권장 출력 위치:
src/react/types/supabase.generated.ts그 다음 단계:
SupabaseDatabaseManual과 generatedDatabase를 비교합니다.SupabaseTableRowMap을 generated tableRow기반으로 교체합니다.- 프론트가 직접 읽지 않는 table은 앱 화면 타입에 노출하지 않습니다.
- 화면 RPC payload는 계속
screenRpc.ts계약을 우선합니다.
Rules
- 운영 DB가 필요한 generated type 갱신은 별도 PR에서 수행합니다.
- 프론트 화면 코드는 DB table shape 대신 domain/screen API 타입을 우선 사용합니다.
- raw table row 타입은 repository/admin/debug/import 경로에서만 사용합니다.
JsonValue와JsonObject는 원본 payload, metadata, Supabase JSONB 컬럼에만 사용합니다.- generated type 도입 전까지 새 table select가 생기면
SupabaseTableRowMap에 먼저 추가합니다. - 알려진 RPC literal은 generic JSON fallback보다
SupabaseRpcArgsMap을 우선하며, 필수 인자가 빠진 호출은 타입 검사에서 실패해야 합니다. - Plans are
sessionrows withstatus = plannedand go through the samesave_session_v5payload (contract_version: 5,expected_user_id, immutablesource_ref; updates additionally requireidandexpected_revision). Bothsave_session_v5anddelete_session_v5require a durable client mutation UUID plus request hash and return a versioned mutation receipt (v2). The formersave_plan_v3/delete_planned_session_v2and theirexpected_updated_atlock are retired (issue #1215, 2026-09-04). Retired workout/plan writer and reconciliation RPCs are compile-time blocked and absent from the public RPC maps.