mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
* fix(ashby): repair broken idempotency dedup and clarify duplicate-webhook errors extractIdempotencyId looked for a webhookActionId field that does not exist anywhere in Ashby's webhook payload schema (confirmed against the live OpenAPI spec), so every delivery — including Ashby's own retries — got a fresh random dedup key and could re-execute workflows. Derive the key from the affected resource's id plus its updatedAt/decidedAt instead. Also surface a clear, actionable message when Ashby's webhook.create rejects a request as a duplicate (seen repeatedly in production logs, where the outbox retried the same failing subscription for ~23 minutes before dead-lettering) instead of the generic API error passthrough. Also add the interview stage `type` field to trigger outputs (present in Ashby's schema, useful for a stage-change trigger) and fix the employmentType description to match Ashby's actual enum values. * fix(ashby): correct offer status enum values in trigger output descriptions acceptanceStatus listed a non-existent "WaitingOnResponse" value and offerStatus was missing "WaitingOnApprovalDefinition" — both caught on a second pass re-checking every enum against Ashby's live OpenAPI spec. * fix(ashby): harden idempotency key against Greptile-flagged collision risks - Return null (skip dedup) when application.updatedAt is absent instead of collapsing to an empty string, which could collide two distinct events sharing an application id onto the same key. - Drop decidedAt from the offerCreate key. It's populated only after the fact, so including it gave a retry of the same delivery a different key than the original attempt once the candidate responded, defeating dedup. offer.id alone is already stable and unique per created offer. * fix(ashby): fall back to a content fingerprint instead of skipping dedup Returning null when application.updatedAt was missing avoided false collisions between distinct events, but also disabled retry dedup entirely for that payload shape — an Ashby retry would get a random key from the idempotency service's own fallback and re-run the workflow. Extract the fallback-fingerprint helper (sha256 of a stably-serialized payload) out of salesforce.ts into the shared providers/utils.ts, and use it in ashby.ts: identical retried bytes hash identically (dedup still works), while two genuinely different events hash differently (no false collision). * chore(ashby): remove inline comments, let names carry the intent * fix(ashby): fingerprint the full data payload, not just application Hashing only data.application missed other fields (e.g. offer on candidateHire) when updatedAt is absent, so two deliveries sharing an application snapshot but differing elsewhere in data could collide onto the same idempotency key. * fix(ashby): rename output field 'type' to 'stageType' to fix build TriggerOutput reserves the 'type' key for the output's own JSON type (e.g. 'string'), so a nested field literally named 'type' inside currentInterviewStage collided with that meta-field and broke the Record<string, TriggerOutput> cast — passing local type-check (which turbo was silently serving a stale cached pass for) but failing Next.js's build-time type check in CI. Renamed to stageType, matching the existing eventType-style convention used elsewhere for API fields literally called 'type'. * fix(ashby): rename currentInterviewStage.type to stageType in delivered data too Renaming the field in the output schema alone (to fix the TriggerOutput build collision) left a mismatch: Ashby's real payload still has currentInterviewStage.type, so a picker/expression using the schema's declared stageType would resolve to undefined at runtime. formatInput now renames the field in the actual delivered payload so it matches what the schema declares. * fix(ashby): fold offer id into the idempotency key when present When application.updatedAt is present, the key ignored sibling data fields — a candidateHire delivery carries both application and offer, so two deliveries sharing an application snapshot could collide even though they concern different offers. Append offer.id to the discriminator when present; it's the only sibling object Ashby's schema ever pairs with application.