Π‘ΠΈΡΡΠ΅ΠΌΠ½ΠΎΠ΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅. Π Π°Π·ΡΠ°Π±ΠΎΡΠΊΠ° Ρ Π½ΡΠ»Ρ. Π€ΠΎΡΠΌΠ°Ρ: ΡΠ΄Π°Π»ΡΠ½Π½ΠΎ, ΡΠ°ΡΡΠΈΡΠ½Π°Ρ ΠΈΠ»ΠΈ ΠΏΠΎΠ»Π½Π°Ρ Π·Π°Π½ΡΡΠΎΡΡΡ ΠΠΎΠ³ΠΎΠ²ΠΎΡ: ΠΠ ΠΈΠ»ΠΈ ΡΠ°ΠΌΠΎΠ·Π°Π½ΡΡΡΠΉ (Π‘ΠΠ/ΠΠΠ) ΠΠΏΠ»Π°ΡΠ°: ΠΏΠΎΡΠ°ΡΠΎΠ²Π°Ρ, ΠΊΠ°Π½Π΄ΠΈΠ΄Π°Ρ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΡΠ²ΠΎΡ ΡΡΠ°Π²ΠΊΡ ΠΏΡΠΈ ΠΎΡΠΊΠ»ΠΈΠΊΠ΅ ΠΠ½ΡΠ΅ΡΠ²ΡΡ: 30-ΠΌΠΈΠ½ΡΡΠ½ΡΠΉ ΡΠ΅Ρ
Π½ΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΠΎΠ·Π²ΠΎΠ½ (ΡΠ°Π·Π±ΠΎΡ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΡ ΠΈ ΠΊΠΎΠ΄Π°) ΠΡΠΎΠ΅ΠΊΡ ΠΠ΅Π»Π°Π΅ΠΌ ΠΌΠΎΠ΄ΡΠ»Ρ ΠΌΠ°ΡΡΠΎΠ²ΠΎΠ³ΠΎ ΠΈΠΌΠΏΠΎΡΡΠ° ΡΡΠ΅Π½ΠΈΠΊΠΎΠ² Π² Π°Π΄ΠΌΠΈΠ½-ΠΏΠ°Π½Π΅Π»ΠΈ: Π·Π°Π³ΡΡΠ·ΠΊΠ° .xlsx, Π°ΡΠΈΠ½Ρ
ΡΠΎΠ½Π½Π°Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π² ΡΠΎΠ½Π΅, ΡΡΠ°ΡΡΡ/Π»ΠΎΠ³ Π² ΡΠ΅Π°Π»ΡΠ½ΠΎΠΌ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, ΠΎΡΡΡΡΡ ΠΎΠ± ΠΎΡΠΈΠ±ΠΊΠ°Ρ
ΠΈ ΠΏΠΎΠ²ΡΠΎΡΠ½ΡΠΉ ΠΈΠΌΠΏΠΎΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ½ΡΡ
ΡΡΡΠΎΠΊ. Π’ΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ ΠΏΠΎ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ, Π½Π°Π΄ΡΠΆΠ½ΠΎΡΡΠΈ ΠΈ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ ΡΠΆΠ΅ ΠΎΠΏΠΈΡΠ°Π½Ρ Π² BRD. ΠΡΠ½ΠΎΠ²Π½ΡΠ΅ Π·Π°Π΄Π°ΡΠΈ ΠΡΠΊΠ΅Π½Π΄ (NestJS, TypeScript) REST API Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ°/ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³Π° Import Job, WS Π΄Π»Ρ ΠΏΡΠΎΠ³ΡΠ΅ΡΡΠ°. ΠΡΠ΅ΡΠ΅Π΄Ρ ΡΠΎΠ½ΠΎΠ²ΠΎΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ (BullMQ/RabbitMQ/Kafka) Ρ ΡΠ΅ΡΡΠ°ΡΠΌΠΈ ΠΈ ΠΈΠ΄Π΅ΠΌΠΏΠΎΡΠ΅Π½ΡΠ½ΠΎΡΡΡΡ. ΠΠ°Π»ΠΈΠ΄Π°ΡΠΈΠΈ ΠΈ Π½ΠΎΡΠΌΠ°Π»ΠΈΠ·Π°ΡΠΈΡ Π΄Π°Π½Π½ΡΡ
(Π΄Π°ΡΡ, ΠΏΠΎΠ», Π‘ΠΠΠΠ‘, ΠΊΠΎΠ½ΡΠ°ΠΊΡΡ). ΠΠΎΠ»ΠΈΡΠΈΠΊΠ° Π΄Π΅Π΄ΡΠΏΠ»ΠΈΠΊΠ°ΡΠΈΠΈ: ATTACH_ONLY ΠΈ UPSERT (whitelist ΠΏΠΎΠ»Π΅ΠΉ). ΠΠΊΡΠΏΠΎΡΡ ΠΎΡΡΡΡΠΎΠ² (XLSX), ΠΏΠ°Π³ΠΈΠ½Π°ΡΠΈΡ ΡΠΏΠΈΡΠΊΠΎΠ². Π€ΡΠΎΠ½ΡΠ΅Π½Π΄ (Vue3 + Quasar) Π‘ΡΡΠ°Π½ΠΈΡΠ° Β«ΠΠ°ΡΡΠΎΠ²ΡΠΉ ΠΈΠΌΠΏΠΎΡΡ ΡΡΠ΅Π½ΠΈΠΊΠΎΠ²Β»: Π·Π°Π³ΡΡΠ·ΠΊΠ° ΡΠ°ΠΉΠ»Π°, Π²ΡΠ±ΠΎΡ Π²Π»Π°Π΄Π΅Π»ΡΡΠ° Π³ΡΡΠΏΠΏΡ, ΠΈΠΌΡ Π³ΡΡΠΏΠΏΡ, Π·Π°ΠΏΡΡΠΊ. Π‘ΡΡΠ°Π½ΠΈΡΠ° ΡΡΠ°ΡΡΡΠ° Import Job: ΠΏΡΠΎΠ³ΡΠ΅ΡΡ (total/ok/error/pending), Π»Π΅Π½ΡΠ° ΡΠΎΠ±ΡΡΠΈΠΉ, ΠΊΠ½ΠΎΠΏΠΊΠΈ Β«Π‘ΠΊΠ°ΡΠ°ΡΡ ΠΎΡΠΈΠ±ΠΊΠΈΒ», Β«ΠΠΎΠ²ΡΠΎΡΠΈΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ½ΡΠ΅Β». Π‘ΠΏΠΈΡΠΎΠΊ Β«ΠΡΡΠΏΠΏΡ ΡΡΠ΅Π½ΠΈΠΊΠΎΠ²Β» Ρ ΠΏΠΎΠΈΡΠΊΠΎΠΌ/ΠΏΠ°Π³ΠΈΠ½Π°ΡΠΈΠ΅ΠΉ; ΠΊΠ°ΡΡΠΎΡΠΊΠ° Π³ΡΡΠΏΠΏΡ ΡΠΎ ΡΠΏΠΈΡΠΊΠΎΠΌ ΡΡΠ°ΡΡΠ½ΠΈΠΊΠΎΠ². ΠΠ°Π±Π»ΡΠ΄Π°Π΅ΠΌΠΎΡΡΡ ΠΈ ΠΊΠ°ΡΠ΅ΡΡΠ²ΠΎ ΠΠ΅ΡΡΠΈΠΊΠΈ (Prometheus/Grafana): p95 Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΈΠΌΠΏΠΎΡΡΠ°, TPS, % ΠΎΡΠΈΠ±ΠΎΠΊ, ΡΠ°Π·ΠΌΠ΅Ρ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ. Sentry/Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅: job_id, row_no, error_code; Π°Π»ΡΡΡΡ ΠΏΠΎ SLO. Π‘ΡΠ΅ΠΊ Backend: NestJS, TypeScript, Node.js, BullMQ/RabbitMQ, Prisma/TypeORM, PostgreSQL, Redis Frontend: Vue 3, Quasar (SSR/SPA), Pinia/TanStack Query, Vite ΠΠ½ΡΡΠ°ΡΡΡΡΠΊΡΡΡΠ°: Docker, Traefik/NGINX, Sentry, Prometheus/Grafana Π€ΠΎΡΠΌΠ°ΡΡ: XLSX, WebSocket Π’ΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ Π£Π²Π΅ΡΠ΅Π½Π½ΠΎ: ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ Π·Π°Π΄Π°Ρ, ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠΈ, ΠΈΠ΄Π΅ΠΌΠΏΠΎΡΠ΅Π½ΡΠ½ΠΎΡΡΡ, ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠΈΡ Π²ΠΎΡΠΊΠ΅ΡΠΎΠ². Π Π°Π±ΠΎΡΠ° Ρ PostgreSQL (ΠΈΠ½Π΄Π΅ΠΊΡΡ, upsert, ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ Π·Π°ΠΏΡΠΎΡΠΎΠ²), Redis. ΠΠΏΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΠ°ΠΉΠ»ΠΎΠ² (XLSX) ΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ½ΠΎΠΉ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ Π΄Π°Π½Π½ΡΡ
. ΠΠΎΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅ PII/Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ (ΠΌΠ°ΡΠΊΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅, ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ ΠΏΡΠ°Π², Π°ΡΠ΄ΠΈΡ). Π‘ΡΠΈΠ»Ρ ΠΊΠΎΠ΄Π°: ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΉ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄, ΠΈΠΌΠΌΡΡΠ°Π±Π΅Π»ΡΠ½ΠΎΡΡΡ, ΡΠΈΡΡΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ; ΠΡΠ΄Π΅Ρ ΠΏΠ»ΡΡΠΎΠΌ ΠΠΏΡΡ Π² Quasar SSR,WS-ΡΡΡΠΈΠΌΠΈΠ½Π³Π°Ρ
, BullMQ; ΠΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ ΠΌΠ΅ΡΡΠΈΠΊ (Prometheus), Π°Π»ΡΡΡΠΎΠ² ΠΈ Sentry ΡΠ΅Π»ΠΈΠ·ΠΎΠ². Π£ΡΠ»ΠΎΠ²ΠΈΡ ΠΠΎΠ³ΠΎΠ²ΠΎΡ: ΠΠ ΠΈΠ»ΠΈ ΡΠ°ΠΌΠΎΠ·Π°Π½ΡΡΡΠΉ (Π‘ΠΠ/ΠΠΠ). ΠΠΏΠ»Π°ΡΠ°: ΠΏΠΎΡΠ°ΡΠΎΠ²Π°Ρ (Π·Π°ΡΠ²ΠΈΡΠ΅ ΡΠ²ΠΎΡ ΡΡΠ°Π²ΠΊΡ, Π²Π°Π»ΡΡΡ ΠΈ Π΄ΠΎΡΡΡΠΏΠ½ΠΎΡΡΡ ΠΏΠΎ ΡΠ°ΡΠ°ΠΌ/Π½Π΅Π΄Π΅Π»Ρ). ΠΡΠΏΠ»Π°ΡΡ ΠΏΠΎ Π·Π°Π²Π΅ΡΡΡΠ½Π½ΡΠΌ ΡΡΠ°ΠΏΠ°ΠΌ. ΠΡΠ°ΡΠΈΠΊ: Π³ΠΈΠ±ΠΊΠΈΠΉ, ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ ΠΏΠΎ MSK ΠΏΡΠΈΠ²Π΅ΡΡΡΠ²ΡΠ΅ΡΡΡ. ΠΡΠΎΡΠ΅ΡΡΡ: ΡΠ΅Π²ΡΡ ΠΊΠΎΠ΄Π°, Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ API. ΠΡΠΈΡΠ΅ΡΠΈΠΈ ΡΡΠΏΠ΅Ρ
Π° (SLO/Definition of Done) ΠΠΌΠΏΠΎΡΡ 500 ΡΡΡΠΎΠΊ: p95 ≤ 60 Ρ ΠΏΡΠΈ Π½ΠΎΡΠΌΠ°Π»ΡΠ½ΠΎΠΉ Π½Π°Π³ΡΡΠ·ΠΊΠ΅. Π‘ΡΠ°ΡΡΡ Π²ΠΈΠ΄Π΅Π½ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ≤ 1 Ρ ΠΏΠΎΡΠ»Π΅ Π·Π°ΠΏΡΡΠΊΠ°. ΠΡΠ±Π»ΠΈΠΊΠ°ΡΡ: 0% Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ATTACH_ONLY; ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΡΠΉ UPSERT ΠΏΠΎ whitelist. ΠΡΡΡΡ ΠΎΡΠΈΠ±ΠΎΠΊ: ΠΏΠΎΠ»Π½ΡΠΉ, Ρ row_no, error_code, ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°ΡΠΈΠ΅ΠΉ ΠΏΠΎ ΠΈΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ. ΠΠ΅ΡΡΠΈΠΊΠΈ/Π»ΠΎΠ³ΠΈ/Π°Π»ΡΡΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½Ρ ΠΡΠΎΡΠ΅ΡΡ ΠΎΡΠ±ΠΎΡΠ° ΠΡΠΊΠ»ΠΈΠΊ: ΠΊΠΎΡΠΎΡΠΊΠΎΠ΅ ΠΏΠΈΡΡΠΌΠΎ + ΡΡΡΠ»ΠΊΠΈ + ΡΡΠ°Π²ΠΊΠ°. 30-ΠΌΠΈΠ½ ΡΠ΅Ρ
ΡΠΎΠ·Π²ΠΎΠ½: Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° ΠΈΠΌΠΏΠΎΡΡΠ°, ΠΈΠ΄Π΅ΠΌΠΏΠΎΡΠ΅Π½ΡΠ½ΠΎΡΡΡ, ΠΊΠΎΠ½ΠΊΡΡΠ΅Π½ΡΠΈΡ Π²ΠΎΡΠΊΠ΅ΡΠΎΠ², ΡΡ
Π΅ΠΌΠ° ΠΠ, UX ΡΡΠ°ΡΡΡΠ°.