Procházet zdrojové kódy

Merge pull request #2918 from thesan/olympia-pioneer-query-node-update

query node - pioneer update
Lezek123 před 3 roky
rodič
revize
0e05e05f96

+ 13 - 4
metadata-protobuf/compiled/index.d.ts

@@ -615,8 +615,11 @@ export interface IMembershipMetadata {
     /** MembershipMetadata name */
     name?: (string|null);
 
-    /** MembershipMetadata avatar */
-    avatar?: (number|null);
+    /** MembershipMetadata avatarObject */
+    avatarObject?: (number|null);
+
+    /** MembershipMetadata avatarUri */
+    avatarUri?: (string|null);
 
     /** MembershipMetadata about */
     about?: (string|null);
@@ -634,12 +637,18 @@ export class MembershipMetadata implements IMembershipMetadata {
     /** MembershipMetadata name. */
     public name: string;
 
-    /** MembershipMetadata avatar. */
-    public avatar: number;
+    /** MembershipMetadata avatarObject. */
+    public avatarObject?: (number|null);
+
+    /** MembershipMetadata avatarUri. */
+    public avatarUri?: (string|null);
 
     /** MembershipMetadata about. */
     public about: string;
 
+    /** MembershipMetadata avatar. */
+    public avatar?: ("avatarObject"|"avatarUri");
+
     /**
      * Creates a new MembershipMetadata instance using the specified properties.
      * @param [properties] Properties to set

+ 62 - 15
metadata-protobuf/compiled/index.js

@@ -1418,7 +1418,8 @@ $root.MembershipMetadata = (function() {
      * @exports IMembershipMetadata
      * @interface IMembershipMetadata
      * @property {string|null} [name] MembershipMetadata name
-     * @property {number|null} [avatar] MembershipMetadata avatar
+     * @property {number|null} [avatarObject] MembershipMetadata avatarObject
+     * @property {string|null} [avatarUri] MembershipMetadata avatarUri
      * @property {string|null} [about] MembershipMetadata about
      */
 
@@ -1446,12 +1447,20 @@ $root.MembershipMetadata = (function() {
     MembershipMetadata.prototype.name = "";
 
     /**
-     * MembershipMetadata avatar.
-     * @member {number} avatar
+     * MembershipMetadata avatarObject.
+     * @member {number|null|undefined} avatarObject
      * @memberof MembershipMetadata
      * @instance
      */
-    MembershipMetadata.prototype.avatar = 0;
+    MembershipMetadata.prototype.avatarObject = null;
+
+    /**
+     * MembershipMetadata avatarUri.
+     * @member {string|null|undefined} avatarUri
+     * @memberof MembershipMetadata
+     * @instance
+     */
+    MembershipMetadata.prototype.avatarUri = null;
 
     /**
      * MembershipMetadata about.
@@ -1461,6 +1470,20 @@ $root.MembershipMetadata = (function() {
      */
     MembershipMetadata.prototype.about = "";
 
+    // OneOf field names bound to virtual getters and setters
+    var $oneOfFields;
+
+    /**
+     * MembershipMetadata avatar.
+     * @member {"avatarObject"|"avatarUri"|undefined} avatar
+     * @memberof MembershipMetadata
+     * @instance
+     */
+    Object.defineProperty(MembershipMetadata.prototype, "avatar", {
+        get: $util.oneOfGetter($oneOfFields = ["avatarObject", "avatarUri"]),
+        set: $util.oneOfSetter($oneOfFields)
+    });
+
     /**
      * Creates a new MembershipMetadata instance using the specified properties.
      * @function create
@@ -1487,10 +1510,12 @@ $root.MembershipMetadata = (function() {
             writer = $Writer.create();
         if (message.name != null && Object.hasOwnProperty.call(message, "name"))
             writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
-        if (message.avatar != null && Object.hasOwnProperty.call(message, "avatar"))
-            writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.avatar);
+        if (message.avatarObject != null && Object.hasOwnProperty.call(message, "avatarObject"))
+            writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.avatarObject);
         if (message.about != null && Object.hasOwnProperty.call(message, "about"))
             writer.uint32(/* id 3, wireType 2 =*/26).string(message.about);
+        if (message.avatarUri != null && Object.hasOwnProperty.call(message, "avatarUri"))
+            writer.uint32(/* id 4, wireType 2 =*/34).string(message.avatarUri);
         return writer;
     };
 
@@ -1529,7 +1554,10 @@ $root.MembershipMetadata = (function() {
                 message.name = reader.string();
                 break;
             case 2:
-                message.avatar = reader.uint32();
+                message.avatarObject = reader.uint32();
+                break;
+            case 4:
+                message.avatarUri = reader.string();
                 break;
             case 3:
                 message.about = reader.string();
@@ -1569,12 +1597,22 @@ $root.MembershipMetadata = (function() {
     MembershipMetadata.verify = function verify(message) {
         if (typeof message !== "object" || message === null)
             return "object expected";
+        var properties = {};
         if (message.name != null && message.hasOwnProperty("name"))
             if (!$util.isString(message.name))
                 return "name: string expected";
-        if (message.avatar != null && message.hasOwnProperty("avatar"))
-            if (!$util.isInteger(message.avatar))
-                return "avatar: integer expected";
+        if (message.avatarObject != null && message.hasOwnProperty("avatarObject")) {
+            properties.avatar = 1;
+            if (!$util.isInteger(message.avatarObject))
+                return "avatarObject: integer expected";
+        }
+        if (message.avatarUri != null && message.hasOwnProperty("avatarUri")) {
+            if (properties.avatar === 1)
+                return "avatar: multiple values";
+            properties.avatar = 1;
+            if (!$util.isString(message.avatarUri))
+                return "avatarUri: string expected";
+        }
         if (message.about != null && message.hasOwnProperty("about"))
             if (!$util.isString(message.about))
                 return "about: string expected";
@@ -1595,8 +1633,10 @@ $root.MembershipMetadata = (function() {
         var message = new $root.MembershipMetadata();
         if (object.name != null)
             message.name = String(object.name);
-        if (object.avatar != null)
-            message.avatar = object.avatar >>> 0;
+        if (object.avatarObject != null)
+            message.avatarObject = object.avatarObject >>> 0;
+        if (object.avatarUri != null)
+            message.avatarUri = String(object.avatarUri);
         if (object.about != null)
             message.about = String(object.about);
         return message;
@@ -1617,15 +1657,22 @@ $root.MembershipMetadata = (function() {
         var object = {};
         if (options.defaults) {
             object.name = "";
-            object.avatar = 0;
             object.about = "";
         }
         if (message.name != null && message.hasOwnProperty("name"))
             object.name = message.name;
-        if (message.avatar != null && message.hasOwnProperty("avatar"))
-            object.avatar = message.avatar;
+        if (message.avatarObject != null && message.hasOwnProperty("avatarObject")) {
+            object.avatarObject = message.avatarObject;
+            if (options.oneofs)
+                object.avatar = "avatarObject";
+        }
         if (message.about != null && message.hasOwnProperty("about"))
             object.about = message.about;
+        if (message.avatarUri != null && message.hasOwnProperty("avatarUri")) {
+            object.avatarUri = message.avatarUri;
+            if (options.oneofs)
+                object.avatar = "avatarUri";
+        }
         return object;
     };
 

+ 4 - 1
metadata-protobuf/proto/Membership.proto

@@ -2,6 +2,9 @@ syntax = "proto2";
 
 message MembershipMetadata {
   optional string name = 1; // Member's real name
-  optional uint32 avatar = 2; // Member's avatar - index into external [assets array](#.Assets)
+  oneof avatar {
+    uint32 avatar_object = 2; // Member's avatar - index into external [assets array](#.Assets)
+    string avatar_uri = 4; // Url to member's avatar
+  }
   optional string about = 3; // Member's md-formatted about text
 }

+ 66 - 31
query-node/mappings/src/council.ts

@@ -1,4 +1,4 @@
-import { EventContext, StoreContext, DatabaseManager } from '@joystream/hydra-common'
+import { EventContext, StoreContext, DatabaseManager, SubstrateEvent } from '@joystream/hydra-common'
 import { CURRENT_NETWORK, deserializeMetadata, genericEventFields } from './common'
 import BN from 'bn.js'
 import { FindConditions, SelectQueryBuilder } from 'typeorm'
@@ -48,6 +48,7 @@ import {
   ElectedCouncil,
   CastVote,
   CandidacyNoteMetadata,
+  CandidacyStatus,
 
   // Misc
   Membership,
@@ -170,7 +171,7 @@ async function getAccountCastVote(
 
   if (!castVote) {
     throw new Error(
-      `No vote cast by the given account in the curent election round. accountId '${account}', cycleId '${electionRound?.cycleId}'`
+      `No vote cast by the given account in the current election round. accountId '${account}', cycleId '${electionRound?.cycleId}'`
     )
   }
 
@@ -221,12 +222,16 @@ async function updateCouncilStage(
 async function startNextElectionRound(
   store: DatabaseManager,
   electedCouncil: ElectedCouncil,
-  blockNumber: number,
+  event: SubstrateEvent,
   electionProblem?: ElectionProblem
 ): Promise<ElectionRound> {
   // finish last election round
   const lastElectionRound = await getCurrentElectionRound(store)
   lastElectionRound.isFinished = true
+  lastElectionRound.endedAtBlock = event.blockNumber
+  lastElectionRound.endedAtTime = new Date(event.blockTimestamp)
+  lastElectionRound.endedAtNetwork = CURRENT_NETWORK
+
   lastElectionRound.nextElectedCouncil = electedCouncil
 
   // save last election
@@ -248,7 +253,7 @@ async function startNextElectionRound(
 
   const stage = new CouncilStageAnnouncing()
   stage.candidatesCount = new BN(0)
-  await updateCouncilStage(store, stage, blockNumber, electionProblem)
+  await updateCouncilStage(store, stage, event.blockNumber, electionProblem)
 
   return electionRound
 }
@@ -257,14 +262,11 @@ async function startNextElectionRound(
   Converts successful council candidate records to council member records.
 */
 async function convertCandidatesToCouncilMembers(
-  store: DatabaseManager,
-  candidates: Candidate[],
+  candidates: Array<Candidate & { memberId: string }>,
   blockNumber: number
 ): Promise<CouncilMember[]> {
-  const councilMembers = await candidates.reduce(async (councilMembersPromise, candidate) => {
-    const councilMembers = await councilMembersPromise
-
-    const member = new Membership({ id: candidate.member.id.toString() })
+  return candidates.map((candidate) => {
+    const member = new Membership({ id: candidate.memberId })
 
     const councilMember = new CouncilMember({
       // id: candidate.id // TODO: are ids needed?
@@ -279,10 +281,27 @@ async function convertCandidatesToCouncilMembers(
       accumulatedReward: new BN(0),
     })
 
-    return [...councilMembers, councilMember]
-  }, Promise.resolve([] as CouncilMember[]))
+    return councilMember
+  })
+}
 
-  return councilMembers
+/**
+  Mark the candidacies as aborted when there is not enough candidates or elected councilor
+ */
+async function abortCandidacies(store: DatabaseManager) {
+  const electionRound = await getCurrentElectionRound(store)
+  const candidates = await store.getMany(Candidate, {
+    where: { electionRoundId: electionRound.id, status: CandidacyStatus.ACTIVE },
+  })
+
+  await Promise.all(
+    candidates.map((candidate) => {
+      if (candidate.status === CandidacyStatus.ACTIVE) {
+        candidate.status = CandidacyStatus.FAILED
+      }
+      return store.save<Candidate>(candidate)
+    })
+  )
 }
 
 /// /////////////// Council events /////////////////////////////////////////////
@@ -306,11 +325,11 @@ export async function council_AnnouncingPeriodStarted({ event, store }: EventCon
 
   // restart elections
   const electedCouncil = await getCurrentElectedCouncil(store)
-  await startNextElectionRound(store, electedCouncil, event.blockNumber)
+  await startNextElectionRound(store, electedCouncil, event)
 }
 
 /*
-  The event is emitted when a candidacy announcment period has ended, but not enough members announced.
+  The event is emitted when a candidacy announcement period has ended, but not enough members announced.
 */
 export async function council_NotEnoughCandidates({ event, store }: EventContext & StoreContext): Promise<void> {
   // common event processing
@@ -323,11 +342,13 @@ export async function council_NotEnoughCandidates({ event, store }: EventContext
 
   await store.save<NotEnoughCandidatesEvent>(notEnoughCandidatesEvent)
 
+  await abortCandidacies(store)
+
   // specific event processing
 
   // restart elections
   const electedCouncil = await getCurrentElectedCouncil(store)
-  await startNextElectionRound(store, electedCouncil, event.blockNumber, ElectionProblem.NOT_ENOUGH_CANDIDATES)
+  await startNextElectionRound(store, electedCouncil, event, ElectionProblem.NOT_ENOUGH_CANDIDATES)
 }
 
 /*
@@ -376,7 +397,7 @@ export async function council_NewCandidate({ event, store }: EventContext & Stor
 
   const electionRound = await getCurrentElectionRound(store)
 
-  // prepare note metadata record (empty until explicitily set via different extrinsic)
+  // prepare note metadata record (empty until explicitly set via different extrinsic)
   const noteMetadata = new CandidacyNoteMetadata({
     bulletPoints: [],
   })
@@ -387,14 +408,13 @@ export async function council_NewCandidate({ event, store }: EventContext & Stor
     stakingAccountId: stakingAccount.toString(),
     rewardAccountId: rewardAccount.toString(),
     member,
-
+    status: CandidacyStatus.ACTIVE,
     electionRound,
     stake: balance,
     stakeLocked: true,
-    candidacyWithdrawn: false,
     votePower: new BN(0),
     noteMetadata,
-    votesRecieved: [],
+    votesReceived: [],
   })
   await store.save<Candidate>(candidate)
 
@@ -422,7 +442,7 @@ export async function council_NewCouncilElected({ event, store }: EventContext &
 
   // specific event processing
 
-  // mark old council as resinged
+  // mark old council as resigned
   const oldElectedCouncil = await getCurrentElectedCouncil(store)
   oldElectedCouncil.isResigned = true
   oldElectedCouncil.endedAtBlock = event.blockNumber
@@ -432,16 +452,29 @@ export async function council_NewCouncilElected({ event, store }: EventContext &
 
   // get election round and its candidates
   const electionRound = await getCurrentElectionRound(store)
+  const candidates = (await store.getMany(Candidate, {
+    where: { electionRoundId: electionRound.id, status: CandidacyStatus.ACTIVE },
+  })) as Array<Candidate & { memberId: string }>
 
-  // TODO: uncomment when following query will be working (after some QN patches make it to Olympia)
-  // const electedCandidates = await store.getMany(Candidate, { where: { electionRoundId: electionRound.id, member: { id_in: electedMemberIds } } })
-  const electedCandidates = (
-    await store.getMany(Candidate, { where: { electionRoundId: electionRound.id }, relations: ['member'] })
-  ).filter((item: Candidate) => electedMemberIds.find((tmpId) => tmpId === item.member.id.toString()))
+  const electedCandidates = candidates.filter((candidate) => electedMemberIds.includes(candidate.memberId))
+
+  // Set elected candidates status
+  electedCandidates.forEach((candidate) => {
+    candidate.status = CandidacyStatus.ELECTED
+  })
+  // Store candidates new statuses
+  await Promise.all(
+    candidates.map((candidate) => {
+      if (candidate.status === CandidacyStatus.ACTIVE) {
+        candidate.status = CandidacyStatus.FAILED
+      }
+      return store.save<Candidate>(candidate)
+    })
+  )
 
   // create new council record
   const electedCouncil = new ElectedCouncil({
-    councilMembers: await convertCandidatesToCouncilMembers(store, electedCandidates, event.blockNumber),
+    councilMembers: await convertCandidatesToCouncilMembers(electedCandidates, event.blockNumber),
     updates: [],
     electedAtBlock: event.blockNumber,
     electedAtTime: new Date(event.blockTimestamp),
@@ -511,11 +544,13 @@ export async function council_NewCouncilNotElected({ event, store }: EventContex
 
   await store.save<NewCouncilNotElectedEvent>(newCouncilNotElectedEvent)
 
+  await abortCandidacies(store)
+
   // specific event processing
 
   // restart elections
   const electedCouncil = await getCurrentElectedCouncil(store)
-  await startNextElectionRound(store, electedCouncil, event.blockNumber, ElectionProblem.NEW_COUNCIL_NOT_ELECTED)
+  await startNextElectionRound(store, electedCouncil, event, ElectionProblem.NEW_COUNCIL_NOT_ELECTED)
 }
 
 /*
@@ -560,7 +595,7 @@ export async function council_CandidacyWithdraw({ event, store }: EventContext &
   // specific event processing
 
   // mark candidacy as withdrawn
-  candidate.candidacyWithdrawn = true
+  candidate.status = CandidacyStatus.WITHDRAWN
   await store.save<Candidate>(candidate)
 }
 
@@ -572,7 +607,7 @@ export async function council_CandidacyNoteSet({ event, store }: EventContext &
 
   const [memberId, note] = new Council.CandidacyNoteSetEvent(event).params
 
-  // load candidate recored
+  // load candidate recorded
   const electionRound = await getCurrentElectionRound(store)
   const candidate = await getCandidate(store, memberId.toString(), electionRound, ['noteMetadata'])
 
@@ -739,7 +774,7 @@ export async function council_CouncilorRewardUpdated({ event, store }: EventCont
 }
 
 /*
-  The event is emitted when funds are transfered from the council budget to an account.
+  The event is emitted when funds are transferred from the council budget to an account.
 */
 export async function council_RequestFunded({ event, store }: EventContext & StoreContext): Promise<void> {
   // common event processing

+ 13 - 4
query-node/mappings/src/membership.ts

@@ -27,6 +27,7 @@ import {
   LeaderInvitationQuotaUpdatedEvent,
   MembershipEntryPaid,
   MembershipEntryInvited,
+  AvatarUri,
 } from 'query-node/dist/model'
 
 async function getMemberById(store: DatabaseManager, id: MemberId): Promise<Membership> {
@@ -69,16 +70,19 @@ async function createNewMemberFromParams(
   params: BuyMembershipParameters | InviteMembershipParameters
 ): Promise<Membership> {
   const { defaultInviteCount } = await getLatestMembershipSystemSnapshot(store)
-  const { root_account: rootAccount, controller_account: controllerAccount, handle, metadata: metatadaBytes } = params
-  const metadata = deserializeMetadata(MembershipMetadata, metatadaBytes)
+  const { root_account: rootAccount, controller_account: controllerAccount, handle, metadata: metadataBytes } = params
+  const metadata = deserializeMetadata(MembershipMetadata, metadataBytes)
   const eventTime = new Date(event.blockTimestamp)
 
+  const avatar = new AvatarUri()
+  avatar.avatarUri = metadata?.avatarUri ?? ''
+
   const metadataEntity = new MemberMetadata({
     createdAt: eventTime,
     updatedAt: eventTime,
     name: metadata?.name || undefined,
     about: metadata?.about || undefined,
-    // TODO: avatar
+    avatar,
   })
 
   const member = new Membership({
@@ -158,7 +162,12 @@ export async function members_MemberProfileUpdated({ store, event }: EventContex
     member.metadata.about = (metadata.about || null) as string | undefined
     member.metadata.updatedAt = eventTime
   }
-  // TODO: avatar
+
+  if (typeof metadata?.avatarUri === 'string') {
+    member.metadata.avatar = new AvatarUri()
+    member.metadata.avatar.avatarUri = metadata.avatarUri
+  }
+
   if (newHandle.isSome) {
     member.handle = bytesToString(newHandle.unwrap())
     member.updatedAt = eventTime

+ 21 - 5
query-node/schemas/council.graphql

@@ -46,6 +46,13 @@ enum ElectionProblem {
   NEW_COUNCIL_NOT_ELECTED
 }
 
+enum CandidacyStatus {
+  ACTIVE
+  WITHDRAWN
+  ELECTED
+  FAILED
+}
+
 type Candidate @entity {
   "Account used for staking currency needed for the candidacy."
   stakingAccountId: String!
@@ -65,8 +72,8 @@ type Candidate @entity {
   "Reflects if the stake is still locked for candidacy or has been already released by the member."
   stakeLocked: Boolean!
 
-  "Reflects if the candidacy was withdrawn before voting started."
-  candidacyWithdrawn: Boolean!
+  "Current candidate status"
+  status: CandidacyStatus!
 
   "Sum of power of all votes received."
   votePower: BigInt!
@@ -80,8 +87,8 @@ type Candidate @entity {
   "The metadata contained in note."
   noteMetadata: CandidacyNoteMetadata!
 
-  "Votes recieved in referendums by this member."
-  votesRecieved: [CastVote!]! @derivedFrom(field: "voteFor")
+  "Votes received in referendums by this member."
+  votesReceived: [CastVote!]! @derivedFrom(field: "voteFor")
 }
 
 type CouncilMember @entity {
@@ -100,7 +107,7 @@ type CouncilMember @entity {
   "Stake used for the council membership."
   stake: BigInt!
 
-  "Block number in which council member recieved the last reward payment."
+  "Block number in which council member received the last reward payment."
   lastPaymentBlock: BigInt!
 
   "Reward amount that should have been paid but couldn't be paid off due to insufficient budget."
@@ -222,6 +229,15 @@ type ElectionRound @entity {
   "Sign if election has already finished."
   isFinished: Boolean!
 
+  "Block number at which the election ended."
+  endedAtBlock: Int
+
+  "Time at which the election ended."
+  endedAtTime: DateTime
+
+  "Network running at the time the election ended."
+  endedAtNetwork: Network
+
   "Vote cast in the election round."
   castVotes: [CastVote!]! @derivedFrom(field: "electionRound")
 

+ 16 - 16
query-node/schemas/forumEvents.graphql

@@ -1,4 +1,4 @@
-type CategoryCreatedEvent @entity {
+type CategoryCreatedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -24,7 +24,7 @@ type CategoryCreatedEvent @entity {
   # The actor is always lead
 }
 
-type CategoryArchivalStatusUpdatedEvent @entity {
+type CategoryArchivalStatusUpdatedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -54,7 +54,7 @@ type CategoryArchivalStatusUpdatedEvent @entity {
   actor: Worker!
 }
 
-type CategoryDeletedEvent @entity {
+type CategoryDeletedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -81,7 +81,7 @@ type CategoryDeletedEvent @entity {
   actor: Worker!
 }
 
-type ThreadCreatedEvent @entity {
+type ThreadCreatedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -113,7 +113,7 @@ type ThreadCreatedEvent @entity {
   # The author is already part of the Thread entity itself and is immutable
 }
 
-type ThreadModeratedEvent @entity {
+type ThreadModeratedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -143,7 +143,7 @@ type ThreadModeratedEvent @entity {
   actor: Worker!
 }
 
-type ThreadMetadataUpdatedEvent @entity {
+type ThreadMetadataUpdatedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -172,7 +172,7 @@ type ThreadMetadataUpdatedEvent @entity {
   # Only author can update the thread title, so no actor information required
 }
 
-type ThreadDeletedEvent @entity {
+type ThreadDeletedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -198,7 +198,7 @@ type ThreadDeletedEvent @entity {
   # Only author can delete the thread, so no actor information required
 }
 
-type ThreadMovedEvent @entity {
+type ThreadMovedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -231,7 +231,7 @@ type ThreadMovedEvent @entity {
   actor: Worker!
 }
 
-type PostAddedEvent @entity {
+type PostAddedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -261,7 +261,7 @@ type PostAddedEvent @entity {
   text: String!
 }
 
-type PostModeratedEvent @entity {
+type PostModeratedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -291,7 +291,7 @@ type PostModeratedEvent @entity {
   actor: Worker!
 }
 
-type PostDeletedEvent @entity {
+type PostDeletedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -321,7 +321,7 @@ type PostDeletedEvent @entity {
   rationale: String!
 }
 
-type PostTextUpdatedEvent @entity {
+type PostTextUpdatedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -365,7 +365,7 @@ type PostReactionResultInvalid @variant {
 
 union PostReactionResult = PostReactionResultCancel | PostReactionResultValid | PostReactionResultInvalid
 
-type PostReactedEvent @entity {
+type PostReactedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -395,7 +395,7 @@ type PostReactedEvent @entity {
   reactingMember: Membership!
 }
 
-type VoteOnPollEvent @entity {
+type VoteOnPollEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -422,7 +422,7 @@ type VoteOnPollEvent @entity {
   votingMember: Membership!
 }
 
-type CategoryStickyThreadUpdateEvent @entity {
+type CategoryStickyThreadUpdateEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"
@@ -452,7 +452,7 @@ type CategoryStickyThreadUpdateEvent @entity {
   actor: Worker!
 }
 
-type CategoryMembershipOfModeratorUpdatedEvent @entity {
+type CategoryMembershipOfModeratorUpdatedEvent implements Event @entity {
   ### GENERIC DATA ###
 
   "(network}-{blockNumber}-{indexInBlock}"

+ 13 - 1
query-node/schemas/membership.graphql

@@ -1,9 +1,21 @@
+type AvatarObject @variant {
+  "The avatar data object"
+  avatarObject: DataObject!
+}
+
+type AvatarUri @variant {
+  "The avatar URL"
+  avatarUri: String!
+}
+
+union Avatar = AvatarObject | AvatarUri
+
 type MemberMetadata @entity {
   "Member's name"
   name: String
 
   "Avatar data object"
-  avatar: DataObject
+  avatar: Avatar
 
   "Short text chosen by member to share information about themselves"
   about: String

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 529 - 366
tests/integration-tests/src/graphql/generated/schema.ts


Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů