Rolagzza 2026-10-05: onboardingvoice public landing: actual product presentation, 5 October 2026

OnboardingVoice este un asistent vocal de onboarding pe care îl integrezi în orice aplicație web cu un singur script tag. Utilizatorul vorbește cu el așa cum ar vorbi cu un coleg de lângă el — „bun, cum îmi invit echipa?" — iar asistentul răspunde cu voce și, în același timp, evidențiază butonul exact de pe ecran, derulează până la el sau pune un tooltip fix unde trebuie să se uite. Problema pe care o atacă o știe orice echipă de SaaS: ghidarea în aplicație e manuală, fragilă și nu o construiește nimeni cu plăcere. Faci de mână un tur cu click-uri, echipa de design livrează un redesign două sprinturi mai târziu și fiecare selector din tur se rupe pe tăcute.

Vreau să fiu sincer din capul locului: ăsta e un prototip. Stack-ul Docker local rulează cap-coadă, widget-ul se buildează și se servește, dar nu e în producție, popularea cu date de demo e stricată din cauza unui mismatch de schemă, iar câteva dintre piesele mai ambițioase sunt planificate, nu construite. O să marchez ce e real și ce nu pe parcurs. Rămâne genul meu preferat de proiect despre care să scriu, fiindcă deciziile interesante sunt încă la vedere, cât betonul e încă moale.

Ideea: voce în loc de tur cu click-uri

Cele mai multe unelte de onboarding sunt o mașină de stări peste DOM. Pasul 1: evidențiază asta. Pasul 2: așteaptă un click. Pasul 3: evidențiază următorul lucru. Merge până când se mută UI-ul și nu se adaptează niciodată la ce anume îl încurcă pe un utilizator concret.

OnboardingVoice inversează logica. În loc de un tur fix, asistentul ascultă ce întrebi, deduce pe ce ecran ești, rezolvă elementul de care ai nevoie și răspunde cu voce plus un indiciu vizual — un highlight, un tooltip, un scroll sau o navigare. În spate folosește Driver.js pentru overlay-urile de tip spotlight și Tippy.js pentru tooltip-uri, cu suport de shadow-DOM, ca indiciile să supraviețuiască în aplicații încărcate de componente fără să scurgă stiluri în pagina gazdă.

Embed-ul e intenționat plictisitor: un singur script tag. Constrângerea asta modelează tot ce vine după. Widget-ul e construit ca web components Lit în TypeScript, bundle-uit cu Rollup și testat cu Vitest, tocmai ca să poată trăi în aplicația altcuiva fără să târască un framework după el.

Selectori self-healing

Funcția de care sunt cel mai atașat e ceea ce am numit selectori self-healing. Selectorii CSS sunt zidul de rezistență al oricărui tur în aplicație și, totodată, primul lucru care crapă când se schimbă UI-ul unui SaaS. Se redenumește o clasă, apare un div wrapper și .btn-primary.invite-cta arată spre nimic.

Abordarea aici e să nu te bazezi pe un singur selector. Fiecare element primește o „semnătură" DOM — un pachet de semnale precum conținutul textual, rolul, poziția și structura din jur — plus un set de fallback-uri. Când selectorul principal ratează, resolver-ul parcurge fallback-urile, iar intenția e ca AI-ul să repare referința potrivind semnătura cu DOM-ul curent și propunând un selector nou. Asta e partea de self-healing: turul își repară singur referințele rupte în loc să eșueze pe tăcute.

Sunt onest legat de maturitate. Rezolvarea pe bază de semnătură și fallback-uri e coloana reală, funcțională, a sistemului. Bucla de reparare cu AI de deasupra e direcția, nu o funcție finisată și testată în luptă. E genul de lucru care dă bine în demo și care are nevoie de multe UI-uri ostile aruncate în el înainte să mă încred în el pe aplicația de producție a unui client.

Voce-la-voce prin WebRTC

Traseul vocal e gândit să fie voce-la-voce reală prin WebRTC, cu proxy către OpenAI Realtime API, plus un traseu separat de speech-to-text și text-to-speech ca fallback pentru medii în care conexiunea realtime nu e viabilă. Backend-ul Django folosește Channels și WebSockets ca să coordoneze sesiunea și să mute evenimentele între browser și model.

E partea pe care aș trata-o ca parțial implementată. Instalația există și arhitectura e corectă, dar „bucla vocală WebRTC merge cap-coadă în producție" nu e o afirmație pe care o pot face onest azi. Ținerea modelului în spatele unui proxy server-side e o alegere deliberată, nu un accident — același raționament despre care am scris în cum ții cheile departe de dispozitiv cu o arhitectură AI server-side. Un widget care ajunge pe site-uri terțe arbitrare e ultimul loc în care vrei o cheie API expusă.

