Sebastian KozłowskiTech Lead · Team Lead PL
Tech Lead · Team Lead · Poznań, Poland Integration · DDD · Teams

I connect systems that can't simply be replaced. I lead the teams that build and run them.

I own the technology stack of our development teams and make sure developers and consultants actually understand each other. Every change starts with one question: what does it cost the business, and what does it put at risk? Sixteen years in retail and B2B sales taught me to ask it.

Role
Tech Lead and Team Lead of the development teams, since 2024
Scope
The whole technology stack, architecture, and how developers work with consultants
Focus
Integrations with legacy systems and Polish government registries (KSeF e-invoicing, POLON)
Approach
Domain-Driven Design, asynchronous integration
Stack
Python, Django, Java, RabbitMQ, Celery, PostgreSQL, GitLab CI
AI at work
Claude Code and Codex, every day
Before
16 years in retail and B2B sales, up to sales director
01Decision log

Problems and decisions

Projects from my work at a software house serving the higher-education sector, written up as architecture decision records. Descriptions are generalised, with no client data.

ADR001

A bridge between REST and a system that only speaks SOAP

REST · JSON→adapter→RabbitMQ→SOAP · XML

Context
New services exchange data over REST and JSON, while the core domain system exposes only SOAP services that cannot be changed.
Decision
An adapter microservice in Django: REST in, SOAP out, with an asynchronous flow through RabbitMQ in between instead of a direct call.
Rationale
The adapter acts as an anti-corruption layer: the legacy model doesn't leak into new services. The queue decouples the clients' pace from the legacy system's pace and leaves room for retries.

Django · RabbitMQ · SOAP · ACL

ADR002

Integration with KSeF, Poland's national e‑invoicing system

invoice→validation→signature→KSeF→status

Context
Structured invoices must be exchanged with a government API that has its own authentication and signing process and strict validation.
Decision
Validate documents before sending, handle the signing process, and map API errors explicitly to states that users understand.
Rationale
With a government system, the most expensive error is the one found after submission. The more you check upfront, the fewer manual corrections later.

KSeF · API · E-invoicing · Validation

ADR003

Data flows between universities and the POLON registry

POLON⇄extract→transform→load⇄university systems

Context
Universities must bulk-submit and fetch data from Poland's national higher-education registry, while their own sources vary in format and quality.
Decision
ETL pipelines: bulk import and export through the registry API, transformation of CSV data, and loading through the clients' system APIs.
Rationale
Separating extract, transform and load means only the stage that failed has to be re-run, not the whole batch.

ETL · POLON · Python · CSV

ADR004

Teams, stack, and a bridge between developers and consultants

consultant→requirement→team→review→CI→release

Scope
I lead the development teams and own the whole stack: Python, Java, frontend. Work planning, code review, architecture decisions, mentoring, GitLab CI pipelines.
Communication
I turn what consultants and clients need into work the teams can deliver, and technical constraints into language the implementation side can act on. Each project leaves API contracts, data-flow diagrams and runbooks behind.
Rationale
An integration outlives the project. Its real cost is decided when someone else has to understand and fix it, and a requirement lost in translation at the start costs the most.

Teams · Stack · Code review · Documentation

02Specification

Principles I keep coming back to

Not technologies, but how I make decisions. Technologies change; these questions stay.

§ 1

Cost and risk first, technology second

Before choosing a solution, I ask what the business loses when the integration is down and what it will cost to maintain. The answer often changes the choice.

§ 2

The legacy system has its rights

I don't push a system I can't change harder than it can take. Pacing, retries and failure handling are part of the design, not fixes after release.

§ 3

Errors must be visible and understandable

An integration that silently loses data is worse than one that stops loudly. Every error should say whether a retry makes sense and who needs to act.

§ 4

Documentation is part of the product

The API contract, the data flow and the failure runbook are written together with the code. Without them, the integration depends on one person's memory.

§ 5

AI speeds things up, but it doesn't make the decisions

I work with Claude Code and Codex every day. They shorten the path from an idea to a working draft, but the model isn't accountable for the architecture or for what goes to production. A person owns the decision, the review and the result.

03Revision history

Experience

The full CV with technologies and details: resume.pdf.

Rev.PeriodChangeWhere
F2024 – presentTech Lead and Team LeadWhole stack (Python, Java, frontend), architecture, leading the teams, working with consultantsKalasoft, Poznań
E2022 – 2024Software DeveloperIntegrations in Python, Django and Celery in a microservice environmentKalasoft, Poznań
D2022Python Developer (freelance)Web applications, automation, small APIsSelf-employed
C2022 – 2027Computer Science, WSB Merito UniversityBSc with a top grade (5.0) and a rector's scholarship; now MSc, advanced databasesPoznań
B2012 – 2022From sales representative to director of sales and business developmentRetail chains, key account management, director from 2021: key accounts, negotiations, building and leading a sales teamOktan Energy – Wina
A2006 – 2011Retail: team manager, chain sales representativeLeading merchandise teams in large-format retail, then selling to retail chainsKaufland, Real, Ambra
04Contact

Let's talk

About integrating systems that can't be replaced, moving off legacy, B2B system architecture, and leading technical teams. Also get in touch if you’d like to work together.