mirror of
https://github.com/versia-pub/server.git
synced 2025-12-06 08:28:19 +01:00
Add more moderation systems, document new APIs
This commit is contained in:
parent
a87c8b6cc5
commit
847e679a10
268
API.md
Normal file
268
API.md
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
# API
|
||||
|
||||
The Lysand project uses the Mastodon API to interact with clients. However, the moderation API is custom-made for Lysand Server, as it allows for more fine-grained control over the server's behavior.
|
||||
|
||||
## Flags, ModTags and ModNotes
|
||||
|
||||
Flags are used by Lysand Server to automatically attribute tags to a status or account based on rules. ModTags and ModNotes are used by moderators to manually tag and take notes on statuses and accounts.
|
||||
|
||||
The difference between flags and modtags is that flags are automatically attributed by the server, while modtags are manually attributed by moderators.
|
||||
|
||||
### Flag Types
|
||||
|
||||
- `content_filter`: (Statuses only) The status contains content that was filtered by the server's content filter.
|
||||
- `bio_filter`: (Accounts only) The account's bio contains content that was filtered by the server's content filter.
|
||||
- `emoji_filter`: The status or account contains an emoji that was filtered by the server's content filter.
|
||||
- `reported`: The status or account was previously reported by a user.
|
||||
- `suspended`: The status or account was previously suspended by a moderator.
|
||||
- `silenced`: The status or account was previously silenced by a moderator.
|
||||
|
||||
### ModTag Types
|
||||
|
||||
ModTag do not have set types and can be anything. Lysand Server autosuggest previously used tags when a moderator is adding a new tag to avoid duplicates.
|
||||
|
||||
### Data Format
|
||||
|
||||
```ts
|
||||
type Flag = {
|
||||
id: string,
|
||||
// One of the following two fields will be present
|
||||
flaggedStatus?: Status,
|
||||
flaggedUser?: User,
|
||||
flagType: string,
|
||||
createdAt: string,
|
||||
}
|
||||
|
||||
type ModTag = {
|
||||
id: string,
|
||||
// One of the following two fields will be present
|
||||
taggedStatus?: Status,
|
||||
taggedUser?: User,
|
||||
mod: User,
|
||||
tag: string,
|
||||
createdAt: string,
|
||||
}
|
||||
|
||||
type ModNote = {
|
||||
id: string,
|
||||
// One of the following two fields will be present
|
||||
notedStatus?: Status,
|
||||
notedUser?: User,
|
||||
mod: User,
|
||||
note: string,
|
||||
createdAt: string,
|
||||
}
|
||||
```
|
||||
|
||||
The `User` and `Status` types are the same as the ones in the Mastodon API.
|
||||
|
||||
## Moderation API Routes
|
||||
|
||||
### `GET /api/v1/moderation/accounts/:id`
|
||||
|
||||
Returns full moderation data and flags for the account with the given ID.
|
||||
|
||||
Output format:
|
||||
|
||||
```ts
|
||||
{
|
||||
id: string, // Same ID as in account field
|
||||
flags: Flag[],
|
||||
modtags: ModTag[],
|
||||
modnotes: ModNote[],
|
||||
account: User,
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/v1/moderation/statuses/:id`
|
||||
|
||||
Returns full moderation data and flags for the status with the given ID.
|
||||
|
||||
Output format:
|
||||
|
||||
```ts
|
||||
{
|
||||
id: string, // Same ID as in status field
|
||||
flags: Flag[],
|
||||
modtags: ModTag[],
|
||||
modnotes: ModNote[],
|
||||
status: Status,
|
||||
}
|
||||
```
|
||||
|
||||
### `POST /api/v1/moderation/accounts/:id/modtags`
|
||||
|
||||
Params:
|
||||
- `tag`: string
|
||||
|
||||
Adds a modtag to the account with the given ID
|
||||
|
||||
### `POST /api/v1/moderation/statuses/:id/modtags`
|
||||
|
||||
Params:
|
||||
- `tag`: string
|
||||
|
||||
Adds a modtag to the status with the given ID
|
||||
|
||||
### `POST /api/v1/moderation/accounts/:id/modnotes`
|
||||
|
||||
Params:
|
||||
- `note`: string
|
||||
|
||||
Adds a modnote to the account with the given ID
|
||||
|
||||
### `POST /api/v1/moderation/statuses/:id/modnotes`
|
||||
|
||||
Params:
|
||||
- `note`: string
|
||||
|
||||
Adds a modnote to the status with the given ID
|
||||
|
||||
### `DELETE /api/v1/moderation/accounts/:id/modtags/:modtag_id`
|
||||
|
||||
Deletes the modtag with the given ID from the account with the given ID
|
||||
|
||||
### `DELETE /api/v1/moderation/statuses/:id/modtags/:modtag_id`
|
||||
|
||||
Deletes the modtag with the given ID from the status with the given ID
|
||||
|
||||
### `DELETE /api/v1/moderation/accounts/:id/modnotes/:modnote_id`
|
||||
|
||||
Deletes the modnote with the given ID from the account with the given ID
|
||||
|
||||
### `DELETE /api/v1/moderation/statuses/:id/modnotes/:modnote_id`
|
||||
|
||||
Deletes the modnote with the given ID from the status with the given ID
|
||||
|
||||
### `GET /api/v1/moderation/modtags`
|
||||
|
||||
Returns a list of all modtags previously used by moderators
|
||||
|
||||
Output format:
|
||||
|
||||
```ts
|
||||
{
|
||||
tags: string[],
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/v1/moderation/accounts/flags/search`
|
||||
|
||||
Allows moderators to search for accounts based on their flags, this can also include status flags
|
||||
|
||||
Params:
|
||||
- `limit`: Number
|
||||
- `min_id`: String. Returns results immediately newer than this ID. In effect, sets a cursor at this ID and paginates forward.
|
||||
- `max_id`: String. All results returned will be lesser than this ID. In effect, sets an upper bound on results.
|
||||
- `since_id`: String. All results returned will be greater than this ID. In effect, sets a lower bound on results.
|
||||
- `flags`: String (optional). Comma-separated list of flag types to filter by. Can be left out to return accounts with at least one flag
|
||||
- `flag_count`: Number (optional). Minimum number of flags to filter by
|
||||
- `include_statuses`: Boolean (optional). If true, includes status flags in the search results
|
||||
- `account_id`: Array of strings (optional). Filters accounts by account ID
|
||||
|
||||
This method returns a `Link` header the same way Mastodon does, to allow for pagination.
|
||||
|
||||
Output format:
|
||||
|
||||
```ts
|
||||
{
|
||||
accounts: {
|
||||
account: User,
|
||||
modnotes: ModNote[],
|
||||
flags: Flag[],
|
||||
statuses?: {
|
||||
status: Status,
|
||||
modnotes: ModNote[],
|
||||
flags: Flag[],
|
||||
}[],
|
||||
}[],
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/v1/moderation/statuses/flags/search`
|
||||
|
||||
Allows moderators to search for statuses based on their flags
|
||||
|
||||
Params:
|
||||
- `limit`: Number
|
||||
- `min_id`: String. Returns results immediately newer than this ID. In effect, sets a cursor at this ID and paginates forward.
|
||||
- `max_id`: String. All results returned will be lesser than this ID. In effect, sets an upper bound on results.
|
||||
- `since_id`: String. All results returned will be greater than this ID. In effect, sets a lower bound on results.
|
||||
- `flags`: String (optional). Comma-separated list of flag types to filter by. Can be left out to return statuses with at least one flag
|
||||
- `flag_count`: Number (optional). Minimum number of flags to filter by
|
||||
- `account_id`: Array of strings (optional). Filters statuses by account ID
|
||||
|
||||
This method returns a `Link` header the same way Mastodon does, to allow for pagination.
|
||||
|
||||
Output format:
|
||||
|
||||
```ts
|
||||
{
|
||||
statuses: {
|
||||
status: Status,
|
||||
modnotes: ModNote[],
|
||||
flags: Flag[],
|
||||
}[],
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/v1/moderation/accounts/modtags/search`
|
||||
|
||||
Allows moderators to search for accounts based on their modtags
|
||||
|
||||
Params:
|
||||
- `limit`: Number
|
||||
- `min_id`: String. Returns results immediately newer than this ID. In effect, sets a cursor at this ID and paginates forward.
|
||||
- `max_id`: String. All results returned will be lesser than this ID. In effect, sets an upper bound on results.
|
||||
- `since_id`: String. All results returned will be greater than this ID. In effect, sets a lower bound on results.
|
||||
- `tags`: String (optional). Comma-separated list of tags to filter by. Can be left out to return accounts with at least one tag
|
||||
- `tag_count`: Number (optional). Minimum number of tags to filter by
|
||||
- `include_statuses`: Boolean (optional). If true, includes status tags in the search results
|
||||
- `account_id`: Array of strings (optional). Filters accounts by account ID
|
||||
|
||||
This method returns a `Link` header the same way Mastodon does, to allow for pagination.
|
||||
|
||||
Output format:
|
||||
|
||||
```ts
|
||||
{
|
||||
accounts: {
|
||||
account: User,
|
||||
modnotes: ModNote[],
|
||||
modtags: ModTag[],
|
||||
statuses?: {
|
||||
status: Status,
|
||||
modnotes: ModNote[],
|
||||
modtags: ModTag[],
|
||||
}[],
|
||||
}[],
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/v1/moderation/statuses/modtags/search`
|
||||
|
||||
Allows moderators to search for statuses based on their modtags
|
||||
|
||||
Params:
|
||||
- `limit`: Number
|
||||
- `min_id`: String. Returns results immediately newer than this ID. In effect, sets a cursor at this ID and paginates forward.
|
||||
- `max_id`: String. All results returned will be lesser than this ID. In effect, sets an upper bound on results.
|
||||
- `since_id`: String. All results returned will be greater than this ID. In effect, sets a lower bound on results.
|
||||
- `tags`: String (optional). Comma-separated list of tags to filter by. Can be left out to return statuses with at least one tag
|
||||
- `tag_count`: Number (optional). Minimum number of tags to filter by
|
||||
- `account_id`: Array of strings (optional). Filters statuses by account ID
|
||||
- `include_statuses`: Boolean (optional). If true, includes status tags in the search results
|
||||
|
||||
This method returns a `Link` header the same way Mastodon does, to allow for pagination.
|
||||
|
||||
Output format:
|
||||
|
||||
```ts
|
||||
{
|
||||
statuses: {
|
||||
status: Status,
|
||||
modnotes: ModNote[],
|
||||
modtags: ModTag[],
|
||||
}[],
|
||||
}
|
||||
```
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Warnings:
|
||||
|
||||
- You are about to drop the column `statusId` on the `Flag` table. All the data in the column will be lost.
|
||||
- You are about to drop the column `userId` on the `Flag` table. All the data in the column will be lost.
|
||||
- You are about to drop the `ModerationData` table. If the table is not empty, all the data it contains will be lost.
|
||||
|
||||
*/
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Flag" DROP CONSTRAINT "Flag_statusId_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "Flag" DROP CONSTRAINT "Flag_userId_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "ModerationData" DROP CONSTRAINT "ModerationData_creatorId_fkey";
|
||||
|
||||
-- DropForeignKey
|
||||
ALTER TABLE "ModerationData" DROP CONSTRAINT "ModerationData_statusId_fkey";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "Flag" DROP COLUMN "statusId",
|
||||
DROP COLUMN "userId",
|
||||
ADD COLUMN "flaggeStatusId" UUID,
|
||||
ADD COLUMN "flaggedUserId" UUID;
|
||||
|
||||
-- DropTable
|
||||
DROP TABLE "ModerationData";
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ModNote" (
|
||||
"id" UUID NOT NULL DEFAULT uuid_generate_v7(),
|
||||
"notedStatusId" UUID,
|
||||
"notedUserId" UUID,
|
||||
"modId" UUID NOT NULL,
|
||||
"note" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "ModNote_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "ModTag" (
|
||||
"id" UUID NOT NULL DEFAULT uuid_generate_v7(),
|
||||
"taggedStatusId" UUID,
|
||||
"taggedUserId" UUID,
|
||||
"modId" UUID NOT NULL,
|
||||
"tag" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "ModTag_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ModNote" ADD CONSTRAINT "ModNote_notedStatusId_fkey" FOREIGN KEY ("notedStatusId") REFERENCES "Status"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ModNote" ADD CONSTRAINT "ModNote_notedUserId_fkey" FOREIGN KEY ("notedUserId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ModNote" ADD CONSTRAINT "ModNote_modId_fkey" FOREIGN KEY ("modId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ModTag" ADD CONSTRAINT "ModTag_taggedStatusId_fkey" FOREIGN KEY ("taggedStatusId") REFERENCES "Status"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ModTag" ADD CONSTRAINT "ModTag_taggedUserId_fkey" FOREIGN KEY ("taggedUserId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "ModTag" ADD CONSTRAINT "ModTag_modId_fkey" FOREIGN KEY ("modId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Flag" ADD CONSTRAINT "Flag_flaggeStatusId_fkey" FOREIGN KEY ("flaggeStatusId") REFERENCES "Status"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Flag" ADD CONSTRAINT "Flag_flaggedUserId_fkey" FOREIGN KEY ("flaggedUserId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
|
@ -127,27 +127,41 @@ model Status {
|
|||
attachments Attachment[]
|
||||
relatedNotifications Notification[]
|
||||
flags Flag[]
|
||||
moderationData ModerationData[]
|
||||
modNotes ModNote[]
|
||||
modTags ModTag[]
|
||||
}
|
||||
|
||||
model ModerationData {
|
||||
model ModNote {
|
||||
id String @id @default(dbgenerated("uuid_generate_v7()")) @db.Uuid
|
||||
status Status @relation(fields: [statusId], references: [id], onDelete: Cascade)
|
||||
statusId String @db.Uuid
|
||||
creator User @relation(fields: [creatorId], references: [id], onDelete: Cascade)
|
||||
creatorId String @db.Uuid
|
||||
notedStatus Status? @relation(fields: [notedStatusId], references: [id], onDelete: Cascade)
|
||||
notedStatusId String? @db.Uuid
|
||||
notedUser User? @relation("ModNoteToUser", fields: [notedUserId], references: [id], onDelete: Cascade)
|
||||
notedUserId String? @db.Uuid
|
||||
mod User @relation("ModNoteToMod", fields: [modId], references: [id], onDelete: Cascade)
|
||||
modId String @db.Uuid
|
||||
note String
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
}
|
||||
|
||||
// Used for moderation purposes
|
||||
model ModTag {
|
||||
id String @id @default(dbgenerated("uuid_generate_v7()")) @db.Uuid
|
||||
taggedStatus Status? @relation(fields: [taggedStatusId], references: [id], onDelete: Cascade)
|
||||
taggedStatusId String? @db.Uuid
|
||||
taggedUser User? @relation("ModNoteToTaggedUser", fields: [taggedUserId], references: [id], onDelete: Cascade)
|
||||
taggedUserId String? @db.Uuid
|
||||
mod User @relation("ModTagToMod", fields: [modId], references: [id], onDelete: Cascade)
|
||||
modId String @db.Uuid
|
||||
tag String
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
// Used to tag notes and accounts with automatic moderation infractions
|
||||
model Flag {
|
||||
id String @id @default(dbgenerated("uuid_generate_v7()")) @db.Uuid
|
||||
status Status @relation(fields: [statusId], references: [id], onDelete: Cascade)
|
||||
statusId String @db.Uuid
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
userId String @db.Uuid
|
||||
flaggedStatus Status? @relation(fields: [flaggeStatusId], references: [id], onDelete: Cascade)
|
||||
flaggeStatusId String? @db.Uuid
|
||||
flaggedUser User? @relation(fields: [flaggedUserId], references: [id], onDelete: Cascade)
|
||||
flaggedUserId String? @db.Uuid
|
||||
flagType String @default("other")
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
|
@ -237,9 +251,12 @@ model User {
|
|||
notifications Notification[] // One to many relation with Notification
|
||||
notified Notification[] @relation("NotificationToNotified") // One to many relation with Notification
|
||||
linkedOpenIdAccounts OpenIdAccount[] // One to many relation with OpenIdAccount
|
||||
flags Flag[] @relation
|
||||
moderationData ModerationData[]
|
||||
flags Flag[]
|
||||
modNotes ModNote[] @relation("ModNoteToUser")
|
||||
modTags ModTag[] @relation("ModNoteToTaggedUser")
|
||||
disableAutomoderation Boolean @default(false)
|
||||
createdModTags ModTag[] @relation("ModTagToMod")
|
||||
createdModNotes ModNote[] @relation("ModNoteToMod")
|
||||
}
|
||||
|
||||
model OpenIdAccount {
|
||||
|
|
|
|||
Loading…
Reference in a new issue