Merge pull request '[reg-fsm] Откат незавершённой регистрации + server-truth шаг (recovery, plan B)' (#95) from feat/registration-fsm into feat/registration-payment-decline
Reviewed-on: #95 Reviewed-by: Алексей Муравьев <chairman.voskhod@gmail.com>
This commit was merged in pull request #95.
This commit is contained in:
@@ -39,6 +39,7 @@ import { CANDIDATE_REPOSITORY, CandidateRepository } from '~/domain/account/repo
|
||||
import { userStatus } from '~/types/user.types';
|
||||
import { PAYMENT_REPOSITORY, PaymentRepository } from '~/domain/gateway/repositories/payment.repository';
|
||||
import { PaymentTypeEnum } from '~/domain/gateway/enums/payment-type.enum';
|
||||
import { PaymentStatusEnum } from '~/domain/gateway/enums/payment-status.enum';
|
||||
import { CandidateStatus } from '~/domain/registration/enum';
|
||||
import { sha256 } from '~/utils/sha256';
|
||||
import { registrationProfileFingerprint } from '~/utils/registration-profile-fingerprint';
|
||||
@@ -377,6 +378,87 @@ export class AccountInteractor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Откат регистрации к редактированию данных (recovery drift/decline).
|
||||
*
|
||||
* Применим ТОЛЬКО до создания аккаунта в блокчейне: после reguser username
|
||||
* необратимо занят, и нужна перерегистрация — это отдельная ветка. Здесь же,
|
||||
* пока аккаунта в цепи нет, безопасно вернуть пайщика к началу:
|
||||
* - снимаем заморозку профиля и e-mail (users.status → created);
|
||||
* - сбрасываем кандидата (документы и отпечаток заявления), чтобы заявление
|
||||
* пришлось переподписать под актуальные данные;
|
||||
* - удаляем непринятую попытку регистрационного платежа, чтобы экран
|
||||
* ожидания не показывал старый отказ.
|
||||
*
|
||||
* Если средства уже приняты (PAID/COMPLETED) — откат запрещён: нужен возврат
|
||||
* средств (отдельная ветка refund).
|
||||
*/
|
||||
async resetRegistration(username: string): Promise<AccountDomainEntity> {
|
||||
const user = await this.userDomainService.getUserByUsername(username);
|
||||
if (!user) {
|
||||
throw new HttpApiError(HttpStatus.NOT_FOUND, `Пользователь ${username} не найден`);
|
||||
}
|
||||
|
||||
// Аккаунт уже в блокчейне → откат к редактированию невозможен (username
|
||||
// занят необратимо).
|
||||
const blockchainAccount = await this.accountDomainService.getBlockchainAccount(username);
|
||||
if (
|
||||
blockchainAccount ||
|
||||
user.status === userStatus['4_Registered'] ||
|
||||
user.status === userStatus['5_Active']
|
||||
) {
|
||||
throw new HttpApiError(
|
||||
HttpStatus.BAD_REQUEST,
|
||||
'Регистрация уже отправлена в блокчейн — откат к редактированию невозможен, требуется перерегистрация.'
|
||||
);
|
||||
}
|
||||
|
||||
// Регистрационный платёж: принятые средства откатывать нельзя (нужен возврат).
|
||||
const payment = await this.paymentRepository.findLatestByUsernameAndType(
|
||||
username,
|
||||
PaymentTypeEnum.REGISTRATION
|
||||
);
|
||||
if (payment) {
|
||||
if (payment.status === PaymentStatusEnum.PAID || payment.status === PaymentStatusEnum.COMPLETED) {
|
||||
throw new HttpApiError(
|
||||
HttpStatus.BAD_REQUEST,
|
||||
'Вступительный взнос уже принят — для отката требуется возврат средств.'
|
||||
);
|
||||
}
|
||||
if (payment.id) {
|
||||
await this.paymentRepository.delete(payment.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Кандидат: чистим документы и отпечаток заявления (потребуется переподпись).
|
||||
const candidate = await this.candidateRepository.findByUsername(username);
|
||||
if (candidate) {
|
||||
let candidateMeta: Record<string, any> = {};
|
||||
try {
|
||||
candidateMeta = candidate.meta ? JSON.parse(candidate.meta) : {};
|
||||
} catch {
|
||||
candidateMeta = {};
|
||||
}
|
||||
delete candidateMeta.registration_profile_fingerprint;
|
||||
await this.candidateRepository.update(username, {
|
||||
status: CandidateStatus.PENDING,
|
||||
documents: {},
|
||||
meta: JSON.stringify(candidateMeta),
|
||||
});
|
||||
}
|
||||
|
||||
// Снимаем заморозку: профиль и e-mail снова можно менять.
|
||||
await this.userDomainService.updateUserByUsername(username, {
|
||||
status: userStatus['1_Created'],
|
||||
is_registered: false,
|
||||
has_account: false,
|
||||
});
|
||||
|
||||
this.logger.log(`Регистрация ${username} откатана к редактированию данных`);
|
||||
|
||||
return await this.accountDomainService.getAccount(username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск приватных аккаунтов по запросу
|
||||
* @param input Входные данные для поиска
|
||||
|
||||
@@ -14,6 +14,8 @@ import { RegisteredAccountDTO } from '../dto/registered-account.dto';
|
||||
import { UpdateAccountInputDTO } from '../dto/update-account-input.dto';
|
||||
import { SearchPrivateAccountsInputDTO } from '../dto/search-private-accounts-input.dto';
|
||||
import { PrivateAccountSearchResultDTO } from '../dto/search-private-accounts-result.dto';
|
||||
import { CurrentUser } from '~/application/auth/decorators/current-user.decorator';
|
||||
import { MonoAccountDomainInterface } from '~/domain/account/interfaces/mono-account-domain.interface';
|
||||
|
||||
export const AccountsPaginationResult = createPaginationResult(AccountDTO, 'Accounts');
|
||||
|
||||
@@ -84,6 +86,16 @@ export class AccountResolver {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
@Mutation(() => AccountDTO, {
|
||||
name: 'resetRegistration',
|
||||
description:
|
||||
'Откатить собственную незавершённую регистрацию к редактированию данных: снимает заморозку профиля и e-mail, сбрасывает подписанное заявление и непринятую попытку вступительного платежа. Доступно только до отправки регистрации в блокчейн; если взнос уже принят — требуется возврат средств.',
|
||||
})
|
||||
@UseGuards(GqlJwtAuthGuard)
|
||||
async resetRegistration(@CurrentUser() currentUser: MonoAccountDomainInterface): Promise<AccountDTO> {
|
||||
return await this.accountService.resetRegistration(currentUser.username);
|
||||
}
|
||||
|
||||
@Mutation(() => AccountDTO, {
|
||||
name: 'updateAccount',
|
||||
description:
|
||||
|
||||
@@ -30,6 +30,12 @@ export class AccountService {
|
||||
return new AccountDTO(account);
|
||||
}
|
||||
|
||||
public async resetRegistration(username: string): Promise<AccountDTO> {
|
||||
const account = await this.accountInteractor.resetRegistration(username);
|
||||
|
||||
return new AccountDTO(account);
|
||||
}
|
||||
|
||||
public async getAccounts(
|
||||
data?: GetAccountsInputDTO,
|
||||
options?: PaginationInputDTO
|
||||
|
||||
@@ -11,6 +11,7 @@ export interface PaymentRepository {
|
||||
// Общие методы
|
||||
findById(id: string): Promise<PaymentDomainInterface | null>;
|
||||
findByHash(hash: string): Promise<PaymentDomainInterface | null>;
|
||||
delete(id: string): Promise<boolean>;
|
||||
create(data: PaymentDomainInterface): Promise<PaymentDomainInterface>;
|
||||
update(id: string, data: Partial<PaymentDomainInterface>): Promise<PaymentDomainInterface | null>;
|
||||
|
||||
|
||||
+5
@@ -31,6 +31,11 @@ export class TypeOrmPaymentRepository implements PaymentRepository {
|
||||
return this.mapToDomainEntity(payment);
|
||||
}
|
||||
|
||||
async delete(id: string): Promise<boolean> {
|
||||
const result = await this.paymentRepository.delete({ id });
|
||||
return (result.affected ?? 0) > 0;
|
||||
}
|
||||
|
||||
async create(data: PaymentDomainInterface): Promise<PaymentDomainInterface> {
|
||||
const payment = new PaymentEntity();
|
||||
payment.hash = data.hash;
|
||||
|
||||
@@ -3667,6 +3667,7 @@ export const ReturnTypes: Record<string,any> = {
|
||||
registerAccount:"RegisteredAccount",
|
||||
registerParticipant:"Account",
|
||||
resetKey:"Boolean",
|
||||
resetRegistration:"Account",
|
||||
restartAnnualGeneralMeet:"MeetAggregate",
|
||||
saveReportDraft:"ReportDraft",
|
||||
selectBranch:"Boolean",
|
||||
|
||||
@@ -6584,6 +6584,8 @@ refresh?: [{ data: ValueTypes["RefreshInput"] | Variable<any, string>},ValueType
|
||||
registerAccount?: [{ data: ValueTypes["RegisterAccountInput"] | Variable<any, string>},ValueTypes["RegisteredAccount"]],
|
||||
registerParticipant?: [{ data: ValueTypes["RegisterParticipantInput"] | Variable<any, string>},ValueTypes["Account"]],
|
||||
resetKey?: [{ data: ValueTypes["ResetKeyInput"] | Variable<any, string>},boolean | `@${string}`],
|
||||
/** Откатить собственную незавершённую регистрацию к редактированию данных: снимает заморозку профиля и e-mail, сбрасывает подписанное заявление и непринятую попытку вступительного платежа. Доступно только до отправки регистрации в блокчейн; если взнос уже принят — требуется возврат средств. */
|
||||
resetRegistration?:ValueTypes["Account"],
|
||||
restartAnnualGeneralMeet?: [{ data: ValueTypes["RestartAnnualGeneralMeetInput"] | Variable<any, string>},ValueTypes["MeetAggregate"]],
|
||||
saveReportDraft?: [{ input: ValueTypes["SaveReportDraftInput"] | Variable<any, string>},ValueTypes["ReportDraft"]],
|
||||
selectBranch?: [{ data: ValueTypes["SelectBranchInput"] | Variable<any, string>},boolean | `@${string}`],
|
||||
@@ -14942,6 +14944,8 @@ refresh?: [{ data: ResolverInputTypes["RefreshInput"]},ResolverInputTypes["Regis
|
||||
registerAccount?: [{ data: ResolverInputTypes["RegisterAccountInput"]},ResolverInputTypes["RegisteredAccount"]],
|
||||
registerParticipant?: [{ data: ResolverInputTypes["RegisterParticipantInput"]},ResolverInputTypes["Account"]],
|
||||
resetKey?: [{ data: ResolverInputTypes["ResetKeyInput"]},boolean | `@${string}`],
|
||||
/** Откатить собственную незавершённую регистрацию к редактированию данных: снимает заморозку профиля и e-mail, сбрасывает подписанное заявление и непринятую попытку вступительного платежа. Доступно только до отправки регистрации в блокчейн; если взнос уже принят — требуется возврат средств. */
|
||||
resetRegistration?:ResolverInputTypes["Account"],
|
||||
restartAnnualGeneralMeet?: [{ data: ResolverInputTypes["RestartAnnualGeneralMeetInput"]},ResolverInputTypes["MeetAggregate"]],
|
||||
saveReportDraft?: [{ input: ResolverInputTypes["SaveReportDraftInput"]},ResolverInputTypes["ReportDraft"]],
|
||||
selectBranch?: [{ data: ResolverInputTypes["SelectBranchInput"]},boolean | `@${string}`],
|
||||
@@ -23473,6 +23477,8 @@ export type ModelTypes = {
|
||||
registerParticipant: ModelTypes["Account"],
|
||||
/** Заменить приватный ключ аккаунта */
|
||||
resetKey: boolean,
|
||||
/** Откатить собственную незавершённую регистрацию к редактированию данных: снимает заморозку профиля и e-mail, сбрасывает подписанное заявление и непринятую попытку вступительного платежа. Доступно только до отправки регистрации в блокчейн; если взнос уже принят — требуется возврат средств. */
|
||||
resetRegistration: ModelTypes["Account"],
|
||||
/** Перезапуск общего собрания пайщиков
|
||||
|
||||
Требуемые роли: chairman. */
|
||||
@@ -32418,6 +32424,8 @@ export type GraphQLTypes = {
|
||||
registerParticipant: GraphQLTypes["Account"],
|
||||
/** Заменить приватный ключ аккаунта */
|
||||
resetKey: boolean,
|
||||
/** Откатить собственную незавершённую регистрацию к редактированию данных: снимает заморозку профиля и e-mail, сбрасывает подписанное заявление и непринятую попытку вступительного платежа. Доступно только до отправки регистрации в блокчейн; если взнос уже принят — требуется возврат средств. */
|
||||
resetRegistration: GraphQLTypes["Account"],
|
||||
/** Перезапуск общего собрания пайщиков
|
||||
|
||||
Требуемые роли: chairman. */
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { client } from 'src/shared/api/client'
|
||||
import { Mutations } from '@coopenomics/sdk'
|
||||
|
||||
async function resetRegistration(): Promise<
|
||||
Mutations.Accounts.ResetRegistration.IOutput[typeof Mutations.Accounts.ResetRegistration.name]
|
||||
> {
|
||||
const { [Mutations.Accounts.ResetRegistration.name]: result } = await client.Mutation(
|
||||
Mutations.Accounts.ResetRegistration.mutation,
|
||||
{}
|
||||
)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export const api = {
|
||||
resetRegistration,
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './model'
|
||||
@@ -0,0 +1,13 @@
|
||||
import { api } from '../api'
|
||||
import { IAccount } from 'src/entities/Account/types';
|
||||
|
||||
export function useResetRegistration() {
|
||||
// Откат собственной незавершённой регистрации к редактированию данных.
|
||||
// Бэкенд снимает заморозку профиля/e-mail, сбрасывает подписанное заявление
|
||||
// и непринятый вступительный платёж. Возвращает обновлённый аккаунт.
|
||||
async function resetRegistration(): Promise<IAccount> {
|
||||
return await api.resetRegistration();
|
||||
}
|
||||
|
||||
return { resetRegistration };
|
||||
}
|
||||
@@ -20,7 +20,7 @@ q-step(
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, watch, ref } from 'vue';
|
||||
import { computed, watch, ref, onBeforeUnmount } from 'vue';
|
||||
import { useCreateUser } from 'src/features/User/CreateUser';
|
||||
import { FailAlert } from 'src/shared/api';
|
||||
import { useSystemStore } from 'src/entities/System/model';
|
||||
@@ -28,16 +28,51 @@ const { info } = useSystemStore();
|
||||
|
||||
import { useCooperativeStore } from 'src/entities/Cooperative';
|
||||
import { useRegistratorStore } from 'src/entities/Registrator';
|
||||
import { useSessionStore } from 'src/entities/Session';
|
||||
import { useAccountStore } from 'src/entities/Account';
|
||||
import { PayWithProvider } from 'src/shared/ui/PayWithProvider';
|
||||
import { Loader } from 'src/shared/ui/Loader';
|
||||
import { Zeus } from '@coopenomics/sdk';
|
||||
|
||||
const store = useRegistratorStore();
|
||||
const api = useCreateUser();
|
||||
const session = useSessionStore();
|
||||
const accountStore = useAccountStore();
|
||||
|
||||
const step = computed(() => store.state.step);
|
||||
const coop = useCooperativeStore();
|
||||
const isCreatingPayment = ref(false);
|
||||
|
||||
// Поллинг приёма оплаты. Провайдер QR (Bank) не эмитит success-колбэк, а деньги
|
||||
// подтверждаются вебхуком на бэке асинхронно — без поллинга экран висит на форме
|
||||
// оплаты до перезагрузки. Каждые 10с подтягиваем аккаунт; как только вступительный
|
||||
// платёж покинул статус PENDING (принят/отклонён) — уходим на шаг ожидания решения
|
||||
// совета, который сам показывает «платёж принят» либо причину отказа.
|
||||
const pollInterval = ref();
|
||||
|
||||
const POLL_TERMINAL_STATUSES = [
|
||||
Zeus.PaymentStatus.PAID,
|
||||
Zeus.PaymentStatus.COMPLETED,
|
||||
Zeus.PaymentStatus.CANCELLED,
|
||||
Zeus.PaymentStatus.EXPIRED,
|
||||
Zeus.PaymentStatus.FAILED,
|
||||
];
|
||||
|
||||
const pollPaymentStatus = async () => {
|
||||
if (!session.username) return;
|
||||
try {
|
||||
const account = await accountStore.getAccount(session.username);
|
||||
session.setCurrentUserAccount(account);
|
||||
const status = session.registrationPayment?.status;
|
||||
if (status && POLL_TERMINAL_STATUSES.includes(status)) {
|
||||
clearInterval(pollInterval.value);
|
||||
store.goTo('WaitingRegistration');
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Ошибка опроса статуса оплаты:', e);
|
||||
}
|
||||
};
|
||||
|
||||
// Computed property для payment с правильной типизацией
|
||||
const payment = computed(() => store.state.payment);
|
||||
|
||||
@@ -67,9 +102,19 @@ const createInitialPayment = async () => {
|
||||
|
||||
// Используем только watch с immediate: true вместо onMounted + watch
|
||||
watch(step, (newValue) => {
|
||||
if (newValue === currentStep) createInitialPayment();
|
||||
if (newValue === currentStep) {
|
||||
createInitialPayment();
|
||||
clearInterval(pollInterval.value);
|
||||
pollInterval.value = setInterval(() => pollPaymentStatus(), 10000);
|
||||
} else {
|
||||
clearInterval(pollInterval.value);
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
clearInterval(pollInterval.value);
|
||||
});
|
||||
|
||||
watch(
|
||||
() => store.state.is_paid,
|
||||
(newValue) => {
|
||||
|
||||
@@ -85,10 +85,19 @@ onMounted(() => {
|
||||
// Есть незавершённый вступительный платёж (ожидание подтверждения денег или
|
||||
// отклонение председателем) — восстанавливаем экран ожидания/отказа даже
|
||||
// после перезагрузки и в любой вкладке. Процесс может тянуться днями.
|
||||
// Приоритет над статусом: при отказе платежа показываем причину, а не гоним
|
||||
// «оплатить заново».
|
||||
if (session.registrationPayment) {
|
||||
store.step = steps.WaitingRegistration;
|
||||
return;
|
||||
}
|
||||
// Сервер — источник истины о шаге: заявление уже подписано (Joined), но
|
||||
// оплаты ещё нет → возвращаем на шаг оплаты. Так процесс переживает
|
||||
// перезагрузку и открытие в другой вкладке, не завися от localStorage.
|
||||
if (userStatus === Zeus.UserStatus.Joined) {
|
||||
store.step = steps.PayInitial;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ div
|
||||
p.q-mt-xs.q-mb-none(v-if='declineMessage') Причина: {{ declineMessage }}
|
||||
p.q-mt-xs.q-mb-none(v-else) Председатель отклонил поступление взноса. Вы можете повторить оплату или поправить данные и подать заявку снова.
|
||||
.row.q-gutter-sm
|
||||
BaseButton(variant='primary', @click='retryPayment') Повторить оплату
|
||||
BaseButton(variant='secondary', @click='fixData') Исправить данные
|
||||
BaseButton(variant='primary', @click='retryPayment', :disable='isResetting') Повторить оплату
|
||||
BaseButton(variant='secondary', @click='fixData', :loading='isResetting') Исправить данные
|
||||
//- Техническая ошибка обработки — направляем в поддержку.
|
||||
template(v-else-if='isFailed')
|
||||
p Произошла ошибка при регистрации. Пожалуйста, обратитесь в поддержку для устранения проблемы.
|
||||
@@ -33,10 +33,14 @@ import { Loader } from 'src/shared/ui/Loader';
|
||||
import { BaseBanner, BaseButton } from 'src/shared/ui/base';
|
||||
import { useRegistratorStore } from 'src/entities/Registrator';
|
||||
import { Zeus } from '@coopenomics/sdk';
|
||||
import { useResetRegistration } from 'src/features/Account/ResetRegistration';
|
||||
import { FailAlert } from 'src/shared/api';
|
||||
|
||||
const store = useRegistratorStore();
|
||||
const session = useSessionStore();
|
||||
const accountStore = useAccountStore();
|
||||
const { resetRegistration } = useResetRegistration();
|
||||
const isResetting = ref(false);
|
||||
|
||||
const currentStep = store.steps.WaitingRegistration;
|
||||
const step = computed(() => store.state.step);
|
||||
@@ -67,10 +71,24 @@ const retryPayment = () => {
|
||||
store.goTo('PayInitial');
|
||||
};
|
||||
|
||||
const fixData = () => {
|
||||
store.state.is_paid = false;
|
||||
store.state.payment = null;
|
||||
store.goTo('SetUserData');
|
||||
// «Исправить данные» = откат регистрации на бэкенде: после подписи заявления
|
||||
// профиль и e-mail заморожены (users.status=joined), локального возврата мало —
|
||||
// сервер снимает заморозку, сбрасывает заявление и непринятый платёж. Только
|
||||
// после этого возвращаем пайщика к редактированию данных.
|
||||
const fixData = async () => {
|
||||
isResetting.value = true;
|
||||
try {
|
||||
const account = await resetRegistration();
|
||||
session.setCurrentUserAccount(account);
|
||||
store.state.is_paid = false;
|
||||
store.state.payment = null;
|
||||
store.state.signature = '';
|
||||
store.goTo('SetUserData');
|
||||
} catch (e: any) {
|
||||
FailAlert(`Не удалось вернуться к редактированию: ${e.message}`);
|
||||
} finally {
|
||||
isResetting.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Опрос аккаунта: пока пайщик ждёт, подтягиваем актуальный статус платежа и
|
||||
|
||||
@@ -59,3 +59,6 @@ export * as StartResetKey from './startResetKey'
|
||||
|
||||
/** Обновить аккаунт в системе провайдера. Обновление аккаунта пользователя производится по username. Мутация позволяет изменить приватные данные пользователя, а также, адрес электронной почты в MONO. Использовать мутацию может только председатель совета. */
|
||||
export * as UpdateAccount from './updateAccount'
|
||||
|
||||
/** Откатить собственную незавершённую регистрацию к редактированию данных (снимает заморозку профиля/e-mail, сбрасывает заявление и непринятый вступительный платёж). Доступно до отправки регистрации в блокчейн. */
|
||||
export * as ResetRegistration from './resetRegistration'
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { accountSelector } from '../../selectors'
|
||||
import { type GraphQLTypes, type InputType, Selector } from '../../zeus/index'
|
||||
|
||||
export const name = 'resetRegistration'
|
||||
|
||||
// Мутация без аргументов: бэкенд берёт пайщика из токена (self-scoped),
|
||||
// откатывая его собственную незавершённую регистрацию к редактированию данных.
|
||||
export const mutation = Selector('Mutation')({
|
||||
[name]: accountSelector,
|
||||
})
|
||||
|
||||
export type IOutput = InputType<GraphQLTypes['Mutation'], typeof mutation>
|
||||
@@ -3667,6 +3667,7 @@ export const ReturnTypes: Record<string,any> = {
|
||||
registerAccount:"RegisteredAccount",
|
||||
registerParticipant:"Account",
|
||||
resetKey:"Boolean",
|
||||
resetRegistration:"Account",
|
||||
restartAnnualGeneralMeet:"MeetAggregate",
|
||||
saveReportDraft:"ReportDraft",
|
||||
selectBranch:"Boolean",
|
||||
|
||||
@@ -6584,6 +6584,8 @@ refresh?: [{ data: ValueTypes["RefreshInput"] | Variable<any, string>},ValueType
|
||||
registerAccount?: [{ data: ValueTypes["RegisterAccountInput"] | Variable<any, string>},ValueTypes["RegisteredAccount"]],
|
||||
registerParticipant?: [{ data: ValueTypes["RegisterParticipantInput"] | Variable<any, string>},ValueTypes["Account"]],
|
||||
resetKey?: [{ data: ValueTypes["ResetKeyInput"] | Variable<any, string>},boolean | `@${string}`],
|
||||
/** Откатить собственную незавершённую регистрацию к редактированию данных: снимает заморозку профиля и e-mail, сбрасывает подписанное заявление и непринятую попытку вступительного платежа. Доступно только до отправки регистрации в блокчейн; если взнос уже принят — требуется возврат средств. */
|
||||
resetRegistration?:ValueTypes["Account"],
|
||||
restartAnnualGeneralMeet?: [{ data: ValueTypes["RestartAnnualGeneralMeetInput"] | Variable<any, string>},ValueTypes["MeetAggregate"]],
|
||||
saveReportDraft?: [{ input: ValueTypes["SaveReportDraftInput"] | Variable<any, string>},ValueTypes["ReportDraft"]],
|
||||
selectBranch?: [{ data: ValueTypes["SelectBranchInput"] | Variable<any, string>},boolean | `@${string}`],
|
||||
@@ -14942,6 +14944,8 @@ refresh?: [{ data: ResolverInputTypes["RefreshInput"]},ResolverInputTypes["Regis
|
||||
registerAccount?: [{ data: ResolverInputTypes["RegisterAccountInput"]},ResolverInputTypes["RegisteredAccount"]],
|
||||
registerParticipant?: [{ data: ResolverInputTypes["RegisterParticipantInput"]},ResolverInputTypes["Account"]],
|
||||
resetKey?: [{ data: ResolverInputTypes["ResetKeyInput"]},boolean | `@${string}`],
|
||||
/** Откатить собственную незавершённую регистрацию к редактированию данных: снимает заморозку профиля и e-mail, сбрасывает подписанное заявление и непринятую попытку вступительного платежа. Доступно только до отправки регистрации в блокчейн; если взнос уже принят — требуется возврат средств. */
|
||||
resetRegistration?:ResolverInputTypes["Account"],
|
||||
restartAnnualGeneralMeet?: [{ data: ResolverInputTypes["RestartAnnualGeneralMeetInput"]},ResolverInputTypes["MeetAggregate"]],
|
||||
saveReportDraft?: [{ input: ResolverInputTypes["SaveReportDraftInput"]},ResolverInputTypes["ReportDraft"]],
|
||||
selectBranch?: [{ data: ResolverInputTypes["SelectBranchInput"]},boolean | `@${string}`],
|
||||
@@ -23473,6 +23477,8 @@ export type ModelTypes = {
|
||||
registerParticipant: ModelTypes["Account"],
|
||||
/** Заменить приватный ключ аккаунта */
|
||||
resetKey: boolean,
|
||||
/** Откатить собственную незавершённую регистрацию к редактированию данных: снимает заморозку профиля и e-mail, сбрасывает подписанное заявление и непринятую попытку вступительного платежа. Доступно только до отправки регистрации в блокчейн; если взнос уже принят — требуется возврат средств. */
|
||||
resetRegistration: ModelTypes["Account"],
|
||||
/** Перезапуск общего собрания пайщиков
|
||||
|
||||
Требуемые роли: chairman. */
|
||||
@@ -32418,6 +32424,8 @@ export type GraphQLTypes = {
|
||||
registerParticipant: GraphQLTypes["Account"],
|
||||
/** Заменить приватный ключ аккаунта */
|
||||
resetKey: boolean,
|
||||
/** Откатить собственную незавершённую регистрацию к редактированию данных: снимает заморозку профиля и e-mail, сбрасывает подписанное заявление и непринятую попытку вступительного платежа. Доступно только до отправки регистрации в блокчейн; если взнос уже принят — требуется возврат средств. */
|
||||
resetRegistration: GraphQLTypes["Account"],
|
||||
/** Перезапуск общего собрания пайщиков
|
||||
|
||||
Требуемые роли: chairman. */
|
||||
|
||||
Reference in New Issue
Block a user