Firas, François Abed El Nabi
Open to Tech Lead & senior engineering roles
I model business domains the way I used to model materials — decompose the messy thing until the structure shows, then build something that survives contact with reality.
PhD in computational material science, retrained as a Java developer, 10 years building software and most of that in the enterprise. Today I lead a team of five and own the architecture rather than only implementing it.
- 10
- 5
- 17
Selected work
- 001
One tenant model serving a solo practice and a medical group; only Site collapses Solo practice · one tenant Tenant · the practice Site — hidden, collapses to one 2 clinics 2 departments Medical group · one tenant Tenant · the group N sites — visible N clinics N departments Between tenants · unrelated businesses, patient data row-level security enforced in the database no tenant set → sentinel matches nothing, returns zero rows The correction that shaped it A solo dentist with two offices and a general/orthodontic split is an ordinary practice, not an enterprise one — so only Site hides. Clinic and department stay first-class for everyone, which is why every caller states its clinic scope regardless of customer size. Independent A Multi-Tenant Practice SaaS for Solo Practitioners and Medical TeamsA practice-management SaaS I build, deploy and run myself on a VPS. Every customer is a tenant, and one organisational model has to fit both a one-person practice and a medical group — without making the small customer pay for the large one's structure.
- 002
Hexagonal architecture: adapters depend on ports, ports depend on the domain core Inbound adapters REST controller Scheduler MQ consumer Inbound ports Use case interfaces Domain core entities aggregates Outbound ports Repository interfaces Adapters JPA Kafka HTTP Every arrow points inward The core imports nothing from the outer rings, so it runs in a unit test with no database, no broker and no HTTP server. Swapping JPA for another store changes one adapter and leaves the domain untouched. Adobis A Hexagonal Reference Architecture for New ServicesMoved new services off an inherited Java monolith onto DDD and Hexagonal boundaries — writing the reference implementation and driving adoption through pairing sessions.
- 003
Tokens layer primitive to semantic to component; components layer primitives to composites to integrations Tokens · three tiers Primitive raw values Semantic what it means Component one component's own components read here Catalogue · the same layering Primitives Button, Chip, Input Composites Card, Stat Badge Integrations wizard, form, stepper Why the third tier exists A kit that only ships primitives passes the burden of composition to every consumer. The integration stories are where a library actually breaks. Independent A Component Library as an Angular WorkspaceAn independently built Material-style UI kit — 35 components, 265 stories — where each component is its own Angular library and every style resolves through a three-tier token system rather than a hardcoded value.
- 004
Nx dependency graph: the five DataChain modules over shared feature and UI libraries DataChain modules · independently deployable DC Viz DC MarketPlace DC Code DC Tag IA access console Feature libraries feature · lineage feature · transform feature · identity feature · catalog Shared ui · design system data-access · api util · types, testing What the graph buys Dependencies only ever point downward, and Nx fails the build if that is violated. Affected-based CI means touching one feature rebuilds one app, not five. Adobis Nx Micro-Frontend ArchitectureRestructured the front end into an Nx monorepo of five applications on Ports and Adapters, so micro-frontends build and release independently.
- 005
Layered ignore rules decide what is published; innermost wins Ignore layers · innermost wins defaults built in .gitignore the vault's own .pkmignore can rescue files nested scoped to subtree Index, rebuilt on every change notes: full text searchable code: names and paths only navigable, not searchable The pruning rule, reproduced on purpose In git, "!dist/keep.ts" does nothing while dist/ is excluded — the walk never opens dist/ to find the exception. Reproducing that means reproducing a limitation, and that is the right call: a tool almost compatible with a familiar format is worse than one exactly compatible, because the gap only ever surfaces as surprise — in the mechanism that decides what becomes public. Independent A Read-Only Reader for Notes and CodeA read-only reader for a notes vault or a code repository — wikilinks, backlinks, search, and a faithful reimplementation of git's layered ignore semantics, pruning behaviour included.
- 006
Job path: outbox to Kafka to Spark, status back over SSE under one trace id Submit · one trace id end to end BFF holds token Outbox same txn Kafka job queue Spark streaming handler per domain status topic → SSE → browser Stuck jobs Reconciler sends bare ids Backend decides re-reads, applies own rules Why the reconciler carries no verdict It sends job ids and nothing else — no thresholds, no reasons. A bug in its query cannot talk the backend into failing a healthy job; it costs a wasted round trip. Independent A Job Execution Platform on Spark and KafkaJobs submitted through a BFF, queued on Kafka, executed by a long-running Spark application and streamed back over SSE under one trace id — with the domain-specific surface narrowed to four extension points.
- 007
BLE device lifecycle: scan, pair, control, with drop-out and recovery paths Happy path Scan discover nearby Pair bond, may fail Control lights, shutters Scenes grouped Reality device drifts out of range · command times out UI shows probable state, retries, never traps the user The design constraint An operation that succeeded a moment ago may not now, so the interface cannot pretend to know a device's state — it represents what is probable and recovers without a restart. Residential software is used by people who did not choose it and will not read documentation, so defaults must be right unconfigured. Capgemini Schneider Electric — Wiser EnergyEnergy and photovoltaic monitoring across EMEA, plus BLE control of lights and shutters from a web app on Android and iOS — where a device is only ever probably in a state.
- 008
SPARK architecture: Java services and a C# projection subsystem bridged by ActiveMQ JVM Spring MVC / Data Apache Storm ElasticSearch ActiveMQ message bridge .NET C# projection calibration physical model AngularJS + ThreeJS Why a broker rather than direct calls The two runtimes have different failure and restart characteristics. A broker between them means the projection side can drop out and recover without stalling the web stack, at the cost of one more piece of infrastructure to run. VISEO SPARK — Spatial Augmented RealityAn EU research project projecting 3D designs onto printed models in real time, with ActiveMQ holding a Java web stack and a C# projection loop apart.
Career
-
Independent Engineering & Self-Hosting
Personal projects — Remote
Building and self-hosting my own systems — a healthcare scheduling platform, a Spark/Kafka job execution engine, a knowledge-vault reader, and two different answers to multi-tenancy — alongside AI-assisted developer tooling. Where the architectural decisions are mine end to end, and the reasoning is written down next to the code.
-
Adobis Group
Tech Lead & Full-Stack Developer — Grenoble, France
Leading a team of 5 on DataChain®, a European sovereign data platform. Four years moving new services off an inherited Java monolith onto DDD and Hexagonal boundaries, and building the tooling the platform's business users work in daily — a visual composer for automation workflows and an IDE-style editor for the formulas Spark evaluates over their data. In production at Boehringer, the State of Geneva and Ayming.
-
Capgemini-Sogeti High Tech
Full-Stack Consultant — Grenoble, France
Consulting for Schneider Electric (Wiser Energy — IoT, solar monitoring, home automation) and EATON (IPM2 — data centre UPS monitoring).
-
VISEO Technologies
Full-Stack Consultant — Grenoble, France
Full-stack developer on SPARK with Politecnico di Milano — an EU research project on Spatial Augmented Reality with real-time 3D projection.
-
Education
MSc, Particle Physics — Université Grenoble Alpes, 2009–2012
PhD, Computational Material Science — Université de Poitiers / Institut PPRIME, 2012–2016 · read the thesis (PDF, 17.5 MB)
Java Software Developer Bootcamp — M2I, 2016–2017
Skills
Languages
French NativeEnglish FluentArabic NativeGerman Intermediate