Engineering Portfolio

Full-stack engineering, architecture, reliability and developer tooling.

Published:

Updated:

About Me

I'm a software engineer working primarily with TypeScript across frontend, backend and delivery infrastructure, with experience across SaaS products and large-scale e-commerce platforms. My recent work has spanned both the modernization of a mature legacy codebase and the development of a new multi-market platform from the ground up. This has included reducing technical debt, replacing legacy integrations, strengthening type safety and testing, and evolving application and API architecture, as well as taking ownership of architectural decisions, CI/CD and production delivery.

I remain actively involved in hands-on product development and production engineering today. Below are selected case studies and engineering work covering different parts of this experience.

Restaurant Services SaaS Platform

Technical Lead · Full-Stack Architecture · 2020-2022 · Germany

Selected case study from my earlier full-stack engineering work.

A multi-tenant SaaS platform for restaurants with customer-facing storefronts, restaurant administration, ordering, delivery, payments, geospatial services and platform-level administration.

I worked as the technical lead across frontend and backend architecture, database design, CI/CD, deployment workflows and developer support.

Selected technologies: TypeScript, React, Node.js, Next JS, Django, PostgreSQL, PostGIS, Docker, Stripe, PayPal, OAuth 2.0, Google Maps APIs, CI/CD

Project Overview

The platform supported restaurant-specific storefronts as well as a central marketplace. Restaurants could also connect custom domains.

Core functionality included:

  • restaurant discovery and filtering
  • custom restaurant domains
  • customer accounts, carts and checkout
  • configurable products and toppings
  • delivery areas and scheduling
  • Stripe and PayPal payments
  • restaurant tariffs and billing
  • platform and restaurant administration
  • PDF billing documents
Restaurant portal homepage
Customer-facing restaurant portal with regional selection and a three-step ordering flow.

Multi-Tenant Architecture

Tenant isolation was one of the main architectural requirements.

Requests to restaurant domains were resolved to a tenant context before API operations. Restaurant data remained tenant-scoped, while the central marketplace supported authorized cross-restaurant customer features such as orders, carts, vouchers and favourites.

Multi-tenant restaurant platform architecture showing restaurant-specific domains resolved to isolated tenant contexts, alongside a central marketplace providing authorized cross-tenant features across multiple restaurants.
Multi-tenant architecture with isolated restaurant contexts and a central marketplace providing authorized cross-tenant features.

Authorization and role-based permissions provided an additional boundary for restricted operations.

Restaurant search interface
Restaurant discovery based on the customer location and available delivery options.
Restaurant search results
Location-based restaurant results using an address and configurable search radius.

Product Domain Modelling

Restaurant products required more than a single product-price model.

The model supported:

  • sizes and variants with different prices
  • topping groups
  • variant-dependent topping prices
  • configurable free topping allowances
  • optional and required selections
  • categories and subcategories
Django administration interface with an embedded React product configurator for managing complex restaurant products, including sizes, dough, sides, topping groups, quantities and prices stored in cents.
Custom React product configurator embedded into Django administration. Complex product options were stored as structured JSON, validated by the backend and used by the storefront to build configurable products and calculate pricing.

A separate administration interface allowed restaurant staff to manage these structures without database-level changes.

Tenant-Level Order Management

Each restaurant operated as an independent tenant with access to its own operational and financial data. The restaurant administration interface provided a dedicated view of orders, including payment amounts, platform fees, taxes, and the resulting earnings for each transaction.

Restaurant administration dashboard showing individual orders with payment amounts, fees, taxes, and restaurant earnings.
Restaurant-level order management gives each restaurant access to its own orders and financial breakdowns, including payments, platform fees, taxes, and the resulting earnings for each order.

The platform also supported a subscription-based model, with different plans defining the services and commercial conditions available to restaurants.

Geospatial Delivery Logic

PostgreSQL with PostGIS was used for restaurant locations and delivery geometry. Google Maps and geocoding APIs supported:

  • restaurant location management
  • delivery-area configuration
  • address geocoding
  • delivery eligibility
  • map-based administration
Restaurant delivery area configuration
Map-based delivery configuration backed by PostGIS spatial data.

Date, Payments and Billing

Time-sensitive functionality included:

  • opening and delivery times
  • scheduled orders and prioritisation
  • subscription and billing periods
  • monthly receipts and reporting

Timestamps were stored consistently while German business-time rules were applied where required.

