
Backend-focused .NET developer with 4+ years of professional experience building and shipping backend and full-stack systems. Most of my work sits where correctness matters most — orders, payments, and vendor settlements that have to be right the first time.
I'm a Senior .NET Developer and Technical Lead at ITLegend, where I own the backend architecture of the e-commerce codebase powering a multi-vendor marketplace and a fashion-retail store across Egypt and Jordan, plus the ITLegend e-learning platform serving 80,000+ users. I lead a small cross-functional team, handling everything from domain modeling to deployment on Linux infrastructure.
My stack is C# / ASP.NET Core, and my approach is Clean Architecture, DDD, and messaging — patterns that keep complexity manageable as products and teams scale.
ITLegend · Cairo, Egypt
Oct 2023 – Present
Remote
Jun 2022 – Oct 2023
A multi-vendor marketplace and a fashion-retail store running on one shared codebase I architected end-to-end: catalog with per-offer pricing, a buy-box engine that picks the winning offer across competing vendors, a vendor settlement subsystem built as an append-only financial ledger with idempotent refund workflows, and a snapshot-based pricing engine that keeps partial refunds free of cent-level drift. Orders persist atomically; a transactional outbox drives Aramex carrier dispatch, and RabbitMQ handles downstream side-effects so they never block the core order.
93 API controllers · 600+ endpoints · 125 domain entities · 309 EF migrations · 4 payment gateways · 177 test files
Self-initiated architecture project built to practice production-style design: Clean Architecture, DDD, Modular Monolith, CQRS (MediatR), and message-driven workflows via RabbitMQ. Implements Catalog and User Management modules with rich domain models, aggregates, and domain events. Includes JWT auth with refresh-token rotation, role-based access, soft-delete with audit trails, health checks, rate limiting, structured logging (Serilog), and unit / integration tests.
Student dashboard response was ~20 s under 300 concurrent users. Diagnosis: one fat endpoint doing too much at runtime. Fix: split by read / write, precompute stats on a schedule, add Redis cache and targeted indexes. Result: under 4 s — more than 5× faster. The platform also runs geo-aware pricing and gateway routing (MaxMind GeoIP2) and fail-closed, cache-first fine-grained authorization.
~80,000 users · 94 controllers · 299 endpoints · ~194 tables across 6 schemas · 300 EF migrations
How I keep marketplace money movement correct, auditable, and safe to retry.
In a multi-vendor marketplace, vendors accrue earnings, the platform deducts commissions, refunds reverse charges, and cash-on-delivery adds edge cases. A single mutable “balance” column is fragile — concurrent updates race, history is lost, and reversals are hard to reason about.
An append-only, immutable ledger. Every money movement is a new immutable entry (credit / debit with a typed reason). The wallet balance is a computed read-model derived from the ledger, not a stored mutable field. Balance-affecting operations use optimistic concurrency. Refunds and commission reversals are modeled as compensating entries, and the workflows are idempotent — a retried or duplicated message never double-charges or double-refunds.
I trade cheap writes and a trivial balance read for correctness, auditability, and safe retries. Reads cost more (roll up the ledger), which I offset with a maintained read-model. For money movement, that trade is worth it.
Keeping order creation consistent and fast while side-effects run out of band.
Placing an order must create the order, its shipments, and the payment record consistently. It also triggers notifications, email, and SMS. If side-effects run inline, a slow or failing provider can delay or break order creation; if the write is split naively, you risk inconsistency (order saved but payment not).
The core write — order + shipments + payment — happens in a single atomic database transaction, so the order is all-or-nothing. Side-effects (notifications / email / SMS) are decoupled: published to RabbitMQ and processed asynchronously by consumers, so a failing provider never blocks or fails the core order.
Side-effects become eventually consistent (a notification may lag or need a retry) in exchange for a fast, reliable core order. For carrier dispatch, where a missed publish means a shipment that never leaves, I closed that window with a transactional outbox: the outbox row commits in the same transaction as shipment approval, and a background worker atomically claims each row with a guarded update plus rowcount check, reclaims orphaned rows via lease timeout, and does query-before-create against Aramex using the shipment id as the carrier idempotency key. Exponential backoff is capped at 60 minutes, and terminal failures dead-letter to an admin retry screen.
Mansoura College Academy · Mansoura, Egypt
2016 – 2020
Native
Professional
I'm always open to discussing new projects, opportunities, or partnerships. Feel free to reach out!