2025-07-11 17:09:04 +01:00
# @modrinth/moderation
2025-07-19 15:04:47 -07:00
This package contains the moderation checklist system used for reviewing projects on Modrinth. It provides a structured and transparent way to define moderation stages, actions, and messages that are displayed to moderators during the review process.
2025-07-11 17:09:04 +01:00
## Structure
The package is organized as follows:
```
/packages/moderation/
├── data/
2025-07-19 15:04:47 -07:00
│ ├── checklist.ts # Main checklist definition - imports and exports all stages
│ ├── messages/ # Markdown files containing message templates
2025-07-11 17:09:04 +01:00
│ │ ├── title/ # Messages for the title stage
│ │ ├── description/ # Messages for the description stage
│ │ └── ... # One directory per stage
2025-07-19 15:04:47 -07:00
│ └── stages/ # Stage definition files
│ ├── title.ts # Title stage definition
│ ├── description.ts # Description stage definition
│ └── ... # One file per stage
2025-07-11 17:09:04 +01:00
└── types/ # Type definitions
2025-07-19 15:04:47 -07:00
├── actions.ts # Action-related types
├── messages.ts # Message-related types
└── stage.ts # Stage-related types
2025-07-11 17:09:04 +01:00
```
2025-07-19 15:04:47 -07:00
## Stages
2025-07-11 17:09:04 +01:00
A stage represents a discrete step in the moderation process, like checking a project's title, description, or links. Each stage has:
- A title displayed to moderators
- A link to guidance documentation
- An optional navigation path to direct moderators to the relevant part of the project page
- A list of actions that moderators can take
Stages are defined in individual files in the `data/stages` directory and are assembled into the complete checklist in `data/checklist.ts` .
2025-07-19 15:04:47 -07:00
## Actions
2025-07-11 17:09:04 +01:00
Actions represent decisions moderators can make for each stage. They can be buttons, dropdowns, toggles, etc. Actions can have:
- Labels displayed to the moderator
- Messages that are included in the final moderation decision
- Suggested moderation status and severity
- Optional text inputs for additional information
- Conditional behavior based on other selected actions
Each action requires a unique `id` field that is used for conditional logic and action relationships. The `suggestedStatus` and `severity` fields help determine the overall moderation outcome.
2025-07-19 15:04:47 -07:00
## Messages
2025-07-11 17:09:04 +01:00
Messages are the actual text that will be included in communications to project authors. To promote maintainability and reuse, messages are stored as Markdown files in the `data/messages` directory, organized by stage.
2025-07-19 15:04:47 -07:00
### Variable replacement
2025-07-11 17:09:04 +01:00
You can use variables in your messages that will be replaced with user input:
1. Define a variable in the `relevantExtraInput` array of an action:
```typescript
relevantExtraInput: [
{
label: 'Explanation for the user',
variable: 'MESSAGE',
required: true,
},
],
```
2. Use the variable in your message with `%VARIABLE%` syntax:
```markdown
# Your Message Title
Here is some explanation about the issue.
%MESSAGE%
More text after the variable.
```
The `%MESSAGE%` placeholder will be replaced with the text entered by the moderator.
2025-07-19 15:04:47 -07:00
## Conditional logic
2025-07-11 17:09:04 +01:00
The moderation system supports conditional behavior that changes based on the selection of other actions.
2025-07-19 15:04:47 -07:00
### Conditional messages
2025-07-11 17:09:04 +01:00
You can define different messages for an action based on other selected actions:
```typescript
{
id: 'my_action',
type: 'button',
label: 'My Action',
weight: 100,
message: async () => (await import('../messages/default-message.md?raw')).default,
conditionalMessages: [
{
conditions: {
requiredActions: ['other_action_id'],
excludedActions: ['another_action_id']
},
message: async () => (await import('../messages/conditional-message.md?raw')).default,
}
]
}
```
2025-07-19 15:04:47 -07:00
### Enabling and disabling actions
2025-07-11 17:09:04 +01:00
Actions can enable or disable other actions when selected:
```typescript
{
id: 'parent_action',
type: 'button',
label: 'Parent Action',
// This will show these actions when parent_action is selected
enablesActions: [
{
id: 'child_action',
type: 'button',
label: 'Child Action',
// ...other properties
}
],
// This will hide actions with these IDs when parent_action is selected
disablesActions: ['incompatible_action_id']
}
```
2025-07-19 15:04:47 -07:00
### Conditional text inputs
2025-07-11 17:09:04 +01:00
Text inputs can be conditionally shown based on selected actions:
```typescript
relevantExtraInput: [
{
label: 'Additional Information',
variable: 'INFO',
showWhen: {
requiredActions: ['specific_action_id'],
excludedActions: ['incompatible_action_id'],
},
},
]
```