External integrations included:

  • Stripe with 3D Secure
  • PayPal
  • Google Maps and geocoding
  • PDF generation

Restaurant plans, billing periods, statistics and receipt generation were configurable through the platform.

Administrative functionality included drag-and-drop ordering of categories, subcategories and products.

Meal category management in admin
Drag-and-drop administration for ordering meal and drink categories and subcategories.
Text
MENU STRUCTURE MANAGEMENT
 
┌──────────── Django Admin ───────────┐        ┌──── Restaurant Storefront ─────┐
│                                     │        │  trattoria-verde.example       │
│  Categories                         │        │                                │
│                                     │        │  BREAKFAST  PIZZA  STARTERS    │
│  ↕ Breakfasts                       │   →    │  DESSERTS   BEVERAGES          │
│  ↕ Pizza                            │        │  ────────────────────────────  │
│      ↕ Homemade                     │        │                                │
│         Margherita                  │        │          [ food hero ]         │
│         Carbonara                   │        │                                │
│      ↕ Vegan Pizzas                 │        │  HOMEMADE   VEGAN PIZZAS       │
│         Vegetable Pizza             │   →    │  ────────────────────────────  │
│  ↕ Starters                         │        │                                │
│  ↕ Desserts                         │        │  Margherita        €11.25      │
│  ↕ Beverages                        │        │  Carbonara           €9.65     │
│                                     │        │                                │
└─────────────────────────────────────┘        └────────────────────────────────┘
              │                                           ▲
              └──────────── persisted ordering ───────────┘
 
      Drag & drop hierarchy              Tenant-specific menu rendering
 
      Categories  ─────────────────────→ top navigation
      Subcategories ───────────────────→ menu sections
      Products ────────────────────────→ ordered product lists

Security

Security-related work included:

  • strict tenant isolation
  • role-based permissions
  • protected administrative operations
  • CSRF protection for state-changing form submissions
  • authentication-state handling
  • CORS and cookie configuration
  • payment-related security constraints

Access restrictions were enforced beyond the frontend UI and before sensitive data operations.

Deployment and Operations

The application ran in Docker- and Kubernetes-based infrastructure. Kubernetes provisioning and cluster configuration were handled by DevOps; I worked with the deployed environments as part of day-to-day development and maintenance.

Text
                    ┌────────────────────────────────────┐
     DevOps ·······>│   Kubernetes-based infrastructure  │
     cluster        │                                    │
     provisioning   │   ┌─────┐ ┌─────────┐ ┌────────┐   │
                    │   │ DEV │ │ STAGING │ │  PROD  │   │
                    │   └─────┘ └─────────┘ └────────┘   │
                    │                 ↑                  │
                    │                 │ restore          │
                    │          ┌──────────────┐          │
                    │          │   Database   │          │
                    │          └──────┬───────┘          │
                    │                 │ dump             │
                    │          ┌──────▼───────┐          │
                    │          │ Backup / Dump│          │
                    │          └──────────────┘          │
                    └────────────────────────────────────┘
                          ↑        ↑          ↑
                          │        │          │
                       deploy   rollback   troubleshoot
                          │        │          │
                    ┌─────────────────────────────────┐
                    │ MY OPERATIONAL RESPONSIBILITIES │
                    │                                 │
                    │ • deployments                   │
                    │ • rollbacks                     │
                    │ • file transfers                │
                    │ • database dumps                │
                    │ • test environment restores     │
                    │ • deployed-app debugging        │
                    └─────────────────────────────────┘

Testing

Testing included:

  • unit testing of application and domain logic
  • acceptance testing of user-facing workflows
  • verification of backend and frontend behaviour across core restaurant operations

Architecture Trade-Offs

The platform was built as a monolith. This kept development and deployment manageable for a small team, but coupling increased as ordering, billing, delivery, payments and administration grew.

If redesigning it today, I would keep the operational simplicity of a monolith initially but define clearer internal domain boundaries. Services would be extracted only where independent scaling, reliability or deployment requirements justified it.

Technical Leadership

My responsibilities included:

  • frontend and backend architecture
  • database design
  • CI/CD and deployment workflows
  • technical decisions and feature decomposition
  • implementation and maintenance
  • supporting less experienced developers

Full-Stack Architecture & Deployment

Independent Project · Full-Stack Engineering · 2022-2024

