eduardweb.
Prezentări & ShowcaseIntermediar#nextjs#showcase#saas#aws-lambda#efactura

SaaS de facturare pentru freelanceri RO: 89 de abonați plătitori și arhitectură de $22/lună

De Ioana Marinescu, 28 iul. 2026 · 10 vizualizări · 3 like-uri

Postat 28 iul. 2026
typescript
async function sendInvoiceToAnafWithRetry(invoiceId: string, retryCount = 0): Promise<AnafResponse> {
  const token = await getValidAnafToken(invoiceId);
  const xmlPayload = await generateUblXml(invoiceId);

  try {
    const response = await fetch('https://api.anaf.ro/prod/FCD/v1/upload/standard', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/xml',
      },
      body: xmlPayload,
    });

    if (!response.ok) {
      throw new Error(`ANAF Error HTTP ${response.status}`);
    }

    return await response.json();
  } catch (err) {
    if (retryCount < 5) {
      const delayMs = Math.pow(2, retryCount) * 1000;
      await new Promise((res) => setTimeout(res, delayMs));
      return sendInvoiceToAnafWithRetry(invoiceId, retryCount + 1);
    }
    throw err;
  }
}

Am scos pe piață un micro-SaaS dedicat freelancerilor din România care vor facturi simple și sincronizare automată cu e-Factura fără să-și prindă urechile în interfețe de anii 2000. În prezent am ajuns la 89 de abonați plătitori și o factură de infrastructură care nu sare de $22 pe lună. Treci mai jos prin arhitectură, stack-ul ales și de ce am evitat infrastructura complicată la început.

Stack-ul și de ce n-am folosit Kubernetes

Când lansezi ceva solo, ultimul lucru pe care ți-l dorești e să fii DevOps la 2 noaptea. Am mers pe variante serverless și PaaS managed unde e posibil:

  • Frontend & API: Next.js App Router găzduit pe Vercel Pro ($20/lună pentru dureri de cap în minus cu domeniile și SSL-ul).
  • Baza de date: PostgreSQL gestionat pe Supabase (tier-ul gratuit acoperă încă liniștit volumul actual).
  • Background Jobs: Upstash Redis + BullMQ pentru procesarea XML-urilor de la ANAF.
  • Generare PDF: Puppeteer rulat într-un AWS Lambda containerizat doar la cerere.

La început făceam render la PDF direct în API Route-ul din Next.js, dar pe Vercel ai limita de 10-15 secunde pe funcții serverless. Când 5 useri generau PDF-uri simultan, Vercel crăpa pe timeout. Mutarea pe AWS Lambda m-a salvat și mă costă sub $1 pe lună.

Integrarea cu e-Factura: Câtă bătaie de cap e cu adevărat?

Dacă ai lucrat vreodată cu API-ul ANAF, știi deja că răspunsurile de tip "Internal Server Error 500" fără niciun detaliu sunt la ordinea zilei. Am învățat repede că nu poți trimite o factură sincron în timp ce userul așteaptă în interfață.

Am construit un sistem de reîncercări (retry cu exponential backoff) în fundal. Când utilizatorul apasă "Trimite în e-Factura", aplicația salvează starea pending_submission și bagă job-ul în coada din Upstash. Un worker verifică starea și încearcă de maxim 5 ori la intervale crescătoare. Dacă ANAF pică marți la prânz (ceea ce se întâmplă des), job-ul se execută noaptea când serverele lor sunt mai libere.

Matematica costurilor lunare

Aici sunt cifrele exacte pentru luna trecută, la 89 de utilizatori activi:

  • Vercel Pro: $20 (aș fi putut rămâne pe Hobby, dar am vrut analytics și timeout mai mare pe API)
  • Supabase: $0 (suntem încă sub limita de 500MB DB și 1GB storage pentru PDF-uri arhivate)
  • AWS Lambda & S3: ~$1.20 (generare PDF și stocare temporară)
  • Upstash Redis: $0 (tier gratuit, sub 10.000 comenzi/zi)
  • Resend (Emailuri transacționale): $0 (sub limita de 3.000/lună)
  • Total lunar: ~$21.20

La un abonament mediu de 7 EUR/lună per utilizator, marja de profit este uriașă pe hârtie. Însă costul real nu e serverul, ci timpul pierdut cu suportul tehnic când ANAF schimbă schemă XML fără să anunțe pe nimeni.

Trade-off-uri și ce aș schimba

Next.js App Router a fost o alegere excelentă pentru viteza de dezvoltare, dar un mare minus este stocarea de sesiuni OAuth 2.0 pentru token-urile de la ANAF (care expiră la 90 de zile). A trebuit să scriu o logică destul de întortocheată pentru refresh automat de token-uri înainte de fiecare job din fundal.

Dacă ar fi să o iau de la capăt, aș separa complet backend-ul de procesare facturi într-un microserviciu mic în Go rulat pe un VPS de $5 de la Hetzner. Node.js mănâncă cam multă memorie când parsează XML-urile alea uriașe de răspuns.

Voi ce stack folosiți pentru proiectele personale care au nevoie de background processing de fișiere?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.