Softwarefrom ideato experience

(Scroll down)
Open 24/7

Got a software dream?Want your code supreme?Bugs on your team?

Better call Salim.
Things I shipped
Selected, 2022—2026Four records
Case 01 — flagship
GeoSoul

A Tunisian fashion platform where anyone designs a garment in 3D in the browser, publishes it, and earns on every sale. No stock, no packing, nothing upfront. I founded it, and I built the 3D.

RoleFounder & engineer
Started27 May 2026
Live1 Aug 2026
StackAngular · three.js · GLSL
The constraint that shaped everything
drag to turn

Cache the bytes, not the scene

I did not model these garments, so the obvious lever — lighter meshes — was never mine to pull. The catalogue was 227 MB of GLB; a single t-shirt was 47 MB of it.

Draco took the catalogue to 17 MB and that t-shirt to 4.8. But compression only fixes the wire. The decoder undoes it on arrival: 4.8 MB becomes 73.4 MB of buffers, 1.79 million triangles, 251 ms of work — for one garment.

So I used the lever I had. Cache the compressed bytes, decode on demand, dispose the previous model before building the next. Thirteen garments in the catalogue, one ever resident.

And this is a workaround, not the fix. The real optimisation is lighter geometry, and that work is next. The two compound: together they reach far below where either lands alone.

Case 02Frontend engineer · 2025 — NOW
Tick8ing

Tick8ing in Tunis — formerly DevYourApp, the engineering arm of cyber-web.be in Belgium. Two years as its frontend engineer, on two products either side of one platform.

The work
product oneThe back office. Where the business client runs its own operation.
product twoThe public side. Where that client’s own audience buys a ticket.
distributionOne platform, many venues — city tourism, theatres, municipal sport, and more besides.
side missionsModel training and IoT builds, both in Python, alongside the Angular work.
Case 03AI & web app developer · 2025
Astree Assurance

A Tunisian insurer’s claim forms arrive as photographs of paper — half printed, half filled in by hand at the roadside, on a bonnet, in whatever light there was. Until this, an agent typed every field off the paper by hand. I built the pipeline that reads them instead, and the platform around it.

RoleAI & web app developer
PeriodJan — Jul 2025
DocumentConstat amiable
StackPython · YOLO-OBB · SpaceOCR
Three things were hard

01 — the data

There was no dataset. So I manufactured one.

This was the first AI project the company had ever run, and the digitisation everyone assumed had already happened had not. No archive of filled forms, no labels, no precedent to copy. What I was handed on day one was a model to train and a blank constat amiable.

So I scanned the paper and defined it. Every text field, every checkbox, the two identity blocks, the signature strips, the collision sketch — each one a named class with a known position on the page. That map is the first artefact of the project, and the pipeline is still measuring itself against it three stages later.

Then a generator filled it. Python, OpenCV, Albumentations, PIL: plausible names, addresses, plate numbers and dates set in handwriting faces, boxes ticked at random, a sketch drawn in the accident square. Every sample was written out with its own annotation file, so the labels were exact by construction rather than by hand.

Clean forms would have taught it nothing. Rotation and skew, lighting swings, blur, ink and coffee stains, shadows and reflections, scan noise, a desk behind the page or nothing behind it at all — twelve structural variants per sample, about 4,600 images, split 70 / 20 / 10.

A blank constat amiable with every field outlined and labelled as a class
The blank form, defined — every field a named class at a known position.
A synthetic constat amiable, filled in handwriting faces, rotated and stained, with its annotations drawn over it
One generated sample: filled, augmented and annotated in the same pass.

02 — the detections

A trained model is not a working one.

YOLO with oriented boxes, trained on that set, validates at precision 0.82, recall 0.90, mAP50 0.88. Respectable numbers. Then you hand it a photograph taken at the roadside and it returns the mess on the left: the same field claimed three times, boxes tilted off their rows, confidences in the forties, detections drifting out into the margin.

Raw detections — After the penalty pass
Raw detectionsAfter the penalty pass

Drag to compare

The fix was to use the one thing the model cannot see — that this is a fixed document. Every field’s position is already known, from the map built in the first pass. So the photograph is fitted to that template, and each detection is scored on how far its centre has drifted from where its field has to be.

The penalty is exponential, so it grows faster the farther out you go. A box slightly off its row is nudged; a box in the wrong section is destroyed.

d = |c_det − c_exp| / √(w² + h²)penalty = exp(5·d) − 1score = clamp(2 − 5·penalty, 0.3, 2.0)conf_adj = conf × scoreA well-placed detection is boosted up to ×2. A stray one is cut to ×0.3.