Studio-ul și labeler-ul cu AI

Ca asta să fie utilizabil de o echipă de SaaS, cineva trebuie să-i spună asistentului ce sunt ecranele și elementele. Aici intră Studio-ul no-code: o interfață de configurare în care fiecare tenant definește ecrane, elemente, intenții și fluxuri de onboarding. Ca să nu fie un exercițiu manual chinuitor, există un labeler sub formă de bookmarklet și extensie de Chrome care parcurge pagina live și folosește AI ca să sugereze etichete de elemente și intenții probabile — îl pui pe aplicația ta, el propune harta, tu o corectezi.

Studio-ul e și locul unde am făcut cel mai pragmatic compromis din tot proiectul. Backend-ul e Django, dar Studio-ul e o aplicație React 18 + Vite cu shadcn/ui care vorbește cu un strat mic de Node/Express și Supabase. Arhitectura curată ar unifica totul pe Django și DRF. N-am făcut-o. Supabase mi-a dat auth, o bază de date și izolare la nivel de rând pentru Studio destul de repede încât unificarea stack-ului m-ar fi costat săptămâni pentru un beneficiu pe care niciun utilizator nu l-ar vedea vreodată. Pentru un prototip care încearcă să demonstreze bucla de bază, asta a fost decizia corectă. Dacă promovează, consolidarea pe un singur backend e un item evident pe listă.

RAG hibrid peste documentele tale

Dincolo de parcurgerea UI-ului, asistentul e gândit să răspundă la întrebări din documentația proprie a unui tenant. E un setup de retrieval hibrid: embeddings dense în pgvector alături de căutare BM25 pe cuvinte-cheie, ca să prindă atât potrivirile semantice, cât și căutările pe termen exact. Un strat de graf Neo4j e planificat ca să modeleze relațiile dintre funcții și fluxuri, dar „planificat" e cuvântul-cheie — nu e construit.

Stack-ul

  • Backend: Django 5 + DRF, Celery + Redis pentru munca asincronă, PostgreSQL cu pgvector, Channels/WebSockets pentru sesiunea realtime, OpenAI API, Sentry pentru erori.
  • Widget: TypeScript + web components Lit, bundle-uit cu Rollup, testat cu Vitest.
  • Studio: React 18 + Vite + shadcn/ui, un strat de Node/Express și Supabase pentru auth și date.
  • Landing: Next.js 16 + React 19 + Tailwind v4, PostHog pentru analytics, deploy pe Vercel/Netlify.
  • Infra: Docker Compose local; Neon și ClickHouse sunt pe foaia de parcurs, neconectate încă.

Izolarea multi-tenant e proiectată în jurul unor baze de date per tenant cu telemetrie de evenimente și analytics — „proiectată" e cuvântul onest, fiindcă bazele de date de producție per tenant nu sunt provizionate.

Unde e acum și ce urmează

Iată statusul candid. Stack-ul Docker local rulează cap-coadă, iar widget-ul se buildează și se servește. Landing page-ul e singura piesă cu config real de deploy. Popularea cu date de demo e stricată dintr-un mismatch de schemă, nu sunt conectate baze de date de producție per tenant, iar Neo4j, ClickHouse și orchestratorul de nivel mai înalt nu-s construite. Mi l-am descris ca fiind „95% gata" — dar ăla e 95% dintr-un demo local, ceea ce e un număr foarte diferit de 95% dintr-un produs.

E și un semn pe care mi-l asum: repo-ul ăsta are peste 30 de fișiere markdown de status și fix. Așa arată construitul solo, asistat de AI, văzut de aproape — o mulțime de „FIX_THIS.md" și „PHASE_3_NOTES.md" care documentează mijlocul dezordonat. Nu e ordonat, iar să pretind altceva ar fi necinstit.

În continuare, în ordine: repararea mismatch-ului de schemă ca demo-ul să se populeze curat, verificarea buclei vocale WebRTC cap-coadă pe o aplicație reală și întărirea resolver-ului self-healing împotriva unor UI-uri care chiar încearcă să-l rupă. După aia, întrebarea dacă provizionez baze de date reale per tenant și colapsez Studio-ul Supabase înapoi pe Django devine o decizie reală, nu una ipotetică.

E unul dintre cele unsprezece produse pe care le construiesc singur acum — dacă vrei contextul mai larg despre cum se încadrează un proiect ca ăsta în portofoliu, am scris despre cum construiesc 11 produse ca fondator solo.

Dacă-ți place să vezi prototipuri trase spre producție în public, cu părțile stricate lăsate la vedere, trimit din când în când note de build. Te poți abona la newsletter — fără spam, doar munca.

voice-aiwebrtcdjangoragsaas-onboarding
Distribuie articolul