Feat: メッセージの送受信 / New: ユーザーのiconプロパティ / New: logエンティティ・リポジトリ / Chg: コミュニティリポジトリのスキーマのiconをoptionalに / Del: 不要なimport / Fix: Vue起動前のindex.htmlの背景色をVueと同期 / Enhance: Service Workerを改善 / Fix: 最初に開いたページが動作しない問題 / Feat: 上部の通知モーダル / Feat: 閉じることができないエラーのモーダルに再読み込みボタンを追加 / Fix: はみ出す挙動などのCSSを修正

This commit is contained in:
2026-05-31 13:54:55 +09:00
parent beb0e25ad9
commit cbf18aec8f
37 changed files with 1174 additions and 83 deletions
@@ -0,0 +1,37 @@
import { Entity, EntityRepositoryType, ManyToOne, OptionalProps, PrimaryKey, Property } from "@mikro-orm/core";
import { LogRepository } from "@/modules/repositories/Log";
import generateUniqueId from "@/lib/id";
import { UserEntity } from "@/modules/entities/User";
@Entity({
tableName: "log",
repository: () => LogRepository,
})
export class LogEntity {
[OptionalProps]?: "id" | "createdBy" | "createdAt";
[EntityRepositoryType]?: LogRepository;
@PrimaryKey({
type: "string",
length: 10,
onCreate: () => generateUniqueId(),
})
id!: string;
@Property({
type: "string",
length: 4096
})
text!: string;
@ManyToOne(() => UserEntity, {
nullable: true,
})
createdBy?: UserEntity;
@Property({
type: "datetime",
onCreate: () => new Date(),
})
createdAt!: Date;
}
@@ -1,12 +1,15 @@
import generateUniqueId from "@/lib/id";
import { Entity, Index, ManyToOne, OptionalProps, PrimaryKey, Property } from "@mikro-orm/core";
import { Entity, EntityRepositoryType, ManyToOne, OptionalProps, PrimaryKey, Property } from "@mikro-orm/core";
import { UserEntity } from "@/modules/entities/User";
import { ChannelEntity } from "@/modules/entities/Channel";
import { MessageRepository } from "@/modules/repositories/Message";
@Entity({
tableName: "message",
repository: () => MessageRepository,
})
export class MessageEntity {
[EntityRepositoryType]?: MessageRepository;
[OptionalProps]?: "id" | "createdAt";
@PrimaryKey({
@@ -30,6 +30,12 @@ export class UserEntity {
})
username!: string;
@Property({
type: "string",
nullable: true,
})
icon?: string;
@Property({
type: "string",
length: 4096,
@@ -9,7 +9,7 @@ export class CommunityRepository extends EntityRepository<CommunityEntity> {
name: z.string().trim().min(1).max(20),
description: z.string().trim().min(1).max(4096),
userid: UserRepository.schema.shape.userid,
icon: z.string().url(),
icon: z.string().url().optional(),
});
async listCommunity(limit: number = 20, sinceData?: string) {
@@ -0,0 +1,17 @@
import { EntityRepository } from "@mikro-orm/postgresql";
import type { LogEntity } from "@/modules/entities/Log";
import z from "zod/v3";
export class LogRepository extends EntityRepository<LogEntity> {
public static schema = z.string().min(1).max(4096);
async insertLog(text: string, userid?: string) {
const log = this.create({
text,
createdBy: userid,
});
await this.em.persist(log).flush();
return log.id;
}
}
@@ -0,0 +1,63 @@
import { EntityRepository } from "@mikro-orm/postgresql";
import type { MessageEntity } from "@/modules/entities/Message";
import z from "zod/v3";
import { ErrorBase } from "@/errors";
export class MessageRepository extends EntityRepository<MessageEntity> {
public static schema = z.object({
message: z.string().trim().min(0).max(4096),
channel: z.string().length(10),
userid: z.string().length(10),
});
async sendMessage(messageText: string, channel: string, user: string) {
const message = this.create({
message: messageText,
channel,
createdBy: user,
});
await this.em.persist(message).flush();
return message.id;
}
async deleteMessage(id: string) {
const message = this.getReference(id);
await this.em.remove(message).flush();
}
async listMessage(channel: string, limit: number = 20, untilData?: string) {
let until = untilData ?? new Date();
if (
untilData &&
isNaN(new Date(untilData).getTime())
) {
const itMessage = await this.findOne({ id: untilData });
if (!itMessage) {
return ErrorBase({
bad: "client",
code: "message_not_found",
message: "対象のメッセージが見つかりませんでした。",
});
}
until = itMessage.createdAt;
}
const findResult = await this.find({
channel,
createdAt: {
$lt: until,
},
}, {
orderBy: {
createdAt: "DESC",
},
limit: limit,
});
return findResult ?? [];
}
}
@@ -8,6 +8,7 @@ export class UserRepository extends EntityRepository<UserEntity> {
public static schema = z.object({
userid: z.string().trim().min(3).max(20),
username: z.string().trim().min(3).max(30),
icon: z.string().url().optional(),
profile: z.string().max(4096).optional(),
email: z.string().trim().min(6).max(254).regex(EmailRegex),
password: z.string().trim().min(8),