migration

Elisara: de la site WordPress de prezentare la platformă de rezervări Angular + Spring Boot

Cum am construit platforma de rezervări elisara.ro peste un site WordPress de prezentare. Angular 17 SSR + Spring Boot, Stripe + Apple Pay, notificări Telegram și Google Calendar pentru terapeute, alerte Sentry către Discord, fără pierderi de SEO pe conținutul existent.

Cuprins

Punctul de plecare

Până la sfârșitul lui mai 2026, elisara.ro era un site WordPress de prezentare: temă personalizată, pagini de servicii, blog cu articole. Funcționalitate de rezervare online: zero. Programările se făceau manual prin WhatsApp — clienta trimitea mesaj cu serviciul dorit, cineva de la platforma de rezervări Elisara răspundea cu o oră disponibilă, iar programarea era notată pe foaie sau în memoria persoanei care răspundea.

Problemele deveneau costisitoare pe măsură ce salonul creștea:

  • Nu se putea rezerva 24/7. Programările intrau doar în orele când răspundea cineva la WhatsApp.
  • Greșeli de comunicare: oră confirmată într-un mesaj, notată diferit în altul, două rezervări pe același slot sau slot-uri uitate complet.
  • Zero reminder-e automate. No-show-urile costau direct ore goale și venit pierdut.
  • Plata se făcea exclusiv la fața locului, cash sau transfer manual. Zero plată în avans, zero deposit pentru rezervări serioase.
  • Zero raportare: imposibil de știut câte rezervări pe lună, ce servicii performau, care zile aveau cele mai multe goluri.

Decizia: construire de la zero a unei platforme reale de rezervări, peste brand-ul și conținutul existent. Marketing-ul rămâne, infrastructura de rezervare e nouă.

Stack-ul ales

Frontend Angular 17 cu SSR, backend Spring Boot 3 pe Java 21, Postgres, totul în Docker. Alegerile care au făcut diferența:

  • Angular SSR: paginile publice livrează HTML complet la primul request. Bot-urile de SEO și utilizatorii pe conexiuni lente văd conținut imediat, nu un schelet care așteaptă JavaScript-ul.
  • Spring Boot 3 + Java 21: virtual threads pentru endpoint-urile de availability (multe IO-uri către agenda salonului), record-uri pentru DTO-uri, stack pe care îl menținem cu rutina unui codebase enterprise.
  • NgRx: state management dedicat fluxului de rezervare (pasul 1: serviciu, pasul 2: dată, pasul 3: plată). Fără el, traversarea pașilor cu Back/Forward în browser pierdea contextul.
  • Stripe Elements + Apple Pay: integrare directă în frontend, pentru control complet pe UX și conformitate PCI fără layer-e intermediare.

Catalogul nou de servicii, cu durată, preț și disponibilitate live din agendă, e vizibil la lista completă de servicii.

Harta de redirect-uri WordPress → routes noi

Site-ul vechi avea câteva zeci de URL-uri indexate de Google: articole de blog, pagini de servicii, pagini de prezentare. O migrare brutală (totul pe homepage sau 404) ar fi șters indexul în două săptămâni și ar fi costat luni de zile de revenire organică.

Am construit o hartă explicită WordPress → nou în nginx, încărcată ca directivă map:

/blog/cum-alegi-tratamentul-X     →  /ghid/cum-alegi-tratamentul-X
/servicii-faciale                 →  /services#faciale
/despre-noi                       →  /despre-noi
…

Fiecare redirect e 301 permanent. Pentru articole am păstrat slug-urile exact, doar prefixul s-a schimbat din /blog/ în /ghid/. Vezi noua secțiune de ghiduri Elisara, care moștenește autoritatea SEO a vechiului blog.

Captură mică dar reală: am avut nevoie de map_hash_bucket_size 128; în nginx pentru că unele slug-uri WordPress vechi depășeau default-ul de 64 și configurația nu valida. Genul de detaliu care iese la nginx -t în pre-flight, nu la cutover.

Plata: Stripe Live + Apple Pay + facturare SmartBill

Stripe Elements expune un flux unificat: card normal, Apple Pay, Google Pay, toate prin același Payment Intent. Pașii care au costat timp real:

  1. Verificare domeniu Apple Pay: fișierul apple-developer-merchantid-domain-association trebuie servit din /.well-known/ pe HTTPS valid, iar Stripe îl revalidează automat. O greșeală de path (/static/ în loc de /.well-known/) blochează lansarea Apple Pay zile întregi după go-live.
  2. Modul abonamente: clienții recurenți preferă pachete (ședințe pre-plătite, reînnoire automată) în loc de rezervări individuale. Acum sunt vizibile la elisara.ro/abonamente și folosesc Stripe Subscriptions.
  3. Facturare SmartBill: după ce plata trece, un webhook Spring Boot creează factura în SmartBill (compatibil e-Factura) și o atașează la chitanța emailtă către client. Zero efort manual pentru salon.

Costul implicit pentru business rămâne același: comision Stripe + abonament SmartBill. Câștigul: zero overhead manual de facturare și Apple Pay disponibil din ziua 1.

Integrări care țin sistemul în viață

