Busabase
Busabase는 AI 에이전트를 위한 오픈소스(MIT) 데이터베이스 및 작업 공간입니다
공개 구인 사이트 피드를 활용한 실운용 dbt 파이프라인, 이중 저장소, 엔드투엔드 테스트, 모든 설계 결정이 기록됨
A production dbt pipeline over public job-board feeds: dual-warehouse, tested end to end, with every design decision on record.
데이터Python · CSSGitHub @AMikhno온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Automated job search pipeline: ingests postings from popular ATS, dedupes and rule-filters them, then transforms via dbt (DuckDB dev / BigQuery prod). V1 covers ingestion + dbt; V2 adds LLM-based ranking against a personal profile and embeddings. Built as an Analytics Engineering portfolio project.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗End-to-end Analytics Engineering project: typed Python ingestion from every ATS with a public keyless feed (nine today — Greenhouse, Lever, Ashby, BambooHR, Recruitee, Workable, Pinpoint, Rippling, SmartRecruiters) into a dual-target dbt project (DuckDB dev / BigQuery prod) that dedupes, lifecycle-tracks, and rule-filters postings — then emails a digest of what's new. LLM relevance scoring (in-warehouse, BigQuery AI) is the scoped V2.
flowchart LR
A[ATS APIs<br/>9 public keyless feeds] -->|"Python adapters<br/>(typed, tested, parallel)"| B[(raw_*_jobs<br/>append-only)]
B --> C[bronze<br/>stg views]
C --> D[silver<br/>union · dedup · lifecycle<br/>filters + soft signals]
D --> E[gold<br/>fct_job_postings<br/>live postings only]
E -->|watermark| F[email digest<br/>new postings only]
D -.->|V2| G[LLM extraction<br/>+ fit scoring]
G -.-> E
Live market charts, design decisions, rendered docs and all 29 ADRs, and the dbt lineage DAG.
Rebuilt in CI on every push to main, or locally with make site (output in _site/). Every number
on the landing page is read from the dbt manifest, the ADRs and the test suite at build time, and
the build fails on a broken link. Every PR's CI run also uploads a site-preview artifact, so a
change to the site can be reviewed before it merges.
Prerequisite: uv (the only one — it installs Python 3.14
itself, per .python-version).
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS/Linux; or: brew install uv
make install # uv venv + pre-commit hooks
cp .env.example .env # ingestion needs no secrets; fill BQ vars only for prod
cp config/companies.example.csv config/companies.csv # your PRIVATE company list (gitignored)
# dbt/profiles.yml is committed (env-var driven, no secrets) — nothing to copy
make ingest # Python -> raw tables (DuckDB by default)
make dbt-dev # bronze -> silver -> gold on DuckDB
make test && make dbt-test
ingest/ per-ATS adapters, source registry, parallel pipeline entrypoint
shared/ config (Pydantic Settings), models, http, storage (one writer, both warehouses)
deliver/ email digest of new postings (watermark in ops.digest_runs)
config/ private company list (gitignored; .example committed)
dbt/ one dual-target project: models/{bronze,silver,gold}, seeds, macros, unit tests
scripts/ repo gates that are not lint or tests (see below), and the Pages site build
site/ landing page template + docs theme for the Pages site
tests/ pytest suite + sanitized fixtures
docs/ decisions/, v2-plan.md, research/ (ARCHITECTURE.md at repo root)
.github/ four workflows, split by permission scope — see ARCHITECTURE.md#automation
Currently 9 ingestion sources, 22 dbt models and 29 ADRs.
Every invariant this project relies on is enforced by something that fails, not by intent.
make lint and make test run locally, in a pre-commit/pre-push hook, and again in CI, which
blocks merge:
| Gate | Guards against |
|---|---|
ruff check + ruff format | style drift, unused code, import order |
mypy --strict | untyped defs; no Any crossing a module boundary |
sqlfluff | dbt SQL style, against the compiled models |
pytest with --cov-fail-under=85 | untested behavior; the gate is never lowered to pass |
| dbt schema + unit tests | model contracts (not_null, unique, accepted_values) |
dbt source freshness | a source that silently stopped landing rows |
scripts/check_docs.py | documentation that points at things which no longer exist |
gitleaks | committed secrets |
actionlint | a workflow that fails validation — which does not fail loudly: it stops running on its schedule and sends no alert, because no run ever starts |
| Dependabot | stale dependencies (uv.lock + pyproject.toml together) |
The docs check is the unusual one. Prose drifts silently — a file is renamed, a make target goes
away, an ADR is superseded, and the sentence referring to it still reads fine, because nothing in
a test suite imports a paragraph. It verifies the references that are mechanically checkable
(relative links, repo paths, line-anchored refs, ADR numbers, make targets, dbt model names,
heading anchors) across both markdown and Python docstrings, and lets a doc assert a number
against the code with an inline <!-- check:… --> marker, so a count cannot rot under an edit.
Deliberate exceptions live in scripts/planned-refs.txt; everything else failing is drift.
Python 3.14 + Pydantic v2 · dbt-core with dbt-duckdb (dev) and dbt-bigquery (prod) · GitHub Actions (twice-daily ingest, freshness gate, email digest of new postings).
V2 (0.2.0) in production — twice-daily ingestion to BigQuery, transform, freshness gate, email digest, plus AI relevance: typed extraction and a 1–5 fit score as dbt models against BigQuery's in-SQL AI functions, score-ordered (never filtered) delivery (ADR-0020), and an embedding matcher that reports which piece of experience a posting resembles.
Deliberately unvalidated so far. Two rankings run side by side — the LLM score and embedding
similarity — because choosing between them without measuring is how a project ends up carrying
both forever. make evaluate scores a ranking by precision@k against human labels, and labels
from an LLM cannot settle it: grading a scorer against its predecessor's judgements rewards
reproducing that predecessor's mistakes. Both rankings are kept until labels exist and a month
of live runs has shown the winner stays the winner; only then does the loser get deleted.
Full design: ARCHITECTURE.md. What is next: TODO.md.
Personal project. Not currently licensed for redistribution.