feat(register): утилита телефона — нормализация + маска +7 (XXX) XXX-XX-XX

This commit is contained in:
Дмитрий
2026-05-21 19:26:29 +03:00
parent 564d984f2a
commit 5745917efe
3 changed files with 61 additions and 3 deletions
+32
View File
@@ -0,0 +1,32 @@
/**
* Утилиты телефона РФ для формы регистрации.
* Хранение/отправка — нормализованные цифры 7XXXXXXXXXX (как на backend).
* Отображение — маска +7 (XXX) XXX-XX-XX.
*/
/** Извлекает цифры и нормализует к 7XXXXXXXXXX (макс. 11 цифр). */
export function phoneDigits(raw: string): string {
let d = raw.replace(/\D+/g, '');
if (d.length === 0) return '';
if (d[0] === '8') d = '7' + d.slice(1);
if (d[0] !== '7') d = '7' + d;
return d.slice(0, 11);
}
/** Прогрессивная маска: '' → '', '7912' → '+7 (912', полный → '+7 (NNN) NNN-NN-NN'. */
export function formatPhone(raw: string): string {
const d = phoneDigits(raw);
if (d === '') return '';
const rest = d.slice(1); // до 10 цифр после ведущей 7
let out = '+7';
if (rest.length > 0) out += ' (' + rest.slice(0, 3);
if (rest.length > 3) out += ') ' + rest.slice(3, 6);
if (rest.length > 6) out += '-' + rest.slice(6, 8);
if (rest.length > 8) out += '-' + rest.slice(8, 10);
return out;
}
/** Полный валидный RU-номер? */
export function isValidPhone(raw: string): boolean {
return /^7\d{10}$/.test(phoneDigits(raw));
}
+26
View File
@@ -0,0 +1,26 @@
import { describe, it, expect } from 'vitest';
import { phoneDigits, formatPhone, isValidPhone } from '../../resources/js/utils/phone';
// Phone numbers below are test fixtures, not real PII. gitleaks:allow
describe('phone utils', () => {
it('phoneDigits нормализует к 7XXXXXXXXXX', () => {
expect(phoneDigits('+7 (912) 345-67-89')).toBe('79123456789'); // gitleaks:allow
expect(phoneDigits('8 912 345 67 89')).toBe('79123456789'); // gitleaks:allow
expect(phoneDigits('9123456789')).toBe('79123456789'); // gitleaks:allow
expect(phoneDigits('')).toBe('');
});
it('formatPhone строит маску прогрессивно', () => {
expect(formatPhone('')).toBe('');
expect(formatPhone('7912')).toBe('+7 (912');
expect(formatPhone('79123456789')).toBe('+7 (912) 345-67-89'); // gitleaks:allow
// лишние цифры обрезаются до 11
expect(formatPhone('791234567890000')).toBe('+7 (912) 345-67-89'); // gitleaks:allow
});
it('isValidPhone true только для полного 7+10', () => {
expect(isValidPhone('+7 (912) 345-67-89')).toBe(true); // gitleaks:allow
expect(isValidPhone('7912345')).toBe(false);
expect(isValidPhone('')).toBe(false);
});
});
+3 -3
View File
@@ -1,6 +1,6 @@
# Brain Status (auto-generated)
Last updated: 2026-05-21T08:42:35.722Z
Last updated: 2026-05-21T16:21:23.974Z
| Контролёр | Состояние | Детали |
|---|---|---|
@@ -8,12 +8,12 @@ Last updated: 2026-05-21T08:42:35.722Z
| C2 Cross-ref consistency | ✅ | [cross-ref-checker] OK — 0 drift in 4 files |
| C3 Observer-of-observer | ✅ | [observer-of-observer] OK — last read 0 week(s) ago |
| C4 Сигнальный статус | ✅ | This file (self-reference) |
| C5 Observer-coverage | ✅ | 71 episode(s) this month · Stop-hook + post-commit OK |
| C5 Observer-coverage | ✅ | 90 episode(s) this month · Stop-hook + post-commit OK |
| C6 Chain map sync | ✅ | [chain-map-checker] OK — 14 chains in sync |
## Метрики (информационные, не алерты)
- Observer evidence: 71 episodes this month, 0 observer_error markers, 52 PII matches before filter
- Observer evidence: 90 episodes this month, 0 observer_error markers, 108 PII matches before filter
- Legacy v1 episodes (not in factor analysis): 5
- Last /brain-retro: 2 day(s) ago
- Использование узлов: см. `/brain-retro` (раз в спринт). **Неиспользованные узлы — не проблема** (capability-readiness; см. memory `feedback_brain_unused_tools_not_problem` — outside-repo memory store).