Skip to main content

Architecture overview

GuildGate centralizes security decisions and write operations for a Discord dashboard server. It does not render a UI, own application data, or require a specific HTTP framework.

Kernel​

createGuildGate() validates configuration at startup and creates these surfaces:

  • gate.action() for guarded operation definitions
  • gate.execute() for request execution
  • gate.sessions for session management
  • gate.cache for tag-based caching
  • gate.owner for maintenance and block policies
  • gate.revokeSession() and gate.revokeUserSessions() for revocation

The kernel applies origin, session, CSRF, policy, rate limit, idempotency, lock, transaction, audit, and realtime decisions under one request ID.

Action layer​

An action combines these parts in one definition:

  1. Parse input
  2. Resolve the resource
  3. Check identity and CSRF
  4. Authorize access
  5. Apply rate limits and idempotency
  6. Check optimistic revision and acquire a distributed lock
  7. Perform the domain write in a transaction
  8. Process cache, realtime, and audit results after commit

In 1.1.0, an action returns at its configured deadline even when the underlying operation ignores AbortSignal. Reservation and lease ownership for a late idempotent result are retained only for a configured bounded period.

Store layer​

GuildGateStores consists of ten small contracts:

MemberResponsibility
sessionsSession lifecycle and per-user cap
oauthStatesSingle-use OAuth state consumption
credentialsEncrypted OAuth credentials
rateLimitsAtomic counters and windows
cacheTTL, stale windows, and tag invalidation
idempotencyReservation ownership and replay results
locksLeases, renewal, and fencing tokens
auditImmutable events and cursor paging
outboxEvent delivery with claim leases
policiesMaintenance, blocks, and policy version

composeStores() combines different backend bundles. For example, persistent records can live in PostgreSQL while short-lived counters and leases use Redis.

Transaction layer​

TransactionAdapter lets a domain write and required audit or outbox records share one commit boundary. The PostgreSQL adapter uses savepoints for nested transactions.

A callback failure after a successful COMMIT does not make the domain write look rolled back. The committed result remains final and the issue is exposed through TransactionPostCommitError or postCommitIssues in action metadata; the write is not repeated.

Realtime layer​

createRealtimeHub() separates connection authorization and delivery limits from the transport. WebSocket and Socket.IO messages pass through the same payload, rate, subscription, activity, and backpressure controls. SSE output can use the same session and channel authorization model.

Sequence and replay support lets clients resume after a disconnect. In multi-worker deployments, events can be claimed and delivered through the outbox.

HTTP and Discord adapters​

The package publishes action handlers for Fastify, Express, and Hono. The discord.js adapter maps guild and permission data into the narrow interface expected by the kernel.

The kernel does not own route structure, database schema, or the Discord client's lifecycle. Those decisions stay in the application.

See the operation lifecycle for the detailed request order.