A proof of concept built during my internship at H.Essers , a logistics company based in Genk, Belgium. The project automates the manual process of forwarding shipment emails from Outlook into an internal dispatch system, using an Outlook Add-in paired with an event-driven backend.
H.Essers is an international logistics and transport company headquartered in Genk, Belgium. With operations across Europe and beyond, they handle complex supply chains for sectors including healthcare, chemicals and general cargo. The company employs thousands of logistics coordinators who manage daily shipment operations , many of which still rely heavily on email workflows.
Logistics coordinators at H.Essers received shipment data by email and had to manually re-enter it into internal dispatch systems. This process was slow, error-prone and impossible to audit at scale.
I designed and built an Outlook Add-in that lets users submit selected emails and attachments directly to a downstream system. Behind an API gateway (Gravitee), a custom Ingest API retrieves the full email via Microsoft Graph and publishes a structured event to a Kafka topic for async downstream processing.
Coordinators can forward an email directly from Outlook without leaving the app. The backend processes it asynchronously, stores the content, and triggers the downstream workflow , fully logged and traceable end to end.
Built with Office.js, the add-in renders a task pane inside Outlook. When a user selects an email and clicks submit, the add-in reads the email metadata and passes it to the API gateway. Authentication is handled via OAuth2 with Microsoft identity platform.
All traffic flows through Gravitee as the API gateway. It handles routing, rate limiting and security policies. The gateway forwards validated requests to the Ingest API running behind it.
The core backend service. It receives the submission from the gateway, fetches the full email and attachments via the Microsoft Graph API using an OBO (On-Behalf-Of) OAuth2 flow, then publishes a structured event to a Kafka topic. Custom handling includes deduplication logic and retry mechanisms.
Events are published to a Kafka topic for async downstream processing. A Kafka consumer service processes each event, with deduplication to prevent duplicate submissions and full audit logging for traceability.
A full CI/CD pipeline was set up for GitHub Actions , including build, test and deployment stages. The pipeline is ready to deploy the full system when the organisation decides to move from proof of concept to production.
Tracks every submission , who submitted what email, when, and with what processing status. The Outlook Add-in reads this database to show the user their submission history directly inside the task pane.
The Ingest API saves the full email body and all attachments to document storage after fetching them from Microsoft Graph. The storage returns document IDs which are then included in the Kafka event for downstream reference.
External Microsoft API used by the Ingest API to retrieve the full email content and attachments. Access is granted via an OBO (On-Behalf-Of) OAuth2 flow , the user's token is exchanged so the backend can fetch emails on their behalf without storing credentials.
Got access to internal systems, studied the existing Gateway API and codebase. Explored Office.js documentation and the Microsoft Graph API. Defined the project scope together with the team and wrote the initial project plan.
Built the initial Outlook Add-in with Office.js. Implemented the task pane UI, email metadata reading and OAuth2 authentication flow. Got the first end-to-end request through the API gateway.
Built the Spring Boot Ingest API with Microsoft Graph OBO flow. Integrated Apache Kafka for async event publishing. Implemented deduplication and retry mechanisms.
Wrote unit and integration tests covering the core flows. Set up the GitHub Actions CI/CD pipeline on Azure. Ran k6 load tests to validate performance under realistic throughput.
Wrote full technical documentation covering architecture decisions, API contracts, deployment steps and known limitations. Presented the proof of concept to the team and handed over the codebase.
Designed and built the full Outlook Add-in from scratch , task pane UI, email metadata reading, attachment handling and OAuth2 authentication flow.
Designed and implemented the entire Ingest API , endpoint contracts, Microsoft Graph OBO flow, Kafka publishing and deduplication logic.
Wrote unit and integration tests end-to-end. Set up k6 load testing to validate throughput and identify bottlenecks before handover.
Set up the full GitHub Actions pipeline , build, test and deployment stages on Azure. Configured environments so the system is production-ready when the organisation decides to roll out.
Wrote full technical documentation covering architecture decisions, API contracts, deployment steps and known limitations , so another developer can pick this up without me.
Owned the entire project independently , from requirements analysis and technical design to implementation, testing and final presentation to the team.
Implementing the On-Behalf-Of OAuth2 flow to fetch emails via Microsoft Graph was the steepest learning curve. Token exchange between the add-in, gateway and backend required careful configuration of Azure app registrations and scopes.
Worked through the Microsoft Identity Platform docs in detail and set up a dedicated test environment to isolate auth issues. Introduced a token cache to reduce latency on subsequent requests.
Working with Kafka in a production enterprise environment was new , existing topics, consumer groups and access policies were already in place. Getting local development to mirror the real environment took significant setup.
Used Docker Compose to spin up a local Kafka instance that matched the production config. Collaborated with the infrastructure team to understand the topic structure before writing any consumer code.
The same email could be submitted multiple times by different coordinators or through retries. Without deduplication, the downstream system would process duplicate shipment entries , a serious data integrity issue.
Implemented idempotency keys based on email message ID. The Ingest API checks against a processed-events store before publishing to Kafka, rejecting known duplicates with a 409 response.
Working within an enterprise release process meant every change needed approval, code had to meet internal standards and deployments followed a fixed schedule , a very different pace from school projects.
Adapted by planning features further ahead and keeping a clear backlog. Used the slower pace to invest more in documentation and test coverage than I would have in a faster environment.
The project is a proof of concept and has not yet been taken into production at the time of handover.
The technical scope was well-chosen , complex enough to be interesting, focused enough to deliver in 13 weeks. Working independently pushed me to make architectural decisions I'd normally defer to a senior developer, and most of them held up well under review.
I'd involve the end users , the logistics coordinators , earlier in the process. My first UI iteration made assumptions about their workflow that turned out to be slightly off. An earlier feedback loop would have saved a week of rework mid-project.
How different enterprise software development feels compared to a school project , the constraints, the process, the care required around security and observability. It made me a more deliberate developer, and confirmed that I want to keep building at this level of complexity.
Technical realisation document describing the implementation, architecture decisions and deliverables of the internship project.
Personal reflection on the internship experience , what went well, what I would do differently, and how the project shaped my growth as a developer.
The initial project plan submitted at the start of the internship , scope, objectives, timeline and technical approach.