150 lines
4.5 KiB
Markdown
150 lines
4.5 KiB
Markdown
# @modrinth/moderation
|
|
|
|
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.
|
|
|
|
## Structure
|
|
|
|
The package is organized as follows:
|
|
|
|
```
|
|
/packages/moderation/
|
|
├── data/
|
|
│ ├── checklist.ts # Main checklist definition - imports and exports all stages
|
|
│ ├── messages/ # Markdown files containing message templates
|
|
│ │ ├── title/ # Messages for the title stage
|
|
│ │ ├── description/ # Messages for the description stage
|
|
│ │ └── ... # One directory per stage
|
|
│ └── stages/ # Stage definition files
|
|
│ ├── title.ts # Title stage definition
|
|
│ ├── description.ts # Description stage definition
|
|
│ └── ... # One file per stage
|
|
└── types/ # Type definitions
|
|
├── actions.ts # Action-related types
|
|
├── messages.ts # Message-related types
|
|
└── stage.ts # Stage-related types
|
|
```
|
|
|
|
## Stages
|
|
|
|
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`.
|
|
|
|
## Actions
|
|
|
|
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.
|
|
|
|
## Messages
|
|
|
|
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.
|
|
|
|
### Variable replacement
|
|
|
|
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.
|
|
|
|
## Conditional logic
|
|
|
|
The moderation system supports conditional behavior that changes based on the selection of other actions.
|
|
|
|
### Conditional messages
|
|
|
|
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,
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Enabling and disabling actions
|
|
|
|
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']
|
|
}
|
|
```
|
|
|
|
### Conditional text inputs
|
|
|
|
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'],
|
|
},
|
|
},
|
|
]
|
|
```
|