> ## Documentation Index
> Fetch the complete documentation index at: https://thehypixelguardians.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# User management

> How the THG Community bot registers members in PostgreSQL on every command.

The bot automatically ensures that everyone who runs a command has a row in the database. No separate
sign-up step — registration happens transparently before the command handler runs.

## How it works

1. **Event handler integration** — user management runs from the main event handlers in `src/events/common.ts`.
2. **Automatic check** — every slash command (and prefix command) checks whether the caller exists in the
   database.
3. **Automatic creation** — if not, a new `User` row is created.
4. **Username updates** — if the row exists but the Discord username changed, it is updated.

## Database model

```prisma theme={null}
model User {
  id        String   @id @default(uuid())
  discordId String   @unique
  username  String
  language  String   @default("nl")
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  // relations: MinecraftLink, FeatureRequest, …
}
```

The internal `User.id` UUID is what foreign keys use — not the Discord snowflake.

## Key functions

### `ensureUserExists(discordId, username)`

* Looks up by Discord id.
* Creates a row when missing.
* Updates `username` when it changed.
* Returns the database user object.

### `getUserByDiscordId(discordId)`

Retrieves a user by Discord id without creating one.

## Event integration

Slash commands call `ensureUserExists` before dispatch:

```typescript theme={null}
if (interaction.user) {
  await ensureUserExists(interaction.user.id, interaction.user.username);
}
```

Prefix commands do the same for `message.author`.

## Error handling

Database errors are logged. If user creation fails, the existing error handler surfaces it to the caller.
Production (`main.ts`) closes the Prisma connection on SIGINT/SIGTERM; development (`dev.ts`) does not.

## Using it in commands

Any command can assume the caller has a `User` row after the event hook runs:

```typescript theme={null}
const user = await ensureUserExists(
  interaction.user.id,
  interaction.user.username,
);

await prisma.featureRequest.create({
  data: {
    userId: user.id,
    // …
  },
});
```

`/profile` uses the same helper instead of duplicating create/update logic.

## Related

* [Commands](/community/commands) — `/profile` views or refreshes the stored row
* [Account linking](/community/account-linking) — links hang off `User.id`
