portofoliu · acest site
Pagina principală a portofoliului cu tema întunecată: o bandă de tag-uri cu tehnologii, titlul, o scurtă prezentare și butoanele către proiecte și către mai multe despre mine.

Privire de ansamblu

Site-ul pe care îl citești: prerandat ca HTML static în engleză, germană și română, cu un API de analytics propriu care numără doar vizitele cititorilor care și-au dat acordul.

Un recrutor deschide pe telefon, cu JavaScript blocat, un link către CV-ul în germană. CV-ul se încarcă oricum complet și în germană, pentru că adresa indică un fișier care îl conține deja.

  • Citește patru studii de caz, CV-ul și paginile legale în engleză, germană sau română
  • Descarcă CV-ul ca PDF, generat în browser
  • Alege tema întunecată sau luminoasă; alegerea se păstrează la vizita următoare
Tot ce face un cititor funcționează fără API; numărătoarea începe doar după ce își dă acordul.
Pe scurt
RolSingurul autor: design, frontend, API și deploy
StructurăUn site Angular 22 prerandat, un API de analytics pe .NET 10 și un dashboard de administrare
LimbiEngleză, germană și română, fiecare compilată ca build separat
Pagini27 de pagini de HTML real: nouă rute în trei limbi
Teste636 de spec-uri de frontend, 572 de teste în browser, 193 de metode de test pe backend
Repository publicSursa completă a site-ului pe care îl citești

Arhitectură

Un site static care stă singur în picioare și un API de care se poate lipsi.

În stânga liniei punctate e tot ce funcționează în continuare cât timp API-ul doarme.
  • Fiecare rută e prerandată la build, așa că host-ul e un folder cu fișiere, fără server propriu.
  • Fiecare limbă e un build separat, în folderul ei, de exemplu /de-DE/cv, pentru că Azure Static Web Apps nu poate ruta după query string.
  • Aplicația Angular e împărțită în straturi (data, core, shared, layout și features), cu săgeata într-o singură direcție, iar niciun feature nu importă altul.
  • API-ul scalează la zero, iar pagina nu îl așteaptă niciodată: dacă nu răspunde, contorul de vizite nu apare.

Proiectarea domeniului

Conținutul e format din date tipizate, așa că un studiu de caz care strică forma nu compilează.

Conținut tipizat la intrare, un folder de fișiere la ieșire. O traducere lipsă oprește linia la ng build.
  • Fiecare text pe care îl vede cititorul are un id de mesaj stabil, ca o extragere nouă să nu lase nicio traducere orfană.
  • O traducere lipsă oprește build-ul, în loc să se revină pe ascuns la engleză.
  • Sub features, conținutul vine din fișierul lui și niciodată din barrel, altfel fiecare studiu de caz ar intra în primul download.

Fluxul de date și de control

O vizită, de la adresă până la contorul de vizite.

Pagina are tot ce îi trebuie înainte de prima cerere către API.

Strategia de testare

Un spec lângă fiecare unitate și teste în browser pe exact build-ul pe care îl va servi host-ul.

  • Rularea pică dacă o componentă, un service, o directivă, un pipe sau un util nu are un spec lângă el.
  • Playwright rulează build-ul de producție pe desktop și pe telefon, servit cu rutele, header-ele și CSP-ul host-ului.
  • Fiecare test în browser pică la o eroare în consolă, la o excepție neprinsă sau la o cerere care iese din site.
  • Proiectele .NET se compilează cu StyleCop și cu avertismentele tratate ca erori, iar domeniul nu referențiază niciun pachet, așa că direcția dependențelor e garantată de compilator.

Ce aș schimba

  • Studiile de caz sunt scrise în TypeScript, așa că pentru o greșeală de tipar într-unul e nevoie de un build și un deploy.
  • Serverul de dezvoltare localizează o singură limbă odată, așa că pentru a verifica o pagină în germană e nevoie de o a doua comandă.
  • Host-ul permite o singură pagină 404, așa că un mic script aduce în locul ei limba potrivită. Un host cu câte un 404 pe folder nu ar avea nevoie de el.
  • Granițele dintre features din configurația de lint sunt listate de mână: un feature nou înseamnă și o modificare în configurație.