Case study 03
Licto: Monitorizare automată a licitațiilor SEAP
Sistem privat care trimite alerte doar pentru anunțurile relevante și urmărește termenele-limită.
Pe scurt
Licto urmărește zilnic anunțurile din SEAP și îi dă operatorului o listă scurtă cu licitațiile care contează pentru firmă.
Pentru fiecare rezultat arată de ce a fost selectat, urmărește termenele-limită și modificările lor și separă licitațiile active de semnalele timpurii. Sistemul își verifică singur și preluarea datelor.
Context
Datele există în portalul public. Problema este să afli rapid ce este nou, ce merită atenție, ce s-a schimbat și ce trebuie făcut astăzi.
Alertele pe cuvinte-cheie aduc prea multe rezultate, iar un scraper fragil se strică la prima schimbare din portal. Licto avea nevoie de o preluare stabilă, reguli adaptate fiecărui client și o interfață pe care echipa să o poată folosi fără ajutor tehnic.
Constrângeri
Sistemul trebuie să fie de încredere atât în zilele cu multe anunțuri, cât și în cele fără rezultate.
- SEAP oferă date JSON utile, dar fără documentație oficială și fără garanția că formatul rămâne la fel.
- Fiecare client urmărește alte coduri CPV, expresii, autorități și valori și are propriile excluderi.
- Zero rezultate poate însemna o zi liniștită sau o preluare defectă. Sistemul trebuie să distingă cele două situații.
- Fiecare rulare verifică și o perioadă deja parcursă, deci duplicatele și alertele repetate trebuie eliminate sigur.
- Datele fiecărui client rămân separate, deși fluxul public este preluat o singură dată și apoi reutilizat.
Ce am livrat
Am construit întregul flux: preluare programată, filtrare, verificare, notificare și monitorizarea funcționării.
- Client pentru API-ul SEAP, cu paginare, reîncercări și filtrare locală.
- Scor de relevanță bazat pe coduri CPV, contextul titlului, autorități, valori și excluderi explicite.
- Remindere pentru termene-limită, urmărirea eratelor și semnale timpurii din consultări, planuri și anunțuri de intenție.
- Liste HTML disponibile offline, notificări prin email și Slack și un dashboard pentru stare, rulări și editarea profilurilor.
- Istoricul rulărilor, detectarea anomaliilor, autentificare, roluri, migrări, backup și teste de regresie.
Arhitectură
O singură preluare, reguli pentru fiecare client
Cum sunt prinse erorile silențioase
Un mesaj de dimineață trimis la timp poate ascunde o preluare incompletă. De aceea, Licto înregistrează fiecare rulare și o compară cu istoricul normal al profilului.
- Sistemul separă cazul „zero anunțuri preluate” de cazul „zero anunțuri relevante”.
- O scădere bruscă a numărului de anunțuri declanșează o alertă.
- Dacă niciun anunț nu mai conține termen de depunere, sistemul semnalează o posibilă schimbare de structură a datelor.
- Un timer separat detectează și cazul în care procesul zilnic nu pornește deloc.
Decizii importante
- Folosirea datelor JSON
- Portalul oferă deja date structurate. Parsarea paginilor HTML ar fi mai fragilă și nu ar aduce informații în plus.
- Structura JSON trebuie totuși monitorizată, fiindcă nu este garantată ca API public de integrare.
- Filtrare locală
- Volumul săptămânal poate fi preluat integral. Așa nu depind de filtrele nedocumentate ale portalului și pot aplica reguli proprii.
- Sursele care cer multe pagini de detaliu au nevoie de limite separate pentru numărul de solicitări.
- Scor determinist
- Fiecare rezultat arată codul CPV, expresia, autoritatea sau excluderea care i-a influențat scorul. Operatorul poate înțelege și regla filtrarea.
- Profilurile trebuie actualizate de mână când se schimbă interesele clientului.
- Suprapunere și deduplicare
- Fiecare rulare se uită suficient de mult în urmă pentru a recupera datele după o eroare temporară. Cheile persistente împiedică dublarea anunțurilor și a reminderelor.
- Baza de date și migrările devin piese critice.
- Un reper pentru fiecare profil
- Același prag zilnic nu funcționează în industrii diferite. Anomaliile sunt evaluate față de rulările reușite ale fiecărui profil.
- La început, sistemul are nevoie de o perioadă de calibrare înainte să poată semnala abateri.
Ce poți verifica
Limite
Integrarea trebuie supravegheată.
Structura SEAP se poate schimba, unele surse cer multe solicitări, iar calitatea rezultatelor depinde de regulile fiecărui client. Pentru că sistemul este privat, acest case study prezintă doar arhitectura și deciziile tehnice, fără datele clienților.
Rol și tech stack
Am proiectat și construit întregul sistem: preluarea și filtrarea datelor, modelul de stare, interfața operatorului, notificările și detectarea erorilor.
Python · requests · profiluri YAML · SQLite · HTML generat · SMTP · Slack · systemd