FloCafe
FloCafe is the free, local-first restaurant POS in the FloPOS ecosystem. Run orders, tables, kitchen display, and local data without a software subscription.
밀리·리디셀렉트·교보 sam·윌라 가용성과 종료 예정을 한 화면에. 예스24 공식 API 기반 도서 검색.
Translation pending
CommercePython · JavaScriptGitHub @ChoYugyeongOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
서가(seoga) — 이 책, 지금 어느 서가에 있나. 도서 가용성 레이어 (예스24 Open API + 밀리 공지 + 하이브리드 검색 + SRE 스택)
Translation pending
Loading the full README.
Read the full README ↗이 책, 지금 어느 서가에 있나 — 책의 가용성 레이어
🟢 라이브: https://seogarok.com (GCP Cloud Run · asia-northeast3 · scale-to-zero) · 18,917권 인덱스 · 하이브리드 검색 · 책 랜딩 16k+ 색인 대응 · 약관/개인정보/출처
왓챠피디아의 책 버전. 단, 포지셔닝은 "추천 서비스"가 아니라 "가용성(어디서 읽을 수 있나) + 종료 추적".
검색엔진: sitemap-index.xml · llms.txt
이 저장소는 두 층으로 구성됩니다.
| 층 | 내용 |
|---|---|
| 프론트엔드 | 다크 테마 SPA (index.html / styles.css / app.js) — 서버가 없으면 자동으로 로컬 데모 모드 |
| 백엔드 | Python 표준 라이브러리 + SQLite 검색 엔진 (server/) — BM25 + 벡터 하이브리드 |
| 수집 | 도서 카탈로그(ingest/books/), 종료 예정 공지(ingest/notices/) 파이프라인 |
cd C:\Dev\seoga
.\run.ps1 # 인덱스 없으면 생성 후 http://127.0.0.1:8100
.\run.ps1 -Reindex # 카탈로그/공지 다시 읽어 재색인
.\run.ps1 -Bench # 검색 벤치마크
수동으로 하려면:
python -m server.sync # data/catalog.jsonl (+ notices.jsonl) -> SQLite
python -m server.app --port 8100 # API + 정적 서버
index.html을 그냥 열어도(file://) 프론트는 동작합니다. 이때는 /api가 없으므로
로컬 데모 모드(38권 큐레이션 + 규칙 기반 검색)로 폴백합니다.
이 저장소는 SRE/DevOps 포트폴리오로도 쓰도록 운영 계층이 붙어 있습니다. "기능이 동작한다"가 아니라 "장애를 어떻게 감지하고 대응하는가" 를 코드·설정·문서로 닫았습니다.
| 계층 | 구현 | 확인 |
|---|---|---|
| 관측성 | /metrics (RED + 도메인 메트릭 15종), stdout JSON 로그(req_id), /healthz(liveness)·/readyz(readiness) 분리 | curl localhost:8100/metrics |
| 스택 | Docker Compose: api + Prometheus + Grafana(대시보드 as code 13패널) | Grafana http://localhost:3001/d/seogarok-sre |
| SLO | 가용성 99.9%(월 43m 12s), 검색 p95 < 300ms, 5xx < 1%, 인덱스 신선도 24h | docs/SRE.md |
| 알림 | 멀티윈도우 멀티번레이트 7종 + 런북 링크 (SeogaApiDown, SeogaErrorBudgetBurnFast …) | http://localhost:9090/alerts |
| 장애 대응 | 카오스 주입 엔드포인트 → 알림 발화 → 복구. 런북 4종 + 포스트모템 | docs/runbooks, docs/postmortem |
| CI | test(오프라인) → build + Trivy 스캔 → compose-smoke | .github/workflows/ci.yml |
| 부하테스트 | k6, SLO를 threshold로 강제 | loadtest/search.js |
docker compose up -d --build # api:8100 · prometheus:9090 · grafana:3001
docker compose --profile load run --rm k6 run /scripts/search.js # 부하테스트
.\scripts\game_day.ps1 -Scenario all # 카오스 주입 → 2~3분 뒤 알림 확인
.\scripts\game_day.ps1 -Scenario reset
실측 (컨테이너 500권 인덱스, k6 25 VU × 50s)
| 지표 | 값 |
|---|---|
| 검색 p95 / p99 | 4.10ms / 5.74ms (SLO 300ms 대비 약 73배 여유) |
| 실패율 / checks | 0.00% (0/2,844) / 100% |
| 처리량 | 56.9 req/s |
| 게임데이 | SeogaSearchLatencyP95High · SeogaErrorBudgetBurnFast FIRING (에러버짓 연소 192x) → 리셋 후 5초 내 복구 |
포트폴리오 관점 정리(이력서 bullet·5분 데모 시나리오)는 PORTFOLIO.md 에 있습니다.
| 항목 | 내용 |
|---|---|
| IaC | terraform/ — Cloud Run v2 · Artifact Registry · GitHub OIDC(WIF) · 최소권한 IAM · scale-to-zero |
| CD | deploy.yml — build&push → 카나리(트래픽 0%) → 스모크 → 100% 승격 → 실패 시 자동 롤백 |
| 키 없는 배포 | 장기 서비스 계정 키 없음. OIDC 토큰을 배포 SA 로 교환(attribute_condition 으로 이 저장소만 허용) |
| 롤백 | gcloud run services update-traffic --to-revisions <직전>=100 (약 20~40초) — deploy-rollback.md |
| 충돌 방지 | ignore_changes = [image, traffic] — Terraform 이 CD/롤백 상태를 되돌리지 않게 역할 분리 |
| 검증 | terraform fmt/validate 통과, actionlint 3개 워크플로 통과, scripts/smoke.sh 5/5 (실행 중 컨테이너 대상 실측) |
| 상표 | docs/trademark-guide.md — KIPRIS 선행 0건, 9·16·35·41류 출원 가이드 |
| 도메인 | domain-cloudflare.md — 도메인 연 1.2~2만원, DNS/SSL/도메인매핑 무료 |
| 무료 티어 | Cloud Run 무료 한도 내(min_instances=0 → 유휴 시 0원, 콜드스타트 약 8~10초, 실측). 이 워크로드의 실제 비용은 $0(Artifact Registry 초과분 월 9센트 수준) |
cd terraform
terraform init -backend=false && terraform validate # 자격증명 없이 검증
# 실제 배포: terraform init -backend-config=... → apply → output github_actions_vars
면접 중 "지금 제 서버"를 보여줘야 할 때, 도메인·계정 없이 로컬 스택을 공개 URL로 노출할 수 있다.
docker compose up -d # 로컬 스택 기동
.\scripts\share_demo.ps1 # 앱(8100) → https://xxx.trycloudflare.com
.\scripts\share_demo.ps1 -Grafana # Grafana(3001) 공개
.\scripts\share_demo.ps1 -Stop # 데모가 끝나면 즉시 종료
https://<random>.trycloudflare.com/healthz → 200 (외부에서 접근 확인)-Stop.
compose 기본값 SEOG_CHAOS=1 이면 /api/_chaos 도 공개되므로 공개 시간을 짧게 유지.스크린샷 (실제 드릴 중 캡처)
/alerts — SeogaSearchLatencyP95High·SeogaErrorBudgetBurnFast FIRINGThis is the beginning of the README. Read the rest at the original. Read the full README ↗