시스템 아키텍처

상위: · 관련: 웹-개요 · 앱-개요

구성 요소

flowchart TB
    userWeb(["👤 사용자 · 웹"])
    userApp(["📱 사용자 · 앱"])

    subgraph app["📱 novato_app · Flutter"]
        direction TB
        webview["웹뷰 (body)"]
        statpad["StatPad · 스탯 입력"]
        webview ~~~ statpad
    end

    web["React 웹앱<br/>novato.kr · Netlify<br/><i>novato_react</i>"]
    supa[("Supabase<br/>PostgreSQL + Realtime")]
    r2[("Cloudflare R2<br/>APK · version.json")]

    userWeb --> web
    userApp --> app
    r2 -->|APK 배포·업데이트| app
    webview -->|웹앱 표시| web
    web <-->|조회 / 기록| supa
    statpad -->|스탯·실시간 송출| supa
    supa -.->|실시간 방송| web

    classDef store fill:#eef,stroke:#88a,color:#224;
    class supa,r2 store;

데이터 흐름 (웹)

Supabase RPC(get_all_data, get_team_rankings, get_player_rankings, get_game_detail, get_league_leaders) → 서비스층 → TanStack Query(useAppData) → Zustand(AppStore) → 컴포넌트

앱 ↔ 웹 연동 계약

  • 앱 body = React 웹앱 웹뷰(앱-개요)
  • 앱 StatPad가 기록한 스탯 → Supabase → 웹 방송 화면(/broadcast, /tvbroadcast)이 표시(앱-StatPad)
  • 실시간: live_scores 테이블(Realtime) 공유
  • +1점 규칙: players.bonus_scorer 컬럼 기반. 통계는 원본, 점수만 +1. 웹·앱 양쪽 구현(크로스 리포 계약)

외부 연동

  • Google Sheets — 웹 /upload 경기 결과 업로드
  • Cloudflare R2 — 앱 APK 바이너리 + version.json(업데이트 체크)
  • Netlify — 웹 배포 (novato / ytbros 사이트 분리 운영, 같은 repo)
  • Streamlit (novato.streamlit.app) — 구 신문 생성기. 앱 연결(메뉴·baseUrl 전환) 2026-07 제거됨(앱-정리후보). Streamlit repo 자체는 잔존.

관련 저장소 (NovatoProject 하위)

폴더내용
novato_reactReact 웹앱 (본체)
novato_appFlutter 앱 (웹뷰 + StatPad)
novato_streamlitStreamlit(구 신문/도구, 레거시 추정)
novato_newspaper신문 관련
NovatoStatPad(구 StatPad 관련 추정)
docs이 문서 vault