// Software developer · C# .NET · full-stack · Durban
From Hello, World
to systems that move real money.
I'm Preshen Naidoo. This site is my journey as a developer, from my first diploma lecture to production .NET systems and AI. Scroll through it one commit at a time.
- years in production
- 3.5
- years in production
- systems worked on in 17 months
- 33
- systems worked on in 17 months
- commits since May 2025
- 1.1k
- commits since May 2025
- a1f03c2 · 2018 · Durban University of Technology
Hello, World.
Higher Certificate in Information Technology at DUT. Programming fundamentals, databases and networking. The first time a program did exactly what I told it to.
- + Programming fundamentals
- + SQL basics
- + Networking
Program.csC#using System; class Program { static void Main() { Console.WriteLine("Hello, World!"); } }What it took: Starting from zero and deciding this was the thing I wanted to be good at.
- b72e9d4 · 2019 – 2021 · Durban University of Technology
Learning to build, not just write.
A Diploma in ICT: Applications Development. Object-oriented design, relational databases and web development, finished through the lockdown years.
- + OOP
- + C#
- + Relational databases
- + Web fundamentals
Student.csC#public class Student { public int Id { get; init; } public string Name { get; init; } = ""; public List<Module> Modules { get; } = new(); public decimal Average() => Modules.Count == 0 ? 0 : Modules.Average(m => m.Mark); }What it took: Three years of study, most of it remote, and finishing anyway.
- c3d81aa · Feb 2023 · Gaming and sports betting
Day one: I didn’t know what a stored procedure was.
I joined my first team knowing no UI frameworks, no APIs and no stored procedures. I read the codebase, asked a lot of questions and shipped small fixes until the patterns made sense.
- + T-SQL
- + Stored procedures
- + Git
- + Azure DevOps
usp_GetOpenOrders.sqlT-SQLCREATE PROCEDURE dbo.usp_GetOpenOrders @CustomerId INT, @Since DATETIME2 AS BEGIN SET NOCOUNT ON; SELECT o.OrderId, o.Total, o.CreatedAt FROM dbo.Orders AS o WHERE o.CustomerId = @CustomerId AND o.Status = 'Open' AND o.CreatedAt >= @Since ORDER BY o.CreatedAt DESC; ENDWhat it took: Saying “I don’t know yet” out loud, then closing that gap every week.
- d90b1e7 · 2023 · Gaming and sports betting
Three frameworks in one year.
Within months I was building front ends in React, Angular and Vue, plus the APIs and Dapper queries behind them. Live data taught me to care about state and performance.
- + React
- + TypeScript
- + Angular
- + Vue
- + Dapper
- + REST APIs
LiveScore.tsxTypeScriptexport function LiveScore({ feed }: { feed: Match[] }) { const [live, setLive] = useState(feed); useEffect(() => { const unsub = subscribe((m) => setLive((prev) => prev.map((x) => (x.id === m.id ? m : x)))); return unsub; }, []); return <ScoreList matches={live} />; }What it took: Evenings with documentation, and rewriting my first components once I knew better.
- e44f0c1 · Mar 2024 · In-house team lead
Leading three developers.
I became team lead for one of two development teams: sprint planning, code reviews and release sign-off, while still writing code. Unblocking people turned out to be a skill of its own.
- + Code review
- + Sprint planning
- + Mentoring
- + CI/CD
azure-pipelines.ymlYAMLtrigger: branches: include: [ main ] stages: - stage: Build jobs: - job: build_and_test steps: - task: DotNetCoreCLI@2 inputs: { command: build } - task: DotNetCoreCLI@2 inputs: { command: test }What it took: Learning to review code kindly and plan for other people, not just myself.
- f1a7d36 · Dec 2024 · By choice
Choosing the keyboard over the meetings.
After nine months I stepped back to engineering full time. I wanted depth: architecture, multi-tenant design, integrations and identity verification.
- + Multi-tenant design
- + JWT auth
- + System design
TenantMiddleware.csC#public interface ITenantContext { Guid TenantId { get; } string ConnectionString { get; } } app.Use(async (ctx, next) => { var tenant = await resolver.ResolveAsync(ctx.Request.Host); ctx.Items["tenant"] = tenant; await next(); });What it took: Knowing what kind of engineer I want to be, and acting on it.
- 07c2be9 · May 2025 · Collections and payments software
A new codebase, and a product in a month.
I joined a collections and payments software house and started shipping in week one: file converters, email tooling, and a document-validation product built from scratch in a single month, with PDF text extraction, OCR for scans and scheduled email jobs.
- + OCR pipelines
- + PDF processing
- + Quartz jobs
- + ASP.NET MVC
DocumentReader.csC#public async Task<ReadResult> ReadAsync(Stream pdf, DocType type) { // cheap path first: text that is already in the PDF var text = await _pdfText.ExtractAsync(pdf); if (string.IsNullOrWhiteSpace(text)) text = await _ocr.RecogniseAsync(await _raster.ToImagesAsync(pdf)); var match = _patterns[type].Match(text); return match.Success ? ReadResult.Found(match) : ReadResult.NeedsReview(text); }What it took: Saying yes to a lot, learning every stack the company runs, and still finishing things.
- 0a93f1d · Sep 2025 · Internal platforms
Rebuilding a live platform, twice.
An ageing internal platform needed replacing. I rewrote it once in MVC, then again as a .NET 8 API with a Vue 3 and TypeScript front end: refresh-token auth, role gating, rate limiting, Kanban boards and release sign-off. Then I built the pipelines and runbook that took it live.
- + Vue 3
- + .NET 8 Web API
- + Azure DevOps pipelines
- + IIS
- + Playwright
useTickets.tsTypeScriptexport function useTickets(filters: Ref<TicketFilters>) { const tickets = ref<Ticket[]>([]); const loading = ref(false); watch(filters, async (f) => { loading.value = true; tickets.value = await api.tickets.list(f); router.replace({ query: toQuery(f) }); // filters survive a refresh loading.value = false; }, { deep: true, immediate: true }); return { tickets, loading }; }What it took: Owning it past the demo: pipelines, a production runbook, a user guide and the support after go-live.
- 1c5e7b2 · Mar 2026 · Integrations
Integrations that move money.
Payment rails like PayShap, Ozow and DebiCheck, a dialer inside the agents’ desktop, and a WhatsApp chatbot that hands customers a secure, time-limited link to pay. Most of my work sits where two systems have to trust each other.
- + Payment rails
- + Telephony APIs
- + Encrypted tokens
- + Angular
- + .NET 10
LoginLinkService.csC#public string CreateLink(string accountRef, TimeSpan ttl) { var payload = new LinkPayload(accountRef, DateTimeOffset.UtcNow.Add(ttl)); var token = _protector.Protect(JsonSerializer.Serialize(payload)); return $"{_options.PortalUrl}/auto-login?t={Uri.EscapeDataString(token)}"; }What it took: Reading other people’s API docs very carefully, and designing for the failure cases first.
- 2f8d64a · Jul 2026 · Architect and sole developer
Local AI with answers you can check.
I designed and built a knowledge platform that runs entirely on local models: a durable ingestion queue, hybrid vector search, agents that cite their sources, and an evaluation harness so quality is measured, not guessed.
- + RAG
- + Qdrant
- + Ollama
- + SignalR
- + Evaluation
Retriever.csC#var dense = await _vectors.SearchAsync(await _embed.EmbedAsync(question), top: 40); var sparse = await _lexical.SearchAsync(question, top: 40); // fuse both result lists, then keep only chunks we can cite var ranked = ReciprocalRankFusion.Merge(dense, sparse) .Where(c => c.Source is not null) .Take(8) .ToList();What it took: Writing the architecture before the code, and testing every endpoint’s security, not just the happy path.
- 18d9e02 · Sep 2026 · Microsoft certification
Certified in AI transformation.
Microsoft Certified: AI Transformation Leader, passed with 90%. AI is already part of how I work. This site was designed and built with Claude as my pair.
- + AI strategy
- + Responsible AI
- + AI-assisted development
certifications.mdMarkdown## Microsoft Certified: AI Transformation Leader - Earned: 11 September 2026 - Score: 90% - Verify: learn.microsoft.com/users/preshennaidoo-0314 > Next up: hands-on Azure AI certificationsWhat it took: Studying after hours alongside a full-time role.
- HEAD · Next · Where I’m heading
Next: AI engineering in .NET.
An intermediate role where I can go deeper into AI integration inside real .NET systems, with more certifications along the way.
- + Open to work
- + Remote or hybrid
roadmap.tsTypeScriptexport const next = { role: "Intermediate Software Developer", focus: ["AI integration", ".NET", "distributed systems"], certifications: ["Azure AI Engineer"], location: "remote | hybrid", } as const;What it took: This part is still being written.
What I work with
- C# 2023
- .NET 10 / 8 2025
- ASP.NET Core Web API 2023
- MVC & Web Forms 2023
- Worker services 2025
- SignalR 2026
- JWT & refresh tokens 2023
- SQL Server 2023
- T-SQL procs & TVPs 2023
- Dapper 2023
- Entity Framework 2023
- PostgreSQL 2023
- SQL database projects 2026
- Vue 3 2025
- TypeScript 2023
- Angular 2023
- React 2023
- Next.js 2024
- Vite 2025
- Tailwind 2023
- Azure DevOps pipelines 2025
- Self-hosted agents 2026
- IIS 2023
- Docker 2024
- Serilog 2025
- Playwright 2026
- Payment rails 2025
- Dialer telephony 2025
- WhatsApp chatbot 2026
- OCR & PDF 2025
- KYC 2024
- RAG 2026
- Qdrant hybrid search 2026
- Ollama 2026
- Evaluation harnesses 2026
- AI-assisted development 2024
The year next to each skill is when I started using it in production.
- ✔ Microsoft Certified: AI Transformation Leader 2026 · 90%
- ✔ Cisco: Networking Essentials
- ✔ Cisco: Introduction to Cybersecurity
- ✔ Cisco: Cybersecurity Essentials
- ✔ NDG Linux Unhatched
Designed and built with Claude as my pair. Every line reviewed by me.
- 01 · designMockups on a Claude design canvas
- 02 · buildNext.js, React Three Fiber, Lenis
- 03 · shipVercel, Neon Postgres, CMS