@drawbridge/drawbridge-agents 0.1.24 → 0.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -54,6 +54,7 @@ skill) so it stops living only in tribal memory.
|
|
|
54
54
|
index manually is not enough; until the boot collMod lands, every insert carrying the field
|
|
55
55
|
fails Mongo 121 (not E11000), so keyed-idempotency writers silently drop their writes
|
|
56
56
|
(2026-07-30 `notification.key` dev outage, Sentry DRAWBRIDGE-SYNC-32).
|
|
57
|
+
- Scraped-asset file reuse keys on `organization + meta.origin + meta.element` **plus
|
|
57
58
|
`meta.render` for pipeline-rendered marks** (sync `resolveAsset` writes/queries it; the field
|
|
58
59
|
and its index live in drawbridge-api `schema/file.js`). `origin` identifies the source asset,
|
|
59
60
|
`render` content-hashes the rendered output — drop `render` from either side and a rendering
|
|
@@ -99,6 +100,32 @@ skill) so it stops living only in tribal memory.
|
|
|
99
100
|
`createdAt`. Re-adding a TTL shorter than any billing interval silently under-bills long cycles
|
|
100
101
|
and blanks reporting past the window — any retention change must clear billing + reporting.
|
|
101
102
|
|
|
103
|
+
## Query params + the OAuth resume target (utils ↔ app-web ↔ api ↔ shopify-app)
|
|
104
|
+
|
|
105
|
+
- `request()` in `@drawbridge/drawbridge-utils` (`lib/fetch.js`) builds EVERY family GET query and
|
|
106
|
+
MUST percent-encode param values — `qs.stringify( params, { encodeValuesOnly : true } )`, never
|
|
107
|
+
`encode : false` (≥0.0.90; pinned by `test/fetch.test.js`). Param values routinely carry user input
|
|
108
|
+
and whole URLs, and with encoding off the first `&` inside a value ends that value while its
|
|
109
|
+
remainder arrives as sibling params. This silently truncated every list search (`search.value` of
|
|
110
|
+
`Smith & Sons` reached the api as `Smith `) and cost the Shopify account link its `redirect_uri`.
|
|
111
|
+
`encodeValuesOnly` — not full encoding — keeps the bracket notation (`search[keys][0]=`) so every
|
|
112
|
+
query the api already parses is byte-identical whenever values needed no escaping.
|
|
113
|
+
- The OAuth resume target (`redirectTo`) is **a URL carrying its own query string**, not a scalar:
|
|
114
|
+
`/api/oauth/authorize?client_id=…&redirect_uri=…&state=…&code_challenge=…`. Every hop must preserve
|
|
115
|
+
it whole — app-web's authorize BFF requires BOTH `client_id` and `redirect_uri` and otherwise falls
|
|
116
|
+
back to `/organizations`, which reads to a merchant as "connecting silently did nothing" rather
|
|
117
|
+
than as an error. Hops that carry it: the `/auth` ↔ `/auth/signup` links, `POST /api/auth/signin`,
|
|
118
|
+
`/oauth/google/start` → the api's `oauth.state` token row → `/api/auth/google`, `/api/switch/:id`,
|
|
119
|
+
and app-web's `proxy.js` auth gate.
|
|
120
|
+
- app-web's `/api/oauth/authorize` stamps `resumed=1` on the resume url when it bounces to `/auth`.
|
|
121
|
+
`getSession()` returns null both for "no session" and for "the api session lookup failed", so a
|
|
122
|
+
blip sends the browser to `/auth`, which resolves the session itself and sends it straight back;
|
|
123
|
+
the marker makes a second unresolved arrival stop instead of trading redirects until the browser
|
|
124
|
+
gives up.
|
|
125
|
+
- The api's `POST /oauth/google/callback` returns `redirectTo` in its 400 body when it read the state
|
|
126
|
+
row before failing, so app-web can keep the resume target across `/auth?error=oauth`. A
|
|
127
|
+
`oauth.state.invalid` failure cannot — that row is what carried the target.
|
|
128
|
+
|
|
102
129
|
## Reporting (api ↔ app-web)
|
|
103
130
|
|
|
104
131
|
- Every reporting request (usage/revenue/redemptions/analytics, org + admin) carries the viewer's
|
|
@@ -145,6 +172,12 @@ skill) so it stops living only in tribal memory.
|
|
|
145
172
|
- The poster worker `$set`s `poster : 0` on every run and APPENDS to `frames[]`. Any script that
|
|
146
173
|
generates a frame must snapshot and restore `poster`/`posterTimestamp`, **including on the
|
|
147
174
|
failure path**, or a retry silently discards the user's thumbnail choice.
|
|
175
|
+
- **Never compare frame timestamps as strings.** drawbridge-api writes `'HH:MM:SS'` (upload
|
|
176
|
+
default `'00:00:00'`) while app-web's scrubber writes `'HH:MM:SS.mmm'`, so `=== '00:00:00'`
|
|
177
|
+
misses the starting frame. That single mistake defeated the api's duplicate guard AND app-web's
|
|
178
|
+
own zero-check on the same day, letting the picker create a second starting frame. Compare
|
|
179
|
+
parsed milliseconds — `frameMilliseconds` in api `route/organization-file.js`, `lib/frames.js`
|
|
180
|
+
in app-web.
|
|
148
181
|
|
|
149
182
|
## Import surfaces
|
|
150
183
|
|
package/package.json
CHANGED