Vitaly

Hi, I'm Vitaly

QA Engineer · AI-assisted · Spec-driven · Mobile · Web · API · Cloud

I build quality into every release.

Commercial QA across mobile and web — and I build and deploy the AI automation that runs it. I set up local test environments, write the coverage, and ship an AI-assisted QA orchestrator that lives on a Linux cloud VM — a Telegram bot that runs the whole pipeline 24/7 and self-updates. Cloud-native and remote-ready: I stay with a release the whole way, from dev and prod to the App Store and Google Play.

✉ Email Telegram 💼 LinkedIn
Languages I speak Ukrainiannative EnglishB2 SpanishA1 ItalianA1 🌍Russiannative
8+ projects Spec-driven QA · OpenSpec Appium · iOS + Android iOS · Android · Web RN · Flutter Django · Laravel Docker envs AI-QA pipelines Load testing · k6 Prometheus · Grafana nginx load balancer HTTP · WebSocket Redis · PostgreSQL Postman · Charles Linux Cloud VM Git CI · self-deploy Telegram bots Claude Code · MCP 5 languages

I'm a QA engineer working mostly on mobile and web apps. I write the test docs, run local mobile and backend environments, cover the cases that matter, and submit builds for App Store and Google Play review.

Running things locally lets me do more than file bugs. I fix the small ones myself with AI-assisted coding, check the fix on my machine, and push it to a feature branch for the developer to review and merge.

I've tested social, gaming and fuel-station apps on iOS and Android, plus e-commerce sites and a big car-sales portal. The work spans frontend, backend, APIs, the database and the UI.

🤖 Signature project

An AI-assisted QA orchestrator I designed and deployed for a Flutter/Django mobile game. A chat command spawns Claude Code to read the task, dig through the Django source for the real API contracts, search or generate test cases in a git-backed store, run live HTTP and WebSocket checks, and post a QA report with the bugs it found. It runs 24/7 on a cloud VM and self-updates from chat.

TelegramClaude CodeJiraDjangogit storeCloud VM

Mobile app + admin panel for the German-speaking market · Flutter · NestJS · React-Admin

Spec-driven development means the team first writes down how a feature must behave, and only then writes the code. That written spec is the contract for everyone, QA included. I built the QA side on top of it: AI agents in Claude Code read every new spec, turn it into tests and run them on real phones, the admin panel and the API. I review what they find and give the final OK.

📜

Tests come straight from the spec

As soon as a feature is described, its tests can be written. Every “this must happen” in the spec gets its own check, so nothing is tested from memory.

🤖

A team of AI testers

Six Claude Code agents, one job each: write tests, look for gaps, run them, explore, report. Each may only change the files it is allowed to.

📱

Real iPhone & Android, driven by Claude Code

The agents tap, type and swipe on real devices: Appium on Android, WebDriverAgent on iPhone. Both run from my Windows machine, no Mac needed.

🔌

API and admin panel too

Server requests are checked with curl against the API contract. The admin panel is clicked through in a browser with Playwright. Logins with 2FA and email codes are automated, and the AI never sees a password.

openspec/changes/add-watchlist-alerts/written before code
  • proposal.mdwhy the change exists
  • design.mdhow it will be built
  • contract.yamlthe API app and backend agree on
  • spec.mdscenarios: what must be true
  • tasks.md[ ] QA-e2e my sign-off box
/test add-watchlist-alerts · runner agentrun
  1. APIcurlowner signs in, watches an item → 201✓
  2. iPhoneWebDriverAgentowner sees the item on Watchlist✓
  3. AndroidAppiumfinder reports a sighting✓
  4. iPhoneWebDriverAgentowner gets the push alert✓
  5. AdminPlaywrightsighting lands in the moderation queue✓

Two real phones, two users · the agent drives both

claude code · one command, the whole pass

> /test add-watchlist-alerts

✓ test author     tests written from the spec

✓ coverage critic no gaps left after 2 rounds

▶ runner          iPhone · Android · Admin · API

✓ reporter        report ready

❚❚ waiting for my OK▍

my commands

/test
test a new feature
/retest
check a fix
/regression
re-check the whole app
/explore
free exploration
/ready
is it ready to ship?

The agent team

  • SonnetTest authorturns the spec into step-by-step tests
  • OpusCoverage criticonly reads, and points out what the tests miss
  • SonnetRunnerruns the tests on phones, the admin panel and the API
  • agentExplorertries the app freely, like a curious user
  • OpusReporterwrites bug reports a developer can act on
  • agentAuto-mappermatches each scenario to existing autotests
Spec-driven developmentOpenSpecClaude Code · agents · skills · hooksAppiumUiAutomator2WebDriverAgentgo-iosPlaywright MCPOpenAPITOTP · email OTPNode.jsFlutter · NestJSGitLab

7
AI agents in the pipeline
1000+
test cases managed
24/7
uptime, self-updating
~min
ticket → QA report

one chat command → a full QA run → a report

Telegram /test TICKET-42 Linux VM bot · systemd · 24/7 spawns Claude Code Claude Code spawned per run 7-agent pipeline jira-reader backend / frontend reader case-lookup → case-writer breaker (HTTP / WS attacks) requirements-checker reporter QA report bugs · compliance TestRail · TestCollab cases · runs synced

🎯 Problem

Manual QA on a fast-moving Flutter/Django game — repetitive ticket checks, scattered coverage, and slow feedback before each release.

🛠 Approach

A Telegram bot on a Linux cloud VM spawns Claude Code per run. The agent pipeline reads the ticket and source code, manages 1000+ test cases, runs live API and WebSocket checks, and syncs results to Jira, TestRail and TestCollab.

✅ Outcome

One command turns a ticket into a real QA report — cases found or generated, live checks, compliance vs. requirements — synced to the team's tools and running 24/7.

Telegram botClaude CodeJiraConfluenceTestRailTestCollabDjangoHTTP · WebSocketLinux Cloud VMsystemd · nginx

I build the stand, drive the load, and watch what gives out first

THE SYSTEM UNDER TEST k6 stress ladder nginx LB round-robin 3 × Next.js one core each pool max 4 PostgreSQL 16 loopback only remote write /api/metrics WHAT WATCHES IT host exporters node-exporter docker-exporter Prometheus 5s scrape Grafana one time axis

🎯 Problem

Latency alone never says what ran out. And one Node process uses one core — a six-core box can look idle while the app already sits at its ceiling.

🛠 Approach

I build the whole stand on a Linux VM: three app copies behind an nginx balancer, Postgres, and a separate Prometheus + Grafana project. k6 climbs a ladder of request rates; four metric sources land on one time axis.

✅ Outcome

Each run names the ceiling and the reason for it — pool queueing, event-loop lag, or host CPU — so the next fix targets the real limit.

three decisions that make the numbers trustworthy

Per-step thresholds

One global p95<3s is measured over every request since the run began, so fast early steps keep the average healthy long after the system fell over. Each step carries its own tag and its own threshold, so it is judged only on its own traffic.

App exposes its own internals

A custom /api/metrics publishes pool queueing, event-loop lag and RSS. Pool waiting means the pool is the limit; loop lag rising means the process is CPU-bound and a bigger pool would make it worse.

Exporter written to fit the host

cAdvisor breaks under Docker’s containerd snapshotter and labels containers with raw ids. I wrote a small exporter against the same API docker stats uses, emitting cumulative counters so a missed scrape cannot become a fake spike.

k6PrometheusGrafanaDocker Composenginx load balancerPostgreSQLnode-exportercustom Python exporterGitLab CI · registryLinux Cloud VM

My contacts