Then group by class, sort by adjusted confidence, keep exactly one. The duplicates collapse, and what survives is what was in the right place all along.

03 — the reading

The budget was zero, so the engine had to be free.

Not a small budget — zero. And nobody writes an OCR engine from scratch inside six months, so the field was whatever cost nothing. I ran four of them over the same crops rather than taking anyone’s word for it.

SpaceOCR won every column by a distance: 6% character error against EasyOCR’s 28, and the fastest of the four. That is what shipped. But 6% is measured over the whole document, and the whole document is mostly print — the handwriting is where the errors live, and the handwriting is the part that matters.

So the output is treated as a signal, not an answer. Rules typed by field: a date is JJ/MM/AAAA or it is wrong, a plate has a shape, a leading digit that only exists because the field’s printed rule was read as a 1 comes off. Required fields validated rather than assumed. And every address round-tripped through the Google Maps API — which is what turns Toris Sidi Hossine back into Sidi Hassine.

Same crops, four engines

EngineCERWERF1ms/img
EasyOCR28%35%70210
Tesseract32%40%65180
SpaceOCRshipped6%10%92140
TrOCR25%32%68160

What the rules recover

SpaceOCR, rawAfter correction
duA
"103111/2022""03/11/2022"
delivre_leA
"12019""2019"
immatriculationB
".5049TU217""5049 TUN 217"
addressB
"Toris Sidi Hossine""Sidi Hassine, Tunisia"
adresse_assureB_line2
"Hassine\n9. Identita""Hassine"
temoins
"ger de A ou B)\nsed un o nidos n.s abubinos""" dropped
End to end
uploadpng · jpeg01segmentyolo-obb02resolvetemplate · penalty03readspaceocr04correctregex · maps05agentverify · decide06

Fail processing and the claim is rejected before an agent opens it. Pass, and it is assigned — the agent can send it back for more, and closes it either way.

Python · YOLO-OBB · OpenCV · Albumentations · SpaceOCR · Google Maps API · React · Express · MySQL
Case 04Lead developer · Binacts · 2024
Itinevel

A global marketplace for travel itineraries: build a multi-day route, publish it, sell it. I designed the architecture from the concept up, led every phase of development, and it scaled into a UK-registered company.

How a route is made
geocodeEvery stop resolved automatically through the Maps API.
optimiseThe order of stops solved, not left to the author.
assembleDays built out of stops; an itinerary built out of days.
sellStripe payments, deployed on Vercel, sold worldwide.
Next.js · Stripe · Google Maps · Vercel
About
I build wholeproducts,not surfaces

Software engineer in Tunis, computer-engineering degree from Esprit, specialised in software architecture. The part that matters is what has shipped: a founded product running custom WebGL in production, an end-to-end computer-vision pipeline for an insurer, and two years on a ticketing platform that venues across Belgium sell through.

I work across the whole stack, and I care most about the seam where engineering becomes something you can feel — the frame budget, the gesture, the moment a model turns into an interface.

Currently

Frontend engineer at Tick8ing in Tunis, two years in — formerly DevYourApp, the engineering arm of cyber-web.be in Belgium. Angular on the platform; Python on the model-training and IoT missions beside it.

Capabilities
Frontend engineeringAngularNext.jsReactTypeScriptDesign systems
3D & shadersthree.jsWebGLGLSLDraco / GLB pipelinesGPU particle systems
AI & computer visionYOLODataset prep & augmentationOCR, print + handwritingPython
Backend & platform.NETSpring BootSymfonyExpressSQL / NoSQLStripe
Record
05/2026 — NOWFounder & engineerGeoSoul
2026 — NOWFreelance · international school platformBRIGHT
2025 — NOWFrontend engineer · AI/IoTTick8ing
01/2025 — 07/2025AI & web app developerAstree Assurance
08/2024 — 11/2024Full-stack developerBinacts · Itinevel
06/2024 — 08/2024Full-stack developerBinacts
07/2023 — 09/2023Full-stack developerCarte Assurance
05/2023 — 07/2023Freelance · e-commerce web & mobileIndependent
01/2022 — 06/2022ERP developer · SAGE X3Discovery Informatique
Education
2022 — 2025Ingénieur en Informatique · Software architectureEsprit
2019 — 2022Licence · Information systems developmentISET
2019Baccalauréat · Computer scienceTunisia
Languages
Arabic — native
French — B2
English — B2
Contact
Let’s talk

A product to build, a model to ship, or an interface that has to feel like something. Write to me.

Tunis, TunisiaLocal time --:--:--
Back to top ↑