OpenAthlete
AGPLv3 endurance training platform: EU-oriented hosting, transparent CTL/ATL/TSB logic in code, self-hosting, and full export. Built in Grenoble.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗개인 수영인의 훈련 준비·플랜·일지·리포트부터 코치의 강습 운영까지 하나의 흐름으로 연결한 웹 서비스입니다.
웹서비스 바로가기 · 기능 지도 · 기술 구조 · 배포 가이드 · 기능 체크리스트 · 품질 검증 게이트
저장소와 배포 URL에는 초기 프로젝트명인
swimtech가 남아 있지만, 사용자에게 표시되는 서비스명은 SwimMate입니다.
SwimMate는 별도의 프로그램이나 설치 마법사가 필요 없는 웹서비스입니다. PC와 모바일 브라우저에서 swimtech.vercel.app에 접속하면 바로 이용할 수 있습니다.
/landing에서는 이번 주 훈련량·최근 기록·다음 추천을 먼저 보여줍니다. 메뉴는 항상 보이는 오늘·기록·플랜·성장 네 흐름과 필요할 때 펼치는 분석·코치/커뮤니티·정보/도구 그룹으로 나뉘며, 서비스 검색과 모바일 하단 빠른 메뉴를 제공합니다. 서비스 상단은 어느 기능에서나 SwimMate·프로필 수정·로그아웃·테마 변경 순서의 공통 헤더를 사용하고 본문과 함께 자연스럽게 스크롤되며, 브라우저 탭과 PWA에는 수영 선수·물결 아이콘을 표시합니다.| 항목 | 내용 |
|---|---|
| 해결하려는 문제 | 훈련 기록, 플랜 작성, 성장 확인, 수영 정보와 코치 피드백이 여러 서비스에 흩어진 문제 |
| 현재 방향 | 영상 분석 중심이 아닌 수영 훈련 도우미와 코치 강습 운영 플랫폼 |
| 주요 사용자 | 개인 수영인, 수강생과 코치, 포트폴리오를 살펴보는 비회원 방문자, 서비스 운영자 |
| 개발 범위 | 기획, UX, 프론트엔드, API, 데이터 모델, 배포, 운영 QA |
| 개발 기간 | 2026.05 ~ 진행 중 |
| 공개 배포 | Vercel 프론트엔드 + Render FastAPI + Neon PostgreSQL |
| 품질 기준 | 기능 추가 시 API/UI QA 매핑, 회귀 테스트, 문서·릴리즈 노트를 함께 갱신 |
수영을 꾸준히 하려면 단순히 기록만 저장하는 것으로는 부족합니다.
SwimMate는 이를 준비도 확인 → 훈련 선택 → 일지 기록 → 성장 리포트 → 다음 훈련 추천의 연속된 흐름으로 풀고 있습니다.
/landing에서 개인 훈련량과 다음 추천을 먼저 확인하고, 설정이 비어 있을 때 현재 수준·주요 목표·주당 훈련 횟수·주로 이용하는 25m/50m 풀 설정 안내를 확인합니다./onboarding?mode=edit 화면에서 언제든 수정할 수 있습니다./my-data에서는 JSON을 직접 가공하지 않아도 평생 누적, 최근 90일 변화, 12개월 추이, 영법·수영장 분포, 기록 습관, 코스별 PB와 다음 행동 제안을 한눈에 확인합니다.상세 훈련 대시보드에서는 누적 기록, 차트, 연속 출석과 준비도 체크까지 자세히 확인합니다.추천·빠른 생성·직접 구성·내 플랜 네 모드에서 기록 단축, 건강 유지, 영법 교정, 취미, 다이어트, 마스터즈 등 목적을 선택합니다.기록 추가로 바로 작성할 수 있고, 스크린샷·워치 가져오기는 하나의 보조 메뉴로 묶었습니다. 월간 목표, 캘린더, 총 거리, 평균 거리, 연속 출석을 함께 보여줍니다.SWIM-XXXX 형식의 코치 코드를 발급받아 복사하거나 공유할 수 있습니다.본인 확인 코치 배지가 표시됩니다.LANE-XXXXXX 반 코드를 직접 입력해 클럽과 해당 반에 동시에 참여합니다.S1, S2 익명 참조를 사용합니다.내 기록, 최근 훈련, 맞춤 추천처럼 사용자가 명시한 질문에만 본인의 훈련 설정·최근 일지 수치·목표·준비도·PB·플랜/세트 수행 요약을 반영합니다./tutorial은 짧은 허브만 보여주고, 개인 훈련·기록/AI 스크린샷·성장 데이터·코치/클럽·정보/도움의 5개 상세 페이지에서 실제 화면과 사용 순서를 나눠 설명합니다./landing, 오른쪽 인증 버튼은 /auth/me 결과에 따라 프로필·로그아웃 또는 로그인을 표시하고 테마 버튼은 모든 상태에서 유지합니다.QA 검증 로그에서 따로 조회합니다. IP 하나만으로는 QA로 분류하지 않습니다.현재 공개 서비스에서 AI는 다음 세 영역에 사용됩니다.
훈련 준비도와 주간 추천은 생성형 AI가 아니라 사용자의 최근 기록과 회복 상태를 설명 가능한 규칙으로 계산합니다. 외부 AI가 응답하지 않아도 코치 강습 운영이 중단되지 않도록 템플릿 폴백을 제공합니다.
훈련 플랜의 교정 포인트 추천은 영상 분석 API 연동 기능이 아닙니다. 사용자가 캐치·호흡·킥·자세 같은 고민을 직접 선택하면 저장된 드릴 세트 규칙으로 플랜을 구성합니다.
영상 업로드 기반 영법 분석은 현재 구현 완료 기능으로 소개하지 않습니다.
/meta, /upload, /viewer, /share/* 주소는 홈으로 이동하거나 410 Gone을 반환합니다.analysis/와 일부 레거시 모듈은 초기 실험 기록으로 남아 있지만 현재 제품 경로와 분리되어 있습니다.analysis_v2/에는 원근 레인 ROI, 레인별 회전 크롭, RTMPose를 사용해 대회 영상의 여러 선수를 실제 레인 ID로 추적하는 오프라인 v0.4 기준선을 구성했습니다. v0.3은 영법 라벨 출처, 시간 기준 신호 처리, 좌우 팔 식별·영법 패턴 충돌, 무릎·발목 가시성, 킥 표본율·스트로크 비율을 검사해 불확실한 숫자를 보류합니다. 영법별 5개씩 총 20개 고정 장면 비교에서 평균 검출 레인은 1.868 → 4.897로 늘었지만 독립 이벤트 정답이 없어 카운트 정확도는 아직 미검증입니다. 실제 영상 정확도 게이트 전까지 공개 API·UI에는 연결하지 않습니다. 권리·비동기 인프라 게이트도 별도로 통과해야 합니다./admin의 영법 분석 TEST 메뉴에 같은 검수 화면과 임시 작업 API를 배포했습니다. 모델 실행에는 관리자 PC 처리기 연결이 필요하며 일반 회원용 분석은 계속 비활성입니다. 실행 조건·보관 정책·검증 상태를 확인하세요. 운영 로그인에 사용하는 자격 증명으로 처리기를 연결한 최종 E2E 확인은 대기 중입니다.다시 공개하려면 대표성 있는 평가 데이터셋, 영법별 품질 기준, 영상 보관·삭제 정책, 별도 비동기 분석 인프라와 배포 환경 E2E 검증을 먼저 갖출 계획입니다. 실험 범위와 공개 전 기준은 영상 분석 v2 문서에 기록합니다.
사용자 브라우저
│
├─ 정적 화면 ───────────────▶ Vercel
│ │
└─ /api, /auth 요청 ──────────┘
▼
Render · FastAPI
│
┌──────────────┼──────────────┐
▼ ▼ ▼
Neon PostgreSQL Google Gemini 외부 연동
├─ Google/Kakao OAuth
├─ Kakao Maps
├─ Jira Cloud
└─ Notion 변경 이력
/api/*, /auth/* 요청을 Render 백엔드에 전달합니다.| 영역 | 기술 |
|---|---|
| Frontend | HTML, CSS, Vanilla JavaScript, Chart.js, Kakao Maps SDK |
| Backend | FastAPI, Pydantic, psycopg2, JWT 쿠키 인증, SlowAPI |
| Database | PostgreSQL · Neon · Alembic |
| AI | Google Gemini, 구조화 출력, 규칙 기반 폴백 |
| Infra | Vercel, Render, GitHub Actions |
| Collaboration/Ops | Jira Cloud REST API·Webhook, Notion 변경 이력 |
| Quality | pytest, Playwright, API 시나리오 QA, UI 크롤러, Postman CLI |
SwimMate는 “화면을 보여주는 곳”, “데이터를 처리하는 서버”, “기록을 저장하는 데이터베이스”를 나누어 둔 구조입니다. 사용자가 보는 화면은 Vercel이 빠르게 내려주고, 버튼을 눌러 기록 저장·로그인·AI 대화 같은 작업을 할 때는 Render의 FastAPI 서버가 처리한 뒤 Neon PostgreSQL에 저장합니다.
| 기술 | 쉽게 말하면 | SwimMate에서 하는 일 |
|---|---|---|
| HTML/CSS/Vanilla JavaScript | 웹 화면을 직접 구성하는 기본 재료 | 대시보드, 훈련 플랜, 일지, 리포트, 코치 화면의 UI와 상호작용 |
| Chart.js | 숫자를 그래프로 보여주는 도구 | 월간 성장 리포트, Jira 분석, 거리·빈도 추이와 관리자 방문·가입 흐름 시각화 |
| Kakao Maps SDK | 카카오 지도 기능을 웹에 붙이는 도구 | 주변 수영장 검색과 지도 표시 |
| Vercel | 정적 웹사이트를 배포하는 서비스 | 사용자가 접속하는 프론트엔드 화면 제공, /api/* 요청을 백엔드로 전달 |
| FastAPI | Python으로 API 서버를 만드는 프레임워크 | 로그인, 훈련 기록, 코치 연동, 커뮤니티, 관리자 API 처리 |
| Pydantic | 서버로 들어오는 데이터의 형식을 검사하는 도구 | 잘못된 요청을 막고 AI가 만든 JSON 결과도 구조화해 검증 |
| Neon PostgreSQL | 클라우드 PostgreSQL 데이터베이스 | 회원, 훈련 일지, 플랜, 리포트, 코치-학생 관계, 커뮤니티 데이터 저장 |
| Alembic | 데이터베이스 변경 이력을 순서대로 적용하는 도구 | Render와 FastAPI 시작 전에 승인된 스키마 리비전을 적용하고 health에서 버전을 확인 |
| psycopg2 | Python 서버가 PostgreSQL과 대화하는 연결 도구 | FastAPI 라우터에서 SQL을 실행 |
| JWT HttpOnly Cookie | 로그인 상태를 안전하게 유지하는 방식 | 사용자가 새로고침해도 로그인 상태를 유지하고 JavaScript 직접 접근을 줄임 |
| SlowAPI | 요청을 너무 많이 보내는 사용자를 제한하는 도구 | AI 채팅, 코치 AI 생성 등 비용이 생길 수 있는 API 호출 보호 |
| Google Gemini | 생성형 AI 모델 | 검수된 지식과 선택적 본인 훈련 요약을 문맥으로 받은 수영 질문 답변, 코치용 단체 강습안·브리핑 생성, 사용자 선택 운동 스크린샷의 구조화된 값 추출 |
| Jira Cloud API | 외부 업무 관리 서비스와 연결하는 API | 코치가 만든 후속 과제를 Jira 업무로 동기화하고 상태를 다시 받아옴 |
| Notion API | Notion 문서를 웹 서비스와 연결하는 API | 공개 릴리즈 노트 /changelog 연동 |
| GitHub Actions | 저장소 변경 후 자동 작업을 실행하는 도구 | 백엔드 변경 시 Render 배포 훅 호출과 health check |
| pytest / Playwright | 코드와 화면을 자동으로 검사하는 도구 | API 계약, 주요 사용자 흐름, 화면 오류를 회귀 테스트 |
| Postman / Postman CLI | API 요청을 실행 가능한 문서와 스모크 테스트로 관리하는 도구 | 쿠키 로그인, 일지→리포트·내 데이터 연동과 관리자 권한 경계를 앱·GitHub Actions에서 재실행 |
핵심은 AI가 모든 판단을 대신하는 서비스가 아니라는 점입니다. 훈련 준비도, 주간 추천, 리포트 계산과 지식 검색은 설명 가능한 규칙·검수된 자료·DB 집계로 처리합니다. Gemini가 운동 스크린샷에서 값을 추출할 때도 곧바로 저장하지 않고 서버 일관성 검사와 사용자의 2차 확인을 거칩니다.
아래 내용은 2026-07-20에 각 서비스의 공식 안내를 다시 확인한 운영 참고값입니다. 요금제와 쿼터는 바뀔 수 있으므로 실제 배포 전에는 링크된 공식 페이지와 각 콘솔의 현재 사용량을 다시 확인해야 합니다.
| 서비스 | 현재 역할 | 무료 범위 판단 |
|---|---|---|
| Vercel Hobby | 프론트엔드 정적 화면과 API rewrite | Hobby 약관상 개인·비상업 용도입니다. 상업 운영 전에는 Pro 등 적합한 요금제를 검토해야 합니다. |
| Render Free Web Service | FastAPI 백엔드 | 공식 무료 안내 기준 15분 동안 인바운드 트래픽이 없으면 중지되고, 워크스페이스당 월 750시간을 공유합니다. 로컬 파일은 영속 저장소로 사용하면 안 됩니다. |
| Neon Free | PostgreSQL 운영 DB | 공식 가격표의 프로젝트별 저장소·CU-hour 한도를 기준으로 운영합니다. CU-hour는 저장 용량이 아니라 DB compute가 활성 상태였던 시간에 가까운 지표입니다. 비활성 5분 뒤 Scale to Zero가 동작하도록 DB를 조회하지 않는 /api/ping만 상시 상태 확인에 사용합니다. |
| Gemini API | AI 코치 대화, 코치 문서 생성, 운동 스크린샷 값 추출 | 앱 자체 제한은 채팅 10회/분, 코치 문서·브리핑 각각 6회/시간, 스크린샷 분석 8회/시간입니다. 모델·프로젝트별 실제 RPM/TPM/RPD는 AI Studio의 활성 한도를 따릅니다. |
| Jira Free | 코치 운영 과제판 | Jira 가격표 기준 최대 10명의 Jira 사용자와 2GB 저장소를 제공합니다. 일반 수영 회원을 Jira 사용자로 만들지 않는 구조입니다. |
| Kakao Maps / Google OAuth / Kakao OAuth | 지도와 로그인 | 무료 여부와 쿼터는 각 콘솔에서 앱별 사용량 확인 필요 |
| Notion API | 릴리즈 노트 | 작은 문서 동기화에는 적합. 공개 화면은 실패 시 서비스 핵심 기능과 분리 |
무료 운영을 오래 유지하려면 AI 호출을 사용자 수에 그대로 비례시키지 않고, 코치 문서 생성과 채팅에 전역 일일 예산을 추가하는 것이 다음 단계입니다. Neon은 DB 연결이 필요한 전체 운영 QA를 주 1회로 제한하고, QA 종료 후 테스트 산출물을 즉시 정리합니다. Render 백엔드는 cold start가 있으므로 공개 체험이 많아질 경우 Vercel/Cloudflare 계열로 통합하거나 Render 유료 인스턴스로 전환하는 선택지가 있습니다.
핵심 자동 테스트와 실제 배포 서비스 검사를 하나의 GitHub Actions 품질 게이트로 관리합니다.
main Push·PR에서는 핵심 테스트를 실행합니다.scripts/qa_runner.py — 인증·대표 홈 리다이렉트·AI 지식 근거와 본인 기록 개인화·개인 데이터 내보내기·장기 인사이트·계정 보안, 운동 스크린샷 확인 토큰, 훈련 기록·테스트 세트·코스별 PB·리포트·익명 결과 카드, 코치 코드, 클럽·반 역할·일정·출석·공지·수행 분석·공개 캠페인, 관리자 API를 실제 사용자 흐름으로 점검scripts/qa_ui_crawler.py — 로그인 목적지, 공통 헤더의 홈·프로필·로그아웃·테마 순서, 수영 아이콘, 역할별 주요 35개 페이지와 고정 fixture 기반 공개 결과 카드·클럽 초대 2개 화면의 DOM을 점검합니다. 2,560·1,440·1,280·1,100·1,024·768·390px에서 헤더 전체 폭·스크롤 이동, 공통 1,280px 콘텐츠 프레임 정렬, 가로 넘침·요소 겹침·비정상 줄바꿈을 검사하고 결과 PNG·초대 경로·콘솔 오류도 함께 확인합니다.tests/postman/SwimMate.postman_collection.json — 공개 health·비로그인 경계, 일반 사용자 쿠키 로그인과 스크린샷 확인 토큰 경계·일지→통계·리포트·익명 결과 카드 생성/조회/종료·내 데이터→삭제, 관리자 방문 그래프·QA 계정 후보·자동화 표식·일반/QA 로그 분리·DB 보존 정책을 28개 요청으로 실행하는 Postman 스모크scripts/database_maintenance.py — 전체 운영 QA가 성공하거나 중간 검사가 실패해도 마지막에 실행합니다. QA 활동 로그는 3일, 모든 활동 로그는 90일만 보존하고 QA가 만든 기능 데이터는 매 실행 후 삭제하되 QA 계정과 재사용 코치 식별자는 유지합니다.docs/QUALITY_GATE.md — 기능 유형별로 반드시 넘어가야 할 검증 기준과 증적 산출물을 정리2026-09-11 관리자 영상 TEST는 50m 경기의 실제 레인·선수를 먼저 확인한 뒤 이동 추적하는 방식으로 변경했습니다. 고정 ROI 드래그 대신 시간별 선수 클릭을 사용하고, 추적이 불확실하면 전체 스트로크·킥 횟수를 보류합니다. 로컬 흐름과 모델 반환은 검증했지만 실영상의 완전 자동 집계 정확도는 아직 미검증입니다. 동작·제한·검증 범위를 참고하세요.
tests/test_swimtech.py의 Playwright 108개 정의는 과거 로컬 통합 환경용 참고 시나리오로 남겨 두었으며 현재 필수 품질 게이트의 통과 수에는 포함하지 않습니다. 배포 검증 증적은 실행마다 생성되는 핵심 HTML·JUnit 리포트, qa_report.json, qa_ui_report.json, UI 스크린샷, 개인 행을 포함하지 않는 database_maintenance_report.json으로 판정합니다.
기능을 추가할 때는 코드만 수정하지 않고 체크리스트, API/UI QA, 계약 테스트와 품질 게이트 문서를 함께 갱신합니다. 특히 준비도, 워치 데이터 비활성 경계, 플랜 품질 검증, 월간 리포트, 챌린지·뱃지, 커뮤니티·알림, 코치 AI, Jira, 관리자 지표는 서로 다른 화면과 데이터가 이어지므로 단순 200 응답보다 실제 데이터 반영과 권한 경계까지 확인합니다.
로그인 검사는 코드에 계정을 저장하지 않고 GitHub Actions Secrets의 일반·학생·관리자 전용 QA 계정으로 수행합니다. 필수 계정이 누락되면 해당 검사를 생략하지 않고 전체 품질 게이트가 실패합니다. 구체적인 판정 기준은 품질 검증 게이트에서 관리합니다.
현재 소스 기준 핵심 Python 318개와 서비스 워커 3개를 로컬에서 통과했습니다. 최종 워크플로 버전의 정기 전체 운영 검증 34007715003에서는 핵심 147개·Alembic 단일 head, 운영 API 53개, 일반·데모·관리자 35개 화면과 공개 결과·클럽 화면 2개를 합친 브라우저 37개, Postman 28개 요청·46개 assertion, 운영 DB 정리를 모두 통과했습니다. 같은 실행의 정리 단계는 QA 활동 1,279건과 QA 기능 데이터 3건을 삭제하고 일반 활동 9,072건, QA 계정 4개와 코치 식별자 1개를 보존했으며 정리 후 만료 로그와 QA 기능 데이터는 0건이었습니다. 브라우저 검사는 네 개 핵심 메뉴·세 개 상세 그룹·검색·모바일 하단 메뉴와 대표 화면의 단계적 펼침을 실제 조작하고, 각 화면을 2,560·1,440·1,280·1,100·1,024·768·390px로 재렌더링해 헤더 전체 폭·스크롤 이동, 사이드바 제외 작업 영역의 최대 1,280px 프레임 정렬, 가로 넘침·요소 겹침·비정상 줄바꿈 0건을 확인합니다.
api/ FastAPI 애플리케이션과 도메인별 라우터
frontend/ 페이지별 HTML·CSS·Vanilla JavaScript
docs/ 기능 지도, 아키텍처, 배포, 품질 문서
scripts/ API QA와 UI 크롤러
tests/ 단위·계약·Playwright E2E·Postman API 스모크
db/ PostgreSQL 스키마와 초기 데이터 스크립트
analysis/ 현재 제품과 분리된 영상 분석 실험 코드
analysis_v2/ 다중 선수 추적·스트로크·킥 카운팅 오프라인 기준선
FEATURE_CHECKLIST.md 기능 우선순위와 완료 기준
frontend/vercel.json 프론트엔드 리다이렉트와 API rewrite
render.yaml FastAPI 배포 설정
개인 프로젝트로 요구사항 정의, 우선순위 결정, 데이터 흐름과 배포 구조 설계, 구현 검토와 회귀 검증을 직접 수행했습니다. 생성형 AI 도구는 반복 구현과 탐색 속도를 높이는 데 활용했지만, 기능 범위 결정과 실제 동작 검증은 테스트와 운영 로그를 기준으로 판단했습니다.