# Md. Abu Ammar — Backend & AI Systems Engineer Site: https://ammar-portfolio-zeta.vercel.app · GitHub: https://github.com/abuammarsami · LinkedIn: https://linkedin.com/in/abu-ammar/ · Email: abuammarsami@gmail.com ## Summary Backend & AI systems engineer. I ship payment rails, distributed platforms — and train quantum circuits. I work where production engineering meets machine learning research — connecting business operations, software architecture, AI, payments, and cloud infrastructure into systems that run every day. Today I lead Web & App Development at Partners Online (Bangladesh & UK), the company behind Partners.com.bd. I design and run the platform end to end — a .NET API, the Flutter apps, and a legacy MVC→API migration — deploying constantly and designing with DDD, vertical slice, and clean architecture principles so the systems stay healthy long after they ship. Before that, at Masjid Solutions, I owned systems across their full lifecycle: payment infrastructure (Stripe, ACH, Apple Pay, Google Pay) supporting millions of dollars in annual volume for 20,000+ users; KioskVisionAI, which watches 120+ donation kiosks across 60+ U.S. organizations with Azure Vision AI; and an automated Salesforce synchronization platform that eliminated manual CRM entry — roughly 200+ releases a year through CI/CD pipelines I architected. The research thread runs in parallel: my undergraduate thesis explored quantum machine learning — variational circuits, encoding methods, hybrid classical-quantum models on PennyLane simulators — and continues through my MS: Bangla POS tagging with knowledge distillation, multi-output CNNs, ensemble methods. My mission: continuously improve systems, automate the repetitive, and innovate at scale. ## Key numbers - $MM+ annual payment volume supported - 120+ kiosks monitored across 60+ orgs - 20,000+ users served by payment systems - 200+ production deployments per year ## Experience ### Partners Online (Bangladesh & UK) — Operation Manager, Web & App Development (March 2026 – Present · Dhaka, Bangladesh (Remote · part-time) · No Borders IT / Partners Online BD & UK Ltd) Lead Web & App Development for Partners.com.bd — Bangladesh's marketplace + business-social platform, expanding into the UK — owning backend architecture, database, cloud infrastructure, deployment, scalability, and security across BD and UK operations. Design and build the product's rebuild end to end: a .NET (Clean Architecture) API, three Flutter apps (General, Executive, City), and a legacy MVC → API migration. Shipped a transactional background-job system (dedicated Hangfire worker, SQL outbox, dead-letter queue, idempotency) and a document-driven agent workflow (open-sourced as the d3 Claude Code skill) that keeps the codebase AI-navigable. ### Masjid Solutions — Software Engineer (December 2023 – May 2026 · Indianapolis, Indiana, USA (Remote)) Engineered backend systems with .NET (MVC & Core), SQL Server, Dapper, LINQ, and Entity Framework powering Islamic schools, memberships, events, and donation management. Designed automated data-import pipelines transforming raw Excel into validated SQL Server schemas — cutting onboarding time for new schools and memberships by 60%. Architected CI/CD with Bitbucket, Jenkins, IIS, and rollback-ready backups — zero-downtime deployments across dev, beta, staging, and production. Built KioskVisionAI, a distributed .NET 9 Aspire app on Azure (Blob Storage, Queues, Vision AI) with GitHub Actions deployments for intelligent kiosk monitoring. Built a Remote Kiosk Device Management System — REST APIs for live monitoring (battery, Wi-Fi, uptime) and remote control (reboot, screenshot), improving support response time. Integrated Stripe + Authorize.Net ACH recurring payments, and Apple Pay / Google Pay via Stripe Payment Intents — tokenized wallet flows that improved donation conversion. Implemented Twilio Lookup API data enrichment to merge duplicate donor records, significantly improving data quality and reporting accuracy. Contributed to monolith-to-microservices migration: Clean + Onion architecture, repository patterns, domain-driven principles. ### Masjid Solutions — SQA Engineer (October 2023 – November 2023 · Remote) Built a data-driven UI automation project (C#, NUnit, Selenium, Serilog, Extent Reports, Jenkins) automating test cases in CI/CD. Automated a critical module's regression suite — 30% fewer regression bugs, more stable release cycle. ### A1QA — QA Automation Engineer (November 2022 – July 2023 · Colorado, USA (Remote)) Developed automated test scenarios with TestNG + Maven + Selenium WebDriver. Implemented CSV-driven data testing for regression and priority-based suites per release. ## Projects & research ### Background Job System — Dedicated Worker, Outbox, Dead-Letter Queue [engineering] (2026-07) — https://ammar-portfolio-zeta.vercel.app/work/background-job-system Summary: Designed and built the background-job subsystem for the Partners.com.bd marketplace backend (.NET, ASP.NET Core, SQL Server) — a dedicated Hangfire worker with an atomic-enqueue outbox, a dead-letter queue, idempotent handlers, least-privilege SQL isolation, and OpenTelemetry-based observability. The single place all async work now lives. Problem: Async work was scattered and fragile. Some ran on hand-rolled BackgroundService polling loops; latency-heavy work (email, image watermarking, PDF generation, document uploads) was awaited inline on HTTP request threads. There was no dashboard, no uniform retry, no dead-letter, and no metrics — and it was causing real defects: a registration flow that could return 500 with a half-created account, an unbounded SMTP hang holding request threads, and a CDN orphan-file leak on failed uploads. A separate legacy scheduler app owned three recurring jobs, one of which credited real user balances and was not idempotent. Approach: Stood up a dedicated Partners.Worker Windows Service (separate host from the API, so job load can never starve request threads) running Hangfire on a locked-down SQL schema, with three priority queues split across IO- and CPU-bound servers (Fig. 1). The correctness layer is the point: every job is idempotent and keyed (each handler is assumed to run at least twice, possibly concurrently on two nodes), and every enqueue is written to a transactional outbox inside the same SQL transaction as the state change it follows — so an enqueue can never commit without its business data, or vice versa (Fig. 2). Failures are classified (transient vs. permanent), retried on a single owning layer, and dead-lettered with full context plus dual-channel alerts when they exhaust (Fig. 3). Security is treated as first-class: write access to the job store is remote code execution, so the worker, the API, and the deploy pipeline each get their own least-privilege SQL principal, and only an allow-listed set of job types can ever be created or executed. The whole thing is kill-switchable per job type and instrumented with OpenTelemetry (the flagship signal is the age of the oldest un-dispatched outbox row — the end-to-end health gauge). I also delivered a 202-plus-status-polling async image pipeline and a rehearsed cutover sequence that retires the legacy scheduler with no window in which it could double-credit a balance — the ordering plus a never-retry pin make a double-payout structurally impossible. Impact: Consolidated all async work behind one observable, secure, idempotent subsystem and eliminated a class of production defects (registration partial-commit, unbounded SMTP timeout, CDN orphan leak). Replaced three hand-rolled polling loops and a standalone scheduler app with uniform, dashboarded, dead-lettered jobs. Shipped incrementally across independently-releasable phases with zero business-rule changes, behind hot-reloadable feature flags, and backed by a test suite that includes live-SQL integration coverage over the actual stored procedures, not just mocks. Stack: .NET, ASP.NET Core, C#, Hangfire (SQL Server storage), Dapper + stored procedures, SQL Server, OpenTelemetry → Prometheus/Grafana, Polly, MailKit, Windows Service host ### Authentication Architecture — One Core, Two Edges, Every Session Revocable [engineering] (2026-07) — https://ammar-portfolio-zeta.vercel.app/work/auth-architecture Summary: Designed the authentication architecture for the Partners.com.bd marketplace (ASP.NET Core Identity, MediatR, SQL Server) around three principles: one core decides *who you are*, each client edge gets the session artifact safest for its medium (HttpOnly cookie for the server-rendered web, bearer JWT + rotating refresh for native mobile), and every session — web or mobile — must be revocable and enumerable server-side. Architected across two accepted ADRs after a four-stream R&D review: one decision core, two transport edges, revocable sessions on both, and a JWKS issuer boundary — with the single-core convergence of the user logins and a full Critical/High hardening set under 832 tests. Problem: Two clients run on one system — a server-rendered MVC web app (cookie auth) and a Flutter mobile app on a JWT + refresh API, plus admin on the web — and the auth decision had drifted apart. Mobile and web-password login were on the shared core, but web Google login still ran through the legacy OnlineShop.Repository.GoogleSignUp and admin was still legacy, so a fix in one place didn't reach the others. Worse, the web session is a stateless self-contained cookie: the whole Identity ticket is serialized into the cookie, 7-day sliding, no absolute timeout, and the server keeps no record — so it cannot be revoked. A stolen cookie can't be killed, "log out everywhere" is impossible, an admin can't terminate a compromised account, and there's no active-devices list. OWASP treats server-side invalidation as mandatory. Approach: One decision core — all auth decisions (credential verify, Google-token validation, lockout, creation policy, issuance) in Partners.Application MediatR handlers over ASP.NET Identity, every surface routing through it. Two transport edges — the browser gets an HttpOnly + Secure + SameSite cookie (a server-rendered app has no browser-JS token store, so it already has the BFF security property), native mobile gets a bearer JWT + rotating refresh (RFC 8252 public client); the edge translates the core's one decision into the right artifact. Revocable sessions on both edges — a custom ITicketStore moves the web ticket server-side (the cookie carries only an opaque 64-bit session key; dbo.UserSession on SQL Server is the store of record — durable, enumerable, and already in the stack, with Redis staying a config-flip for the day we scale to multiple web instances), and mobile refresh tokens carry a FamilyId so a reused token revokes the whole family — unified into one enumerable "Active Sessions & Devices" model. And a JWKS issuer boundary — move token trust from a shared symmetric secret to asymmetric ES256/RS256 + a .well-known/jwks.json endpoint, so a future OIDC drop-in (OpenIddict on the same AspNetUsers store) is a config change, not a rewrite. The IdP stays in-house: no managed provider has a BD region (data residency), and Entra can't import ASP.NET password hashes without a mass reset. Impact: The user logins converge on one core (mobile + web-password already there, web Google now too — the last un-migrated user path, which fixed the "already logged in this browser" bug by construction), plus a full Critical/High hardening set — two Criticals and six Highs plus twelve review findings, closing the PK-as-verification-token hole, gating Google on email_verified , moving reset URLs server-side per country, reordering the rate-limiter after auth, making admin logins enumeration-safe with a PBKDF2 timing-equalizer and a sign-out-on-any-failure guard, and unifying the Data-Protection key ring — all under 832 tests. And the architecture around it is the part that ages well: revocation is a first-class property on both edges, not something bolted on after a breach; the JWKS boundary means a dedicated OIDC server (OpenIddict on the same AspNetUsers store) is a config change rather than a rewrite; and keeping the IdP in-house is what keeps the whole thing free of a data-residency problem, a per-MAU cost cliff, and a forced ASP.NET password-hash migration. It's a security design that reaches for the top-1% property — every session killable, server-side — and builds the seams that let the rest arrive without a rebuild. Stack: .NET, ASP.NET Core, C#, ASP.NET Core Identity, MediatR, FluentValidation, Dapper + stored procedures, SQL Server, JWT / refresh tokens, JWKS (ES256/RS256), HybridCache, OAuth 2.0 / OIDC ### Payments Platform — One Generic Ledger, Self-Healing Settlement [engineering] (2026-06) — https://ammar-portfolio-zeta.vercel.app/work/payments-platform Summary: Designed and built the payments platform for the Partners.com.bd marketplace backend (.NET, ASP.NET Core, SQL Server) — one generic `dbo.Payment` money ledger that serves every paid feature, a vendor-agnostic `IPaymentGateway` abstraction with a country-aware resolver, a single self-healing settlement coordinator, and a Hangfire reconciliation backstop. It replaces a legacy wide table (`dbo.OnlinePayment`) that stored money as text and trusted the client's callback. Problem: The legacy dbo.OnlinePayment crammed every paid feature's columns and bKash's API shape into one wide table, with Amount stored as NVARCHAR(200) — money as free text. Worse than the schema was the settlement logic: four features had copy-pasted verify→claim→fulfil code that had drifted apart, and every one of them short-circuited a re-delivered callback with an already settled → return success line. A 2026-06-18 review found the money-loss bug that hides behind that line (finding C1): if the domain write failed after the payment was claimed, the user was charged and the feature never delivered — and the re-delivered callback that could have completed it was thrown away. There was no reconciliation, no atomic claim, and no server-side amount cross-check. Approach: Collapsed the plumbing into ONE generic ledger. A Purpose discriminator plus a nullable ReferenceId link a dbo.Payment row back to the feature's own domain row, so status, idempotency, settlement, refunds and reconciliation live exactly once (Fig. 3) — five features (Boost, BundlePurchase, Membership, ProfileFee, Advertisement) now reuse it. Money is DECIMAL(18,2) ; three identifiers separate the internal Id , the external PublicId GUID, and a Stripe-style pay_… receipt code; the create idempotency key is unique per user (a global key would be an IDOR). Vendors sit behind IPaymentGateway (create / execute / verify-callback / resolve-webhook-reference / refund), and a resolver indexes every injected gateway by provider and per-country availability — adding a vendor is one class, one DI line, and listing it under a country. Bundle (internal balance) and bKash (real four-call tokenized checkout with a process-wide grant-token cache and an execute→query fallback) are implemented; Nagad, Rocket, SSLCommerz, Stripe and PayHere drop in behind the same seam as one class and one DI line each. The correctness core is a single PaymentSettlementCoordinator that every settler delegates to, supplying only its idempotent fulfil step (Fig. 1). It resolves the gateway by the payment row's server-trusted country, verifies with the vendor (the one trusted settlement gate), cross-checks the vendor's captured amount against the server-stored order ( AMOUNT_MISMATCH otherwise), and atomically claims Pending → Settled exactly once via a guarded SQL UPDATE . Then it always runs fulfilment — on a fresh claim, on a lost claim race, and on a re-delivered already-settled callback — because each fulfilment stored procedure stamps FulfilledDate exactly once ( WHERE FulfilledDate IS NULL ), making the domain write idempotent and letting a settled-but-unfulfilled row self-heal on the next pass. A Hangfire job runs every five minutes with three disjoint passes (Fig. 2): sweep inline-Bundle fulfilled-but-Pending rows to Settled, expire abandoned intents past a 30-minute TTL, and re-dispatch the idempotent settle command for settled-but-unfulfilled rows (giving up after 168 hours). On the create side, a retried "start payment" is deduped today at the SQL layer by a per-user IdempotencyKey unique index; on top of that, a MediatR pipeline behavior (ADR-0008; required header + SHA-256 body hash, 7-day payment TTL) backs a curated 13-endpoint rollout of the highest-risk commands. Impact: The already settled → return success money-loss path is gone by construction: the coordinator re-runs idempotent fulfilment on every attempt, FulfilledDate prevents double credit, and reconciliation is the backstop. Four drifting settlers became one audited pipeline; the unsafe deferred-debit dbo.WalletDebit primitive was deleted so the double-debit pattern can't return. Backed by ~883 automated tests (the coordinator alone has a dedicated suite), with the full settlement flow validated end to end against the bKash tokenized checkout. The gateway abstraction is deliberately extensible — Bundle and bKash are implemented and five more providers drop in behind the same IPaymentGateway seam — and RefundAsync lives on every gateway. The whole point is a single property: where money is on the line the design is boring on purpose — one ledger, one coordinator, one idempotency column, one reconciliation job — so a captured payment with nothing delivered, or a double charge, is impossible by construction rather than merely unlikely. Stack: .NET, ASP.NET Core, C#, MediatR, Dapper + stored procedures, SQL Server, Hangfire (recurring reconciliation), bKash Tokenized Checkout, FluentValidation, xUnit ### Professional Profile & CV Builder — One Server-Side Renderer, Six Designs, One Gate [engineering] (2026-06) — https://ammar-portfolio-zeta.vercel.app/work/cv-builder Summary: Rebuilt the Partners.com.bd "Download My CV" feature from a client-side browser hack into a server-owned single source of truth, across a Flutter app and a .NET API. A structured professional-profile editor (four domains, full CRUD) feeds one server-side QuestPDF generator that renders six professional designs identically for web and mobile; the six-design paywall is enforced *inside the renderer* against a server-trusted flag, not in the UI; and the one place the generator touches the network — the avatar fetch — is hardened against SSRF. The 52-BDT unlock runs on the generic `dbo.Payment` ledger. Problem: The legacy MVC dashboard rendered the CV client-side with html2pdf.js from the user's professional-profile data (a header plus four lists — academic qualifications, employment history, skills/languages, projects/theses); a free user got Design 1 and a 52-BDT "Professional Profile" unlocked the other five. Three flaws fall out of that: the paywall was UI-deep (nothing server-side stopped a client requesting a locked design), a future mobile app would re-implement the templates and drift into a second, different CV, and the data had insert-and-delete stored procedures only — no edit. The new API and mobile app had none of the feature. Per project rule, the client-side approach was not to be copied. Approach: Make the server the single source of truth for the rendered artifact, not just the data. One QuestPDF generator behind ICvDocumentGenerator (Application interface, Infrastructure impl) owns all six templates; web and mobile both call it and get byte-identical PDFs. The generator is a thin dispatcher over a shared CvRenderModel (the render-ready view derived once), a CvTheme palette table, and font-safe CvComponents (accent-dot bullets are drawn, not an icon font — no "tofu" glyphs), with one ICvTemplate class per design and a Classic fallback rather than a blank. The paywall moves into GenerateCv ( design != 1 && !IsProfessionalProfile → CV_DESIGN_LOCKED 403); GetCvDesigns exposes a per-design isUnlocked flag for display only. The four profile domains get full add/edit/delete, every write scoped WHERE Id = @Id AND UserId = @UserId with enumeration-safe NOT_FOUND ; one aggregation SP dbo.UserCvDataGetByUserId (five result sets) feeds both preview and generator. The embedded avatar is best-effort and hardened — fetched only for an absolute HTTPS URL on the configured CDN host, magic-byte sniffed, resilience-wrapped — and degrades to a drawn initials circle on any failure. The 52-BDT unlock is built on the generic dbo.Payment platform (bundle inline or bKash), flipping IsProfessionalProfile . Impact: "The CV" has one definition — six designs rendered server-side by one generator that web and mobile both consume, byte-for-byte, so there is no web-versus-app drift. The paywall is enforced where the bytes are made, so a guessed design number gets a 403 , not a free CV, and the free tier is genuinely Design 1. The professional data has a proper editor (four domains, full CRUD, owner-scoped writes). The one network touchpoint is SSRF-guarded, magic-byte-checked, and resilience-wrapped, so the generator can't be turned into a network probe and a broken CDN photo can never 500 the download (it degrades to initials). Covered by 664 application + 40 infrastructure tests (with the Flutter app under its own suite), including a %PDF smoke for every design over full and near-empty data. Built on the generic payment ledger, so the CV unlock inherits the same self-healing settlement guarantees as every other paid feature. Stack: .NET, ASP.NET Core, C#, MediatR, Dapper + stored procedures, SQL Server, QuestPDF (server-side PDF), HybridCache, bKash / generic payment ledger, Flutter, xUnit ### MVC → API Strangler Migration — Retiring a Monolith Without Going Dark [engineering] (2026-05) — https://ammar-portfolio-zeta.vercel.app/work/mvc-to-api-migration Summary: Migrated the Partners.com.bd marketplace off a legacy five-layer `OnlineShop` MVC monolith onto a new .NET Clean-Architecture core (ASP.NET Core, MediatR, Dapper + stored procedures) using the strangler-fig pattern. The new JSON API for the Flutter apps is built directly on the core, where a single `_mediator.Send(...)` reaches a handler that is the use case; each surviving Razor controller calls that same seam, one endpoint at a time, so the old pages keep serving live traffic and their indexed URLs while the data path underneath them runs on the new core. Every endpoint's crossover is gated by a layer-by-layer parity audit — not a big-bang rewrite. Problem: The old OnlineShop MVC app is a five-layer monolith where the service layer is pure one-line delegation and all logic is crammed into repositories. It filters ads with NVARCHAR route strings (whitespace-stripped by regex, with hardcoded 'all' / 'bangladesh' sentinels), pays two DB round trips per listing page and three-to-four per detail page (including a hidden N+1 ShopName lookup inside a repository), increments the view counter with a read-then-write race inside a transaction that wraps the read, runs detail SPs at commandTimeout: 0 , blocks on async with .Result , wraps every action in Task.Run(() => View(...)) , and has no server-side validation at all — pageIndex = -1000 reaches the stored procedure untouched. It works, ranks on Google, and takes money, which is exactly why it can't simply be switched off. Approach: Strangle the data path, not the UI. The MediatR handler becomes the use case — LoggingBehavior → ValidationBehavior → Handler — with the repository interface in the Application layer and Dapper/SP execution in Infrastructure, fully async with default timeouts. That handler is reached by the new API controller via _mediator.Send() for mobile, and each surviving MVC controller calls the same _mediator.Send() and maps the returned DTO back onto its Razor ViewModel , so the web page renders unchanged and its SEO URL is preserved. The ad domain is sliced per category ( Vehicles/Properties/Electronics/Lifestyle/Jobs ), each with its own repository interface, query, validator, immutable DTO, and stored procedure; one SP per category replaces the single fat Get_AllAdsPage_AllTypeOfAds , using integer FK filters, OFFSET/FETCH instead of temp tables, no read transaction, and one call that returns items + promoted sections + count. Click counts increment atomically on the primary key. Each endpoint crosses the seam only after a parity audit proves the new path reproduces the old behavior. Impact: Detail-page round trips dropped from three-to-four to one (~67–75% fewer), listing pages from two to one (~50%); the click-count race, the read-wrapping transactions and temp tables, the commandTimeout: 0 pool hazard, and the .Result / Task.Run anti-patterns are all gone, and server-side validation exists for the first time. The decorative service layer is deleted. A layer-by-layer parity audit gates every crossover: it ranked fifteen defects in the old path and — crucially — caught two paid promotion tiers (Hurry Up, Jump Up) that had a filter parameter but no result set, a revenue feature flagged at the gate before it could silently vanish in a "looks done" migration. The display-ad boundary is drawn by design: Google AdSense stays UI-only and the DB-driven display-ad subsystem stays its own feature group — neither is dragged into the marketplace ad API. Stack: .NET, ASP.NET Core, C#, MediatR, FluentValidation, Dapper + stored procedures, SQL Server, ASP.NET MVC (legacy `OnlineShop`), Razor, Clean Architecture ### Async Image Pipeline — Upload-First UX, Server-Owned Lifecycle, Bounded CDN Cost [engineering] (2026-05) — https://ammar-portfolio-zeta.vercel.app/work/async-image-pipeline Summary: Designed and built the ad-image pipeline for the Partners.com.bd marketplace across both ends — a Flutter app and a .NET API. Photos upload the moment they're picked (per-photo progress, retry just the failed one), and a server-owned lifecycle — a `dbo.PendingImageUpload` staging row, a draft-driven heartbeat TTL, a commit step, and a background sweeper — guarantees that anything abandoned is cleaned off BunnyCDN, no matter what the client does. Built across five coordinated phases and three hardening rounds. Problem: Upload-first is the mobile UX users expect (unreliable networks, immediate feedback, multi-session drafts), but it creates orphan images — photos uploaded then never attached to an ad, costing CDN storage forever. There are three orphan classes, where most solutions handle only one: (A) true abandons (uploaded, app closed, no draft), (B) stale drafts (saved, never returned to), and (C) removed-during-compose. The mobile app keeps drafts locally (Hive, 1.5s debounced auto-save), so the server has no visibility into them — ruling out any naive "delete after N hours," which would erase photos a user is still curating. And the client can't be trusted to clean up: it can be killed, uninstalled, offline, or mid-device-switch at exactly the moment cleanup matters. Approach: Invert ownership — the image's lifecycle becomes a server-owned state machine and the client only makes requests against it. Every upload inserts a tracked staging row (opaque PendingImageId , owner, CDN path, ExpiresAt = NOW + 7d ). While a draft is alive, each auto-save posts a keep-alive that pushes ExpiresAt = LEAST(NOW + 7d, UploadedAt + 15d) — monotonic, so the live draft tells the server the photos are still wanted, with a 15-day hard cap bounding storage. Ad-create resolves the ids for ownership + freshness, inlines the URLs, and flips CommittedAt (any bad id → IMAGE_INVALID 422, ad not created); discard sets DiscardedAt = ExpiresAt = NOW for instant reaping. An ImageCleanupWorker runs every 30 minutes behind a Redis SETNX lock, deletes expired/discarded rows from the CDN with bounded concurrency, dead-letters at an attempt cap, and hard-deletes after an audit window. A server backstop never trusts the client: magic-byte validation (JPEG/PNG/WebP, derives Content-Type ), explicit per-endpoint request-body limits (which killed the 100 MB-Vehicle 413 ); the same ADR-0010 backstop design carries EXIF/GPS metadata stripping (already shipping for profile/cover photos) and edge-resized delivery variants from one stored original via the CDN Optimizer. Impact: CDN cost is structurally bounded (an orphan is gone within the hard cap + one sweep), all three orphan classes are handled, and on the upload path the multi-image 413 class is eliminated and hostile uploads are rejected by magic-byte validation. Built both-ends over five phases under 149 server + 17 Flutter tests, through three hardening rounds that surfaced 50+ findings — every Critical/High/Medium fixed — including a Critical where the sweeper derived the delete path from the public URL, hit a 404 , treated it as success, and would have leaked the real file forever (fixed by carrying the storage path separately). Because deletion is irreversible, the sweeper carries a dry-run mode (log-only, for validating the delete set) and a killswitch that stops all deletes within 30 minutes with the CDN files and tracking rows intact — the brakes that make an automated, guaranteed cleanup safe to run. Stack: .NET, ASP.NET Core, C#, MediatR, Dapper + stored procedures, SQL Server, Redis (distributed lock), BunnyCDN (storage + delivery), BackgroundService / IHostedService, Serilog, Flutter, Hive (mobile drafts) ### Startup Success Prediction with Ensemble Classification [research] (2025-09) — https://ammar-portfolio-zeta.vercel.app/work/startup-success-prediction Summary: Ensemble ML that predicts startup viability from key attributes, for data-driven founder and investor decisions. Problem: Startup outcomes hinge on many weak signals; single classifiers underfit the interactions between funding, market, and team attributes. Approach: Compared AdaBoost, Random Forest, LGBM, Decision Tree, SVM, and Extra Trees, then combined the strongest into an ensemble voting classifier; full EDA and model-comparison methodology on a structured startup dataset. Impact: Identified the most effective classification approach for the dataset and packaged insights for entrepreneur/investor decision-making. Stack: Python, Scikit-learn, Pandas, Matplotlib, Seaborn GitHub: https://github.com/abuammarsami/Startups-Success-Prediction-using-Ensemble-Classification ### Age, Gender & Race Estimation with a Multi-Output CNN [research] (2025-09) — https://ammar-portfolio-zeta.vercel.app/work/multi-output-cnn Summary: One shared feature extractor, three specialized heads — simultaneous demographic estimation from facial images on UTKFace. Problem: Age, gender, and race manifest as subtle, entangled variations in facial features — harder than standard object classification, and training three separate models wastes shared structure. Approach: Multi-output CNN on UTKFace (20k+ images): shared convolutional trunk with separable convolutions, batch norm, and dropout; three output branches (age regression, gender and race classification); data augmentation throughout. Model kept to ~15 MB. Impact: Age MAE ≈ 6.8 years (R² = 0.814), gender accuracy ≈ 94.2% , race accuracy ≈ 87.1% — production-quality multi-task results in a deployable model size. Stack: Python, TensorFlow/Keras, CNNs, UTKFace GitHub: https://github.com/abuammarsami/Age-Gender-and-Race-Estimation-with-Multi-Output-CNN-Architecture ### KioskVisionAI [engineering] (2025-06) — https://ammar-portfolio-zeta.vercel.app/work/kioskvisionai Summary: Cloud-native distributed app that watches a fleet of donation kiosks with Azure Vision AI — orchestrated by .NET Aspire, deployed by generated GitHub Actions. Problem: Donation kiosks deployed across U.S. mosques fail silently — a frozen screen or dead battery means lost donations until someone physically notices. Support needed eyes on every device without anyone standing in front of it. Approach: Built a distributed .NET 9 Aspire application: kiosk screenshots flow into Azure Blob Storage, Queues fan out analysis work, and Azure Vision AI inspects each frame for anomalies, enriching metadata and firing event-driven notifications. Aspire provides orchestration, observability, and service discovery across the microservices. Provisioned with Azure Developer CLI (azd), which then auto-generated the GitHub Actions workflows for continuous delivery. Impact: Streamlined DevOps pipeline with reduced manual configuration, faster deployments, and full observability across services — intelligent monitoring for the entire kiosk fleet. Stack: .NET 9, .NET Aspire, Azure Blob Storage, Azure Queues, Azure Vision AI, Azure Developer CLI (azd), GitHub Actions ### Salesforce Synchronization Platform [engineering] (2025-03) — https://ammar-portfolio-zeta.vercel.app/work/salesforce-sync-platform Summary: Automated integration platform keeping payment systems and Salesforce CRM in sync — daily jobs, custom mappings, retries, and error recovery instead of manual entry. Problem: Payment and donor data lived in the payment platform; the operations team lived in Salesforce. Keeping them consistent meant daily manual data entry — slow, error-prone, and unscalable. Approach: Built an automated synchronization platform: scheduled daily jobs pull transaction and donor data, apply custom field mappings and data transformations, and push to Salesforce with retry handling and error recovery — data consistency managed end-to-end rather than record-by-record. Impact: Eliminated manual CRM entry, improved Salesforce accuracy, and turned a recurring operations chore into an automated workflow. Stack: .NET, Salesforce API, SQL Server, scheduled background services ### ACH Payment Integration — One-time & Recurring [engineering] (2025-01) — https://ammar-portfolio-zeta.vercel.app/work/ach-payment-integration Summary: Secure ACH, Apple Pay, and Google Pay payment workflows for donation kiosks and recurring billing across Stripe and Authorize.Net. Problem: U.S. mosque clients needed low-fee recurring donations (ACH beats card fees substantially for large recurring gifts) plus modern wallet checkout — across two payment processors, without compromising compliance or reliability. Approach: Implemented ACH workflows on both Stripe and Authorize.Net APIs for one-time and recurring transactions covering schools, events, and memberships. Added Apple Pay and Google Pay through Stripe Payment Intents with tokenized wallet flows. Hardened the pipeline for retries, webhooks, and reconciliation. Impact: Payment rails supporting millions of dollars in annual volume for 20,000+ users — secure recurring revenue for every client, faster mobile checkout, and improved donation conversion across one-time and recurring payments. Stack: .NET Core, Stripe API (Payment Intents, ACH), Authorize.Net API, SQL Server, webhooks ### Remote Kiosk Device Management System [engineering] (2024-08) — https://ammar-portfolio-zeta.vercel.app/work/remote-kiosk-management Summary: Web portal for live monitoring and remote control of donation kiosk fleets. Problem: Supporting kiosks in the field meant blind debugging — no visibility into battery, connectivity, or uptime, and every fix required someone on-site. Approach: Built a web-based management portal integrating KLR REST APIs for device insights (battery, Wi-Fi, uptime) and remote commands (reboot, screenshot), with live status views for the support team. Impact: Materially improved support response time — most issues now diagnosed and fixed remotely. Stack: .NET, REST APIs (KLR), SQL Server, JavaScript/Alpine.js ### Data Import & Onboarding Automation [engineering] (2024-04) — https://ammar-portfolio-zeta.vercel.app/work/data-import-automation Summary: Automated SQL Server pipelines that turn messy client Excel templates into validated production schemas. Problem: Onboarding a new school or membership org meant hand-massaging spreadsheet exports into the database — slow, error-prone, and unscalable as the client base grew. Approach: Built automated data-import pipelines that ingest client Excel templates, validate against schema rules, transform, and load into SQL Server — with clear error reporting for bad rows instead of silent corruption. Impact: Onboarding time for new schools and memberships reduced by 60% , with schema validation and consistency guaranteed. Stack: SQL Server, .NET, Excel automation ### Machine Learning in the Realm of Quantum (B.Sc. Thesis) [research] (2022-08) — https://ammar-portfolio-zeta.vercel.app/work/quantum-machine-learning-thesis Summary: Undergraduate thesis (CSE499, North South University, supervised by Dr. Mahdy Rahman Chowdhury): a state-of-the-art review of quantum machine learning plus head-to-head MNIST experiments — a 4-qubit quanvolutional network and a continuous-variable photonic QNN against classical baselines. Problem: Classical ML hits scaling walls that quantum computing may sidestep — but which QML models actually work today, how do you get classical data into a quantum circuit, and where do hybrid models genuinely help? The literature was fragmented and the honest baselines were missing. Approach: Built and trained two first-generation hybrid models in PennyLane + Keras on MNIST: a quanvolutional network (2×2 patches angle-encoded into 4 qubits via RY rotations, random variational layer, Pauli-Z readout as feature channels) and a continuous-variable QNN on a photonic simulator (squeezers, interferometers, displacement, Kerr gates; 4 quantum layers, 56 quantum parameters) — each against an equivalized classical network, comparing accuracy and convergence speed. Impact: Quanvolution reached 92% test accuracy vs 96% classical (and converged to optimum loss faster); the CV-QNN reached 72% vs 88% . An honest, measured picture of the NISQ era — and the foundation for this site: the same parameter-shift mathematics now trains live in the hero and teaches visitors in /learn . The full thesis is distilled at /research/quantum-machine-learning-thesis . Stack: Python, PennyLane, TensorFlow/Keras, Strawberry Fields, Jupyter GitHub: https://github.com/abuammarsami/CSE499.06-QML- ### Bangla POS Tagging with Knowledge Distillation [research] (2022-08) — https://ammar-portfolio-zeta.vercel.app/work/bangla-pos-tagging Summary: Directed research (CSE498, North South University, supervised by Dr. Nabeel Mohammed): fighting severe class imbalance in Bangla POS tagging by distilling a decision tree's leaf-node "dark knowledge" into a neural student — the reverse of the usual distillation direction. Problem: Bangla is low-resource: the main benchmark (Microsoft IL-POST, 102,933 hand-annotated tags) is heavily imbalanced across its 30 tag classes, so plain neural taggers overfit the majority tags and ignore the rare ones. Approach: Extracted contextual embeddings from three Bangla BERT models and probed all 12 layers with a self-built polysemy dataset to pick the most semantic layer per model. Observed that a decision-tree tagger degrades less on rare tags than a neural network, then treated the class distributions in the tree's terminal nodes as soft targets — distilling tree → network. PyTorch, scikit-learn, Hugging Face. Impact: Best student reached 0.69 macro-F1 / 0.79 accuracy , with two transferable findings: tree and network performance move in opposite directions across BERT depth, and the last BERT layer is not always the most semantic. The distillation idea carried into later work on network-intrusion detection. Distilled write-up at /research/bangla-pos-tagging . Stack: Python, PyTorch, Scikit-learn, Hugging Face, BERT ## Publications & theses (full text distilled at /research) ### Bangla POS Tagging Using Supervised Learning and Knowledge Distillation [thesis] (Directed research (CSE498), North South University, 2022) — https://ammar-portfolio-zeta.vercel.app/research/bangla-pos-tagging Authors: Md. Abu Ammar, Sadia Afrin Tamanna · supervised by Dr. Nabeel Mohammed Abstract: Part-of-speech tagging for Bangla — a low-resource language whose main benchmark, Microsoft IL-POST, is severely class-imbalanced — using contextual embeddings from three Bangla BERT models. A decision tree proves less biased by the imbalance than a neural network, motivating an unusual distillation direction: treat the class counts in the tree's leaf nodes as a probability distribution and distill that "dark knowledge" from the tree into the neural student . Results: The best student reached 0.69 macro-F1 / 0.79 accuracy on test (Sagorsarker, layer 7); the best tree reached 0.46 / 0.60. Two findings stand out: the tree's performance falls with deeper BERT layers while the network's rises — evidence they consume the embedding geometry differently — and layer probing showed the last layer is not always the most semantic. The full distilled-student evaluation was left incomplete when the semester ended, so this manuscript deliberately claims the method, not a headline number. PDF: https://ammar-portfolio-zeta.vercel.app/papers/bangla-pos-tagging.pdf ### Machine Learning In The Realm Of Quantum: The State-Of-The-Art, Challenges, Future Vision and Applications Of It [thesis] (B.Sc. thesis (CSE499), North South University, 2022) — https://ammar-portfolio-zeta.vercel.app/research/quantum-machine-learning-thesis Authors: Md. Abu Ammar, Sadia Afrin Tamanna · supervised by Dr. Mahdy Rahman Chowdhury Abstract: A comprehensive review of the state of the art in quantum machine learning, paired with hands-on classification experiments: two first-generation hybrid quantum-classical models — a quanvolutional neural network on a gate-based simulator and a continuous-variable quantum neural network on a photonic simulator — trained on MNIST and compared head-to-head against classical baselines on accuracy and convergence. Results: The classical baselines won — and the margins are the finding. The quanvolutional model reached 92% test accuracy against a 96% classical CNN, and converged to its optimum loss faster than the classical model. The CV-QNN reached 72% against an 88% classical baseline. First-generation QML models trained on classical data did not beat optimized classical networks, but the gate-based approach came close — the honest state of the NISQ era, measured directly. PDF: https://ammar-portfolio-zeta.vercel.app/papers/quantum-machine-learning-thesis.pdf ### Deep Learning-Based Blood Cell Detection in Microscopic Images for Enhanced Disease Recognition with RetinaNet [report] (Graduate coursework (CSE583, Digital Image Processing), North South University, 2023) — https://ammar-portfolio-zeta.vercel.app/research/blood-cell-detection Authors: Md. Abu Ammar, Sadia Afrin Tamanna Abstract: Fine-tuning a pretrained RetinaNet (ResNet backbone + feature pyramid network, focal loss) on the BCCD microscopy dataset to detect red blood cells, white blood cells, and platelets — 364 images, 4,888 annotations, three classes — reaching mAP 0.876 at IoU 0.5 and 55.25% at IoU 0.50:0.95 on the test split. Results: mAP 0.876 @ IoU 0.5 and 55.25% @ 0.50:0.95 on test. Honest comparison: specialized YOLO variants do better on BCCD (YOLOv5x 0.923, CST-YOLO 0.927 @ 0.5) — the fine-tuned single-stage RetinaNet gets close without architecture surgery, which was the point of the exercise. PDF: available on request ### Exploring New Attack Patterns in Computer Networks through Anomaly Detection and Knowledge Distillation [report] (Graduate research report, North South University, 2023) — https://ammar-portfolio-zeta.vercel.app/research/network-anomaly-detection Authors: Md. Abu Ammar, Sadia Afrin Tamanna Abstract: Signature-based intrusion detection can't see attacks it has no signature for. This work trains four classical supervised models on the CICIDS2017 network-traffic benchmark, selects the strongest (a decision tree) as a teacher, and distills its knowledge into a neural student intended to flag anomalous — potentially novel — traffic patterns without predefined signatures. Results: The teacher was excellent: 0.97 test macro-F1 / 0.98 accuracy (KNN close behind at 0.96). The distilled student managed only 0.75 / 0.79 — a negative result we report as the finding it is. Tree-structured knowledge did not transfer into the student the way soft-label distillation from a neural teacher does; decision boundaries a tree encodes as hard axis-aligned splits don't survive the trip through a softmax. PDF: available on request ## Skills - Backend: .NET Core, ASP.NET MVC, .NET Aspire, Entity Framework, Dapper, Repository Pattern, Clean/Onion Architecture, Django, REST APIs, SignalR - AI/ML: PyTorch, TensorFlow/Keras, Scikit-learn, Hugging Face (BERT), Pandas, NumPy, knowledge distillation, ensemble methods, CNNs (multi-output), NLP - Quantum: PennyLane, IBMQ, Qiskit (basics), variational quantum circuits, encoding methods, hybrid classical-quantum models, CVQNN, quanvolutional networks - DevOps & Cloud: Azure (Functions, App Services, Blob Storage, Queues, Vision AI), Azure Developer CLI (azd), GitHub Actions, Jenkins, Bitbucket Pipelines, IIS, PowerShell, Docker basics - Frontend: Razor pages, HTML5, CSS3, JavaScript (ES6+), Alpine.js - Testing: Selenium, NUnit, TestNG, REST Assured, Aquality Framework, Postman, Vitest-style unit testing - Databases: Microsoft SQL Server, MySQL, PostgreSQL - Payments & APIs: Stripe (Payment Intents, ACH, wallets), Authorize.Net, Twilio Lookup, KLR Kiosk APIs ## Interactive quantum curriculum (/learn) - Lesson 1: The qubit — A bit is a light switch: on or off. A qubit is a point on a sphere — and that difference is the whole story. - Lesson 2: Superposition — "Both at once" has a precise meaning: the arrow sits on the equator. - Lesson 3: Entanglement — Two qubits can hold information that neither one carries alone. Watch each sphere forget — while the pair remembers. - Lesson 4: Measurement — Looking at a qubit is not free. Measurement is a weighted dice roll — and it destroys the state you rolled. - Lesson 5: Training a quantum circuit — Put dials on a quantum circuit and it becomes a machine-learning model. This is quantum machine learning — and it's what runs on this site's homepage. - Lesson 6: Quanvolution: QML on images — A convolution slides a filter across an image. A quanvolution slides a quantum circuit. This was my thesis. ## Education - MS in Computer Science, North South University (expected Nov 2026) - BS in Computer Science (minor: Mathematics), North South University, CGPA 3.58/4.00