Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

トランプ・カード機能を実装 #470

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/api-server/codegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ overwrite: true
schema: './tmp/schema.gql'
documents: './graphql/**/*.graphql'
generates:
../../packages/typed-document-node-v0.7.8/src/generated/graphql.ts:
../../packages/typed-document-node-v0.7.11/src/generated/graphql.ts:
plugins:
- 'typescript'
- 'typescript-operations'
Expand Down
54 changes: 54 additions & 0 deletions apps/api-server/graphql/documents.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ fragment CreateRoomResult on CreateRoomResult {
}
}

fragment DeckTemplate on DeckTemplate {
id
valueJson
createdAt
listPermission
updatePermission
deletePermission
}

fragment FileItem on FileItem {
filename
thumbFilename
Expand Down Expand Up @@ -269,6 +278,27 @@ query GetAvailableGameSystems {
}
}

query GetDeckTemplate($id: String!) {
result: getDeckTemplate(id: $id) {
...DeckTemplate
}
}

query GetDeckTemplatesList {
result: getDeckTemplatesList {
__typename
... on GetDeckTemplatesListSuccessResult {
deckTemplates {
id
createdAt
listPermission
updatePermission
deletePermission
}
}
}
}

query GetDiceHelpMessages($id: String!) {
result: getDiceHelpMessage(id: $id)
}
Expand Down Expand Up @@ -425,6 +455,12 @@ mutation ChangeParticipantName($roomId: String!, $newName: String!) {
}
}

mutation CreateDeckTemplate($valueJson: String!) {
result: createDeckTemplate(valueJson: $valueJson) {
...DeckTemplate
}
}

mutation CreateRoom($input: CreateRoomInput!) {
result: createRoom(input: $input) {
__typename
Expand All @@ -437,6 +473,10 @@ mutation CreateRoom($input: CreateRoomInput!) {
}
}

mutation DeleteDeckTemplate($deckTemplateId: String!) {
result: deleteDeckTemplate(deckTemplateId: $deckTemplateId)
}

mutation DeleteFiles($filenames: [String!]!) {
result: deleteFiles(filenames: $filenames)
}
Expand Down Expand Up @@ -553,6 +593,20 @@ mutation UpdateBookmark($roomId: String!, $newValue: Boolean!) {
}
}

mutation UpdateDeckTemplate($valueJson: String!, $deckTemplateId: String!) {
result: updateDeckTemplate(valueJson: $valueJson, deckTemplateId: $deckTemplateId) {
__typename
... on UpdateDeckTemplateSuccessResult {
currentValue {
...DeckTemplate
}
}
... on UpdateDeckTemplateFailureResult {
failureType
}
}
}

mutation WritePublicMessage(
$roomId: String!
$text: String!
Expand Down
7 changes: 6 additions & 1 deletion apps/api-server/src/entities-graphql/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
TwoWayOperation,
apply,
composeDownOperation,
createRoomStats,
decodeDbState,
decodeDownOperation,
diff,
Expand Down Expand Up @@ -108,12 +109,16 @@ export namespace GlobalRoom {
role: participantEntity?.role,
};
}
return {
const roomWithoutStats: Omit<RoomState, 'stats'> = {
...result,
createdBy: roomEntity.createdBy,
name: roomEntity.name,
participants,
};
return {
...roomWithoutStats,
stats: createRoomStats(roomWithoutStats),
};
};

const downOperation = (entity: RoomOp) => {
Expand Down
75 changes: 75 additions & 0 deletions apps/api-server/src/entities/deckTemplate/entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { State, deckTemplateTemplate } from '@flocon-trpg/core';
import {
Entity,
IdentifiedReference,
Index,
JsonType,
ManyToOne,
PrimaryKey,
Property,
} from '@mikro-orm/core';
import { PermissionType } from '../../enums/PermissionType';
import { easyFlake } from '../../utils/easyFlake';
import { User } from '../user/entity';

// 競合編集はRoomと比べて発生しづらいと考えられるため、DeckTemplateのOperationはDBに保存していない。

type DeckTemplateType = State<typeof deckTemplateTemplate>;

@Entity()
export class DeckTemplate {
public constructor({
createdBy,
value,
listPermission,
updatePermission,
deletePermission,
}: {
createdBy: IdentifiedReference<User, 'userUid'>;
value: DeckTemplateType;
listPermission: PermissionType;
updatePermission: PermissionType;
deletePermission: PermissionType;
}) {
this.createdBy = createdBy;
this.value = value;
this.listPermission = listPermission;
this.updatePermission = updatePermission;
this.deletePermission = deletePermission;
}

@PrimaryKey()
public id: string = easyFlake();

// eslint-disable-next-line @typescript-eslint/no-inferrable-types
@Property({ version: true, index: true })
public version: number = 1;

@Property({ type: Date, nullable: true, onCreate: () => new Date(), index: true })
public createdAt?: Date;

@Property({ type: Date, nullable: true, onUpdate: () => new Date(), index: true })
public updatedAt?: Date;

@Property({ type: JsonType })
public value: DeckTemplateType;

@Property({ type: 'string' })
@Index()
public listPermission: PermissionType;

@Property({ type: 'string' })
@Index()
public updatePermission: PermissionType;

@Property({ type: 'string' })
@Index()
public deletePermission: PermissionType;

// eslint-disable-next-line @typescript-eslint/no-inferrable-types
@Property()
public revision: number = 0;

@ManyToOne(() => User)
public createdBy!: IdentifiedReference<User, 'userUid'>;
}
4 changes: 4 additions & 0 deletions apps/api-server/src/entities/user/entity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Collection, Entity, ManyToMany, OneToMany, PrimaryKey, Property } from '@mikro-orm/core';
import { BaasType } from '../../enums/BaasType';
import { DeckTemplate } from '../deckTemplate/entity';
import { File } from '../file/entity';
import { FileTag } from '../fileTag/entity';
import { Participant } from '../participant/entity';
Expand Down Expand Up @@ -33,6 +34,9 @@ export class User {
@OneToMany(() => FileTag, x => x.user, { orphanRemoval: true })
public fileTags = new Collection<FileTag>(this);

@OneToMany(() => DeckTemplate, x => x.createdBy, { orphanRemoval: true })
public deckTemplates = new Collection<DeckTemplate>(this);

@OneToMany(() => RoomPubMsg, x => x.createdBy, { orphanRemoval: true })
public roomPubMsgs = new Collection<RoomPubMsg>(this);

Expand Down
1 change: 1 addition & 0 deletions apps/api-server/src/enums/FilePermissionType.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/** Consider using `PermissionType` instead. */
export enum FilePermissionType {
// 自分以外アクセスできない。自分がEntryしているかどうかは考慮しない。
Private = 'Private',
Expand Down
3 changes: 3 additions & 0 deletions apps/api-server/src/enums/OperateDeckTemplateFailureType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum OperateDeckTemplateFailureType {
NotFound = 'NotFound',
}
7 changes: 7 additions & 0 deletions apps/api-server/src/enums/PermissionType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export enum PermissionType {
// 自分以外アクセスできない。自分がEntryしているかどうかは考慮しない。
Private = 'Private',

// Entryしているユーザーならば誰でもアクセス可能。
Entry = 'Entry',
}
3 changes: 3 additions & 0 deletions apps/api-server/src/enums/UpdateDeckTemplateFailureType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export enum UpdateDeckTemplateFailureType {
NotFound = 'NotFound',
}
64 changes: 64 additions & 0 deletions apps/api-server/src/graphql/objects/deckTemplate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Field, ID, ObjectType } from 'type-graphql';
import { PermissionType } from '../../enums/PermissionType';
import { OperatedBy } from './operatedBy';

@ObjectType()
export class DeckTemplate {
@Field(() => ID, {
description: 'サーバーで管理されているID。ソートすると作成した時系列順になる。',
})
public id!: string;

@Field({
description:
'DeckTemplateのState。@flocon-trpg/coreのstate(deckTemplateTemplate).decode(...)でdecodeできる。',
})
public valueJson!: string;

@Field({ nullable: true })
public createdAt?: number;

@Field(() => PermissionType)
public listPermission!: PermissionType;

@Field(() => PermissionType)
public updatePermission!: PermissionType;

@Field(() => PermissionType)
public deletePermission!: PermissionType;
}

@ObjectType()
export class DeckTemplateAsListItem {
@Field(() => ID, {
description: 'サーバーで管理されているID。ソートすると作成した時系列順になる。',
})
public id!: string;

@Field({ nullable: true })
public createdAt?: number;

@Field(() => PermissionType)
public listPermission!: PermissionType;

@Field(() => PermissionType)
public updatePermission!: PermissionType;

@Field(() => PermissionType)
public deletePermission!: PermissionType;
}

@ObjectType()
export class DeckTemplateOperation {
@Field()
public revisionTo!: number;

@Field(() => OperatedBy, {
nullable: true,
description: 'operateDeckOperationを実行した人物。promoteなどの結果の場合はnullishになる。',
})
public operatedBy?: OperatedBy;

@Field({ description: 'DeckTemplateのUpOperationをJSONにした値。' })
public valueJson!: string;
}
10 changes: 10 additions & 0 deletions apps/api-server/src/graphql/objects/operatedBy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Field, ObjectType } from 'type-graphql';

