{"id":51537614,"url":"https://github.com/databricks-solutions/microbricks","last_synced_at":"2026-07-09T10:01:47.205Z","repository":{"id":366842343,"uuid":"1270560260","full_name":"databricks-solutions/microbricks","owner":"databricks-solutions","description":"Databricks blueprint to build and deploy apps using a microservice based architecture","archived":false,"fork":false,"pushed_at":"2026-06-23T13:38:24.000Z","size":3200,"stargazers_count":0,"open_issues_count":16,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-23T15:27:42.692Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://erinaldidb.github.io/microbricks/deck/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/databricks-solutions.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE.md","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-15T20:45:59.000Z","updated_at":"2026-06-23T13:45:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/databricks-solutions/microbricks","commit_stats":null,"previous_names":["databricks-solutions/microbricks"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/databricks-solutions/microbricks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/databricks-solutions%2Fmicrobricks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/databricks-solutions%2Fmicrobricks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/databricks-solutions%2Fmicrobricks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/databricks-solutions%2Fmicrobricks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/databricks-solutions","download_url":"https://codeload.github.com/databricks-solutions/microbricks/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/databricks-solutions%2Fmicrobricks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35295106,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-09T10:01:46.015Z","updated_at":"2026-07-09T10:01:47.165Z","avatar_url":"https://github.com/databricks-solutions.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/brand/microbricks-logo.png\" alt=\"microbricks — powered by Databricks\" width=\"640\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cem\u003eA solution accelerator for building microservices on Databricks.\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/databricks-solutions/microbricks/actions/workflows/deploy-dev.yml\"\u003e\u003cimg alt=\"deploy-dev\" src=\"https://img.shields.io/github/actions/workflow/status/databricks-solutions/microbricks/deploy-dev.yml?branch=develop\u0026label=deploy-dev\u0026style=flat-square\u0026logo=githubactions\u0026logoColor=white\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/databricks-solutions/microbricks/actions/workflows/deploy-test.yml\"\u003e\u003cimg alt=\"deploy-test\" src=\"https://img.shields.io/github/actions/workflow/status/databricks-solutions/microbricks/deploy-test.yml?branch=main\u0026label=deploy-test\u0026style=flat-square\u0026logo=githubactions\u0026logoColor=white\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/databricks-solutions/microbricks/actions/workflows/deploy-prod.yml\"\u003e\u003cimg alt=\"deploy-prod\" src=\"https://img.shields.io/github/actions/workflow/status/databricks-solutions/microbricks/deploy-prod.yml?label=deploy-prod\u0026style=flat-square\u0026logo=githubactions\u0026logoColor=white\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/databricks-solutions/microbricks/actions/workflows/pr-validate.yml\"\u003e\u003cimg alt=\"pr-validate\" src=\"https://img.shields.io/github/actions/workflow/status/databricks-solutions/microbricks/pr-validate.yml?label=pr-validate\u0026style=flat-square\u0026logo=githubactions\u0026logoColor=white\"\u003e\u003c/a\u003e\n  \u003cimg alt=\"status\" src=\"https://img.shields.io/badge/status-phases%201--7%20complete-success?style=flat-square\"\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg alt=\"license\" src=\"https://img.shields.io/github/license/databricks-solutions/microbricks?style=flat-square\"\u003e\u003c/a\u003e\n  \u003ca href=\"CONTRIBUTING.md\"\u003e\u003cimg alt=\"PRs welcome\" src=\"https://img.shields.io/badge/PRs-welcome-brightgreen?style=flat-square\"\u003e\u003c/a\u003e\n  \u003cimg alt=\"GitFlow\" src=\"https://img.shields.io/badge/workflow-GitFlow-orange?style=flat-square\u0026logo=git\u0026logoColor=white\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"Databricks Apps\" src=\"https://img.shields.io/badge/Databricks-Apps-FF3621?style=flat-square\u0026logo=databricks\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Lakebase\" src=\"https://img.shields.io/badge/Lakebase-Postgres%20Autoscale-336791?style=flat-square\u0026logo=postgresql\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Asset Bundles\" src=\"https://img.shields.io/badge/Asset%20Bundles-DAB-FF3621?style=flat-square\u0026logo=databricks\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Unity Catalog OBO\" src=\"https://img.shields.io/badge/Auth-Unity%20Catalog%20OBO-FF3621?style=flat-square\u0026logo=databricks\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"GitHub Actions\" src=\"https://img.shields.io/badge/CI-GitHub%20Actions-2088FF?style=flat-square\u0026logo=githubactions\u0026logoColor=white\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"Python 3.11+\" src=\"https://img.shields.io/badge/Python-3.11%2B-3776AB?style=flat-square\u0026logo=python\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"FastAPI\" src=\"https://img.shields.io/badge/FastAPI-0.119-009688?style=flat-square\u0026logo=fastapi\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Strawberry GraphQL\" src=\"https://img.shields.io/badge/Strawberry-GraphQL-E10098?style=flat-square\u0026logo=graphql\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Pydantic v2\" src=\"https://img.shields.io/badge/Pydantic-v2-E92063?style=flat-square\u0026logo=pydantic\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Alembic\" src=\"https://img.shields.io/badge/Alembic-migrations-6BA539?style=flat-square\"\u003e\n  \u003cimg alt=\"APX\" src=\"https://img.shields.io/badge/APX-framework-FF3621?style=flat-square\"\u003e\n  \u003cimg alt=\"uv\" src=\"https://img.shields.io/badge/uv-package%20manager-DE5FE9?style=flat-square\u0026logo=uv\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"pytest\" src=\"https://img.shields.io/badge/pytest-tested-0A9EDC?style=flat-square\u0026logo=pytest\u0026logoColor=white\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"React 19\" src=\"https://img.shields.io/badge/React-19-61DAFB?style=flat-square\u0026logo=react\u0026logoColor=black\"\u003e\n  \u003cimg alt=\"TypeScript 5.9\" src=\"https://img.shields.io/badge/TypeScript-5.9-3178C6?style=flat-square\u0026logo=typescript\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Vite 8\" src=\"https://img.shields.io/badge/Vite-8-646CFF?style=flat-square\u0026logo=vite\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"TanStack Router + Query\" src=\"https://img.shields.io/badge/TanStack-Router%20%2B%20Query-FF4154?style=flat-square\u0026logo=reactquery\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Apollo Client\" src=\"https://img.shields.io/badge/Apollo%20Client-GraphQL-311C87?style=flat-square\u0026logo=apollographql\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Tailwind CSS 4\" src=\"https://img.shields.io/badge/Tailwind-4-06B6D4?style=flat-square\u0026logo=tailwindcss\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"shadcn/ui\" src=\"https://img.shields.io/badge/shadcn%2Fui-components-000000?style=flat-square\u0026logo=shadcnui\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"bun\" src=\"https://img.shields.io/badge/bun-toolchain-000000?style=flat-square\u0026logo=bun\u0026logoColor=white\"\u003e\n\u003c/p\u003e\n\n---\n\n**microbricks** demonstrates how to build microservices on Databricks using **Databricks Apps** for the runtime, **Lakebase Autoscale Postgres** for per-service state, **OBO authentication** for end-to-end user identity, and **DABs + GitHub Actions** for CI/CD across dev/test/prod.\n\nThe demo domain is healthcare: six backend services that loosely follow HL7 FHIR resource boundaries, plus one frontend portal with an in-process BFF.\n\n\u003e **Status:** Phases 1–7 complete — six backend services + the BFF + the DAB bundle + six GitHub Actions workflows are all in place. The workflows now run end-to-end against the dev workspace via M2M (service-principal) auth, build every apx frontend, deploy all seven apps in parallel, and resolve each app's canonical URL (with workspace ID) from the apps API. Dev is also fully runnable from a workstation via `scripts/ci-local.sh`. See [`ROADMAP.md`](ROADMAP.md) for the full phase breakdown and [open work](#open-work) for what's next.\n\n---\n\n## At a glance\n\n```\nBrowser  →  hc-portal (frontend + BFF)  →  6 backend services  →  6 Lakebase databases\n            └── REST /api/bff/...           └── one DB per service, no shared schema\n            └── GraphQL /api/graphql        └── each exposes /api/graphql (Strawberry)\n            └── forwards OBO token\n```\n\n- **6 backend services** (`patient`, `provider`, `appointment`, `lab`, `prescription`, `billing`), each its own Databricks App with its own Lakebase project. Each exposes both REST (`/api/v1/`) and GraphQL (`/api/graphql`) endpoints via Strawberry.\n- **1 frontend** (`hc-portal`) — a [BFF](https://samnewman.io/patterns/architectural/bff/) that orchestrates calls and joins data in-memory. Holds no data of its own. Exposes a **GraphQL gateway** at `/api/graphql` with DataLoader-based batch resolution and nested cross-service traversal.\n- **OBO auth** end-to-end. Every Postgres connection is opened with the calling user's OAuth credential, so Unity Catalog enforces access at the data layer.\n- **No backend-to-backend calls.** The BFF is the only place where data from multiple services is joined.\n- **Dual API surface.** REST endpoints remain stable; GraphQL coexists and enables field selection, nested traversal, and partial-failure handling natively. The frontend is being migrated page-by-page from React Query (REST) to Apollo Client (GraphQL).\n\nDetailed architecture: [`ARCHITECTURE.md`](ARCHITECTURE.md). Data model: [`HEALTHCARE_DATA_MODEL.md`](HEALTHCARE_DATA_MODEL.md). Implementation plan: [`ROADMAP.md`](ROADMAP.md). Brand assets: [`docs/brand/`](docs/brand/README.md).\n\n---\n\n## Prerequisites\n\n| Tool              | Min version | Install                                                                |\n| ----------------- | ----------- | ---------------------------------------------------------------------- |\n| Databricks CLI    | `1.2.1`     | `brew install databricks` (the GitHub Actions workflows pin `1.2.1`)   |\n| `apx`             | latest      | `curl -fsSL https://databricks-solutions.github.io/apx/install.sh \\| sh` |\n| `uv`              | latest      | `curl -LsSf https://astral.sh/uv/install.sh \\| sh`                       |\n| `bun`             | latest      | `curl -fsSL https://bun.sh/install \\| bash`                              |\n| `gh`              | latest      | `brew install gh`                                                      |\n| `psql` (optional) | 16          | `brew install postgresql@16`                                           |\n\n`apx` + `bun` are needed at deploy time (CI and local) because each apx project's React UI is built into `src/\u003cpkg\u003e/__dist__/` before `bundle deploy` — see [`scripts/build-frontends.sh`](scripts/build-frontends.sh).\n\n\nThree Databricks workspaces (FE-VM serverless type, required for Lakebase + Apps):\n\n\n| Profile   | Workspace          | Used for                                                                    |\n| --------- | ------------------ | --------------------------------------------------------------------------- |\n| `hc-dev`  | dev workspace URL  | `develop` branch + per-feature-branch preview environments (local dev + PR) |\n| `hc-test` | test workspace URL | `release/*` branches and `main` HEAD                                        |\n| `hc-prod` | prod workspace URL | tagged releases (`v*`)                                                      |\n\n\nConfigure them in `~/.databrickscfg`:\n\n```bash\ndatabricks auth login --host https://\u003cdev-workspace\u003e.cloud.databricks.com --profile hc-dev\ndatabricks auth login --host https://\u003ctest-workspace\u003e.cloud.databricks.com --profile hc-test\ndatabricks auth login --host https://\u003cprod-workspace\u003e.cloud.databricks.com --profile hc-prod\n```\n\n---\n\n## Quickstart\n\n```bash\n# 1. Clone\ngit clone https://github.com/databricks-solutions/microbricks.git\ncd microbricks\n\n# 2. Validate the bundle (no Databricks calls, just YAML + schema checks)\ndatabricks bundle validate -t dev\n\n# 3. Bootstrap dev: lint + tests + provision 6 Lakebase projects + alembic +\n#    build frontend UIs + `bundle deploy -t dev` + `bundle run` per app +\n#    /healthz smoke. ci-local.sh wraps every step the GitHub Actions\n#    `deploy-dev.yml` workflow runs in CI.\n./scripts/ci-local.sh deploy dev\n\n# 4. Seed synthetic patient/provider/appointment/lab/prescription/billing\n#    data into the freshly-provisioned production branches.\nmake seed-dev\n```\n\nThe seven dev apps (`patient`, `provider`, `appointment`, `lab`, `prescription`, `billing`, `hc-portal`) come up RUNNING — the `bundle run` step in CI submits an app deployment per app in parallel and waits for `RUNNING` state. Lakebase endpoints scale to zero after 1h idle, so an inactive dev environment is ~$0.\n\nAlready have a deployed bundle and just want to (re-)launch the apps? Use the standalone helper:\n\n```bash\n# Plain trunk-dev: deploy bundle, then start all seven apps (parallel-friendly)\n./scripts/deploy-and-run-bundle.sh dev\n\n# Already deployed — just kick a new app deployment per app\n./scripts/deploy-and-run-bundle.sh dev --skip-deploy --restart\n\n# Iterate on a subset\n./scripts/deploy-and-run-bundle.sh dev --only=patient,lab\n```\n\nFor the per-PR / per-feature-branch workflow:\n\n```bash\n# Day-to-day fast loop: lint + tests + bundle-validate, no deploy.\n./scripts/ci-local.sh pr-validate --no-deploy\n\n# Full preview deploy: provision 6 feature branches off `production`, alembic\n# on changed services, deploy 7 preview apps suffixed `-\u003cslug\u003e`, smoke-test.\n./scripts/ci-local.sh pr-validate\n\n# Tear it all down when you're done iterating.\n./scripts/ci-local.sh pr-cleanup\n```\n\nSee `CONTRIBUTING.md` \"Running CI locally\" for the full reference. Every step can also be driven by Claude Code — open the repo in Claude Code and the project-local skills (`.claude/skills/`) are auto-discovered.\n\n---\n\n## Repository layout\n\n```\n.\n├── README.md                       # This file\n├── ARCHITECTURE.md                 # Architecture reference\n├── HEALTHCARE_DATA_MODEL.md        # Per-service data model\n├── CONTRIBUTING.md                 # GitFlow + PR rules + \"Running CI locally\"\n├── ROADMAP.md                      # Phased implementation plan (all phases ✅ except 8)\n├── Makefile                        # `make seed-dev` and per-service seed targets\n├── databricks.yml                  # Root DAB (3 targets: dev / test / prod)\n├── resources/                      # DAB resource includes (apps + BFF + shared)\n├── services/                       # 6 backend microservices (one APX project each)\n│   ├── patient/                    # ✅ all six scaffolded; auth.py / db.py / migrations\n│   ├── provider/                   #     are byte-identical except for entity names\n│   ├── appointment/                #     each exposes REST + GraphQL (Strawberry)\n│   ├── lab/\n│   ├── prescription/\n│   └── billing/\n├── frontend/\n│   └── hc-portal/                  # ✅ React UI + BFF; REST aggregation + GraphQL\n│                                   #     gateway with DataLoaders + Apollo Client\n├── scripts/\n│   ├── ci-local.sh                 # Local CI emulator — pr-validate / pr-cleanup /\n│   │                               #     deploy {dev,test,prod} / nightly-cleanup\n│   ├── build-frontends.sh          # Auto-discovers apx projects under frontend/\n│   │                               #     and runs `apx frontend build` for each\n│   ├── deploy-and-run-bundle.sh    # `bundle deploy` + per-app `bundle run` in\n│   │                               #     one verb (with --only / --skip-deploy /\n│   │                               #     --restart / --no-wait / --var passthrough)\n│   ├── sanitize-branch-slug.sh     # Code-branch -\u003e Lakebase-/preview-slug transform\n│   ├── lakebase-project-{up,down}.sh   # Per-env Lakebase project lifecycle\n│   ├── lakebase-branch-{up,down}.sh    # Per-feature-branch lifecycle\n│   └── seeds/                      # Shared seed primitives (deterministic UUIDs)\n├── tests/seeds/                    # Cross-service ID-stability tests (no DB needed)\n├── docs/\n│   ├── brand/                      # Logo + icon + Photoshop source\n│   └── diagrams/                   # *.drawio + exported *.png\n├── .github/\n│   ├── workflows/                  # 6 workflows: pr-validate, pr-cleanup,\n│   │                               # deploy-{dev,test,prod}, nightly-orphan-cleanup\n│   └── release-template.md         # PR template for release/* -\u003e main PRs\n└── .claude/                        # Project-local Claude Code skills (auto-discovered)\n    └── skills/\n        ├── hc-microservice-scaffold/\n        ├── hc-lakebase-branching/\n        ├── hc-obo-auth/\n        ├── hc-dab-deployment/\n        ├── hc-bff-pattern/\n        └── hc-gitflow-cicd/\n```\n\n---\n\n## Working with this repo via Claude Code\n\nThe repo ships six project-local skills under `.claude/skills/`. Each one codifies a piece of the reference architecture so that future contributors (and Claude Code itself) follow the same patterns.\n\n\n| Ask Claude Code…                                            | Skill that fires           |\n| ----------------------------------------------------------- | -------------------------- |\n| \"Scaffold a new service called X\"                           | `hc-microservice-scaffold` |\n| \"Spin up a Lakebase branch for my feature\" / \"tear it down\" | `hc-lakebase-branching`    |\n| \"Add a new route to the patient service\"                    | `hc-obo-auth`              |\n| \"Deploy to test\"                                            | `hc-dab-deployment`        |\n| \"Add a BFF endpoint that joins patient + appointment\"       | `hc-bff-pattern`           |\n| \"Add a GraphQL query / migrate a page to GraphQL\"           | `hc-graphql`               |\n| \"Cut a release / open a PR\"                                 | `hc-gitflow-cicd`          |\n\n\n---\n\n## CI/CD\n\nThe repo ships six workflows under `.github/workflows/`, all pinned to Databricks CLI `1.2.1`:\n\n| Workflow                     | Trigger                                           | What it does                                                                                                                                                                                                                                                                                  |\n| ---------------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `pr-validate.yml`            | PR open/sync against `develop`/`release/*`/`main` | Path-scoped matrix: lint + unit tests for changed services, BFF tests, bundle-validate, provision per-feature Lakebase branches, alembic, build apx frontends, parallel `bundle deploy` + per-app `bundle run`, /healthz smoke, resolve canonical URLs from the apps API, comment URLs on PR |\n| `pr-cleanup.yml`             | PR close (merged or not)                          | `bundle destroy` of the preview + tear down 6 Lakebase feature branches                                                                                                                                                                                                                       |\n| `deploy-dev.yml`             | Push to `develop`                                 | Same shape (no path filter, all six services + portal): alembic on `production` branches, build frontends, `bundle deploy -t dev`, parallel `bundle run` per app, wait for `RUNNING`, /healthz smoke                                                                                          |\n| `deploy-test.yml`            | Push to `release/*` or `main`                     | Same shape, `-t test`                                                                                                                                                                                                                                                                         |\n| `deploy-prod.yml`            | Push tag `v*` on `main`                           | Same shape, `-t prod`, gated by manual approval on the `prod` GitHub environment                                                                                                                                                                                                              |\n| `nightly-orphan-cleanup.yml` | Daily cron (04:17 UTC) + manual                   | GC Lakebase feature branches whose PR is closed                                                                                                                                                                                                                                               |\n\nA few details worth knowing:\n\n- **Auth: M2M (service-principal) via the OAuth `client_credentials` flow.** Each deploy job writes a `~/.databrickscfg` profile (`hc-dev` / `hc-test` / `hc-prod`) from `vars.DATABRICKS_HOST_\u003cENV\u003e` + `secrets.DATABRICKS_CLIENT_ID` + `secrets.DATABRICKS_CLIENT_SECRET` scoped to the matching GitHub environment. Smoke tests mint a short-lived bearer by POSTing `client_credentials` to `${DATABRICKS_HOST}/oidc/v1/token` (no PATs, no `databricks auth token` — that's U2M-only). OIDC trust is the documented migration path; the inline rationale lives in `pr-validate.yml`.\n- **Frontends are built in CI.** `scripts/build-frontends.sh` auto-discovers every apx project under `frontend/` (anything with both `pyproject.toml` and `package.json`) and runs `apx frontend build` — `bundle deploy` only syncs files, so without this step the deployed app would 404 on every page route. The bundle force-includes the resulting `src/\u003cpkg\u003e/__dist__/` via `sync.include` in `databricks.yml`.\n- **Apps deploy in parallel.** `bundle deploy` wires the cross-app `CAN_USE` ACLs at deploy-time, so the seven `bundle run` calls (six services + `hc-portal`) fire concurrently. Wall time becomes `max(app startup)` rather than `sum`. Each subshell logs to its own file so a failure surfaces a clean log instead of interleaved noise.\n- **Smoke tests are strict.** Both the status code AND the body are asserted (`200` + literal `{\"ok\":true}`) — Databricks Apps' OBO gateway returns 200-with-HTML for unauthenticated requests, which would fool a vanilla `curl -fsS`.\n- **Environment URLs come from the apps API.** The Apps platform embeds the workspace ID into each app hostname (e.g. `hc-portal-\u003cworkspace-id\u003e.azure.databricksapps.com`), so we can't construct it client-side. Each deploy workflow's final step calls `databricks apps get hc-portal -o json` and feeds the canonical URL into `environment.url` and (for previews) into the PR comment table.\n\n\u003e **Note:** GH-hosted runners may not reach the dev workspace if FE-VM's managed IP allowlist is in effect — see the `github-runner-ip-acl` finding. Where that's the case, `scripts/ci-local.sh` runs the same logical pipelines from a developer's machine where the IP is already allowlisted. See `CONTRIBUTING.md` \"Running CI locally\" for the dev/CI division of labor.\n\n---\n\n## Open work\n\nThe phased plan in [`ROADMAP.md`](ROADMAP.md) is mostly done — phases 1-7 (six services + BFF + seed data + DAB bundle + dev rollout + workflows, including parallel `bundle run`, frontend build step in CI, M2M auth, and canonical URL resolution from the apps API) are ✅. Phase 8 wraps it up:\n\n- **Confirm CI ↔ Databricks reachability per env** — verify each workspace's IP allowlist (if any) admits GH-hosted runner egress; otherwise pick one of the three options in the `github-runner-ip-acl` finding.\n- **Fresh-clone test** — verify a stranger can go from `git clone` to a working PR with a preview app in under 30 minutes following only README + CONTRIBUTING.\n- **Runbooks** — `docs/runbooks/{prod-rollback,hotfix,lakebase-branch-orphan}.md`.\n- **Cost audit** — confirm idle endpoints scale to zero (already wired: 1h `suspend_timeout_duration` in `scripts/lakebase-project-up.sh` + `scripts/lakebase-branch-up.sh`); document expected dev-env monthly cost.\n\nFuture / optional follow-ups (Phases 9–14 in [`ROADMAP.md`](ROADMAP.md)): service-mesh observability, saga/events demo, RLS demo, read-replica for prod, multi-region, shared APX UI library.\n\n---\n\n## License\n\nSee [LICENSE](LICENSE). This is a reference architecture the data model is illustrative and the synthetic data is intentionally non-realistic.\n\n---\n\n## Libraries\n\n| Library | Role | License |\n|---------|------|---------|\n| [FastAPI](https://github.com/tiangolo/fastapi) | HTTP framework for all services and the BFF | MIT |\n| [Pydantic v2](https://github.com/pydantic/pydantic) | Request/response validation and settings | MIT |\n| [Strawberry GraphQL](https://github.com/strawberry-graphql/strawberry) | GraphQL API layer in the BFF | MIT |\n| [uvicorn](https://github.com/encode/uvicorn) | ASGI server | BSD-3-Clause |\n| [psycopg 3](https://github.com/psycopg/psycopg) | PostgreSQL driver (async + connection pooling) | LGPL-3.0 |\n| [SQLAlchemy](https://github.com/sqlalchemy/sqlalchemy) | ORM used by Alembic migrations | MIT |\n| [Alembic](https://github.com/sqlalchemy/alembic) | Database schema migrations | MIT |\n| [httpx](https://github.com/encode/httpx) | Async HTTP client (service-to-service calls) | BSD-3-Clause |\n| [Databricks SDK for Python](https://github.com/databricks/databricks-sdk-py) | Workspace client, OBO credential generation | Apache-2.0 |\n| [React](https://github.com/facebook/react) | Frontend UI library | MIT |\n| [TanStack Router](https://github.com/TanStack/router) | Type-safe file-based routing | MIT |\n| [TanStack Query](https://github.com/TanStack/query) | Server-state management and caching | MIT |\n| [Apollo Client](https://github.com/apollographql/apollo-client) | GraphQL client (used alongside REST hooks) | MIT |\n| [Vite](https://github.com/vitejs/vite) | Frontend build tooling and dev server | MIT |\n| [Tailwind CSS](https://github.com/tailwindlabs/tailwindcss) | Utility-first CSS framework | MIT |\n| [shadcn/ui](https://github.com/shadcn-ui/ui) | Accessible UI component primitives | MIT |\n| [uv](https://github.com/astral-sh/uv) | Python package/project manager | MIT |\n| [Bun](https://github.com/oven-sh/bun) | JavaScript runtime and package manager | MIT |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatabricks-solutions%2Fmicrobricks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatabricks-solutions%2Fmicrobricks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatabricks-solutions%2Fmicrobricks/lists"}