feat(gbp): Phase 1 — Google Business Profile auth + location discovery#508
Draft
arberx wants to merge 2 commits into
Draft
feat(gbp): Phase 1 — Google Business Profile auth + location discovery#508arberx wants to merge 2 commits into
arberx wants to merge 2 commits into
Conversation
bb4d87e to
2197a99
Compare
| locations?: Array<{ name: string; title?: string; websiteUri?: string; categories?: { primaryCategory?: { displayName?: string } } }> | ||
| }) { | ||
| fetchSpy.mockImplementation((url: string) => { | ||
| if (url.includes('mybusinessaccountmanagement.googleapis.com')) { |
| if (url.includes('mybusinessaccountmanagement.googleapis.com')) { | ||
| return Promise.resolve({ ok: true, status: 200, text: async () => JSON.stringify({ accounts: opts.accounts ?? [] }) }) | ||
| } | ||
| if (url.includes('mybusinessbusinessinformation.googleapis.com')) { |
| migrate(db) | ||
|
|
||
| const apiKeyPlain = `cnry_${crypto.randomBytes(16).toString('hex')}` | ||
| const hashed = crypto.createHash('sha256').update(apiKeyPlain).digest('hex') |
Adds the foundation for the local-AEO surface: a new `integration-google-business-profile` package, OAuth scope branching for the existing Google connector (`gsc | ga4 | gbp`), and a `gbp_locations` table with explicit selection state. Surfaces four new endpoints (`POST /gbp/locations/discover`, `GET /gbp/locations`, `PUT /gbp/locations/:locationName/selection`, `DELETE /gbp/connection`), matching ApiClient methods, `canonry gbp …` CLI commands, and a new `gbp` MCP toolkit with four tools and OpenAPI classifications. Ships the setup playbook as a canonry skill reference (`skills/canonry-setup/references/google-business-profile.md`) including Google's access-form prerequisites quoted from the official docs. Phase 2 (sync run + reviews/keywords/metrics/Q&A/lodging/place-actions tables) is unblocked and follows the data-model decisions baked in here (range-replace, value-or-threshold union, snapshot-on-change for lodging attributes).
2197a99 to
268bea2
Compare
…guards Adds `packages/contracts/src/retry.ts` with `backoffDelayMs`, `withRetry`, and `isRetryableHttpError` — Google's documented jittered exponential backoff (`random() * baseDelayMs * 2^attempt`) plus a generic retry wrapper that takes any `isRetryable` predicate and supports `Retry-After` overrides via `computeDelayMs`. Replaces five near-identical `withRetry` copies in the provider packages (claude, gemini, openai, perplexity, local) with thin shims, migrates GA4's `withGa4Retry` and GBP's `gbpFetchGet` to wrap the shared helper, and threads GBP-specific guards: a new `GbpApiError.quotaLimitValue` field distinguishes the 0-QPM access-form gate (don't retry — Google hasn't approved you yet) from a transient 300-QPM ceiling (retry with backoff). The route mapper now emits distinct quotaExceeded messages for the two cases. Net: ~250 lines of duplicated retry math + control flow collapse into one 90-line helper. Adds 17 retry tests + 7 GBP-specific guard tests; total suite jumps from 3271 to 3288 green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lays the foundation for canonry's local-AEO surface: a new
integration-google-business-profilepackage, OAuth scope branching for the existing Google connector (gsc | ga4 | gbp), and agbp_locationstable with explicit per-location selection state. Adds four endpoints (POST /gbp/locations/discover,GET /gbp/locations,PUT /gbp/locations/:locationName/selection,DELETE /gbp/connection) with matching typed ApiClient methods,canonry gbp …CLI commands, and a newgbpMCP toolkit (4 tools) wired through OpenAPI classifications. The setup playbook — including Google's access-form prerequisites quoted from the official docs — ships as a canonry skill reference atskills/canonry-setup/references/google-business-profile.md. Phase 2 (sync run + reviews/keywords/metrics/Q&A/lodging/place-actions tables) is unblocked.Test plan