Integrations and Webhooks — SPEC

Start here → AGENTS.md · SPEC_INDEX.md · SECURITY.md.

Metadata

FieldValue
Module idintegrations-and-webhooks
Source path(s)src/pages/integration/, src/pages/api/my-integrations.ts, src/pages/api/my-webhooks.ts, src/pages/api/webhooks.ts, src/pages/api/remove-authorization.ts, related components/stores
Doc kindModule spec
Coverage score100% assessed 2026-07-24; 14/14 mandatory fields PRESENT, OAuth/API/store evidence routed
Generated frommodule-spec @ 0.2.1
generated_by / approved_by / updated_atcodex (gpt-5.6) / repository owner scope approval / 2026-07-24
Validation statuspass-with-warnings; validator claude-opus-4-8-1m (runtime independent of codex), target HEAD b9c7321ee3642bdb0137734e187a102a7f5de9be, assessed 2026-07-24; 0 Blocking, 0 Important, 0 Medium, 2 Minor; full suite environment-blocked (Node 24 + registry pending)

Evidence Rules

Current routes, shared adapters, stores/components, and tests define behavior. Prior OAuth/my-integrations/webhook specs were mapped to current operations, state, validation, and failure paths.

Source Material Register

Source materialScopeDecisionDisposition
Integration OAuth specificationconnect/callbackverified/correctedCurrent cookie/state/navigation/redirect flow
My integrations API specificationlist/disconnect UI/APIverifiedPublic surfaces and state flow
Webhook management specificationlist/create/deleteverified/correctedCurrent body/query validation and store transitions

Overview

This module supports native integration connection, the authenticated My Integrations page, authorization removal, and webhook listing/creation/deletion. The browser uses same-origin APIs and Nano Stores; route handlers acquire server session tokens and call the Hydra/Webex adapter layer.

Purpose / Responsibility

Owns user-visible integration and webhook lifecycle orchestration; upstream services remain the system-of-record.

Stack

Astro endpoints/pages, React islands, Nano Stores, Hydra/Webex adapters, secure cookies, Vitest.

Folder / Package Structure

src/pages/
├── integration/[integrationId]/connect.ts
├── integration/auth.ts
├── my-integrations.astro
└── api/{my-integrations,my-webhooks,webhooks,remove-authorization}.ts
src/components/{MyIntegrations,Webhooks,WebhookConnectButton,WebhookAppGate}.tsx
src/stores/{myIntegrations,authorizations,webhooks}Store.ts

Key Files (source of truth)

FileHolds
integration/[integrationId]/connect.tsconnect validation/state/cookies/authorization redirect
integration/auth.tsstate validation, token exchange, result redirect
api/webhooks.tscreate/delete validation and response status
api/my-*.tsauthenticated list responses
src/lib/adapters/data-service.tsintegrations/webhooks domain calls
related stores/componentsbrowser state/UI flow

Public Surface

Contract IDTypeSurfacePurposeCompatibilityDetailRoot
integration.connectHTTPGET /integration/:integrationId/connectStart native OAuthpath/query/redirect stableroute fileCONTRACTS.md
integration.callbackHTTPGET /integration/authComplete native OAuthresult query stableroute fileCONTRACTS.md
integrations.list/removeHTTPGET /api/my-integrations, DELETE /api/remove-authorizationManage authorizationsJSON/status stableAPI filesCONTRACTS.md
webhooks.list/create/deleteHTTPGET /api/my-webhooks, POST/DELETE /api/webhooksManage webhooksbody/query/status stableAPI filesCONTRACTS.md

Requires (dependencies)

Authenticated server session, Hydra/Webex APIs, adapter types/validation constants, CSRF middleware/client helper, safe URL helpers, integration/webhook stores and notifications.

Requirements

IDWHATWHYSource EvidenceTest EvidenceGapsConfidence
INT-R-001Integration connect MUST validate the integration ID, scopes, navigation provenance, authentication, and safe return path before setting OAuth cookies/redirecting.Prevents open redirect, drive-by connect, and invalid upstream requests.src/pages/integration/[integrationId]/connect.ts, src/lib/url-safety.tstests/unit/lib/integration-routes.test.tsnonePRESENT
INT-R-002Integration callback MUST delete temporary cookies, compare state, map denial/failure/success to safe return-query results, and never expose tokens to the browser.Preserves secure understandable OAuth completion.src/pages/integration/auth.tstests/unit/lib/integration-routes.test.tsnonePRESENT
INT-R-003My Integrations and My Webhooks list endpoints MUST require auth and return validated item arrays.Prevents cross-user disclosure and malformed UI data.src/pages/api/my-integrations.ts, src/pages/api/my-webhooks.ts, src/lib/adapters/data-service.tstests/unit/lib/api-routes.test.ts, tests/unit/lib/adapters/data-service.test.tsnonePRESENT
INT-R-004Webhook creation/deletion MUST validate body size, JSON/query fields, supported webhook type/name constraints, and use CSRF-protected authenticated calls.Prevents abusive/invalid webhook mutations.src/pages/api/webhooks.ts, src/lib/adapters/types.ts, src/middleware.tstests/unit/lib/api-webhooks.test.tsnonePRESENT
INT-R-005Browser stores/UI MUST represent independent loading/error/result state for list, add, delete, and disconnect operations and update lists only on success.Prevents false success and stale management UI.src/components/MyIntegrations.tsx, src/components/Webhooks.tsx, src/stores/webhooksStore.tstests/unit/stores/myIntegrationsStore.test.ts, tests/unit/stores/webhooksStore.test.ts, tests/unit/stores/authorizationsStore.test.tsfull page E2E may be environment-dependentPRESENT

