mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-04 02:49:57 +08:00
refactor(server): rename settings to user-settings (#11161)
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
-- CreateTable
|
-- CreateTable
|
||||||
CREATE TABLE "settings" (
|
CREATE TABLE "user_settings" (
|
||||||
"user_id" VARCHAR NOT NULL,
|
"user_id" VARCHAR NOT NULL,
|
||||||
"created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
"created_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
"updated_at" TIMESTAMPTZ(3) NOT NULL,
|
"updated_at" TIMESTAMPTZ(3) NOT NULL,
|
||||||
"payload" JSONB NOT NULL,
|
"payload" JSONB NOT NULL,
|
||||||
|
|
||||||
CONSTRAINT "settings_pkey" PRIMARY KEY ("user_id")
|
CONSTRAINT "user_settings_pkey" PRIMARY KEY ("user_id")
|
||||||
);
|
);
|
||||||
|
|
||||||
-- AddForeignKey
|
-- AddForeignKey
|
||||||
ALTER TABLE "settings" ADD CONSTRAINT "settings_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
ALTER TABLE "user_settings" ADD CONSTRAINT "user_settings_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ model User {
|
|||||||
createdAiJobs AiJobs[] @relation("createdAiJobs")
|
createdAiJobs AiJobs[] @relation("createdAiJobs")
|
||||||
// receive notifications
|
// receive notifications
|
||||||
notifications Notification[] @relation("user_notifications")
|
notifications Notification[] @relation("user_notifications")
|
||||||
settings Settings?
|
settings UserSettings?
|
||||||
|
|
||||||
@@index([email])
|
@@index([email])
|
||||||
@@map("users")
|
@@map("users")
|
||||||
@@ -747,7 +747,7 @@ model Notification {
|
|||||||
@@map("notifications")
|
@@map("notifications")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Settings {
|
model UserSettings {
|
||||||
userId String @id @map("user_id") @db.VarChar
|
userId String @id @map("user_id") @db.VarChar
|
||||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||||
@@ -755,5 +755,5 @@ model Settings {
|
|||||||
|
|
||||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
|
|
||||||
@@map("settings")
|
@@map("user_settings")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ export * from './blobs';
|
|||||||
export * from './invite';
|
export * from './invite';
|
||||||
export * from './notification';
|
export * from './notification';
|
||||||
export * from './permission';
|
export * from './permission';
|
||||||
export * from './settings';
|
|
||||||
export * from './testing-app';
|
export * from './testing-app';
|
||||||
export * from './testing-module';
|
export * from './testing-module';
|
||||||
export * from './user';
|
export * from './user';
|
||||||
|
export * from './user-settings';
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
export * from './workspace';
|
export * from './workspace';
|
||||||
|
|||||||
+10
-5
@@ -1,7 +1,12 @@
|
|||||||
import type { SettingsType, UpdateSettingsInput } from '../../core/user/types';
|
import type {
|
||||||
|
UpdateUserSettingsInput,
|
||||||
|
UserSettingsType,
|
||||||
|
} from '../../core/user/types';
|
||||||
import type { TestingApp } from './testing-app';
|
import type { TestingApp } from './testing-app';
|
||||||
|
|
||||||
export async function getSettings(app: TestingApp): Promise<SettingsType> {
|
export async function getUserSettings(
|
||||||
|
app: TestingApp
|
||||||
|
): Promise<UserSettingsType> {
|
||||||
const res = await app.gql(
|
const res = await app.gql(
|
||||||
`
|
`
|
||||||
query settings {
|
query settings {
|
||||||
@@ -17,13 +22,13 @@ export async function getSettings(app: TestingApp): Promise<SettingsType> {
|
|||||||
return res.currentUser.settings;
|
return res.currentUser.settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateSettings(
|
export async function updateUserSettings(
|
||||||
app: TestingApp,
|
app: TestingApp,
|
||||||
input: UpdateSettingsInput
|
input: UpdateUserSettingsInput
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const res = await app.gql(
|
const res = await app.gql(
|
||||||
`
|
`
|
||||||
mutation updateSettings($input: UpdateSettingsInput!) {
|
mutation updateUserSettings($input: UpdateUserSettingsInput!) {
|
||||||
updateSettings(input: $input)
|
updateSettings(input: $input)
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
@@ -89,7 +89,7 @@ test('should create invitation notification and email', async t => {
|
|||||||
test('should not send invitation email if user setting is not to receive invitation email', async t => {
|
test('should not send invitation email if user setting is not to receive invitation email', async t => {
|
||||||
const { notificationService } = t.context;
|
const { notificationService } = t.context;
|
||||||
const inviteId = randomUUID();
|
const inviteId = randomUUID();
|
||||||
await t.context.models.settings.set(member.id, {
|
await t.context.models.userSettings.set(member.id, {
|
||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
});
|
});
|
||||||
const invitationMailCount = t.context.module.mails.count('MemberInvitation');
|
const invitationMailCount = t.context.module.mails.count('MemberInvitation');
|
||||||
@@ -150,7 +150,7 @@ test('should not send invitation accepted email if user settings is not receive
|
|||||||
const { notificationService } = t.context;
|
const { notificationService } = t.context;
|
||||||
const inviteId = randomUUID();
|
const inviteId = randomUUID();
|
||||||
// should not send email if user settings is not receive invitation email
|
// should not send email if user settings is not receive invitation email
|
||||||
await t.context.models.settings.set(owner.id, {
|
await t.context.models.userSettings.set(owner.id, {
|
||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
});
|
});
|
||||||
const invitationAcceptedMailCount =
|
const invitationAcceptedMailCount =
|
||||||
@@ -560,7 +560,7 @@ test('should send mention email by user setting', async t => {
|
|||||||
|
|
||||||
// update user setting to not receive mention email
|
// update user setting to not receive mention email
|
||||||
const mentionMailCount = t.context.module.mails.count('Mention');
|
const mentionMailCount = t.context.module.mails.count('Mention');
|
||||||
await t.context.models.settings.set(member.id, {
|
await t.context.models.userSettings.set(member.id, {
|
||||||
receiveMentionEmail: false,
|
receiveMentionEmail: false,
|
||||||
});
|
});
|
||||||
await notificationService.createMention({
|
await notificationService.createMention({
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export class NotificationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async sendMentionEmail(input: MentionNotificationCreate) {
|
private async sendMentionEmail(input: MentionNotificationCreate) {
|
||||||
const userSetting = await this.models.settings.get(input.userId);
|
const userSetting = await this.models.userSettings.get(input.userId);
|
||||||
if (!userSetting.receiveMentionEmail) {
|
if (!userSetting.receiveMentionEmail) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -104,7 +104,7 @@ export class NotificationService {
|
|||||||
// make it easier to test in dev mode
|
// make it easier to test in dev mode
|
||||||
this.logger.debug(`Invite link: ${inviteUrl}`);
|
this.logger.debug(`Invite link: ${inviteUrl}`);
|
||||||
}
|
}
|
||||||
const userSetting = await this.models.settings.get(input.userId);
|
const userSetting = await this.models.userSettings.get(input.userId);
|
||||||
if (!userSetting.receiveInvitationEmail) {
|
if (!userSetting.receiveInvitationEmail) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ export class NotificationService {
|
|||||||
const inviterUserId = input.userId;
|
const inviterUserId = input.userId;
|
||||||
const inviteeUserId = input.body.createdByUserId;
|
const inviteeUserId = input.body.createdByUserId;
|
||||||
const workspaceId = input.body.workspaceId;
|
const workspaceId = input.body.workspaceId;
|
||||||
const userSetting = await this.models.settings.get(inviterUserId);
|
const userSetting = await this.models.userSettings.get(inviterUserId);
|
||||||
if (!userSetting.receiveInvitationEmail) {
|
if (!userSetting.receiveInvitationEmail) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import test from 'ava';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
createTestingApp,
|
createTestingApp,
|
||||||
getSettings,
|
getUserSettings,
|
||||||
TestingApp,
|
TestingApp,
|
||||||
updateSettings,
|
updateUserSettings,
|
||||||
} from '../../../__tests__/utils';
|
} from '../../../__tests__/utils';
|
||||||
|
|
||||||
let app: TestingApp;
|
let app: TestingApp;
|
||||||
@@ -19,7 +19,7 @@ test.after.always(async () => {
|
|||||||
|
|
||||||
test('should get user settings', async t => {
|
test('should get user settings', async t => {
|
||||||
await app.signup();
|
await app.signup();
|
||||||
const settings = await getSettings(app);
|
const settings = await getUserSettings(app);
|
||||||
t.deepEqual(settings, {
|
t.deepEqual(settings, {
|
||||||
receiveInvitationEmail: true,
|
receiveInvitationEmail: true,
|
||||||
receiveMentionEmail: true,
|
receiveMentionEmail: true,
|
||||||
@@ -28,30 +28,30 @@ test('should get user settings', async t => {
|
|||||||
|
|
||||||
test('should update user settings', async t => {
|
test('should update user settings', async t => {
|
||||||
await app.signup();
|
await app.signup();
|
||||||
await updateSettings(app, {
|
await updateUserSettings(app, {
|
||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
receiveMentionEmail: false,
|
receiveMentionEmail: false,
|
||||||
});
|
});
|
||||||
const settings = await getSettings(app);
|
const settings = await getUserSettings(app);
|
||||||
t.deepEqual(settings, {
|
t.deepEqual(settings, {
|
||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
receiveMentionEmail: false,
|
receiveMentionEmail: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
await updateSettings(app, {
|
await updateUserSettings(app, {
|
||||||
receiveMentionEmail: true,
|
receiveMentionEmail: true,
|
||||||
});
|
});
|
||||||
const settings2 = await getSettings(app);
|
const settings2 = await getUserSettings(app);
|
||||||
t.deepEqual(settings2, {
|
t.deepEqual(settings2, {
|
||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
receiveMentionEmail: true,
|
receiveMentionEmail: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
await updateSettings(app, {
|
await updateUserSettings(app, {
|
||||||
// ignore undefined value
|
// ignore undefined value
|
||||||
receiveInvitationEmail: undefined,
|
receiveInvitationEmail: undefined,
|
||||||
});
|
});
|
||||||
const settings3 = await getSettings(app);
|
const settings3 = await getUserSettings(app);
|
||||||
t.deepEqual(settings3, {
|
t.deepEqual(settings3, {
|
||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
receiveMentionEmail: true,
|
receiveMentionEmail: true,
|
||||||
@@ -61,7 +61,7 @@ test('should update user settings', async t => {
|
|||||||
test('should throw error when update user settings with invalid input', async t => {
|
test('should throw error when update user settings with invalid input', async t => {
|
||||||
await app.signup();
|
await app.signup();
|
||||||
await t.throwsAsync(
|
await t.throwsAsync(
|
||||||
updateSettings(app, {
|
updateUserSettings(app, {
|
||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
// @ts-expect-error invalid value
|
// @ts-expect-error invalid value
|
||||||
receiveMentionEmail: null,
|
receiveMentionEmail: null,
|
||||||
@@ -75,7 +75,7 @@ test('should throw error when update user settings with invalid input', async t
|
|||||||
test('should not update user settings when not logged in', async t => {
|
test('should not update user settings when not logged in', async t => {
|
||||||
await app.logout();
|
await app.logout();
|
||||||
await t.throwsAsync(
|
await t.throwsAsync(
|
||||||
updateSettings(app, {
|
updateUserSettings(app, {
|
||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
receiveMentionEmail: false,
|
receiveMentionEmail: false,
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import {
|
|||||||
Throttle,
|
Throttle,
|
||||||
UserNotFound,
|
UserNotFound,
|
||||||
} from '../../base';
|
} from '../../base';
|
||||||
import { Models, SettingsSchema } from '../../models';
|
import { Models, UserSettingsSchema } from '../../models';
|
||||||
import { Public } from '../auth/guard';
|
import { Public } from '../auth/guard';
|
||||||
import { sessionUser } from '../auth/service';
|
import { sessionUser } from '../auth/service';
|
||||||
import { CurrentUser } from '../auth/session';
|
import { CurrentUser } from '../auth/session';
|
||||||
@@ -32,10 +32,10 @@ import {
|
|||||||
ManageUserInput,
|
ManageUserInput,
|
||||||
PublicUserType,
|
PublicUserType,
|
||||||
RemoveAvatar,
|
RemoveAvatar,
|
||||||
SettingsType,
|
|
||||||
UpdateSettingsInput,
|
|
||||||
UpdateUserInput,
|
UpdateUserInput,
|
||||||
|
UpdateUserSettingsInput,
|
||||||
UserOrLimitedUser,
|
UserOrLimitedUser,
|
||||||
|
UserSettingsType,
|
||||||
UserType,
|
UserType,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
@@ -168,20 +168,20 @@ export class UserSettingsResolver {
|
|||||||
})
|
})
|
||||||
async updateSettings(
|
async updateSettings(
|
||||||
@CurrentUser() user: CurrentUser,
|
@CurrentUser() user: CurrentUser,
|
||||||
@Args('input', { type: () => UpdateSettingsInput })
|
@Args('input', { type: () => UpdateUserSettingsInput })
|
||||||
input: UpdateSettingsInput
|
input: UpdateUserSettingsInput
|
||||||
) {
|
) {
|
||||||
SettingsSchema.parse(input);
|
UserSettingsSchema.parse(input);
|
||||||
await this.models.settings.set(user.id, input);
|
await this.models.userSettings.set(user.id, input);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ResolveField(() => SettingsType, {
|
@ResolveField(() => UserSettingsType, {
|
||||||
name: 'settings',
|
name: 'settings',
|
||||||
description: 'Get user settings',
|
description: 'Get user settings',
|
||||||
})
|
})
|
||||||
async getSettings(@CurrentUser() me: CurrentUser): Promise<SettingsType> {
|
async getSettings(@CurrentUser() me: CurrentUser): Promise<UserSettingsType> {
|
||||||
return await this.models.settings.get(me.id);
|
return await this.models.userSettings.get(me.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import type { User } from '@prisma/client';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
PublicUser,
|
PublicUser,
|
||||||
Settings,
|
UserSettings,
|
||||||
SettingsInput,
|
UserSettingsInput,
|
||||||
WorkspaceUser,
|
WorkspaceUser,
|
||||||
} from '../../models';
|
} from '../../models';
|
||||||
import { type CurrentUser } from '../auth/session';
|
import { type CurrentUser } from '../auth/session';
|
||||||
@@ -115,7 +115,7 @@ export class RemoveAvatar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ObjectType()
|
@ObjectType()
|
||||||
export class SettingsType implements Settings {
|
export class UserSettingsType implements UserSettings {
|
||||||
@Field({ description: 'Receive invitation email' })
|
@Field({ description: 'Receive invitation email' })
|
||||||
receiveInvitationEmail!: boolean;
|
receiveInvitationEmail!: boolean;
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ export class ManageUserInput {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@InputType()
|
@InputType()
|
||||||
export class UpdateSettingsInput implements SettingsInput {
|
export class UpdateUserSettingsInput implements UserSettingsInput {
|
||||||
@Field({ description: 'Receive invitation email', nullable: true })
|
@Field({ description: 'Receive invitation email', nullable: true })
|
||||||
receiveInvitationEmail?: boolean;
|
receiveInvitationEmail?: boolean;
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -43,7 +43,7 @@ test.after(async t => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should get a user settings with default value', async t => {
|
test('should get a user settings with default value', async t => {
|
||||||
const settings = await t.context.models.settings.get(user.id);
|
const settings = await t.context.models.userSettings.get(user.id);
|
||||||
t.deepEqual(settings, {
|
t.deepEqual(settings, {
|
||||||
receiveInvitationEmail: true,
|
receiveInvitationEmail: true,
|
||||||
receiveMentionEmail: true,
|
receiveMentionEmail: true,
|
||||||
@@ -51,28 +51,28 @@ test('should get a user settings with default value', async t => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should update a user settings', async t => {
|
test('should update a user settings', async t => {
|
||||||
const settings = await t.context.models.settings.set(user.id, {
|
const settings = await t.context.models.userSettings.set(user.id, {
|
||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
});
|
});
|
||||||
t.deepEqual(settings, {
|
t.deepEqual(settings, {
|
||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
receiveMentionEmail: true,
|
receiveMentionEmail: true,
|
||||||
});
|
});
|
||||||
const settings2 = await t.context.models.settings.get(user.id);
|
const settings2 = await t.context.models.userSettings.get(user.id);
|
||||||
t.deepEqual(settings2, settings);
|
t.deepEqual(settings2, settings);
|
||||||
|
|
||||||
// update existing setting
|
// update existing setting
|
||||||
const setting3 = await t.context.models.settings.set(user.id, {
|
const setting3 = await t.context.models.userSettings.set(user.id, {
|
||||||
receiveInvitationEmail: true,
|
receiveInvitationEmail: true,
|
||||||
});
|
});
|
||||||
t.deepEqual(setting3, {
|
t.deepEqual(setting3, {
|
||||||
receiveInvitationEmail: true,
|
receiveInvitationEmail: true,
|
||||||
receiveMentionEmail: true,
|
receiveMentionEmail: true,
|
||||||
});
|
});
|
||||||
const setting4 = await t.context.models.settings.get(user.id);
|
const setting4 = await t.context.models.userSettings.get(user.id);
|
||||||
t.deepEqual(setting4, setting3);
|
t.deepEqual(setting4, setting3);
|
||||||
|
|
||||||
const setting5 = await t.context.models.settings.set(user.id, {
|
const setting5 = await t.context.models.userSettings.set(user.id, {
|
||||||
receiveMentionEmail: false,
|
receiveMentionEmail: false,
|
||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
});
|
});
|
||||||
@@ -80,13 +80,13 @@ test('should update a user settings', async t => {
|
|||||||
receiveInvitationEmail: false,
|
receiveInvitationEmail: false,
|
||||||
receiveMentionEmail: false,
|
receiveMentionEmail: false,
|
||||||
});
|
});
|
||||||
const setting6 = await t.context.models.settings.get(user.id);
|
const setting6 = await t.context.models.userSettings.get(user.id);
|
||||||
t.deepEqual(setting6, setting5);
|
t.deepEqual(setting6, setting5);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should throw error when update settings with invalid payload', async t => {
|
test('should throw error when update settings with invalid payload', async t => {
|
||||||
await t.throwsAsync(
|
await t.throwsAsync(
|
||||||
t.context.models.settings.set(user.id, {
|
t.context.models.userSettings.set(user.id, {
|
||||||
// @ts-expect-error invalid setting input types
|
// @ts-expect-error invalid setting input types
|
||||||
receiveInvitationEmail: 1,
|
receiveInvitationEmail: 1,
|
||||||
}),
|
}),
|
||||||
@@ -17,10 +17,10 @@ import { HistoryModel } from './history';
|
|||||||
import { NotificationModel } from './notification';
|
import { NotificationModel } from './notification';
|
||||||
import { MODELS_SYMBOL } from './provider';
|
import { MODELS_SYMBOL } from './provider';
|
||||||
import { SessionModel } from './session';
|
import { SessionModel } from './session';
|
||||||
import { SettingsModel } from './settings';
|
|
||||||
import { UserModel } from './user';
|
import { UserModel } from './user';
|
||||||
import { UserDocModel } from './user-doc';
|
import { UserDocModel } from './user-doc';
|
||||||
import { UserFeatureModel } from './user-feature';
|
import { UserFeatureModel } from './user-feature';
|
||||||
|
import { UserSettingsModel } from './user-settings';
|
||||||
import { VerificationTokenModel } from './verification-token';
|
import { VerificationTokenModel } from './verification-token';
|
||||||
import { WorkspaceModel } from './workspace';
|
import { WorkspaceModel } from './workspace';
|
||||||
import { WorkspaceFeatureModel } from './workspace-feature';
|
import { WorkspaceFeatureModel } from './workspace-feature';
|
||||||
@@ -40,7 +40,7 @@ const MODELS = {
|
|||||||
docUser: DocUserModel,
|
docUser: DocUserModel,
|
||||||
history: HistoryModel,
|
history: HistoryModel,
|
||||||
notification: NotificationModel,
|
notification: NotificationModel,
|
||||||
settings: SettingsModel,
|
userSettings: UserSettingsModel,
|
||||||
copilotSession: CopilotSessionModel,
|
copilotSession: CopilotSessionModel,
|
||||||
copilotContext: CopilotContextModel,
|
copilotContext: CopilotContextModel,
|
||||||
copilotJob: CopilotJobModel,
|
copilotJob: CopilotJobModel,
|
||||||
@@ -104,10 +104,10 @@ export * from './feature';
|
|||||||
export * from './history';
|
export * from './history';
|
||||||
export * from './notification';
|
export * from './notification';
|
||||||
export * from './session';
|
export * from './session';
|
||||||
export * from './settings';
|
|
||||||
export * from './user';
|
export * from './user';
|
||||||
export * from './user-doc';
|
export * from './user-doc';
|
||||||
export * from './user-feature';
|
export * from './user-feature';
|
||||||
|
export * from './user-settings';
|
||||||
export * from './verification-token';
|
export * from './verification-token';
|
||||||
export * from './workspace';
|
export * from './workspace';
|
||||||
export * from './workspace-feature';
|
export * from './workspace-feature';
|
||||||
|
|||||||
+12
-12
@@ -4,27 +4,27 @@ import z from 'zod';
|
|||||||
|
|
||||||
import { BaseModel } from './base';
|
import { BaseModel } from './base';
|
||||||
|
|
||||||
export const SettingsSchema = z.object({
|
export const UserSettingsSchema = z.object({
|
||||||
receiveInvitationEmail: z.boolean().default(true),
|
receiveInvitationEmail: z.boolean().default(true),
|
||||||
receiveMentionEmail: z.boolean().default(true),
|
receiveMentionEmail: z.boolean().default(true),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type SettingsInput = z.input<typeof SettingsSchema>;
|
export type UserSettingsInput = z.input<typeof UserSettingsSchema>;
|
||||||
export type Settings = z.infer<typeof SettingsSchema>;
|
export type UserSettings = z.infer<typeof UserSettingsSchema>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings Model
|
* UserSettings Model
|
||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SettingsModel extends BaseModel {
|
export class UserSettingsModel extends BaseModel {
|
||||||
@Transactional()
|
@Transactional()
|
||||||
async set(userId: string, setting: SettingsInput) {
|
async set(userId: string, setting: UserSettingsInput) {
|
||||||
const existsSetting = await this.get(userId);
|
const existsSetting = await this.get(userId);
|
||||||
const payload = SettingsSchema.parse({
|
const payload = UserSettingsSchema.parse({
|
||||||
...existsSetting,
|
...existsSetting,
|
||||||
...setting,
|
...setting,
|
||||||
});
|
});
|
||||||
await this.db.settings.upsert({
|
await this.db.userSettings.upsert({
|
||||||
where: {
|
where: {
|
||||||
userId,
|
userId,
|
||||||
},
|
},
|
||||||
@@ -36,16 +36,16 @@ export class SettingsModel extends BaseModel {
|
|||||||
payload,
|
payload,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.logger.log(`Settings updated for user ${userId}`);
|
this.logger.log(`UserSettings updated for user ${userId}`);
|
||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
async get(userId: string): Promise<Settings> {
|
async get(userId: string): Promise<UserSettings> {
|
||||||
const row = await this.db.settings.findUnique({
|
const row = await this.db.userSettings.findUnique({
|
||||||
where: {
|
where: {
|
||||||
userId,
|
userId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return SettingsSchema.parse(row?.payload ?? {});
|
return UserSettingsSchema.parse(row?.payload ?? {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1018,7 +1018,7 @@ type Mutation {
|
|||||||
updateRuntimeConfigs(updates: JSONObject!): [ServerRuntimeConfigType!]!
|
updateRuntimeConfigs(updates: JSONObject!): [ServerRuntimeConfigType!]!
|
||||||
|
|
||||||
"""Update user settings"""
|
"""Update user settings"""
|
||||||
updateSettings(input: UpdateSettingsInput!): Boolean!
|
updateSettings(input: UpdateUserSettingsInput!): Boolean!
|
||||||
updateSubscriptionRecurring(idempotencyKey: String @deprecated(reason: "use header `Idempotency-Key`"), plan: SubscriptionPlan = Pro, recurring: SubscriptionRecurring!, workspaceId: String): SubscriptionType!
|
updateSubscriptionRecurring(idempotencyKey: String @deprecated(reason: "use header `Idempotency-Key`"), plan: SubscriptionPlan = Pro, recurring: SubscriptionRecurring!, workspaceId: String): SubscriptionType!
|
||||||
|
|
||||||
"""Update an user"""
|
"""Update an user"""
|
||||||
@@ -1363,14 +1363,6 @@ type ServerServiceConfig {
|
|||||||
name: String!
|
name: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
type SettingsType {
|
|
||||||
"""Receive invitation email"""
|
|
||||||
receiveInvitationEmail: Boolean!
|
|
||||||
|
|
||||||
"""Receive mention email"""
|
|
||||||
receiveMentionEmail: Boolean!
|
|
||||||
}
|
|
||||||
|
|
||||||
type SpaceAccessDeniedDataType {
|
type SpaceAccessDeniedDataType {
|
||||||
spaceId: String!
|
spaceId: String!
|
||||||
}
|
}
|
||||||
@@ -1510,7 +1502,12 @@ input UpdateDocUserRoleInput {
|
|||||||
workspaceId: String!
|
workspaceId: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
input UpdateSettingsInput {
|
input UpdateUserInput {
|
||||||
|
"""User name"""
|
||||||
|
name: String
|
||||||
|
}
|
||||||
|
|
||||||
|
input UpdateUserSettingsInput {
|
||||||
"""Receive invitation email"""
|
"""Receive invitation email"""
|
||||||
receiveInvitationEmail: Boolean
|
receiveInvitationEmail: Boolean
|
||||||
|
|
||||||
@@ -1518,11 +1515,6 @@ input UpdateSettingsInput {
|
|||||||
receiveMentionEmail: Boolean
|
receiveMentionEmail: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
input UpdateUserInput {
|
|
||||||
"""User name"""
|
|
||||||
name: String
|
|
||||||
}
|
|
||||||
|
|
||||||
input UpdateWorkspaceInput {
|
input UpdateWorkspaceInput {
|
||||||
"""Enable AI"""
|
"""Enable AI"""
|
||||||
enableAi: Boolean
|
enableAi: Boolean
|
||||||
@@ -1572,6 +1564,14 @@ type UserQuotaUsageType {
|
|||||||
storageQuota: SafeInt! @deprecated(reason: "use `UserQuotaType['usedStorageQuota']` instead")
|
storageQuota: SafeInt! @deprecated(reason: "use `UserQuotaType['usedStorageQuota']` instead")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserSettingsType {
|
||||||
|
"""Receive invitation email"""
|
||||||
|
receiveInvitationEmail: Boolean!
|
||||||
|
|
||||||
|
"""Receive mention email"""
|
||||||
|
receiveMentionEmail: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
type UserType {
|
type UserType {
|
||||||
"""User avatar url"""
|
"""User avatar url"""
|
||||||
avatarUrl: String
|
avatarUrl: String
|
||||||
@@ -1612,7 +1612,7 @@ type UserType {
|
|||||||
quotaUsage: UserQuotaUsageType!
|
quotaUsage: UserQuotaUsageType!
|
||||||
|
|
||||||
"""Get user settings"""
|
"""Get user settings"""
|
||||||
settings: SettingsType!
|
settings: UserSettingsType!
|
||||||
subscriptions: [SubscriptionType!]!
|
subscriptions: [SubscriptionType!]!
|
||||||
token: tokenType! @deprecated(reason: "use [/api/auth/sign-in?native=true] instead")
|
token: tokenType! @deprecated(reason: "use [/api/auth/sign-in?native=true] instead")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1536,7 +1536,7 @@ export const updateUserProfileMutation = {
|
|||||||
export const updateUserSettingsMutation = {
|
export const updateUserSettingsMutation = {
|
||||||
id: 'updateUserSettingsMutation' as const,
|
id: 'updateUserSettingsMutation' as const,
|
||||||
op: 'updateUserSettings',
|
op: 'updateUserSettings',
|
||||||
query: `mutation updateUserSettings($input: UpdateSettingsInput!) {
|
query: `mutation updateUserSettings($input: UpdateUserSettingsInput!) {
|
||||||
updateSettings(input: $input)
|
updateSettings(input: $input)
|
||||||
}`,
|
}`,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
mutation updateUserSettings($input: UpdateSettingsInput!) {
|
mutation updateUserSettings($input: UpdateUserSettingsInput!) {
|
||||||
updateSettings(input: $input)
|
updateSettings(input: $input)
|
||||||
}
|
}
|
||||||
@@ -1455,7 +1455,7 @@ export interface MutationUpdateRuntimeConfigsArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface MutationUpdateSettingsArgs {
|
export interface MutationUpdateSettingsArgs {
|
||||||
input: UpdateSettingsInput;
|
input: UpdateUserSettingsInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MutationUpdateSubscriptionRecurringArgs {
|
export interface MutationUpdateSubscriptionRecurringArgs {
|
||||||
@@ -1851,14 +1851,6 @@ export interface ServerServiceConfig {
|
|||||||
name: Scalars['String']['output'];
|
name: Scalars['String']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SettingsType {
|
|
||||||
__typename?: 'SettingsType';
|
|
||||||
/** Receive invitation email */
|
|
||||||
receiveInvitationEmail: Scalars['Boolean']['output'];
|
|
||||||
/** Receive mention email */
|
|
||||||
receiveMentionEmail: Scalars['Boolean']['output'];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SpaceAccessDeniedDataType {
|
export interface SpaceAccessDeniedDataType {
|
||||||
__typename?: 'SpaceAccessDeniedDataType';
|
__typename?: 'SpaceAccessDeniedDataType';
|
||||||
spaceId: Scalars['String']['output'];
|
spaceId: Scalars['String']['output'];
|
||||||
@@ -2019,18 +2011,18 @@ export interface UpdateDocUserRoleInput {
|
|||||||
workspaceId: Scalars['String']['input'];
|
workspaceId: Scalars['String']['input'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateSettingsInput {
|
export interface UpdateUserInput {
|
||||||
|
/** User name */
|
||||||
|
name?: InputMaybe<Scalars['String']['input']>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateUserSettingsInput {
|
||||||
/** Receive invitation email */
|
/** Receive invitation email */
|
||||||
receiveInvitationEmail?: InputMaybe<Scalars['Boolean']['input']>;
|
receiveInvitationEmail?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
/** Receive mention email */
|
/** Receive mention email */
|
||||||
receiveMentionEmail?: InputMaybe<Scalars['Boolean']['input']>;
|
receiveMentionEmail?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateUserInput {
|
|
||||||
/** User name */
|
|
||||||
name?: InputMaybe<Scalars['String']['input']>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface UpdateWorkspaceInput {
|
export interface UpdateWorkspaceInput {
|
||||||
/** Enable AI */
|
/** Enable AI */
|
||||||
enableAi?: InputMaybe<Scalars['Boolean']['input']>;
|
enableAi?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
@@ -2080,6 +2072,14 @@ export interface UserQuotaUsageType {
|
|||||||
storageQuota: Scalars['SafeInt']['output'];
|
storageQuota: Scalars['SafeInt']['output'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UserSettingsType {
|
||||||
|
__typename?: 'UserSettingsType';
|
||||||
|
/** Receive invitation email */
|
||||||
|
receiveInvitationEmail: Scalars['Boolean']['output'];
|
||||||
|
/** Receive mention email */
|
||||||
|
receiveMentionEmail: Scalars['Boolean']['output'];
|
||||||
|
}
|
||||||
|
|
||||||
export interface UserType {
|
export interface UserType {
|
||||||
__typename?: 'UserType';
|
__typename?: 'UserType';
|
||||||
/** User avatar url */
|
/** User avatar url */
|
||||||
@@ -2113,7 +2113,7 @@ export interface UserType {
|
|||||||
quota: UserQuotaType;
|
quota: UserQuotaType;
|
||||||
quotaUsage: UserQuotaUsageType;
|
quotaUsage: UserQuotaUsageType;
|
||||||
/** Get user settings */
|
/** Get user settings */
|
||||||
settings: SettingsType;
|
settings: UserSettingsType;
|
||||||
subscriptions: Array<SubscriptionType>;
|
subscriptions: Array<SubscriptionType>;
|
||||||
/** @deprecated use [/api/auth/sign-in?native=true] instead */
|
/** @deprecated use [/api/auth/sign-in?native=true] instead */
|
||||||
token: TokenType;
|
token: TokenType;
|
||||||
@@ -3417,7 +3417,7 @@ export type GetUserSettingsQuery = {
|
|||||||
currentUser: {
|
currentUser: {
|
||||||
__typename?: 'UserType';
|
__typename?: 'UserType';
|
||||||
settings: {
|
settings: {
|
||||||
__typename?: 'SettingsType';
|
__typename?: 'UserSettingsType';
|
||||||
receiveInvitationEmail: boolean;
|
receiveInvitationEmail: boolean;
|
||||||
receiveMentionEmail: boolean;
|
receiveMentionEmail: boolean;
|
||||||
};
|
};
|
||||||
@@ -4051,7 +4051,7 @@ export type UpdateUserProfileMutation = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type UpdateUserSettingsMutationVariables = Exact<{
|
export type UpdateUserSettingsMutationVariables = Exact<{
|
||||||
input: UpdateSettingsInput;
|
input: UpdateUserSettingsInput;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type UpdateUserSettingsMutation = {
|
export type UpdateUserSettingsMutation = {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
type GetUserSettingsQuery,
|
type GetUserSettingsQuery,
|
||||||
getUserSettingsQuery,
|
getUserSettingsQuery,
|
||||||
type UpdateSettingsInput,
|
type UpdateUserSettingsInput,
|
||||||
updateUserSettingsMutation,
|
updateUserSettingsMutation,
|
||||||
} from '@affine/graphql';
|
} from '@affine/graphql';
|
||||||
import { Store } from '@toeverything/infra';
|
import { Store } from '@toeverything/infra';
|
||||||
@@ -12,7 +12,7 @@ export type UserSettings = NonNullable<
|
|||||||
GetUserSettingsQuery['currentUser']
|
GetUserSettingsQuery['currentUser']
|
||||||
>['settings'];
|
>['settings'];
|
||||||
|
|
||||||
export type UpdateUserSettingsInput = UpdateSettingsInput;
|
export type { UpdateUserSettingsInput };
|
||||||
|
|
||||||
export class UserSettingsStore extends Store {
|
export class UserSettingsStore extends Store {
|
||||||
constructor(private readonly gqlService: GraphQLService) {
|
constructor(private readonly gqlService: GraphQLService) {
|
||||||
|
|||||||
Reference in New Issue
Block a user