Un site de rezervări nu se oprește la "click și ai plătit". În spatele unui flux care arată simplu există un lanț de notificări și alerte care trebuie să funcționeze și la 3 dimineața. Ce e cusut în Elisara acum:

  • Email + SMS pentru clienți: confirmare imediată după rezervare, reminder cu 24 de ore înainte de programare, notificare la reprogramare sau anulare. Email-ul vine prin SMTP propriu, cu DKIM și SPF configurate corect ca să nu cadă în spam. SMS-ul folosește furnizor local pentru deliverability bună pe rețelele românești.
  • Telegram pentru terapeute: fiecare terapeută își leagă chat-ul de Telegram printr-un token, o singură dată. După aceea, fiecare rezervare nouă apare instant ca mesaj cu numele clientei, serviciul, ora și opțiunea de confirmare. Two-way: terapeuta răspunde cu comenzi simple (/agenda, /azi) direct din Telegram, fără să intre în admin panel.
  • Google Calendar sync pentru terapeute: fiecare terapeută își autorizează contul Google o singură dată prin OAuth. După aceea, orice rezervare nouă apare automat ca eveniment în Google Calendar-ul ei, cu titlul, ora, durata și clienta. Vizibilitatea agendei vine direct în calendarul cu care lucrează zilnic, fără să trebuiască să verifice un al doilea sistem.
  • Sentry pentru erori backend: orice excepție în Spring Boot e capturată automat, grupată pe semnătură de stack trace (o mie de manifestări ale aceluiași bug ajung un singur issue) și include contextul request-ului (URL, metodă, utilizator). Rutat către Discord-ul crawlerra, unde echipa noastră vede alerta sub un minut.
  • Al doilea strat de alerting: un script care urmărește jurnalul backend-ului la fiecare 5 minute și postează pe Discord dacă apar pattern-uri suspecte (timeout-uri, excepții necapturate). Plasă de siguranță pentru cazul în care Sentry-ul însuși ar avea probleme.
  • Dashboard de monitoring intern: metrici live pentru rata de succes a plăților, distribuția canalelor (card / Apple Pay / Google Pay), volumul de rezervări pe zi, utilizarea terapeutelor și conexiuni active la baza de date. Vizibil doar echipei de administrare.

Operațional, înseamnă că o eroare în producție declanșează între 1 și 5 minute o alertă în chat-ul echipei noastre. Pentru salon, înseamnă că nu pierde rezervări din cauza unui bug pe care nimeni nu îl vede.

Cutover-ul: DNS flip + certificat + fereastră scurtă

Cutover programat pentru sâmbătă noaptea, 31 mai 2026. Pașii, în ordine:

  1. T-30 min: snapshot la baza de date WordPress și la directorul /opt/elisara de pe server.
  2. T-0: DNS A record schimbat de la IP-ul vechi la IP-ul nou. TTL redus la 60 de secunde cu o zi înainte, ca propagarea să fie rapidă.
  3. T+2 min: majoritatea traficului rezolva deja la noul IP. Let's Encrypt HTTP-01 challenge rulat via --webroot. Acceptăm o fereastră scurtă de cert mismatch (câteva minute) ca tradeoff vs DNS-01, care e mai complicat și cere API la registrarul de DNS.
  4. T+5 min: cert OK, Apple Pay verifică .well-known/, plățile live testate cu un card real (1 RON, refund imediat).
  5. T+15 min: tot stack-ul verificat, comutarea declarată definitivă.

Plan de rollback documentat înainte (DNS înapoi la WordPress, snapshot restore) dar nu a fost nevoie.

Ce e live acum

Din 31 mai 2026, elisara.ro rulează pe noul stack. Ce funcționează măsurabil:

  • SSR rapid pe toate route-urile publice.
  • Stripe Live + Apple Pay, ambele testate cu plăți reale înainte de go-live.
  • SmartBill emite factura automat la fiecare plată reușită.
  • URL-urile vechi redirect-ate 301 către echivalentele noi, fără scădere observată în Search Console în prima săptămână.
  • Salonul adaugă servicii noi din admin panel, fără developer. Programări 24/7, plată online opțională, reminder-e automate, totul integrat în calendarele terapeutelor.

Dacă vrei să vezi rezultatul în producție, programează direct la elisara.ro. Fluxul de rezervare e gândit să nu îți ceară cont sau parolă pentru o singură vizită.

Întrebări frecvente

Cât a durat migrarea Elisara?

Dezvoltarea a rulat în paralel cu site-ul WordPress live timp de câteva luni, iar cutover-ul real a durat sub 20 de minute. Tot stack-ul nou a fost construit, testat și pre-deployat pe un domeniu intern (dev.elisara.ro) înainte de cutover, ca să eliminăm orice surpriză la flip-ul de DNS. Cutover-ul efectiv (snapshot, DNS, cert, Apple Pay verify, smoke test) a fost o fereastră scurtă noaptea.

Cum am evitat pierderea de SEO la migrare?

O hartă explicită de redirect-uri 301 în nginx, slug-uri păstrate identic pentru articole și conținutul migrat 1:1. Fiecare URL vechi indexat de Google a fost mapat la echivalentul nou înainte de cutover, validat cu nginx -t, apoi testat manual cu curl -I pentru fiecare slug critic. În prima săptămână după go-live nu am observat scădere de trafic organic în Search Console.

De ce Angular SSR și nu Next.js sau Astro?

Pentru că operăm Angular și Spring Boot enterprise zilnic, iar fluxul de rezervare are state suficient de complex încât NgRx-ul a meritat costul. Next.js și Astro sunt opțiuni excelente pentru proiecte React-first sau content-first. Pentru Elisara, alegerea s-a făcut pe coerența stack-ului în mâinile aceleiași echipe care îl menține: același limbaj de tipuri end-to-end (TypeScript la front, Java records la back) și aceeași disciplină de release pe care o aplicăm și pentru clienți enterprise.