Files
GMW/services/discord-gateway
dependabot[bot] 0aef0b6c08 build(deps-dev): bump the development group
Bumps the development group in /services/discord-gateway with 2 updates: [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) and [drizzle-kit](https://github.com/drizzle-team/drizzle-orm).


Updates `@types/node` from 26.4.0 to 26.6.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `drizzle-kit` from 0.31.10 to 0.31.11
- [Release notes](https://github.com/drizzle-team/drizzle-orm/releases)
- [Commits](https://github.com/drizzle-team/drizzle-orm/compare/drizzle-kit@0.31.10...drizzle-kit@0.31.11)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 26.6.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: development
- dependency-name: drizzle-kit
  dependency-version: 0.31.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-24 14:25:56 +00:00
..

Discord Gateway

Event-driven selfbot service: captures Discord events, runs LLM moderation, publishes everything to Redis for the backend to consume.

Architecture, invariants and the AI pipeline are documented in ARCHITECTURE.md — that file is the source of truth. This README only covers how to run it.

Commands

pnpm install
pnpm typecheck     # tsc --noEmit
pnpm lint          # biome check --diagnostic-level=error .
pnpm test          # vitest run (138 tests)
pnpm build         # tsc — CI/prod builds run this inside nix, which also
                   # runs scripts/fix-imports.mjs to rewrite @/ aliases and
                   # extensionless imports for Node ESM
pnpm dev           # tsx watch src/index.ts
pnpm start         # node dist/index.js

Deployment is CI-only: nix build .#discord-gateway → Attic cache → systemd restart on the VPS. Do not build/hand-copy the artifact.

Layout

src/
├── index.ts                 # entry → initializeDiscordGateway()
├── app/                     # process lifecycle
│   ├── bootstrap.ts         #   startup order: config → DB → services → metrics → login
│   ├── lifecycle.ts         #   everything wired on the Discord 'ready' hook
│   ├── process-guards.ts    #   SIGINT/SIGTERM + uncaught error policy
│   ├── metrics-collector.ts #   AI pipeline Prometheus gauges
│   ├── shutdown.ts          #   graceful shutdown sequence
│   └── retention.ts         #   expired-record cleanup scheduler
├── shared/                  # infrastructure — never imports from modules/
│   ├── config/ database/ logger/ errors/ utils/
│   ├── discord/clientOptions.ts
│   ├── redis-channels.ts    #   canonical Redis channel + command constants
│   └── moderation-types.ts  #   domain types shared across services
└── modules/                 # feature modules (each exposes an index.ts facade)
    ├── ai-moderation/       #   LLM moderation pipeline (largest module)
    ├── message-capture/     #   Discord listeners + message/attachment DB
    ├── attachment-upload/   #   download → resize → upload
    ├── event-broadcaster/   #   Redis pub/sub publisher
    ├── command-handler/     #   backend → gateway commands over Redis
    ├── gateway-metrics/     #   Prometheus /metrics (METRICS_PORT)
    ├── monitor/             #   weekly digest scheduler
    └── reaction-tracking/ thread-tracking/ user-presence/
        channel-topic/ guild-member-events/

Dependency direction is one-way: index.ts → app/ → modules/ → shared/. Callers outside a module import its index.ts facade, never an internal file.

Testing

Vitest, tests in tests/. Config supplies dummy env vars so the suite runs without live Postgres/Redis/Qdrant; external services are mocked. llmE2e.test.ts is skipped by default and needs real credentials (pnpm test:e2e:live).