Skip to content

Commit

Permalink
[#1675] add type for validated metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
j-dyczka committed Aug 8, 2024
1 parent 7492ac3 commit 672d9d8
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 153 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ changes.
- Remove incorrect @value property to fix validating the metadata body [Issue 1687](https://github.com/IntersectMBO/govtool/issues/1687)
- Fix PDF not enabled in default deployments
- Fix displaying incorrect connected to Voltaire GovTool network
- Runtime error at /edit_drep when metadata incorrect [Issue 1675](https://github.com/IntersectMBO/govtool/issues/1675)

### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { postValidate } from "@services";
import { MUTATION_KEYS } from "@consts";
import { MetadataValidationDTO } from "@models";

export const useValidateMutation = () => {
export const useValidateMutation = <MetadataType>() => {
const { data, isLoading, mutateAsync } = useMutation({
mutationFn: (body: MetadataValidationDTO) => postValidate(body),
mutationFn: (body: MetadataValidationDTO) => postValidate<MetadataType>(body),
mutationKey: [MUTATION_KEYS.postValidateKey],
});

Expand Down
4 changes: 2 additions & 2 deletions govtool/frontend/src/hooks/queries/useGetDRepListQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { UseInfiniteQueryOptions, useInfiniteQuery } from "react-query";
import { QUERY_KEYS } from "@consts";
import { useCardano } from "@context";
import { GetDRepListArguments, getDRepList } from "@services";
import { InfinityDRepData } from "@/models";
import { DRepData, Infinite } from "@/models";

export const useGetDRepListInfiniteQuery = (
{
Expand All @@ -13,7 +13,7 @@ export const useGetDRepListInfiniteQuery = (
sorting,
status,
}: GetDRepListArguments,
options?: UseInfiniteQueryOptions<InfinityDRepData>,
options?: UseInfiniteQueryOptions<Infinite<DRepData>>,
) => {
const { pendingTransaction } = useCardano();

Expand Down
59 changes: 33 additions & 26 deletions govtool/frontend/src/models/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,38 +39,29 @@ export enum DRepListSort {
Status = "Status",
}

export interface DRepData {
drepId: string;
view: string;
url: string;
metadataHash: string;
export interface DrepDataDTO {
deposit: number;
votingPower: number;
drepId: string;
latestTxHash?: string;
metadataHash?: string;
status: DRepStatus;
type: "DRep" | "SoleVoter";
url?: string;
view: string;
votingPower?: number;
}

export interface DRepData extends DrepDataDTO {
bio: string | null;
dRepName: string | null;
email: string | null;
references: string[];
metadataStatus: MetadataValidationStatus | null;
metadataValid: boolean;
}
export type InfinityDRepData = {
elements: DRepData[];
page: number;
pageSize: number;
total: number;
};

export type Vote = "yes" | "no" | "abstain";

export type InfinityProposals = {
elements: ProposalData[];
page: number;
pageSize: number;
total: number;
};

type ProposalVote = {
date: string;
drepId: string;
Expand All @@ -82,30 +73,39 @@ type ProposalVote = {
vote: Vote;
};

export type ProposalData = {
export type ProposalDataDTO = {
abstainVotes: number;
createdDate: string;
createdEpochNo: number;
details?: ActionDetailsType;
expiryDate: string;
expiryEpochNo: number;
id: string;
index: number;
metadataValid: boolean;
metadataHash: string;
noVotes: number;
txHash: string;
type: string;
url: string;
yesVotes: number;
abstract?: string;
details?: ActionDetailsType;
metadataHash?: string;
metadataStatus: MetadataValidationStatus | null;
motivation?: string;
rationale?: string;
references?: string[];
title?: string;
url?: string;
};
export interface VotedProposal {

export type ProposalData = ProposalDataDTO & {
metadataStatus: MetadataValidationStatus | null;
metadataValid: boolean;
}

export type VotedProposalDTO = {
vote: ProposalVote;
proposal: ProposalDataDTO;
}

export type VotedProposal = {
vote: ProposalVote;
proposal: ProposalData;
}
Expand All @@ -115,3 +115,10 @@ export type CurrentDelegation = {
dRepView: string | null;
txHash: string | null;
} | null;

export type Infinite<T> = {
elements: T[];
page: number;
pageSize: number;
total: number;
}
20 changes: 17 additions & 3 deletions govtool/frontend/src/models/metadataValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,29 @@ export enum MetadataStandard {
CIPQQQ = "CIPQQQ",
}

export type ValidateMetadataResult = {
export type ValidateMetadataResult<MetadataType> = {
status?: MetadataValidationStatus;
valid: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
metadata?: any;
metadata?: MetadataType;
};

export type MetadataValidationDTO = {
url: string;
hash: string;
standard?: MetadataStandard;
};

export type DRepMetadata = {
bio?: string;
dRepName?: string;
email?: string;
references?: string[];
};

export type ProposalMetadata = {
abstract?: string;
motivation?: string;
rationale?: string;
references?: string[];
title?: string;
}
34 changes: 7 additions & 27 deletions govtool/frontend/src/services/requests/getDRepList.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {
type InfinityDRepData,
type Infinite,
type DRepStatus,
type DRepListSort,
MetadataStandard,
DRepData,
DrepDataDTO,
} from "@models";
import { API } from "../API";
import { postValidate } from "./metadataValidation";
import { mapDtoToDrep } from "@/utils";

export type GetDRepListArguments = {
filters?: string[];
Expand All @@ -23,8 +24,8 @@ export const getDRepList = async ({
pageSize = 10,
searchPhrase = "",
status = [],
}: GetDRepListArguments): Promise<InfinityDRepData> => {
const response = await API.get<InfinityDRepData>("/drep/list", {
}: GetDRepListArguments): Promise<Infinite<DRepData>> => {
const response = await API.get<Infinite<DrepDataDTO>>("/drep/list", {
params: {
page,
pageSize,
Expand All @@ -38,28 +39,7 @@ export const getDRepList = async ({
const validatedResponse = {
...response.data,
elements: await Promise.all(
response.data.elements.map(async (drep) => {
if (drep.metadataStatus || drep.metadataValid) {
return drep;
}
if (drep.url && drep.metadataHash) {
const validationResponse = await postValidate({
url: drep.url,
hash: drep.metadataHash,
standard: MetadataStandard.CIPQQQ,
});
return {
...drep,
bio: validationResponse.metadata?.bio,
dRepName: validationResponse.metadata?.dRepName,
email: validationResponse.metadata?.email,
references: validationResponse.metadata?.references,
metadataStatus: validationResponse.status || null,
metadataValid: validationResponse.valid,
};
}
return drep;
}),
response.data.elements.map(async (drep) => mapDtoToDrep(drep)),
),
};

Expand Down
42 changes: 8 additions & 34 deletions govtool/frontend/src/services/requests/getDRepVotes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MetadataStandard, VotedProposal } from "@models";
import { VotedProposal, VotedProposalDTO } from "@models";
import { API } from "../API";
import { postValidate } from "./metadataValidation";
import { mapDtoToProposal } from "@/utils";

type GetDRepVotesParams = {
type?: string[];
Expand All @@ -14,42 +14,16 @@ export const getDRepVotes = async ({
}: {
dRepID: string;
params: GetDRepVotesParams;
}) => {
}): Promise<VotedProposal[]> => {
const urlBase = `/drep/getVotes/${dRepID}`;

const { data } = await API.get<VotedProposal[]>(urlBase, { params });
const { data } = await API.get<VotedProposalDTO[]>(urlBase, { params });

const validatedData = await Promise.all(
data.map(async (votedProposal) => {
if (
votedProposal.proposal.metadataStatus ||
votedProposal.proposal.metadataValid
) {
return votedProposal;
}

if (votedProposal.proposal.url && votedProposal.proposal.metadataHash) {
const validationResponse = await postValidate({
url: votedProposal.proposal.url,
hash: votedProposal.proposal.metadataHash,
standard: MetadataStandard.CIP108,
});

return {
...votedProposal,
proposal: {
...votedProposal.proposal,
abstract: validationResponse.metadata?.abstract,
motivation: validationResponse.metadata?.motivation,
title: validationResponse.metadata?.title,
rationale: validationResponse.metadata?.rationale,
references: validationResponse.metadata?.references,
metadataStatus: validationResponse.status || null,
metadataValid: validationResponse.valid,
},
};
}
}),
data.map(async (votedProposal) => ({
...votedProposal,
proposal: await mapDtoToProposal(votedProposal.proposal),
}))
);

return validatedData;
Expand Down
36 changes: 7 additions & 29 deletions govtool/frontend/src/services/requests/getProposal.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,19 @@
import { MetadataStandard, VotedProposal } from "@/models";
import { VotedProposal, VotedProposalDTO } from "@/models";
import { API } from "../API";
import { postValidate } from "./metadataValidation";
import { mapDtoToProposal } from "@/utils";

export const getProposal = async (
proposalId: string,
drepId?: string,
): Promise<VotedProposal> => {
const encodedHash = encodeURIComponent(proposalId);

const { data } = await API.get<VotedProposal>(
const { data } = await API.get<VotedProposalDTO>(
`/proposal/get/${encodedHash}?drepId=${drepId}`,
);

if (data.proposal.metadataStatus || data.proposal.metadataValid) {
return data;
}
if (!data.proposal.url || !data.proposal.metadataHash) {
return data;
}

const validationResponse = await postValidate({
url: data.proposal.url,
hash: data.proposal.metadataHash,
standard: MetadataStandard.CIP108,
});

return {
...data,
proposal: {
...data.proposal,
title: validationResponse.metadata?.title,
abstract: validationResponse.metadata?.abstract,
motivation: validationResponse.metadata?.motivation,
rationale: validationResponse.metadata?.rationale,
references: validationResponse.metadata?.references,
metadataStatus: validationResponse.status || null,
metadataValid: validationResponse.valid,
},
};
return {
...data,
proposal: await mapDtoToProposal(data.proposal),
};
};
34 changes: 6 additions & 28 deletions govtool/frontend/src/services/requests/getProposals.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { InfinityProposals, MetadataStandard } from "@models";
import { Infinite, ProposalData, ProposalDataDTO } from "@models";

import { postValidate } from "./metadataValidation";
import { API } from "../API";
import { mapDtoToProposal } from "@/utils";

export type GetProposalsArguments = {
dRepID?: string;
Expand All @@ -20,8 +20,8 @@ export const getProposals = async ({
pageSize = 7,
searchPhrase = "",
sorting = "",
}: GetProposalsArguments): Promise<InfinityProposals> => {
const response = await API.get<InfinityProposals>("/proposal/list", {
}: GetProposalsArguments): Promise<Infinite<ProposalData>> => {
const response = await API.get<Infinite<ProposalDataDTO>>("/proposal/list", {
params: {
page,
pageSize,
Expand All @@ -35,31 +35,9 @@ export const getProposals = async ({
const validatedResponse = {
...response.data,
elements: await Promise.all(
response.data.elements.map(async (proposal) => {
if (proposal.metadataStatus || proposal.metadataValid) {
return proposal;
}
if (proposal.url && proposal.metadataHash) {
const validationResponse = await postValidate({
url: proposal.url,
hash: proposal.metadataHash,
standard: MetadataStandard.CIP108,
});
return {
...proposal,
abstract: validationResponse.metadata?.abstract,
motivation: validationResponse.metadata?.motivation,
title: validationResponse.metadata?.title,
rationale: validationResponse.metadata?.rationale,
references: validationResponse.metadata?.references,
metadataStatus: validationResponse.status || null,
metadataValid: validationResponse.valid,
};
}

return proposal;
}),
response.data.elements.map((proposalDTO) => mapDtoToProposal(proposalDTO)),
),
};

return validatedResponse;
};
Loading

0 comments on commit 672d9d8

Please sign in to comment.