Skip to content

Commit 9f03198

Browse files
committed
feat: implement community rules validator
1 parent 51d2690 commit 9f03198

25 files changed

+723
-125
lines changed

api-schema.graphql

+2
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ type Mutation {
385385
userUpdateRuleCondition(input: UserUpdateRuleConditionInput!, ruleConditionId: String!): RuleCondition
386386
userUpdateUser(input: UserUpdateUserInput!): User
387387
userValidateRule(address: String!, ruleId: String!): [RuleCondition!]
388+
userValidateRules(communityId: String!): JSON
388389
userVerifyIdentityChallenge(input: VerifyIdentityChallengeInput!): IdentityChallenge
389390
}
390391

@@ -404,6 +405,7 @@ type Network {
404405
type NetworkAsset {
405406
accounts: [String!]!
406407
amount: String!
408+
group: String
407409
owner: String!
408410
}
409411

libs/api/backup/data-access/src/lib/api-backup.service.ts

+17-8
Original file line numberDiff line numberDiff line change
@@ -123,22 +123,31 @@ export class ApiBackupService {
123123
async restoreBackup(name: string) {
124124
const backup = await this.readBackupFile(name)
125125

126-
const userIds = await this.core.data.user
127-
.findMany({ select: { id: true } })
128-
.then((users) => users.map((user) => user.id))
126+
const [usernames, userIds] = await Promise.all([
127+
this.core.data.user.findMany({ select: { username: true } }).then((users) => users.map((user) => user.username)),
128+
this.core.data.user.findMany({ select: { id: true } }).then((users) => users.map((user) => user.id)),
129+
])
129130

130-
const toCreate = backup.data.users.filter((user: { id: string }) => !userIds.includes(user.id))
131+
const toCreate = backup.data.users.filter((user: { id: string; username: string }) => {
132+
return !userIds.includes(user.id) && !usernames.includes(user.username)
133+
})
131134
if (!toCreate.length) {
132135
this.logger.verbose(`No new users to create`)
133136
return true
134137
}
135138
for (const user of toCreate) {
136139
const { identities, ...userData } = user
137-
const newUser = await this.core.data.user.create({
138-
data: { ...userData, identities: { create: identities } },
139-
})
140+
try {
141+
const newUser = await this.core.data.user.create({
142+
data: { ...userData, identities: { create: identities } },
143+
})
140144

141-
this.logger.verbose(`Created user ${newUser.username} with id ${newUser.id} and ${identities.length} identities`)
145+
this.logger.verbose(
146+
`Created user ${newUser.username} with id ${newUser.id} and ${identities.length} identities`,
147+
)
148+
} catch (error) {
149+
this.logger.error(`Failed to create user ${user.username}: ${error}`)
150+
}
142151
}
143152
return true
144153
}

libs/api/community-member/data-access/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ export * from './lib/dto/user-create-community-member.input'
77
export * from './lib/dto/user-find-many-community-member.input'
88
export * from './lib/dto/user-update-community-member.input'
99
export * from './lib/entity/community-member-paging.entity'
10+
export * from './lib/entity/community-member-rule.entity'
1011
export * from './lib/entity/community-member.entity'
1112
export * from './lib/entity/community-role.enum'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Field, ObjectType } from '@nestjs/graphql'
2+
import { Rule } from '@pubkey-link/api-rule-data-access'
3+
import { CommunityMember } from './community-member.entity'
4+
5+
@ObjectType()
6+
export class CommunityMemberRule {
7+
@Field()
8+
id!: string
9+
@Field({ nullable: true })
10+
createdAt?: Date
11+
@Field({ nullable: true })
12+
updatedAt?: Date
13+
@Field()
14+
memberId!: string
15+
@Field({ nullable: true })
16+
member?: CommunityMember
17+
@Field()
18+
ruleId!: string
19+
@Field({ nullable: true })
20+
rule?: Rule
21+
}
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,28 @@
11
import { Injectable } from '@nestjs/common'
2+
import { CommunityRole } from '@prisma/client'
3+
import { ApiCoreService } from '@pubkey-link/api-core-data-access'
24
import { ApiAdminCommunityService } from './api-admin-community.service'
35
import { ApiUserCommunityService } from './api-user-community.service'
46

57
@Injectable()
68
export class ApiCommunityService {
7-
constructor(readonly admin: ApiAdminCommunityService, readonly user: ApiUserCommunityService) {}
9+
constructor(
10+
readonly core: ApiCoreService,
11+
readonly admin: ApiAdminCommunityService,
12+
readonly user: ApiUserCommunityService,
13+
) {}
14+
15+
async ensureCommunityAdmin(userId: string, communityId: string) {
16+
const found = await this.core.data.community.findUnique({
17+
where: { id: communityId },
18+
include: { members: { where: { userId, role: CommunityRole.Admin } } },
19+
})
20+
if (!found) {
21+
throw new Error(`Community ${communityId} not found`)
22+
}
23+
if (!found.members.length) {
24+
throw new Error(`User ${userId} is not an admin of community ${communityId}`)
25+
}
26+
return found
27+
}
828
}

libs/api/community/data-access/src/lib/dto/admin-create-community.input.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { NetworkCluster } from '@pubkey-link/api-network-data-access'
44
@InputType()
55
export class AdminCreateCommunityInput {
66
@Field(() => NetworkCluster)
7-
cluster: NetworkCluster
7+
cluster!: NetworkCluster
88
@Field()
99
name!: string
1010
@Field({ nullable: true })

libs/api/community/data-access/src/lib/dto/user-create-community.input.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { NetworkCluster } from '@pubkey-link/api-network-data-access'
44
@InputType()
55
export class UserCreateCommunityInput {
66
@Field(() => NetworkCluster)
7-
cluster: NetworkCluster
7+
cluster!: NetworkCluster
88
@Field()
99
name!: string
1010
@Field({ nullable: true })

0 commit comments

Comments
 (0)