Skip to content

Latest commit

 

History

35 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

austin.metacog.co.kr — 오스틴 정착 가이드

미국 텍사스 오스틴에 정착하는 한국인을 위한 정보 사이트. GitHub Pages 로 배포하고, 매일 새벽(오스틴 시각) 지역 이벤트와 소식을 자동으로 갱신한다.

두 종류의 정보

정착 지식 최신 정보
어디에 content/**/*.md data/events.json, data/news.json
누가 쓰나 사람 자동 수집
얼마나 자주 필요할 때 매일 새벽
왜 나눴나 변화가 느리고 정확성이 중요하다 매일 바뀌고 원문 링크가 최종 근거다

구조

content/<분야>/*.md      가이드 원본 (YAML front matter + 마크다운)
data/site.yaml           사이트 제목, 분야 정의
data/checklist.yaml      90일 체크리스트
data/sources.yaml        수집 소스 정의
data/notices.yaml        마감이 있는 공지 (수동 관리) — 상단에 크게 노출된다
data/prices.yaml         장바구니 가격 (사람이 확인한 값)
data/prices-auto.yaml    자동 생성 — Gemini 조회 결과. 직접 고치지 않는다
data/free-admission.yaml 무료 개방일 (수동 관리, 주간 자동 재확인)
data/curated.yaml        RSS 가 없는 한인 커뮤니티 정보 (수동 관리)
data/events.json         자동 생성 — 직접 고치지 않는다
data/news.json           자동 생성 — 직접 고치지 않는다
pipeline/collect.py      RSS/iCal/Socrata 수집 → data/*.json
pipeline/enrich.py       한국어 변환 (선택 — 토큰이 있을 때만)
pipeline/build.py        content + data → public/
pipeline/templates/      Jinja2 템플릿
assets/                  CSS, JS, 이미지
public/                  빌드 산출물 (git 에 넣지 않는다)

로컬에서 돌리기

python3 -m venv .venv
.venv/bin/pip install -r pipeline/requirements.txt

.venv/bin/python pipeline/build.py              # 사이트 빌드 → public/
.venv/bin/python -m http.server -d public 8000  # http://localhost:8000

수집은 네트워크가 필요하다.

.venv/bin/python pipeline/collect.py --dry-run  # 수집만, 파일은 안 씀
.venv/bin/python pipeline/collect.py            # data/*.json 갱신
.venv/bin/python pipeline/collect.py --check    # 각 소스 URL 응답 상태만 점검

글 추가하기

content/<분야>/<슬러그>.md 를 만든다. front matter 의 여섯 항목이 모두 있어야 한다.

---
title: 문서 제목
description: 한 줄 설명 (목록과 검색 결과에 쓰인다)
category: essentials        # data/site.yaml 의 분야 id
order: 30                   # 분야 안에서의 순서 — 정착 순서를 반영한다
updated: 2026-09-06         # 최종 확인일 (YYYY-MM-DD)
tags: [DPS, 면허]
sources:                    # 공식 출처 — 최소 한 개
  - label: 출처 이름
    url: https://...
---

updatedsources 는 필수다. 없으면 빌드가 실패한다. 정착 정보는 틀리면 실제 손해로 이어지므로, 관례가 아니라 검사로 막는다.

최종 확인일이 오래되면(data/site.yamlstale_after_days) 페이지에 "확인한 지 오래됨" 배지가 자동으로 붙는다. 이때는 출처를 다시 확인하고 날짜를 갱신한다.

마감이 있는 공지 추가하기

지원금 접수처럼 마감이 걸린 정보는 목록에 묻히면 놓친다. data/notices.yaml 에 넣으면 홈과 이벤트 페이지 상단, 그리고 /deadlines/ 에 크게 노출된다.

notices:
  - id: acme-fy28
    title: 오스틴 시 창작 지원금 (ACME)
    summary: 개인 예술가·뮤지션·비영리 문화단체 대상. 5천~25만 달러.
    deadline: 2027-08-18        # 공식 출처에서 확인한 날짜만 적는다
    url: https://www.austintexas.gov/arts-culture/funding-programs
    audience: 예술·문화 종사자
  • 남은 일수를 D-day 로 보여주고, 14일 이내면 강조한다.
  • 마감이 지나면 빌드가 자동으로 내린다. 손으로 지울 필요가 없다.
  • deadlineYYYY-MM-DD 날짜가 아니면 빌드가 실패한다. 추정 날짜를 넣지 못하게 막는다.
  • 날짜가 해마다 달라지는 기한(건강보험 공개등록, 재산세 납부 등)은 notices 가 아니라 같은 파일의 recurring 에 넣는다. D-day 를 계산하지 않고 시기와 공식 링크만 보여준다.

한인회 공지처럼 피드가 없는 출처의 마감 정보가 여기로 들어온다.

자동화

cron (UTC 09:17 = 오스틴 04:17 CDT)
  └─ collect.py   RSS/iCal/Socrata 수집
       └─ enrich.py   한국어 변환 (토큰이 있을 때만)
            └─ 수집 결과 커밋
                 └─ build.py → GitHub Pages 배포

하이브리드로 설계했다. enrich.py 는 인증 수단이 없으면 아무 일도 하지 않고 정상 종료한다. 그래서 토큰이 없어도 이벤트·소식은 원문 제목으로 매일 갱신되고, 사이트는 절대 깨지지 않는다. 토큰을 등록하면 그때부터 한국어 요약이 켜진다.

수집도 마찬가지로 실패에 관대하다. 소스 하나가 죽어도 나머지는 수집되고, 전부 실패하면 직전 데이터를 그대로 유지한다.

워크플로

파일 언제 하는 일
daily.yml 매일 새벽 · 수동 · main 푸시 수집 → 변환 → 빌드 → 배포
validate-sources.yml 매주 월요일 · 수동 각 소스 URL 이 살아 있는지 점검

schedule 트리거는 기본 브랜치의 워크플로 파일에서만 동작한다. 이 코드가 main 에 들어가야 매일 자동으로 돈다.

소스가 죽었을 때

피드 URL 은 예고 없이 바뀐다. 실제로 처음 등록한 10개 중 6개가 죽어 있었다. validate-sources.yml 을 실행하면 각 소스의 HTTP 상태와 수집 건수가 요약으로 나온다. 실패한 소스는 data/sources.yaml 에서 URL 을 고치거나 enabled: false 로 내린다.

검증되지 않은 URL 을 파이프라인에 바로 넣지 않는다. sources.yamlcandidates 섹션에 넣으면 점검 워크플로가 probe 하지만 수집은 무시한다. 점검을 통과한 것만 events / news 로 옮긴다.

일시적 실패와 죽은 소스는 다르게 다룬다. 타임아웃·연결 실패·429·5xx 는 최대 3회 재시도하고, 404 는 재시도하지 않는다.

한 소스가 목록을 독점하지 않도록 소스별 상한을 둔다 (이벤트 25건, 소식 6건). 그리고 소식의 유효 기간은 소스마다 다르게 줄 수 있다. 지역 방송의 2주 지난 기사는 낡았지만 미술관 전시 안내는 몇 달째 유효하기 때문이다. sources.yamlwindow_days 로 지정한다 (기본 14일).

  - id: blanton
    window_days: 120   # 전시는 몇 달씩 이어진다
    name: Blanton Museum of Art

가격 조회 (선택)

CLAUDE_CODE_OAUTH_TOKEN 이 있으면 주간 점검이 매장 가격을 조회해 data/prices-auto.yaml 에 쓴다. 사람이 확인한 data/prices.yaml 과 섞지 않는다.

이 단계만 웹 검색을 켠다. 다른 Claude 단계(한국어 변환, 무료 개방일 재확인)는 도구를 끄고 부르는데, 재확인 쪽은 페이지를 스크립트가 직접 가져와 모델에게는 판정만 시키기 위해서다 — 그래야 판정 근거가 우리가 인용하는 URL 과 항상 일치한다. 가격은 상품 페이지를 찾아야 해서 검색이 필요하다.

조회 대상은 prices.yaml 의 매장 중 fetch: true 인 것뿐이다. 호출 수가 곧 실행 시간이라 대상을 좁게 유지한다 (품목 20개씩 묶어 매장당 2회).

지난 조회 결과를 지우지 않는다. 가격이 내렸는지 알려면 과거 시점이 필요하다. 품목·매장별로 최근 6개 시점까지 보관한다.

가격이 내린 것

같은 품목·매장의 최근 두 시점을 비교해, 내린 것을 /prices/ 상단에 모아 보여준다. 많이 내린 순서다. 오른 것은 아래에 한 줄로 요약한다.

  • 같은 날 같은 매장에 여러 기록이 있으면(브랜드가 다른 경우) 그날 가장 싼 값을 그 매장의 그날 가격으로 본다. 사람이 실제로 고를 값이기 때문이다.
  • 2% 미만 변동은 노이즈로 보고 표시하지 않는다.
  • 사람이 확인한 값과 AI 조회 값 모두 대상이지만, AI 조회 건은 배너에서도 「AI 조회」로 표시한다.

가격은 틀리면 가장 나쁜 종류의 데이터라 안전장치를 넣었다.

  • 상품 URL 이 없으면 버린다. 독자가 직접 확인할 수 없는 숫자는 싣지 않는다. 그 URL 은 링크 검사에도 걸리므로 죽으면 드러난다.
  • 확인된 값과 자릿수가 다르면 버린다. 같은 품목에 사람이 확인한 값이 있으면 그 단위가격의 1/5 ~ 5배를 벗어난 값은 조회 오류로 본다.
  • 사이트에서 「AI 조회」로 구분해 표시하고, 「가장 쌈」 배지는 사람이 확인한 값에만 붙인다. AI 가 틀렸을 때 그걸 근거로 매장을 고르게 하면 안 된다.

토큰이나 claude CLI 가 없으면 이 단계는 조용히 건너뛴다.

외부 링크 확인

가이드마다 붙인 공식 출처 링크가 404 면 문서 자체가 쓸모없어진다. checklinks.pycontent/ 의 sources, curated.yaml, notices.yaml 의 모든 URL 을 확인하고, 깨진 링크가 있으면 점검 워크플로를 실패시킨다.

404/410 은 '깨짐'으로 실패를 유발하지만, 403/429 는 '차단'으로 분리해 사람이 판단하게 한다. 정부 사이트 상당수가 데이터센터 IP 를 막기 때문에 자동으로 실패 처리하면 안 된다.

설정

항목 어디
사이트 제목·분야 data/site.yaml
도메인 CNAME, data/site.yamlbase_url
오래됨 배지 기준 일수 data/site.yamlstale_after_days
수집 소스 data/sources.yaml
한국어 변환·가격 조회 모델 워크플로 환경변수 CLAUDE_MODEL (기본 sonnet)
가격 자동 조회 대상 매장 data/prices.yamlfetch: true

정확성에 대해

이 사이트는 정착 절차를 안내하는 참고 자료이고, 이민·세무·법률 자문이 아니다. 수수료·기한·자격 요건은 자주 바뀐다. 모든 문서에 최종 확인일과 공식 출처를 붙여 두었으니, 실제로 움직이기 전에 출처 링크에서 다시 확인해야 한다.

틀린 내용을 발견하면 이슈로 알려 주면 확인해 반영한다.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages