mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
refactor(backend): default badges, always return a badge (#8430)
* default badges, always return a badge - default badges for trophy and verification - always return a badge instead of null - isDefault field on Badge lint fixes * default_verification svg * add default-trophy Co-authored-by: Sebastian Stein <sebastian@codepassion.de> --------- Co-authored-by: Sebastian Stein <sebastian@codepassion.de>
This commit is contained in:
parent
873cd6cd34
commit
5883818b91
12
backend/public/img/badges/default_trophy.svg
Normal file
12
backend/public/img/badges/default_trophy.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg width="400" height="346.67" version="1.1" viewBox="0 0 400 346.67" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<linearGradient id="linearGradient4" x1="708.76" x2="493.17" y1="280.91" y2="65.326" gradientTransform="translate(-404.06 .215)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#c1c1c1" offset="0"/>
|
||||
<stop stop-color="#fcfcfc" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path d="m-0.21505 173.98 100.65-173.76h198.71l101.08 173.76-99.785 172.04-201.29 0.43011z" fill="#bebebe"/>
|
||||
<path d="m22.482 173.91 89.236-154.07h176.18l89.617 154.07-88.473 152.54-178.47 0.38135z" fill="url(#linearGradient4)"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 773 B |
28
backend/public/img/badges/default_verification.svg
Normal file
28
backend/public/img/badges/default_verification.svg
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="513"
|
||||
height="444"
|
||||
version="1.1"
|
||||
id="svg3"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs3" />
|
||||
<g
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
id="g3">
|
||||
<path
|
||||
fill="#333"
|
||||
d="M384.5.297L512.325 221.9l-128 221.702-255.825.102L.675 222.1 128.675.4z"
|
||||
id="path1" />
|
||||
<g
|
||||
fill="#ffffff"
|
||||
id="g2"
|
||||
transform="translate(92)">
|
||||
<path
|
||||
d="m 35.01,367.726 c -0.08,-21.169 -0.205,-53.162 21.257,-71.332 3.817,-3.253 9.93,-7.497 17.321,-9.224 2.575,-0.523 4.956,-0.756 7.262,-0.979 4.438,-0.431 8.27,-0.804 12.054,-2.9 l 4.954,-2.846 c 9.87,-5.655 19.194,-10.996 28.226,-17.377 5.085,-3.632 6.726,-15.73 6.095,-25.428 -0.214,-2.792 -1.893,-5.7 -3.67,-8.777 -1.097,-1.901 -2.232,-3.867 -3.065,-5.916 l -0.073,-0.199 a 56.976,56.976 0 0 1 -0.422,-1.443 c -1.195,-4.205 -1.933,-6.378 -2.386,-7.476 -7.029,-0.944 -11.8,-8.647 -12.888,-21.006 l -0.031,-0.557 c -0.645,-12.785 0.808,-16.13 2.316,-17.716 0.24,-0.254 0.505,-0.475 0.783,-0.666 -1.754,-16.051 3.115,-32.521 13.358,-44.704 9.314,-11.079 21.955,-17.18 35.592,-17.18 3.73,0 7.55,0.458 11.355,1.362 25.63,6.228 41.679,30.27 40.062,59.227 0.53,0.251 1.018,0.61 1.44,1.066 2.752,2.964 2.47,10.97 2.22,14.276 l -0.024,0.41 c -0.335,5.236 -0.684,10.65 -3.052,15.73 -1.739,3.918 -4.405,6.242 -6.76,8.29 -2.396,2.089 -4.288,3.735 -5.294,6.885 -0.7,2.416 -1.645,4.866 -2.559,7.235 -1.752,4.538 -3.407,8.827 -3.54,13.244 -0.427,10.222 1.17,18.391 4.172,21.359 5.097,5.163 13.003,9.391 19.978,13.121 1.6,0.855 3.166,1.692 4.654,2.517 9.28,5.052 16.07,7.915 25.309,8.557 9.118,0.849 18.056,5.193 24.754,11.97 0.736,0.641 1.82,1.744 3.694,3.648 4.416,4.492 4.416,4.492 4.426,5.852 l 0.007,0.758 c 10.783,17.702 11.14,40.656 11.415,58.169 l 0.05,3.28 -3.278,0.028 c -42.05,0.363 -84.058,0.677 -126.058,0.993 -42.12,0.314 -84.232,0.632 -126.367,0.994 L 35.024,371 Z"
|
||||
id="path2" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@ -4,6 +4,7 @@ type Badge {
|
||||
icon: String!
|
||||
createdAt: String
|
||||
description: String!
|
||||
isDefault: Boolean!
|
||||
|
||||
rewarded: [User]! @relation(name: "REWARDED", direction: "OUT")
|
||||
verifies: [User]! @relation(name: "VERIFIES", direction: "OUT")
|
||||
|
||||
@ -125,10 +125,10 @@ type User {
|
||||
|
||||
categories: [Category] @relation(name: "CATEGORIZED", direction: "OUT")
|
||||
|
||||
badgeVerification: Badge @relation(name: "VERIFIES", direction: "IN")
|
||||
badgeVerification: Badge! @neo4j_ignore
|
||||
badgeTrophies: [Badge]! @relation(name: "REWARDED", direction: "IN")
|
||||
badgeTrophiesCount: Int! @cypher(statement: "MATCH (this)<-[:REWARDED]-(r:Badge) RETURN COUNT(r)")
|
||||
badgeTrophiesSelected: [Badge]! @neo4j_ignore
|
||||
badgeTrophiesSelected: [Badge!]! @neo4j_ignore
|
||||
badgeTrophiesUnused: [Badge]! @neo4j_ignore
|
||||
badgeTrophiesUnusedCount: Int! @neo4j_ignore
|
||||
|
||||
|
||||
@ -100,6 +100,7 @@ describe('Badges', () => {
|
||||
id
|
||||
badgeVerification {
|
||||
id
|
||||
isDefault
|
||||
}
|
||||
badgeTrophies {
|
||||
id
|
||||
@ -204,7 +205,7 @@ describe('Badges', () => {
|
||||
data: {
|
||||
setVerificationBadge: {
|
||||
id: 'regular-user-id',
|
||||
badgeVerification: { id: 'verification_moderator' },
|
||||
badgeVerification: { id: 'verification_moderator', isDefault: false },
|
||||
badgeTrophies: [],
|
||||
},
|
||||
},
|
||||
@ -226,7 +227,7 @@ describe('Badges', () => {
|
||||
data: {
|
||||
setVerificationBadge: {
|
||||
id: 'regular-user-id',
|
||||
badgeVerification: { id: 'verification_admin' },
|
||||
badgeVerification: { id: 'verification_admin', isDefault: false },
|
||||
badgeTrophies: [],
|
||||
},
|
||||
},
|
||||
@ -255,7 +256,7 @@ describe('Badges', () => {
|
||||
data: {
|
||||
setVerificationBadge: {
|
||||
id: 'regular-user-2-id',
|
||||
badgeVerification: { id: 'verification_moderator' },
|
||||
badgeVerification: { id: 'verification_moderator', isDefault: false },
|
||||
badgeTrophies: [],
|
||||
},
|
||||
},
|
||||
@ -299,6 +300,7 @@ describe('Badges', () => {
|
||||
id
|
||||
badgeVerification {
|
||||
id
|
||||
isDefault
|
||||
}
|
||||
badgeTrophies {
|
||||
id
|
||||
@ -403,7 +405,7 @@ describe('Badges', () => {
|
||||
data: {
|
||||
rewardTrophyBadge: {
|
||||
id: 'regular-user-id',
|
||||
badgeVerification: null,
|
||||
badgeVerification: { id: 'default_verification', isDefault: true },
|
||||
badgeTrophies: [{ id: 'trophy_rhino' }],
|
||||
},
|
||||
},
|
||||
@ -530,6 +532,7 @@ describe('Badges', () => {
|
||||
id
|
||||
badgeVerification {
|
||||
id
|
||||
isDefault
|
||||
}
|
||||
badgeTrophies {
|
||||
id
|
||||
@ -596,7 +599,7 @@ describe('Badges', () => {
|
||||
data: {
|
||||
revokeBadge: {
|
||||
id: 'regular-user-id',
|
||||
badgeVerification: { id: 'verification_moderator' },
|
||||
badgeVerification: { id: 'verification_moderator', isDefault: false },
|
||||
badgeTrophies: [],
|
||||
},
|
||||
},
|
||||
@ -610,7 +613,7 @@ describe('Badges', () => {
|
||||
data: {
|
||||
revokeBadge: {
|
||||
id: 'regular-user-id',
|
||||
badgeVerification: { id: 'verification_moderator' },
|
||||
badgeVerification: { id: 'verification_moderator', isDefault: false },
|
||||
badgeTrophies: [],
|
||||
},
|
||||
},
|
||||
@ -631,7 +634,7 @@ describe('Badges', () => {
|
||||
data: {
|
||||
revokeBadge: {
|
||||
id: 'regular-user-id',
|
||||
badgeVerification: null,
|
||||
badgeVerification: { id: 'default_verification', isDefault: true },
|
||||
badgeTrophies: [{ id: 'trophy_rhino' }],
|
||||
},
|
||||
},
|
||||
@ -659,7 +662,7 @@ describe('Badges', () => {
|
||||
data: {
|
||||
revokeBadge: {
|
||||
id: 'regular-user-id',
|
||||
badgeVerification: null,
|
||||
badgeVerification: { id: 'default_verification', isDefault: true },
|
||||
badgeTrophies: [{ id: 'trophy_rhino' }],
|
||||
},
|
||||
},
|
||||
|
||||
@ -6,6 +6,22 @@
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
import { neo4jgraphql } from 'neo4j-graphql-js'
|
||||
|
||||
export const defaultTrophyBadge = {
|
||||
id: 'default_trophy',
|
||||
type: 'trophy',
|
||||
icon: '/img/badges/default_trophy.svg',
|
||||
description: '',
|
||||
createdAt: '',
|
||||
}
|
||||
|
||||
export const defaultVerificationBadge = {
|
||||
id: 'default_verification',
|
||||
type: 'verification',
|
||||
icon: '/img/badges/default_verification.svg',
|
||||
description: '',
|
||||
createdAt: '',
|
||||
}
|
||||
|
||||
export default {
|
||||
Query: {
|
||||
Badge: async (object, args, context, resolveInfo) =>
|
||||
@ -123,4 +139,8 @@ export default {
|
||||
}
|
||||
},
|
||||
},
|
||||
Badge: {
|
||||
isDefault: async (parent, _params, _context, _resolveInfo) =>
|
||||
[defaultTrophyBadge.id, defaultVerificationBadge.id].includes(parent.id),
|
||||
},
|
||||
}
|
||||
|
||||
@ -81,6 +81,7 @@ const setTrophyBadgeSelected = gql`
|
||||
badgeTrophiesCount
|
||||
badgeTrophiesSelected {
|
||||
id
|
||||
isDefault
|
||||
}
|
||||
badgeTrophiesUnused {
|
||||
id
|
||||
@ -96,6 +97,7 @@ const resetTrophyBadgesSelected = gql`
|
||||
badgeTrophiesCount
|
||||
badgeTrophiesSelected {
|
||||
id
|
||||
isDefault
|
||||
}
|
||||
badgeTrophiesUnused {
|
||||
id
|
||||
@ -1242,15 +1244,40 @@ describe('setTrophyBadgeSelected', () => {
|
||||
badgeTrophiesSelected: [
|
||||
{
|
||||
id: 'trophy_bear',
|
||||
isDefault: false,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
badgeTrophiesUnused: [
|
||||
{
|
||||
@ -1275,17 +1302,40 @@ describe('setTrophyBadgeSelected', () => {
|
||||
badgeTrophiesSelected: [
|
||||
{
|
||||
id: 'trophy_bear',
|
||||
isDefault: false,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{
|
||||
id: 'trophy_panda',
|
||||
isDefault: false,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
badgeTrophiesUnused: [],
|
||||
badgeTrophiesUnusedCount: 0,
|
||||
@ -1295,8 +1345,8 @@ describe('setTrophyBadgeSelected', () => {
|
||||
)
|
||||
})
|
||||
|
||||
describe('set badge to null', () => {
|
||||
it('returns the user with no badge set on the selected slot', async () => {
|
||||
describe('set badge to null or default', () => {
|
||||
beforeEach(async () => {
|
||||
await mutate({
|
||||
mutation: setTrophyBadgeSelected,
|
||||
variables: { slot: 0, badgeId: 'trophy_bear' },
|
||||
@ -1305,7 +1355,9 @@ describe('setTrophyBadgeSelected', () => {
|
||||
mutation: setTrophyBadgeSelected,
|
||||
variables: { slot: 5, badgeId: 'trophy_panda' },
|
||||
})
|
||||
})
|
||||
|
||||
it('returns the user with no badge set on the selected slot when sending null', async () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: setTrophyBadgeSelected,
|
||||
@ -1319,15 +1371,101 @@ describe('setTrophyBadgeSelected', () => {
|
||||
badgeTrophiesSelected: [
|
||||
{
|
||||
id: 'trophy_bear',
|
||||
isDefault: false,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
],
|
||||
badgeTrophiesUnused: [
|
||||
{
|
||||
id: 'trophy_panda',
|
||||
},
|
||||
],
|
||||
badgeTrophiesUnusedCount: 1,
|
||||
},
|
||||
},
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('returns the user with no badge set on the selected slot when sending default_trophy', async () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: setTrophyBadgeSelected,
|
||||
variables: { slot: 5, badgeId: 'default_trophy' },
|
||||
}),
|
||||
).resolves.toEqual(
|
||||
expect.objectContaining({
|
||||
data: {
|
||||
setTrophyBadgeSelected: {
|
||||
badgeTrophiesCount: 2,
|
||||
badgeTrophiesSelected: [
|
||||
{
|
||||
id: 'trophy_bear',
|
||||
isDefault: false,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
badgeTrophiesUnused: [
|
||||
{
|
||||
@ -1411,7 +1549,44 @@ describe('resetTrophyBadgesSelected', () => {
|
||||
data: {
|
||||
resetTrophyBadgesSelected: {
|
||||
badgeTrophiesCount: 2,
|
||||
badgeTrophiesSelected: [null, null, null, null, null, null, null, null, null],
|
||||
badgeTrophiesSelected: [
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
id: 'default_trophy',
|
||||
isDefault: true,
|
||||
},
|
||||
],
|
||||
badgeTrophiesUnused: [
|
||||
{
|
||||
id: 'trophy_panda',
|
||||
|
||||
@ -11,6 +11,7 @@ import { neo4jgraphql } from 'neo4j-graphql-js'
|
||||
import { TROPHY_BADGES_SELECTED_MAX } from '@constants/badges'
|
||||
import { getNeode } from '@db/neo4j'
|
||||
|
||||
import { defaultTrophyBadge, defaultVerificationBadge } from './badges'
|
||||
import log from './helpers/databaseLogger'
|
||||
import Resolver from './helpers/Resolver'
|
||||
import { mergeImage, deleteImage } from './images/images'
|
||||
@ -412,13 +413,15 @@ export default {
|
||||
MERGE (user)-[:SELECTED{slot: toInteger($slot)}]->(badge)
|
||||
RETURN user {.*}
|
||||
`
|
||||
const queryNull = `
|
||||
const queryEmpty = `
|
||||
MATCH (user:User {id: $userId})
|
||||
OPTIONAL MATCH (user)-[slotRelation:SELECTED {slot: $slot}]->(:Badge)
|
||||
DELETE slotRelation
|
||||
RETURN user {.*}
|
||||
`
|
||||
const result = await transaction.run(badgeId ? queryBadge : queryNull, {
|
||||
const isDefault = !badgeId || badgeId === defaultTrophyBadge.id
|
||||
|
||||
const result = await transaction.run(isDefault ? queryEmpty : queryBadge, {
|
||||
userId,
|
||||
badgeId,
|
||||
slot,
|
||||
@ -538,7 +541,7 @@ export default {
|
||||
})
|
||||
try {
|
||||
const badgesSelected = await query
|
||||
const result = Array(TROPHY_BADGES_SELECTED_MAX).fill(null)
|
||||
const result = Array(TROPHY_BADGES_SELECTED_MAX).fill(defaultTrophyBadge)
|
||||
badgesSelected.map((record) => {
|
||||
result[record.get('slot')] = record.get('badge')
|
||||
return true
|
||||
@ -550,21 +553,17 @@ export default {
|
||||
session.close()
|
||||
}
|
||||
},
|
||||
badgeTrophiesUnused: async (_parent, _params, context, _resolveInfo) => {
|
||||
const {
|
||||
user: { id: userId },
|
||||
} = context
|
||||
|
||||
badgeTrophiesUnused: async (parent, _params, context, _resolveInfo) => {
|
||||
const session = context.driver.session()
|
||||
|
||||
const query = session.writeTransaction(async (transaction) => {
|
||||
const query = session.readTransaction(async (transaction) => {
|
||||
const result = await transaction.run(
|
||||
`
|
||||
MATCH (user:User {id: $userId})<-[:REWARDED]-(badge:Badge)
|
||||
MATCH (user:User {id: $parent.id})<-[:REWARDED]-(badge:Badge)
|
||||
WHERE NOT (user)-[:SELECTED]-(badge)
|
||||
RETURN badge {.*}
|
||||
`,
|
||||
{ userId },
|
||||
{ parent },
|
||||
)
|
||||
return result.records.map((record) => record.get('badge'))
|
||||
})
|
||||
@ -576,21 +575,17 @@ export default {
|
||||
session.close()
|
||||
}
|
||||
},
|
||||
badgeTrophiesUnusedCount: async (_parent, _params, context, _resolveInfo) => {
|
||||
const {
|
||||
user: { id: userId },
|
||||
} = context
|
||||
|
||||
badgeTrophiesUnusedCount: async (parent, _params, context, _resolveInfo) => {
|
||||
const session = context.driver.session()
|
||||
|
||||
const query = session.writeTransaction(async (transaction) => {
|
||||
const query = session.readTransaction(async (transaction) => {
|
||||
const result = await transaction.run(
|
||||
`
|
||||
MATCH (user:User {id: $userId})<-[:REWARDED]-(badge:Badge)
|
||||
MATCH (user:User {id: $parent.id})<-[:REWARDED]-(badge:Badge)
|
||||
WHERE NOT (user)-[:SELECTED]-(badge)
|
||||
RETURN toString(COUNT(badge)) as count
|
||||
`,
|
||||
{ userId },
|
||||
{ parent },
|
||||
)
|
||||
return result.records.map((record) => record.get('count'))[0]
|
||||
})
|
||||
@ -602,6 +597,28 @@ export default {
|
||||
session.close()
|
||||
}
|
||||
},
|
||||
badgeVerification: async (parent, _params, context, _resolveInfo) => {
|
||||
const session = context.driver.session()
|
||||
|
||||
const query = session.writeTransaction(async (transaction) => {
|
||||
const result = await transaction.run(
|
||||
`
|
||||
MATCH (user:User {id: $parent.id})<-[:VERIFIES]-(verification:Badge)
|
||||
RETURN verification {.*}
|
||||
`,
|
||||
{ parent },
|
||||
)
|
||||
return result.records.map((record) => record.get('verification'))[0]
|
||||
})
|
||||
try {
|
||||
const result = await query
|
||||
return result ?? defaultVerificationBadge
|
||||
} catch (error) {
|
||||
throw new Error(error)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
},
|
||||
...Resolver('User', {
|
||||
undefinedToNull: [
|
||||
'actorId',
|
||||
@ -642,7 +659,6 @@ export default {
|
||||
invitedBy: '<-[:INVITED]-(related:User)',
|
||||
location: '-[:IS_IN]->(related:Location)',
|
||||
redeemedInviteCode: '-[:REDEEMED]->(related:InviteCode)',
|
||||
badgeVerification: '<-[:VERIFIES]-(related:Badge)',
|
||||
},
|
||||
hasMany: {
|
||||
followedBy: '<-[:FOLLOWS]-(related:User)',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user