Full-stack system design, deployment and operational ownership.

I designed, developed, deployed and operated a personal full-stack application across the frontend, backend and infrastructure layers.

The system combined a React frontend with a Node.js GraphQL backend, ArangoDB and Redis Streams for asynchronous message queues and event processing. The backend used command-driven use cases, dependency injection, repositories and application events, with an architecture influenced by ports-and-adapters patterns.

Beyond application development, I built and maintained the deployment path myself: Dockerized services, Nginx configuration, DigitalOcean infrastructure, GitHub Actions CI/CD, database backups and recovery procedures.

Selected technologies: TypeScript, React, Node.js, GraphQL, ArangoDB, Redis Streams, Docker, Nginx, DigitalOcean, GitHub Actions

Engineering focus: Full-Stack Architecture · System Design · DevOps Mindset · Operational Ownership

Full-stack architecture showing the React frontend, GraphQL backend, DigitalOcean infrastructure, Nginx, Docker services, Redis and ArangoDB.
System architecture and deployment boundaries across the frontend, backend and infrastructure.

The project gave me hands-on experience with the concerns that appear once an application leaves local development: deployment automation, service configuration, persistence, infrastructure boundaries, backups and recovery.

→ Read the full Engineering Lab case study

Reliability & E2E Engineering

E2E Engineering · 2023-2026 · Professional Work

E2E automation since 2023, with dedicated ownership of test architecture and maintenance from 2025.

E2E Suite Ownership

From 2025, I became the primary engineer responsible for an existing E2E suite that had been largely abandoned after its initial implementation.

I inherited roughly 70-80 legacy tests with obsolete scenarios, duplicated market-specific coverage, unreliable selectors and synchronization issues. Rather than expanding the existing structure, I gradually redesigned the suite around reusable Playwright tests and configuration-driven execution.

My work included:

  • reviewing and restructuring legacy tests
  • removing obsolete scenarios and repairing business-critical coverage
  • migrating Cypress tests to Playwright
  • introducing stable data-testid selectors
  • replacing arbitrary waits with explicit synchronization
  • building reusable helpers and fixtures
  • replacing market-specific test duplication with tag-based execution
  • supporting multiple environments, locales and B2B/B2C configurations
  • integrating execution and reporting into CI/CD
  • investigating flaky failures across UI, network and application state

The suite has since grown from roughly 70-80 inherited tests to around 300 maintainable E2E scenarios. Many of these scenarios are reused across different markets and configurations rather than duplicated into separate market-specific test suites.

CI/CD and Execution

The migration was not a one-to-one Cypress rewrite. Test architecture, execution strategy and CI integration were redesigned together.

Parallel Playwright execution reduced a representative CI run from approximately 13.5 minutes to around 6-7 minutes while the overall coverage continued to grow.

The suite is now also executed on a daily schedule, providing continuous regression feedback rather than relying only on occasional manual execution.

CI coverage spans:

  • locales and regional behaviour
  • B2B and B2C flows
  • authentication and logout
  • checkout and payment flows
  • consent-dependent behaviour
  • external integrations
  • error and rejected-operation paths

Tests are distributed across separate CI jobs for different markets and configurations. As a result, the approximately 300 logical test scenarios can produce substantially more individual test executions across the full CI matrix.

API Contract Testing

In addition to browser-level E2E coverage, I introduced contract tests that validate API responses against expected schemas.

This provides a separate signal for API and test-data inconsistencies and helps distinguish application regressions from failures caused by unstable environment or staging data.

Together, the E2E and contract-test pipelines regularly surface regressions, integration problems and data inconsistencies during ongoing development, including issues that could otherwise reach production.

Impact & Scale

  • ~70-80 inherited legacy E2E tests → ~300 maintainable scenarios
  • ~13.5 min → ~6-7 min for a representative parallelized CI run
  • daily scheduled regression execution
  • reusable tag-based coverage across markets instead of duplicating entire suites
  • multiple market, locale, environment and B2B/B2C configurations
  • browser-level E2E coverage complemented by API contract validation

Secure Upload & Checkout Architecture

Independent Project · Full-Stack Engineering · 2026 · Lok Chan Art

Selected case study from a larger production application. This section focuses on the secure upload and checkout architecture.

I designed and implemented the upload and checkout workflow for custom portrait commissions on Lok Chan Art.

The main requirement was to accept relatively large customer images without proxying file bytes through the application backend, while keeping storage access restricted.

