Enhance activation request validation and documentation
CI / Backend (build + test) (push) Failing after 1m37s
CI / Frontend (lint + typecheck + build) (push) Successful in 44s

- Updated the `RequestActivationCommandValidator` to require a non-empty comment, ensuring that users provide necessary identification information.
- Modified integration tests to validate the new requirement for a comment, including a test for handling empty comments.
- Updated API documentation to reflect that the comment is now mandatory and clarified its purpose.
- Enhanced frontend components to enforce comment requirements and provide user guidance on the comment's importance.
This commit is contained in:
Leonid Pershin
2026-07-30 03:23:03 +03:00
parent a8358b930d
commit cc7e2a7f8f
8 changed files with 45 additions and 16 deletions
@@ -37,10 +37,13 @@ export function ActivationGate({ children }: { children: ReactNode }) {
}
if (data.isActivated) return <>{children}</>
const trimmedComment = comment.trim()
const handleSubmit = async () => {
if (!trimmedComment) return
setSubmitting(true)
try {
await requestActivation(comment.trim() || undefined)
await requestActivation(trimmedComment)
await queryClient.invalidateQueries({ queryKey: ['activation-status'] })
} catch (error) {
const message = error instanceof HttpError && error.status === 409 ? t('activation.alreadyPending') : t('auth.genericError')
@@ -66,12 +69,17 @@ export function ActivationGate({ children }: { children: ReactNode }) {
<Label htmlFor="comment">{t('activation.commentLabel')}</Label>
<textarea
id="comment"
className="min-h-24 rounded-md border border-border bg-transparent px-3 py-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-primary/50"
required
aria-required="true"
maxLength={500}
placeholder={t('activation.commentPlaceholder')}
className="min-h-24 rounded-md border border-border bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-primary/50"
value={comment}
onChange={(e) => setComment(e.target.value)}
/>
<p className="text-xs text-muted-foreground">{t('activation.commentHint')}</p>
</div>
<Button onClick={handleSubmit} disabled={submitting}>
<Button onClick={handleSubmit} disabled={submitting || !trimmedComment}>
{t('activation.submit')}
</Button>
</>
+2 -2
View File
@@ -5,6 +5,6 @@ export function getActivationStatus() {
return apiRequest<ActivationStatusDto>('/activation/status')
}
export function requestActivation(comment: string | undefined) {
return apiRequest<ActivationRequestDto>('/activation/request', { method: 'POST', body: { comment: comment ?? null } })
export function requestActivation(comment: string) {
return apiRequest<ActivationRequestDto>('/activation/request', { method: 'POST', body: { comment } })
}
+8 -4
View File
@@ -60,8 +60,10 @@ const resources = {
activation: {
title: 'Аккаунт не активирован',
description:
'Чтобы создавать конфиги, дождитесь активации администратором. Можно оставить комментарий к заявке.',
commentLabel: 'Комментарий (необязательно)',
'Чтобы создавать конфиги, дождитесь активации администратором. Обязательно напишите в комментарии, кто вы и откуда — иначе администратор не сможет вас опознать.',
commentLabel: 'Комментарий (обязательно)',
commentPlaceholder: 'Например: Никита, коллега Артёма с работы',
commentHint: 'Укажите, кто вы и откуда: имя и как связаны с администратором.',
submit: 'Запросить активацию',
pending: 'Заявка на активацию отправлена, ожидайте решения администратора.',
alreadyPending: 'У вас уже есть необработанная заявка на активацию.',
@@ -652,8 +654,10 @@ const resources = {
activation: {
title: 'Account not activated',
description:
'Wait for an administrator to activate your account before creating configs. You can leave a comment with your request.',
commentLabel: 'Comment (optional)',
'Wait for an administrator to activate your account before creating configs. You must state in the comment who you are and where you are from — otherwise the administrator cannot identify you.',
commentLabel: 'Comment (required)',
commentPlaceholder: 'For example: Nikita, Artems coworker',
commentHint: 'State who you are and where you are from: your name and how you know the administrator.',
submit: 'Request activation',
pending: 'Activation request sent, waiting for administrator review.',
alreadyPending: 'You already have a pending activation request.',