@ObjectType()
export class OperatedBy {
@Field()
public userUid!: string;

@Field()
public clientId!: string;
}
14 changes: 3 additions & 11 deletions apps/api-server/src/graphql/objects/room.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Field, ID, ObjectType } from 'type-graphql';
import { ParticipantRoleType } from '../../enums/ParticipantRoleType';
import { OperatedBy } from './operatedBy';

@ObjectType()
export class RoomGetState {
Expand Down Expand Up @@ -33,15 +34,6 @@ since v0.7.2`,
public role?: ParticipantRoleType | undefined;
}

@ObjectType()
class OperatedBy {
@Field()
public userUid!: string;

@Field()
public clientId!: string;
}

export const roomOperation = 'RoomOperation';

@ObjectType()
Expand All @@ -53,11 +45,11 @@ export class RoomOperation {

@Field(() => OperatedBy, {
nullable: true,
description: 'operateRoomを呼んだ人物。promoteなどの結果の場合はnullishになる。',
description: 'operateRoomを実行した人物。promoteなどの結果の場合はnullishになる。',
})
public operatedBy?: OperatedBy;

@Field({ description: 'room.upOperationをJSONにしたもの。idならばnullish。' })
@Field({ description: 'RoomのUpOperationをJSONにした値。' })
public valueJson!: string;
}

Expand Down
8 changes: 8 additions & 0 deletions apps/api-server/src/graphql/registerEnumTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import { WriteRoomPublicMessageFailureType } from '../enums/WriteRoomPublicMessa
import { WriteRoomSoundEffectFailureType } from '../enums/WriteRoomSoundEffectFailureType';
import { WritingMessageStatusInputType } from '../enums/WritingMessageStatusInputType';
import { WritingMessageStatusType } from '../enums/WritingMessageStatusType';
import { PermissionType } from '@/enums/PermissionType';
import { UpdateDeckTemplateFailureType } from '@/enums/UpdateDeckTemplateFailureType';

let hasRegistered = false;
export const registerEnumTypes = (): void => {
Expand Down Expand Up @@ -99,6 +101,9 @@ export const registerEnumTypes = (): void => {
// TODO: 破壊的変更のあるアップデートの際にあわせて、'ParticipantRoleType' に変更する
name: 'ParticipantRole',
});
registerEnumType(PermissionType, {
name: 'PermissionType',
});
registerEnumType(PieceLogType, {
name: 'PieceLogType',
});
Expand All @@ -117,6 +122,9 @@ export const registerEnumTypes = (): void => {
registerEnumType(UpdateBookmarkFailureType, {
name: 'UpdateBookmarkFailureType',
});
registerEnumType(UpdateDeckTemplateFailureType, {
name: 'UpdateDeckTemplateFailureType',
});
registerEnumType(WriteRoomPrivateMessageFailureType, {
name: 'WriteRoomPrivateMessageFailureType',
});
Expand Down
Loading