Upload Architecture

Architecture diagram showing a secure direct-to-storage upload flow with short-lived authorization, temporary S3 storage, checkout, payment webhook, and permanent order storage
Authorization and file transfer follow separate paths: the application issues short-lived authorization, files upload directly to temporary object storage, and paid-order assets are promoted to permanent storage after payment confirmation.

→ Open architecture diagram in Excalidraw

Direct Upload with Short-Lived Authorization

The backend authorizes uploads but does not proxy the image itself. The browser uploads directly to object storage using temporary server-issued authorization.

Upload authorization is short-lived — approximately two minutes — and a new token is requested when required instead of keeping a long-lived upload credential in client state.

This avoids an unnecessary binary-data hop through the application server while keeping storage operations controlled by backend authorization.

Upload Guardrails

The flow combines:

  • maximum file size and file-count limits
  • allowed MIME types and file validation
  • short-lived authorization
  • restricted storage operations
  • CORS restrictions
  • rate limiting
  • temporary draft storage
  • automatic expiration of abandoned uploads
  • separation of temporary and permanent order files

Uploaded customer files are treated as untrusted input, and security-sensitive restrictions do not rely only on client-side validation.

Temporary Storage and Checkout

Uploads begin as temporary drafts. Abandoned uploads expire instead of remaining as permanent assets.

After successful checkout, a server-side payment webhook triggers order processing and promotion of the required files to permanent order storage.

The browser is therefore not treated as the authoritative source of payment completion.

Security Model

The upload flow uses layered controls rather than a single security mechanism:

Text
Request Validation
       ↓
Rate Limiting
       ↓
Short-Lived Authorization
       ↓
File / Storage Restrictions
       ↓
Temporary Lifecycle
       ↓
Server-Side Payment Confirmation
       ↓
Permanent Order Storage

This case study covers one part of a larger production application. The project overview explores the broader architecture, transactional email, internationalization, SEO and performance, and links to a detailed case study of the production domain migration.

Explore the engineering behind Lok Chan Art →

Dev Content Automation

Personal Project · Developer Tooling · 2026 · In progress

I started building dev-content-automation for myself to make it easier to turn engineering work into posts. The idea is to bring my notes, selected code excerpts, and diagrams together in a draft I can review and edit.

The current tool runs locally and uses templates to prepare an MDX article, a LinkedIn draft, and supporting visuals. It records source references so I can trace the excerpts back to the code. I choose the material, write the explanations, and review the result before publishing.

Technologies: TypeScript, Node.js, Zod, MDX, Mermaid.

Author notes, selected code, and Mermaid diagrams feed a local draft generator. Article and social drafts, visual assets, and source references go through author review before publication.
From selected project material to drafts and visuals, followed by my review and edits.

The pipeline is now used to prepare articles for the Engineering Lab. It gathers evidence from the underlying projects and repositories, traces relationships between files and architectural components, and uses those findings to prepare structured drafts and supporting materials for author review.

The articles currently published in the Engineering Lab were prepared with this workflow and then reviewed and edited before publication.

Explore the Engineering Lab →

Engineering Beyond the Frontend

My work regularly extends beyond UI implementation.

Frontend & application: TypeScript, React, Next.js, localization, complex state and user flows

Backend & data: Node.js, APIs, GraphQL, PostgreSQL, ArangoDB, PostGIS, Redis, authentication and authorization, access and refresh token handling

Integrations: OAuth 2.0 / Google authentication, payments, webhooks, Google Maps and geocoding APIs, AWS S3 object storage

Delivery & reliability: Docker, Kubernetes-based environments, CI/CD, E2E automation, production debugging

I am comfortable working across browser, API, database and external-service boundaries while keeping ownership boundaries explicit — for example, using Kubernetes-based infrastructure without claiming responsibility for cluster provisioning.

AI-Assisted Engineering

I use coding agents for implementation, exploration, refactoring and debugging, with the same review standards I apply to manually written code.

My workflow typically includes:

  • providing architecture, types, constraints and expected behaviour as context
  • reviewing generated changes for incorrect assumptions and unnecessary complexity
  • checking edge cases, type safety, error handling and security implications
  • validating changes with static analysis and automated tests
  • keeping architectural and delivery decisions under human ownership

AI-assisted development increases implementation speed, but generated output is still treated as code that must be understood and verified.