enhance(backend): DBのコラム設定としてcreatedAtの値を入れるように/お知らせ機能API修正

This commit is contained in:
まっちゃとーにゅ
2023-11-20 06:04:59 +09:00
parent 455c7eb653
commit 2883f28b87
71 changed files with 730 additions and 219 deletions

View File

@@ -12,9 +12,10 @@ import { MiAnnouncementRead } from '@/models/_.js';
import { bindThis } from '@/decorators.js';
import { Packed } from '@/misc/json-schema.js';
import { IdService } from '@/core/IdService.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
import { AnnouncementEntityService } from '@/core/entities/AnnouncementEntityService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
import { ModerationLogService } from '@/core/ModerationLogService.js';
import { UserEntityService } from '@/core/entities/UserEntityService.js';
@Injectable()
export class AnnouncementService {
@@ -30,6 +31,7 @@ export class AnnouncementService {
private idService: IdService,
private userEntityService: UserEntityService,
private announcementEntityService: AnnouncementEntityService,
private globalEventService: GlobalEventService,
private moderationLogService: ModerationLogService,
) {
@@ -45,7 +47,7 @@ export class AnnouncementService {
@bindThis
public async getUnreadAnnouncements(user: MiUser): Promise<Packed<'Announcement'>[]> {
const q = this.announcementsRepository.createQueryBuilder('announcement');
q.leftJoin(
q.leftJoinAndSelect(
MiAnnouncementRead,
'read',
'read."announcementId" = announcement.id AND read."userId" = :userId',
@@ -53,7 +55,8 @@ export class AnnouncementService {
);
q
.where('announcement.isActive = true')
.where('read.id IS NULL')
.andWhere('announcement.isActive = true')
.andWhere('announcement.silence = false')
.andWhere(new Brackets(qb => {
qb.orWhere('announcement.userId = :userId', { userId: user.id });
@@ -62,15 +65,14 @@ export class AnnouncementService {
.andWhere(new Brackets(qb => {
qb.orWhere('announcement.forExistingUsers = false');
qb.orWhere('announcement.id > :userId', { userId: user.id });
}))
.andWhere('read.id IS NULL');
}));
q.orderBy({
'announcement."displayOrder"': 'DESC',
'announcement.id': 'DESC',
});
return this.packMany(
return this.announcementEntityService.packMany(
await q.getMany(),
user,
);
@@ -94,7 +96,7 @@ export class AnnouncementService {
userId: values.userId,
}).then(x => this.announcementsRepository.findOneByOrFail(x.identifiers[0]));
const packed = (await this.packMany([announcement], null))[0];
const packed = (await this.announcementEntityService.packMany([announcement], null))[0];
if (values.userId) {
this.globalEventService.publishMainStream(values.userId, 'announcementCreated', {
@@ -136,7 +138,7 @@ export class AnnouncementService {
limit: number,
offset: number,
moderator: MiUser,
): Promise<(MiAnnouncement & { userInfo: Packed<'UserLite'> | null, readCount: number })[]> {
): Promise<(MiAnnouncement & { userInfo: Packed<'UserLite'> | null, reads: number })[]> {
const query = this.announcementsRepository.createQueryBuilder('announcement');
if (userId) {
query.andWhere('announcement."userId" = :userId', { userId: userId });
@@ -173,7 +175,7 @@ export class AnnouncementService {
return announcements.map(announcement => ({
...announcement,
userInfo: packedUsers.find(u => u.id === announcement.userId) ?? null,
readCount: reads.get(announcement) ?? 0,
reads: reads.get(announcement) ?? 0,
}));
}
@@ -188,6 +190,7 @@ export class AnnouncementService {
await this.announcementsRepository.update(announcement.id, {
updatedAt: new Date(),
isActive: values.isActive,
title: values.title,
text: values.text,
/* eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- 空の文字列の場合、nullを渡すようにするため */
@@ -195,11 +198,10 @@ export class AnnouncementService {
display: values.display,
icon: values.icon,
forExistingUsers: values.forExistingUsers,
silence: values.silence,
needConfirmationToRead: values.needConfirmationToRead,
closeDuration: values.closeDuration,
displayOrder: values.displayOrder,
isActive: values.isActive,
silence: values.silence,
userId: values.userId,
});
@@ -305,7 +307,7 @@ export class AnnouncementService {
'announcement.id': 'DESC',
});
return this.packMany(
return this.announcementEntityService.packMany(
await query
.limit(limit)
.offset(offset)
@@ -315,32 +317,29 @@ export class AnnouncementService {
}
@bindThis
public async countUnreadAnnouncements(me: MiUser): Promise<number> {
const query = this.announcementsRepository.createQueryBuilder('announcement');
query.leftJoinAndSelect(
public async countUnreadAnnouncements(user: MiUser): Promise<number> {
const q = this.announcementsRepository.createQueryBuilder('announcement');
q.leftJoinAndSelect(
MiAnnouncementRead,
'read',
'read."announcementId" = announcement.id AND read."userId" = :userId',
{ userId: me.id },
{ userId: user.id },
);
query.andWhere('read.id IS NULL');
query.andWhere('announcement."isActive" = true');
query
.andWhere(
new Brackets((qb) => {
qb.orWhere('announcement."userId" = :userId', { userId: me.id });
qb.orWhere('announcement."userId" IS NULL');
}),
)
.andWhere(
new Brackets((qb) => {
qb.orWhere('announcement."forExistingUsers" = false');
qb.orWhere('announcement.id > :userId', { userId: me.id });
}),
);
q
.where('read.id IS NULL')
.andWhere('announcement.isActive = true')
.andWhere('announcement.silence = false')
.andWhere(new Brackets(qb => {
qb.orWhere('announcement.userId = :userId', { userId: user.id });
qb.orWhere('announcement.userId IS NULL');
}))
.andWhere(new Brackets(qb => {
qb.orWhere('announcement.forExistingUsers = false');
qb.orWhere('announcement.id > :userId', { userId: user.id });
}));
return query.getCount();
return q.getCount();
}
@bindThis
@@ -359,27 +358,4 @@ export class AnnouncementService {
this.globalEventService.publishMainStream(user.id, 'readAllAnnouncements');
}
}
@bindThis
public async packMany(
announcements: (MiAnnouncement & { isRead?: boolean | null })[],
me: { id: MiUser['id'] } | null | undefined,
): Promise<Packed<'Announcement'>[]> {
return announcements.map(announcement => ({
id: announcement.id,
createdAt: this.idService.parse(announcement.id).date.toISOString(),
updatedAt: announcement.updatedAt?.toISOString() ?? null,
text: announcement.text,
title: announcement.title,
imageUrl: announcement.imageUrl,
icon: announcement.icon,
display: announcement.display,
needConfirmationToRead: announcement.needConfirmationToRead,
closeDuration: announcement.closeDuration,
displayOrder: announcement.displayOrder,
silence: announcement.silence,
forYou: announcement.userId === me?.id,
isRead: announcement.isRead ?? undefined,
}));
}
}

View File

@@ -57,12 +57,14 @@ export class AntennaService implements OnApplicationShutdown {
case 'antennaCreated':
this.antennas.push({
...body,
createdAt: new Date(body.createdAt),
lastUsedAt: new Date(body.lastUsedAt),
});
break;
case 'antennaUpdated':
this.antennas[this.antennas.findIndex(a => a.id === body.id)] = {
...body,
createdAt: new Date(body.createdAt),
lastUsedAt: new Date(body.lastUsedAt),
};
break;

View File

@@ -80,6 +80,7 @@ import PerUserDriveChart from './chart/charts/per-user-drive.js';
import ApRequestChart from './chart/charts/ap-request.js';
import { ChartManagementService } from './chart/ChartManagementService.js';
import { AbuseUserReportEntityService } from './entities/AbuseUserReportEntityService.js';
import { AnnouncementEntityService } from './entities/AnnouncementEntityService.js';
import { AntennaEntityService } from './entities/AntennaEntityService.js';
import { AppEntityService } from './entities/AppEntityService.js';
import { AuthSessionEntityService } from './entities/AuthSessionEntityService.js';
@@ -214,6 +215,7 @@ const $ApRequestChart: Provider = { provide: 'ApRequestChart', useExisting: ApRe
const $ChartManagementService: Provider = { provide: 'ChartManagementService', useExisting: ChartManagementService };
const $AbuseUserReportEntityService: Provider = { provide: 'AbuseUserReportEntityService', useExisting: AbuseUserReportEntityService };
const $AnnouncementEntityService: Provider = { provide: 'AnnouncementEntityService', useExisting: AnnouncementEntityService };
const $AntennaEntityService: Provider = { provide: 'AntennaEntityService', useExisting: AntennaEntityService };
const $AppEntityService: Provider = { provide: 'AppEntityService', useExisting: AppEntityService };
const $AuthSessionEntityService: Provider = { provide: 'AuthSessionEntityService', useExisting: AuthSessionEntityService };
@@ -348,6 +350,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
ApRequestChart,
ChartManagementService,
AbuseUserReportEntityService,
AnnouncementEntityService,
AntennaEntityService,
AppEntityService,
AuthSessionEntityService,
@@ -477,6 +480,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$ApRequestChart,
$ChartManagementService,
$AbuseUserReportEntityService,
$AnnouncementEntityService,
$AntennaEntityService,
$AppEntityService,
$AuthSessionEntityService,
@@ -606,6 +610,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
ApRequestChart,
ChartManagementService,
AbuseUserReportEntityService,
AnnouncementEntityService,
AntennaEntityService,
AppEntityService,
AuthSessionEntityService,
@@ -734,6 +739,7 @@ const $ApQuestionService: Provider = { provide: 'ApQuestionService', useExisting
$ApRequestChart,
$ChartManagementService,
$AbuseUserReportEntityService,
$AnnouncementEntityService,
$AntennaEntityService,
$AppEntityService,
$AuthSessionEntityService,

View File

@@ -382,6 +382,7 @@ export class NoteCreateService implements OnApplicationShutdown {
private async insertNote(user: { id: MiUser['id']; host: MiUser['host']; }, data: Option, tags: string[], emojis: string[], mentionedUsers: MinimumUser[]) {
const insert = new MiNote({
id: this.idService.gen(data.createdAt?.getTime()),
createdAt: data.createdAt!,
fileIds: data.files ? data.files.map(file => file.id) : [],
replyId: data.reply ? data.reply.id : null,
renoteId: data.renote ? data.renote.id : null,

View File

@@ -158,6 +158,7 @@ export class ReactionService {
const record: MiNoteReaction = {
id: this.idService.gen(),
createdAt: new Date(),
noteId: note.id,
userId: user.id,
reaction,

View File

@@ -131,6 +131,7 @@ export class RoleService implements OnApplicationShutdown {
if (cached) {
cached.push({
...body,
createdAt: new Date(body.createdAt),
updatedAt: new Date(body.updatedAt),
lastUsedAt: new Date(body.lastUsedAt),
});
@@ -144,6 +145,7 @@ export class RoleService implements OnApplicationShutdown {
if (i > -1) {
cached[i] = {
...body,
createdAt: new Date(body.createdAt),
updatedAt: new Date(body.updatedAt),
lastUsedAt: new Date(body.lastUsedAt),
};
@@ -163,6 +165,7 @@ export class RoleService implements OnApplicationShutdown {
if (cached) {
cached.push({
...body,
createdAt: new Date(body.createdAt),
expiresAt: body.expiresAt ? new Date(body.expiresAt) : null,
});
}

View File

@@ -51,6 +51,7 @@ export class WebhookService implements OnApplicationShutdown {
if (body.active) {
this.webhooks.push({
...body,
createdAt: new Date(body.createdAt),
latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null,
});
}
@@ -61,11 +62,13 @@ export class WebhookService implements OnApplicationShutdown {
if (i > -1) {
this.webhooks[i] = {
...body,
createdAt: new Date(body.createdAt),
latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null,
};
} else {
this.webhooks.push({
...body,
createdAt: new Date(body.createdAt),
latestSentAt: body.latestSentAt ? new Date(body.latestSentAt) : null,
});
}

View File

@@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Inject, Injectable } from '@nestjs/common';
import { DI } from '@/di-symbols.js';
import type { AnnouncementsRepository, AnnouncementReadsRepository, MiAnnouncement, MiUser } from "@/models/_.js";
import type { Packed } from '@/misc/json-schema.js';
import { bindThis } from '@/decorators.js';
import { IdService } from '@/core/IdService.js';
@Injectable()
export class AnnouncementEntityService {
constructor(
@Inject(DI.announcementsRepository)
private announcementsRepository: AnnouncementsRepository,
@Inject(DI.announcementReadsRepository)
private announcementReadsRepository: AnnouncementReadsRepository,
private idService: IdService,
) {
}
@bindThis
public async pack(
src: MiAnnouncement['id'] | MiAnnouncement & { isRead?: boolean | null },
me: { id: MiUser['id'] } | null | undefined,
): Promise<Packed<'Announcement'>> {
const announcement = typeof src === 'object'
? src
: await this.announcementsRepository.findOneByOrFail({
id: src,
}) as MiAnnouncement & { isRead?: boolean | null };
if (me && announcement.isRead === undefined) {
announcement.isRead = await this.announcementReadsRepository
.countBy({
announcementId: announcement.id,
userId: me.id,
})
.then((count: number) => count > 0);
}
return {
id: announcement.id,
createdAt: this.idService.parse(announcement.id).date.toISOString(),
updatedAt: announcement.updatedAt?.toISOString() ?? null,
title: announcement.title,
text: announcement.text,
imageUrl: announcement.imageUrl,
icon: announcement.icon,
display: announcement.display,
forYou: announcement.userId === me?.id,
needConfirmationToRead: announcement.needConfirmationToRead,
closeDuration: announcement.closeDuration,
displayOrder: announcement.displayOrder,
silence: announcement.silence,
isRead: announcement.isRead !== null ? announcement.isRead : undefined,
};
}
@bindThis
public async packMany(
announcements: (MiAnnouncement['id'] | MiAnnouncement & { isRead?: boolean | null } | MiAnnouncement)[],
me: { id: MiUser['id'] } | null | undefined,
) : Promise<Packed<'Announcement'>[]> {
return (await Promise.allSettled(announcements.map(x => this.pack(x, me))))
.filter(result => result.status === 'fulfilled')
.map(result => (result as PromiseFulfilledResult<Packed<'Announcement'>>).value);
}
}

View File

@@ -13,7 +13,8 @@ export class MiAbuseReportResolver {
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of AbuseReportResolver',
comment: 'The created date of the AbuseReportResolver.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;

View File

@@ -12,6 +12,13 @@ export class MiAbuseUserReport {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the AbuseUserReport.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public targetUserId: MiUser['id'];

View File

@@ -13,6 +13,13 @@ export class MiAccessToken {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the AccessToken.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Column('timestamp with time zone', {
nullable: true,
})

View File

@@ -11,6 +11,13 @@ export class MiAd {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Ad.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column('timestamp with time zone', {
comment: 'The expired date of the Ad.',

View File

@@ -12,6 +12,13 @@ export class MiAnnouncement {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Announcement.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Column('timestamp with time zone', {
comment: 'The updated date of the Announcement.',
nullable: true,

View File

@@ -14,6 +14,13 @@ export class MiAnnouncementRead {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the AnnouncementRead.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -13,6 +13,13 @@ export class MiAntenna {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Antenna.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column('timestamp with time zone')
public lastUsedAt: Date;

View File

@@ -12,6 +12,13 @@ export class MiApp {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the App.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -13,6 +13,13 @@ export class MiAuthSession {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the AuthSession.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column('varchar', {
length: 128,

View File

@@ -11,6 +11,13 @@ export class MiAvatarDecoration {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the AvatarDecoration.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Column('timestamp with time zone', {
nullable: true,
})

View File

@@ -13,6 +13,13 @@ export class MiBlocking {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Blocking.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -13,6 +13,13 @@ export class MiChannel {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Channel.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column('timestamp with time zone', {
nullable: true,

View File

@@ -14,6 +14,13 @@ export class MiChannelFavorite {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the ChannelFavorite.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -14,6 +14,13 @@ export class MiChannelFollowing {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the ChannelFollowing.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -12,6 +12,13 @@ export class MiClip {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Clip.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column('timestamp with time zone', {
nullable: true,

View File

@@ -14,6 +14,13 @@ export class MiClipFavorite {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the ClipFavorite.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -14,6 +14,13 @@ export class MiDriveFile {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the DriveFile.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -12,6 +12,13 @@ export class MiDriveFolder {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the DriveFolder.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Column('varchar', {
length: 128,
comment: 'The name of the DriveFolder.',

View File

@@ -12,6 +12,13 @@ export class MiFlash {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Flash.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column('timestamp with time zone', {
comment: 'The updated date of the Flash.',

View File

@@ -14,6 +14,13 @@ export class MiFlashLike {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the FlashLike.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -13,6 +13,13 @@ export class MiFollowRequest {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the FollowRequest.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -14,6 +14,13 @@ export class MiFollowing {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Following.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -14,6 +14,13 @@ export class MiGalleryLike {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the GalleryLike.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -13,6 +13,13 @@ export class MiGalleryPost {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the GalleryPost.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column('timestamp with time zone', {
comment: 'The updated date of the GalleryPost.',

View File

@@ -12,6 +12,13 @@ export class MiModerationLog {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the ModerationLog.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -13,6 +13,13 @@ export class MiMuting {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Muting.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column('timestamp with time zone', {
nullable: true,

View File

@@ -18,6 +18,13 @@ export class MiNote {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Note.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -14,6 +14,13 @@ export class MiNoteFavorite {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the NoteFavorite.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -14,6 +14,13 @@ export class MiNoteReaction {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the NoteReaction.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -13,6 +13,13 @@ export class MiNoteThreadMuting {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the NoteThreadMuting.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -14,6 +14,13 @@ export class MiPage {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Page.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column('timestamp with time zone', {
comment: 'The updated date of the Page.',

View File

@@ -14,6 +14,13 @@ export class MiPageLike {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the PageLike.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -12,6 +12,13 @@ export class MiPasswordResetRequest {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the PasswordResetRequest.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index({ unique: true })
@Column('varchar', {
length: 256,

View File

@@ -14,6 +14,13 @@ export class MiPollVote {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the PollVote.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -14,6 +14,13 @@ export class MiPromoRead {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the PromoRead.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -12,6 +12,13 @@ export class MiRegistrationTicket {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the RegistrationTicket.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index({ unique: true })
@Column('varchar', {
length: 64,

View File

@@ -13,6 +13,13 @@ export class MiRegistryItem {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the RegistryItem.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Column('timestamp with time zone', {
comment: 'The updated date of the RegistryItem.',
})

View File

@@ -13,6 +13,13 @@ export class MiRenoteMuting {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the RenoteMuting.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -14,7 +14,8 @@ export class MiRetentionAggregation {
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Note.',
comment: 'The created date of the GalleryPost.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;

View File

@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { Entity, Column, PrimaryColumn } from 'typeorm';
import { Entity, Column, PrimaryColumn, Index } from 'typeorm';
import { id } from './util/id.js';
type CondFormulaValueAnd = {
@@ -89,6 +89,13 @@ export class MiRole {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Role.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Column('timestamp with time zone', {
comment: 'The updated date of the Role.',
})

View File

@@ -14,6 +14,13 @@ export class MiRoleAssignment {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the RoleAssignment.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -12,6 +12,13 @@ export class MiSignin {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Signin.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -12,6 +12,13 @@ export class MiSwSubscription {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the SwSubscriptipnpon.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { PrimaryColumn, Entity, Column } from 'typeorm';
import { PrimaryColumn, Entity, Column, Index } from 'typeorm';
@Entity('used_username')
export class MiUsedUsername {
@@ -12,7 +12,11 @@ export class MiUsedUsername {
})
public username: string;
@Column('timestamp with time zone')
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the UsedUsername.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
constructor(data: Partial<MiUsedUsername>) {

View File

@@ -13,6 +13,13 @@ export class MiUser {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the User.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column('timestamp with time zone', {
nullable: true,

View File

@@ -13,7 +13,10 @@ export class MiUserIp {
@PrimaryGeneratedColumn()
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the UserIp.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;

View File

@@ -12,6 +12,13 @@ export class MiUserList {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the UserList.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -14,6 +14,13 @@ export class MiUserListFavorite {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the UserListFavorite.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -14,6 +14,13 @@ export class MiUserListMembership {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the UserListMembership.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -14,6 +14,13 @@ export class MiUserNotePining {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the UserNotePining.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column(id())
public userId: MiUser['id'];

View File

@@ -11,6 +11,13 @@ export class MiUserPending {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the UserPending.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index({ unique: true })
@Column('varchar', {
length: 128,

View File

@@ -14,6 +14,13 @@ export class MiWebhook {
@PrimaryColumn(id())
public id: string;
@Index()
@Column('timestamp with time zone', {
comment: 'The created date of the Webhook.',
default: () => 'CURRENT_TIMESTAMP',
})
public createdAt: Date;
@Index()
@Column({
...id(),

View File

@@ -58,6 +58,10 @@ export const packedAnnouncementSchema = {
type: 'number',
optional: false, nullable: false,
},
silence: {
type: 'boolean',
optional: false, nullable: false,
},
isRead: {
type: 'boolean',
optional: true, nullable: false,

View File

@@ -69,6 +69,10 @@ export const meta = {
type: 'number',
optional: false, nullable: false,
},
silence: {
type: 'boolean',
optional: false, nullable: false,
},
isRead: {
type: 'boolean',
optional: true, nullable: false,
@@ -86,10 +90,10 @@ export const paramDef = {
icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'], default: 'info' },
display: { type: 'string', enum: ['normal', 'banner', 'dialog'], default: 'normal' },
forExistingUsers: { type: 'boolean', default: false },
silence: { type: 'boolean', default: false },
needConfirmationToRead: { type: 'boolean', default: false },
closeDuration: { type: 'number', default: 0 },
displayOrder: { type: 'number', default: 0 },
silence: { type: 'boolean', default: false },
userId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
},
required: ['title', 'text', 'imageUrl'],
@@ -109,10 +113,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
icon: ps.icon,
display: ps.display,
forExistingUsers: ps.forExistingUsers,
silence: ps.silence,
needConfirmationToRead: ps.needConfirmationToRead,
closeDuration: ps.closeDuration,
displayOrder: ps.displayOrder,
silence: ps.silence,
userId: ps.userId,
}, me);

View File

@@ -79,6 +79,10 @@ export const meta = {
type: 'number',
optional: false, nullable: false,
},
silence: {
type: 'boolean',
optional: false, nullable: false,
},
userId: {
type: 'string',
optional: false, nullable: true,
@@ -128,13 +132,13 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
display: announcement.display,
isActive: announcement.isActive,
forExistingUsers: announcement.forExistingUsers,
silence: announcement.silence,
needConfirmationToRead: announcement.needConfirmationToRead,
closeDuration: announcement.closeDuration,
displayOrder: announcement.displayOrder,
silence: announcement.silence,
userId: announcement.userId,
user: announcement.userInfo,
reads: announcement.readCount,
reads: announcement.reads,
}));
});
}

View File

@@ -35,10 +35,10 @@ export const paramDef = {
icon: { type: 'string', enum: ['info', 'warning', 'error', 'success'] },
display: { type: 'string', enum: ['normal', 'banner', 'dialog'] },
forExistingUsers: { type: 'boolean' },
silence: { type: 'boolean' },
needConfirmationToRead: { type: 'boolean' },
closeDuration: { type: 'number', default: 0 },
displayOrder: { type: 'number', default: 0 },
silence: { type: 'boolean' },
isActive: { type: 'boolean' },
},
required: ['id'],
@@ -66,10 +66,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
display: ps.display,
icon: ps.icon,
forExistingUsers: ps.forExistingUsers,
silence: ps.silence,
needConfirmationToRead: ps.needConfirmationToRead,
closeDuration: ps.closeDuration,
displayOrder: ps.displayOrder,
silence: ps.silence,
isActive: ps.isActive,
}, me);
});