Full-stack and AI automation engineer. Zimbabwe, UTC+2.

I build the software small businesses run on.

Websites, WhatsApp assistants, automations and back-office systems for companies in Zimbabwe, Zambia and the UK.

01 · WhatsApp assistants

Chiedza answered 3,572 customer messages in one month.

Chiedza is an AI sales assistant for a solar company. From 9 September to 8 October 2026 it handled 3,572 WhatsApp messages and logged 361 leads straight onto the sales board.

3,572
messages handled
361
leads created
30
days

Chenai does the same job for Slab Sales Africa, and can find and share any of 3,559 past social posts.

02 · Infrastructure

One server I run myself, under every bot.

An Ubuntu server with a firewall, reverse proxy and automatic TLS. It runs self-hosted n8n, Supabase and the WhatsApp gateway for several client numbers, plus Docker staging copies of client stores.

03 · Websites

20+ client projects, built for the client's own hosting.

From a Next.js storefront for TV Sales & Home with about 2,000 products, to Triangle Country Club, live at trianglecountryclub.com. Fast on a phone, and easy for the client's team to keep up to date.

Systems that do real work

The jobs I enjoy most sit behind the website: stock, orders, approvals, customer messages and the records that prove who did what.

In build, Oct 2026 to Mar 2027

TV Sales & Home e-commerce rebuild

A new storefront for TV Sales & Home, a furniture and appliance retailer in the Axia group. Next.js on Vercel in front of WooCommerce, with categories kept in step with the company's OpenBravo ERP.

  • ~2,000 products
  • 1,755 live URLs mapped so search rankings carry over
  • Unit and end-to-end tests, security scans, and a feature, develop, staging, production release path
  1. feature
  2. develop
  3. staging
  4. main

Live

Chiedza, an AI sales assistant for solar

Answers enquiries on WhatsApp for a solar company and logs each lead straight onto their monday.com sales board.

3,572 messages and 361 leads from 9 Sep to 8 Oct 2026.

Live

Chenai, a WhatsApp sales assistant

Answers product questions for Slab Sales Africa, shares links to any of 3,559 past social posts, and hands warm leads to a sales rep. A second model checks every hand-off before it goes through.

Replaced a 161-node workflow with one path. Social posts now go out only after the owner approves them on WhatsApp.

Planned, docs complete

ZimTickets

Event ticketing for Zimbabwe on web, Android and iOS. Organisers list events, buyers pay by EcoCash, OneMoney, InnBucks, ZimSwitch or card, and tickets scan at the door.

Task portal showing a list of assigned tasks

Deployed

Team task portal with WhatsApp reminders

Workspaces, projects, tasks and assignees on PostgreSQL. The database itself sends reminders to people's WhatsApp when work is due.

Masvingo Chicks website home page

Assistant live, site in final review

Masvingo Chicks: site, agent network and poultry assistant

React site with a 3D map of sales agents, a PHP and MySQL agent application system, and a WhatsApp assistant in TypeScript on Claude that answers poultry and price questions, behind a send guard.

Websites

Built for the client's hosting, fast on a phone, and easy for their team to keep up to date. Hover a site to see it on mobile.

Some of this work was delivered with Single Thorn Studio and Rhino Creative. KW Enterprises design by Samuel Smith.

The side of code

Short pieces from real projects, to show how I think about the parts that can go wrong.

The client's rule was that no customer ever gets a message they did not ask for. So every send passes one gate, and there is no override flag for a bug or a bad prompt to flip.

// guard.ts (Masvingo Chicks WhatsApp assistant)
async function dmDecision(redis: Redis, number: string): Promise<SendDecision> {
  if (!/^\d{8,15}$/.test(number)) {
    return { allowed: false, reason: "not a personal number" };
  }
  if (isStaff(number)) return { allowed: true, reason: "staff" };

  const seen = await redis.get(inboundKey(number));
  if (!seen) {
    // The branch that makes an unsolicited customer message impossible.
    log.warn("blocked outbound to a number with no open inbound window", { number });
    return { allowed: false, reason: "no inbound message inside the reply window" };
  }
  if (expired(seen)) return { allowed: false, reason: "reply window expired" };

  return { allowed: true, reason: "reply" };
}

Automations and the servers under them

Automations

Daily post approval
Picks the next product photo, writes a caption, frames it, and posts only after the owner taps approve on WhatsApp.
Video posting
Overlays a branded frame on product clips with FFmpeg and publishes to Facebook and Instagram Reels.
Guest reviews import
Moves reviews from a team spreadsheet onto a WordPress site every hour, with no copy and paste.
WhatsApp to monday.com
An AI assistant for a solar company that logs enquiries straight onto their sales board.
Agency job intake
Slack commands that turn a client brief into a job card and route it to design, film or edit.

What I run myself

  • Ubuntu server with a firewall, reverse proxy and automatic TLS
  • Self-hosted n8n for workflows
  • Self-hosted Supabase (PostgreSQL, auth, scheduled jobs)
  • WhatsApp gateway for several client numbers
  • Docker staging copies of client stores
  • cPanel hosting, PHP and MySQL for sites that need to live there

Tools I use most

  • TypeScript
  • React
  • Next.js
  • Node
  • PHP
  • PostgreSQL
  • MySQL
  • WordPress
  • WooCommerce
  • n8n
  • Docker
  • Python
  • Playwright
  • Claude and Gemini APIs

How I work

Your rules go in the code

If something must never happen, like a message to a customer who did not ask or a price the AI made up, I build it so it cannot happen, not just so it usually does not.

Every change has a trail

Work moves through version control and a staging copy before it goes live. You can see what changed, when, and who changed it.

Customer data stays put

Staging uses product data only. Real customer records stay where they belong and are never copied to a test server.

Plain updates, written down

Scope, decisions and open questions live in a document you can read, so nothing depends on someone's memory of a call.

Have something that needs building?

Tell me what the business does and where it hurts.

Email me

hello@keithwithasideofcode.com