Backend Engineering
Services built for concurrency and correctness under load: atomic money handling, token identity, and persistence taken off the request path.
-
Real-Time Betting Validation API
FeaturedHigh-concurrency bet validation in Rust
Accepts live betting tickets and validates odds, checks balance and debits it inside a single Redis Lua script, then acknowledges the client before the write reaches PostgreSQL. Persistence runs off the request path through a Redis Streams consumer group that replays its pending list on startup, so a worker killed mid-batch re-processes rather than drops. Money is i64 cents end to end — the domain layer has no floating-point arithmetic.
- 1,000 req/s at p99 300 ms under k6 load tests
- Hexagonal layering: domain declares ports as traits, imports no infrastructure
- Unlabelled Prometheus counters, so series count cannot grow unbounded
- Rust
- Actix-Web
- Redis Streams
- PostgreSQL
- Docker
- k6
- Prometheus
-
Secure Banking Auth Service
FeaturedToken identity with refresh-token theft detection
Refresh tokens are opaque, stored only as SHA-256 digests, and grouped into families where each token is exchangeable exactly once. That single-use rule turns theft into a detectable event: if a token is ever exchanged twice, the service revokes the whole family instead of guessing which side is the attacker. Access tokens carry jti and ver claims, so a live JWT can be withdrawn before it expires.
- Rotation race closed in SQL (UPDATE ... WHERE used_at IS NULL), not in application code
- Redis deny list keyed by jti with TTL equal to the token's remaining life
- Per-endpoint permission RBAC; one version bump retires unbounded live tokens
- Rust
- Axum
- PostgreSQL
- Redis
- JWT
- SHA-256
-
Rust/Axum backend for a lead-generation catalogue
A catalogue platform for companies that do not sell online but generate leads through quotations. The public side browses products with search, filters and PDF datasheets and submits quote requests; behind it sits an admin panel with full CRUD over products and categories, file uploads and request management. Peruvian tax IDs are validated with the Módulo 11 checksum rather than a length check, so an invalid RUC is rejected at the form instead of downstream.
- Rust and Axum over PostgreSQL, with S3-compatible file storage
- JWT authentication with Argon2id password hashing
- Astro and TypeScript frontend with Nano Stores for shared state
- Rust
- Axum
- PostgreSQL
- JWT
- Argon2id
- Astro
- TypeScript
- S3
Data Science
Pipelines over real, messy public data, evaluated against a stated baseline — and labelled as unevaluated where no labelled ground truth exists.
-
GoalData League
FeaturedFootball retrieval and ranking over 1.75M event actions
Ingests match records, rosters and event streams into a relational schema, compresses player-seasons into PCA embeddings, and serves item-item similarity search: given a player-season, it ranks the closest comparables from a position-filtered pool. The same embedding backs a clustering layer, a k-NN similarity graph and an ILP starting-XI optimizer.
- 94,525 matches · 1,751,751 event actions · 52,387 player-seasons
- Recall@10 0.1435 vs 0.0614 baseline; MRR 0.1788 vs 0.0773; NDCG@10 0.1146 vs 0.0430
- Leave-one-out over 3,670 player-seasons, 1,662 queries, identical evaluation pool for both systems
- Python
- Polars
- pandas
- scikit-learn
- PCA
- Parquet
- Streamlit
-
Hospital Bed Prediction
FeaturedDistributed gradient descent in Go over 200,000 records
Three generalized linear models — one logistic, two linear — trained by gradient descent in Go to predict mortality risk, survival days and treatment cost. Training parallelizes two ways over the same map-reduce code: a goroutine fan-out inside a node, and a parameter-server cluster over net/rpc across nodes. The REST, JWT and WebSocket layers are standard library; go.mod declares two direct dependencies.
- Mortality AUC 0.770 against a 0.500 random-ranking reference; accuracy 0.832
- Survival R² 0.906 (RMSE 199 days) · Cost R² 0.983 (RMSE $1,494)
- 2.95× speedup saturating at 4 workers on a 4-core machine, measured over 3 repetitions
- Go
- MongoDB
- Redis
- net/rpc
- Docker
-
Entity resolution linking candidates to public sanction records
A medallion pipeline in Polars that consolidates Peruvian presidential and congressional candidates from JNE, Congress and government transparency portals, links each one to companies sanctioned by OSCE, and scores a reproducible risk index served by a FastAPI read layer over Parquet. Deterministic ID-to-tax-ID matches and fuzzy name matches are tagged separately on every row, so an unverifiable guess never looks like a documented link.
- Five-stage layout: raw → staging → normalized → matched → curated
- Financial risk on median + MAD × 1.4826 rather than mean and standard deviation, because declared assets are heavily skewed
- No labelled ground truth for the matcher — precision and recall are unmeasured, and the repository says so
- Python
- Polars
- FastAPI
- Parquet
- FAISS
- Docker
Artificial Intelligence
Embedding retrieval, computer vision and NLP pipelines — with the evaluation gap stated plainly wherever the accuracy work is not done yet.
-
Embedding-based student/offer matching across four services
Student profiles and company offers are turned into field-weighted text, embedded with a multilingual sentence-transformer, indexed in Qdrant and ranked by cosine k-NN. A two-sided swipe layer records intent and promotes a pair to a match only when both sides swipe right. Field importance is expressed by repeating terms in the input text — required skills ×10, area ×8 — because the encoder has no per-field weighting input.
- Four services; 20 relational tables under async SQLAlchemy, laid out as ports and adapters
- Spanish text lemmatized and stop-word filtered with spaCy before encoding
- Recommender is unevaluated: no held-out split and no relevance labels yet, stated in the repository
- Python
- FastAPI
- PostgreSQL
- Qdrant
- sentence-transformers
- spaCy
-
Licence-plate detection from detector to field apps
A YOLOv8 detector trained on 2,620 annotated Peruvian licence-plate photos, wrapped in a Flask service that crops the plate and runs OCR over it. An Electron desktop app is the inspection station and an Expo mobile app is the field client; both talk to the same HTTP API over one Supabase schema.
- 4,144 boxes over 2,433 training images — 1.70 plates per image, so multi-object rather than single-object
- Median box 504 px², 0.12% of the frame: below the COCO small-object threshold, which is what drives imgsz
- Detector has no committed evaluation — no mAP figure is claimed, and the repository says why
Collaborative repository — hosted under a teammate's account.
- Python
- YOLOv8
- PaddleOCR
- Flask
- Supabase
- Electron
- React Native
-
Pictogram-based communication assistant
An augmentative-communication web app that turns Spanish text into pictograms in real time. A FastAPI backend serves both REST and WebSocket chat, lemmatises incoming text with spaCy before looking the terms up against the ARASAAC pictogram set, and drives a sentence builder and a tutor assistant on a React client.
- FastAPI over REST and WebSockets; React and Vite client
- spaCy es_core_news_lg lemmatises Spanish before the pictogram lookup, so inflected forms resolve to one symbol
- Photo-to-pictogram classification is listed as conditional in the repository — treat that piece as partial
- Python
- FastAPI
- WebSockets
- spaCy
- TensorFlow/Keras
- React
- Vite
- Tailwind CSS
Hub Central
Systems that cross more than one layer and more than one language: a pipeline with the client that consumes it, a backend with the model and the interface on top.
-
Semantic Search — Court Records
FeaturedConcurrent anonymization pipeline for judicial case files
A Go worker-pool pipeline that normalizes and anonymizes the text of Peruvian Constitutional Court case records, fed by a Python scraper and EDA layer that build the corpus. The measurement question the repository answers is how a channel-fed goroutine pool scales from 15 to 150 workers.
- 149,387 source case records; pipeline scales to a combined corpus of roughly 1.4M rows
- 10.26× throughput going from 15 to 150 workers, measured over 1,100 timed runs committed to the repo
- Efficiency above 100% is an artifact of a simulated per-record cost, not real CPU work — flagged as a limitation
- Go
- Python
- pandas
- semantic search
-
CV ingestion, simulated AI interview, automated ranking
A recruiter-facing platform that stores uploaded CVs, extracts structured information from the PDFs, runs a simulated interview through a conversational assistant, and produces an automated ranking of candidates per job offer. FastAPI backend with a React and TypeScript client.
- Prototype stage: persistence is an in-memory cache, not a database
- Scoring combines interview performance with fit against the offer
- Python
- FastAPI
- React
- TypeScript
- Tailwind CSS
- PDF extraction
-
Academic tutoring platform on Java + Spring Boot
A tutoring marketplace covering registration, tutor availability, session booking, simulated payments, session links and reviews. Java/Spring Boot REST backend against a relational schema, with a React and TypeScript client; the repository carries the UML model, the database diagram and the full delivered backlog.
- 16 user stories delivered end to end
- Roughly 90% of the API endpoints built by me
- Relational schema and UML diagrams committed alongside the code
Developer on a five-person university team; I built roughly 90% of the API endpoints.
- Java
- Spring Boot
- React
- TypeScript
- SQL
Experience
Where the work was paid, shipped to users, or both.
-
Zoluxiones
Software Engineering Intern · IT consultancy · current role
Software engineering intern at an IT consultancy, working on internal platform and automation work. Client deliverables and internal products are confidential and are deliberately not described here.
- Current role
- Backend and automation work under confidentiality
- Python
- TypeScript
- PostgreSQL
- Docker
- CI/CD
-
Co-founder · CV-matching marketplace shipped to real users
Co-founded a platform connecting university students with real project challenges posted by companies, and took it to real users. The backend owns the relational domain — students, companies, offers, skills, matches and agreements — over async SQLAlchemy and PostgreSQL, and delegates candidate ranking to a separate AI service over HTTP.
- 15 domain entities and 8 use cases behind explicit port interfaces
- 8 HTTP endpoints; FastAPI confined to the input adapter
- No automated tests and no CI test stage — stated in the repository
- Python
- FastAPI
- SQLAlchemy
- PostgreSQL
- JWT
- gunicorn
- Azure
-
Kreante
No-Code Developer Intern · MVP delivery on Bubble
Built functional MVPs on Bubble so client ideas could be validated with users before any engineering budget was committed.
- No-code delivery on Bubble
- Bubble
- No-code