Design Overview

Native integration OAuth uses short-lived cookies separate from the main login state. Management routes use the main server session and adapter facade. React components coordinate stores and same-origin API calls; successful mutations update lists and notifications without owning upstream persistence.

Data Flow

flowchart LR
  UI --> ClientApi["same-origin API"]
  ClientApi --> Auth["requireAuth"]
  Auth --> Service["DataService/Hydra client"]
  Service --> Webex
  Webex --> Service --> APIResponse --> Stores --> UI
  UI --> Connect --> CI["integration OAuth"] --> Callback --> UI

Sequence Diagram(s)

Operation groupDiagramFailure coverage
Native connectconnect → OAuth → callbackinvalid ID/navigation/state, denial, exchange failure
List managementsession → upstream → validated itemsunauthenticated/upstream/schema error
Webhook mutationCSRF/body validation → upstream → list updatevalidation, conflict/upstream failure
sequenceDiagram
  participant U as User
  participant UI as Management UI
  participant A as App Hub API
  participant W as Webex
  U->>UI: create/delete/disconnect
  UI->>A: same-origin request + CSRF
  A->>A: requireAuth + validate
  A->>W: authorized mutation
  alt success
    W-->>A: result
    A-->>UI: 201/204/200
    UI->>UI: update store + success notification
  else failure
    W-->>A: error
    A-->>UI: stable error status
    UI->>UI: preserve list + error notification
  end
sequenceDiagram
  participant U as User
  participant C as Connect route
  participant I as Identity provider
  participant A as Callback route
  U->>C: navigate /integration/:id/connect
  C->>C: validate id/scopes/navigation/session/return
  C-->>I: state cookies + 302 authorize
  I-->>A: code or denial + state
  A->>A: clear cookies + compare state + exchange
  A-->>U: 302 safe return with result query
sequenceDiagram
  participant UI as My Integrations UI
  participant A as List API
  participant S as DataService
  UI->>A: GET integration/webhook list
  A->>A: requireAuth
  alt authenticated
    A->>S: fetch and validate items
    S-->>A: items
    A-->>UI: JSON list
  else invalid session/upstream
    A-->>UI: stable error
  end

Class / Component Relationships

classDiagram
  class MyIntegrations
  class Webhooks
  class IntegrationRoutes
  class ApiRoutes
  class NanoStores
  class DataService
  MyIntegrations --> NanoStores
  Webhooks --> NanoStores
  MyIntegrations --> ApiRoutes
  Webhooks --> ApiRoutes
  ApiRoutes --> DataService
  IntegrationRoutes --> DataService

Use Cases

State Model

myIntegrationsStore, authorizationsStore, and webhooksStore keep separate list/loading/error and mutation-loading/error fields. OAuth completion communicates transient result through safe query parameters rather than browser token state.

Business Rules & Invariants

Concurrency & Reactive Flow

State Machine

stateDiagram-v2
  [*] --> Loading
  Loading --> Ready: list success
  Loading --> Error: list failure
  Ready --> Mutating: add/delete/disconnect
  Mutating --> Ready: success + list update
  Mutating --> Error: failure + list preserved
  Error --> Loading: retry

UI Flow

Error Handling & Failure Modes

ConditionSignalRecovery
Not authenticated401/login redirect pathlogin
Invalid ID/state/returnsafe error redirect or 400/403restart valid flow
Invalid webhook input400/413 JSON errorcorrect form
Upstream auth/failuremapped route errorrefresh/login/retry
Delete succeeds204remove list item

Pitfalls

Module Do’s / Don’ts

Key Design Trade-off

Same-origin management APIs and server sessions add an application hop, but keep credentials out of the browser and centralize validation/observability.

Test-Case Strategy (module)

Cover OAuth success/denial/bad state/navigation/return paths; list auth/schema failures; webhook body/type/name/status paths; store success/error/reset; and representative authenticated E2E when environment credentials exist.

BehaviorEvidenceGap
integration routesintegration-routes.test.tslive provider integration
webhook APIsapi-webhooks.test.tslive Webex integration
stores/componentsstore/component suitesenvironment-gated full E2E

Traceability