Insights

Notes from the build.

Short, practical write-ups on the decisions we make most often - written for the people who have to live with the result.

ERP

What an Odoo ERP costs in Libya, and what moves the price

The licence is free. The price is the number of things that have to agree with each other.

The first question is almost always about the licence, and it is the wrong question. Odoo Community is free to use and already covers sales, purchasing, inventory, accounting and POS. Nobody here should be paying for software they can download.

What you actually pay for is agreement. Every system that has to hold the same truth as the ERP - the shop, the app, the warehouse sheet, the bank, the kitchen screen - is a piece of work with a design, an edge case and a failure mode. One branch selling one way is a short project. Four branches, an online store, delivery and two payment providers is a different order of magnitude, on the same free licence.

The second driver is distance from the default. Odoo has an opinion about how a purchase order becomes a bill. If your business matches it, configuration is enough. If it does not, someone writes a module, and that module has to keep working through the next version upgrade - the cost people forget to count.

The third is data. Ten years of stock and customers in spreadsheets, with three spellings of the same supplier, is a migration rather than an import. It is the least glamorous line in the proposal and the one that decides whether anyone trusts the system in week one.

So the honest answer to "what does it cost" is another question: what has to agree with what, and how far is your process from the default? We work that out on a free scoping call and put the scope and the number in writing before anything starts.

Payments

Accepting Sadad, Edfali, Tadawul and Mumalaat online: what a T-Lync integration involves

The callback is unsigned, the landline is refused late, and there is no refund API. Here is how we build around each.

Taking card and wallet payments in Libya means T-Lync, the gateway sitting in front of Tadawul, Edfali, Sadad and Mumalaat. The API itself is small. The care is all in what it does not promise.

The webhook is not signed. Anyone who learns the URL can post a success message, so nothing is ever fulfilled on the callback alone: we treat it as a hint and re-verify the transaction against the gateway's own receipt before anything of value changes hands. A scheduled sweep picks up the callbacks that never arrive, and every transaction in that sweep is isolated, so one unconfirmable payment cannot roll back everybody else's order.

Verification runs over SMS, so landlines are refused - and refused late. A perfectly valid Tripoli landline passes ordinary phone validation and comes back rejected by the gateway after the customer has filled in the entire form. We validate for a mobile number at the form instead, which turns a dead end into a one-field correction.

Amounts below the gateway's minimum are rejected before the customer ever sees a payment page, so the cart has to know that floor. And there is no refund API: a refund is a human action in the merchant portal. That changes how you design cancellations, not just how you process them.

None of this is exotic once you have shipped it twice. It is also invisible in any vendor demo, which is the real reason to ask whoever is building your store whether they have been through it.

AI

When private AI is the right answer - and when it isn't

Running a model on your own hardware is not automatically better. It is better in specific situations, and expensive in the rest.

The question we get asked is "can we have our own AI?" The useful question is narrower: what data does it need to see, and where is that data allowed to be?

If the answer involves contracts, patient records, payroll, unreleased designs or anything a regulator would ask about, a hosted model becomes a policy problem before it becomes a technical one. Running locally removes that conversation entirely - the documents never leave the building, there is no per-seat subscription, and nothing changes underneath you when a vendor updates their terms.

The trade is real, though. You buy the hardware once and own it, along with the responsibility for keeping it running. A local model will not match the largest hosted models on open-ended reasoning. And someone has to maintain it.

Where it wins clearly: answering questions against a fixed internal corpus - your policies, your manuals, your ticket history. That is retrieval plus a competent model, and a competent model is one you can host yourself. Where it usually loses: anything needing frontier-level reasoning, or a workload so occasional that dedicated hardware sits idle.

Our rule of thumb: if the data is sensitive and the questions are repetitive, host it yourself. If the data is public and the questions are open-ended, don't.

ERP

The ERP is not the project. The integrations are.

Most ERP implementations we are called in to rescue were not failed installs. They were successful installs that nothing else could talk to.

Installing an ERP is a solved problem. ERPnext and Odoo both go in reliably, and the vendor documentation is good. That is not where projects die.

They die at the seams. The shop takes an order but the ERP finds out the next morning. Stock is right in the warehouse and wrong on the website. Finance exports a spreadsheet, edits it, and re-imports it, which means for a few hours a day the accounting truth lives in someone's downloads folder.

Every one of those is an integration that was descoped to make a number look better. And each one quietly recreates the manual work the ERP was bought to remove.

So we scope integrations first and the ERP second. Which systems must agree, how quickly, and what happens when one is unreachable - answer that before choosing modules. A smaller ERP that is genuinely connected beats a larger one bolted alongside the business.

The practical test: after go-live, can anyone in the company still do their job in a spreadsheet? If yes, the integration work is not finished.

Engineering

What building software for Libya actually involves

The hard parts are rarely the code. They are payments, verification, connectivity and Arabic - and they surprise teams who have not shipped here.

An international agency can build a beautiful ordering app and still fail to deliver here, because the assumptions underneath it are wrong.

Payments come first. Card-on-file checkout is not the default path for most customers, so the flow has to accommodate local payment providers and cash-on-delivery as first-class options rather than an afterthought bolted onto a Stripe-shaped design.

Verification runs on phone numbers. SMS and OTP are the practical identity layer, which means the sign-up flow, the retry logic and the failure messages all have to be designed for it - including what happens when a message is slow to arrive.

Connectivity is uneven. Interfaces need to survive a bad connection: optimistic UI, retries that are safe to repeat, and a clear state when something has not gone through. An app that assumes constant bandwidth will feel broken.

Arabic is not a translation pass. Right-to-left changes layout, iconography direction, number and date handling, and typography - and text length shifts against the design. Building bilingual from the start costs a fraction of retrofitting it later.

None of this is exotic once you have done it. That is the actual argument for hiring people who already have.

Engineering

Building for the moment the connection drops

A sales app that stops when the signal does is not a sales app. It is a form that happens to be on a phone.

Coverage is not a constant here. A rep is in a shop with three bars, then in a warehouse with none, then on a road where it comes and goes. If the software treats the connection as a given, every one of those becomes a person standing still, holding a phone, watching a spinner.

The fix is architectural rather than cosmetic. An offline-first app keeps its own copy of what it needs on the device: the catalogue, the prices, the customer list, the stock figures as of the last sync. Orders are written locally and queued. Nothing about the workflow changes when the signal goes, which is the entire point.

When the connection returns, the queue drains into the central system on its own. The interesting work is in the conflicts: two devices editing the same customer, a price that changed while a device was dark, an order taken against stock that has since sold. Those rules are a business decision rather than a developer's guess, and we settle them before the first screen is drawn.

Building this way costs more. It is also the difference between software the field team uses and software the field team routes around, which is why we ask about coverage in the first conversation instead of discovering it at the pilot.

Infrastructure

A backup nobody has restored is not a backup

Most of the companies we audit do have a copy of their data. Very few have ever tried to bring it back.

The pattern repeats. The contracts, the payroll, the customer list and the year's invoices exist in one extra place: a drive in a desk, a laptop that goes home at night, a folder somebody copies to a USB stick when they remember. It feels like a backup because there is a second copy of the file.

It fails in four ordinary ways rather than one dramatic one. The drive breaks or is lost, and years of trading history go with it. Ransomware encrypts the machine and the attached drive together, because the backup was plugged in at the time. Nobody can say which of five similarly named folders is current. And the one person who understands the arrangement is away the week it matters.

A real arrangement has three properties. It runs without anyone remembering to start it. It keeps a copy somewhere the original cannot reach, so a single bad event cannot take both. And somebody restores from it on a schedule, to prove that what comes back is complete and current.

The third is the one that gets skipped, and it is the only one that turns a folder into a recovery plan. Until a restore has actually been done, the backup is a belief rather than a fact.

So the scoping question is not how much storage you have. It is how long the business can be stopped, and how much work you can afford to lose. Answer those two and the design follows - then we test the restore on a date in the calendar, while nothing is on fire.

ERP

Buy it, configure it, or build it

The honest answer is usually the middle one, which is also the one nobody sells you.

The question arrives as a binary: do we take the ready-made system, or have something written for us? Framed that way it becomes a question about price, and ready-made always wins, because the cost of the thing you did not build stays invisible until you are living inside it.

Buy where your process is ordinary and the product is mature. Accounting, email, file storage, payroll: there is nothing to be gained from a bespoke version of a solved problem, and a great deal to lose in maintaining one.

Build where the process is the thing you compete on. If your dispatch logic, your pricing rules or the way you handle a return is a reason customers stay, that logic deserves software shaped around it rather than a text field labelled notes.

Most businesses sit between the two, which is why we start with configuration. Odoo out of the box has an opinion about how a purchase becomes a bill. If yours is close to it, settings are enough and the upgrade path stays clean. Where the business genuinely differs we write a module for that part and only that part, because every line of custom code is a line somebody maintains through the next version.

The trap is the option nobody names: buying something that almost fits. The gap fills with spreadsheets and habits, the workarounds harden into the process, and two years later the company runs on a system it pays for and a shadow system it does not. We would rather talk you out of a build than sell you one.

Scoping

A website, a system, or an app: which one you actually need

Three different projects get requested in the same sentence, and picking the wrong one is an expensive way to learn the difference.

The request usually arrives as a need for something digital. Underneath it sit three quite different projects with different costs, timelines and owners, and the most useful thing we can do on a first call is work out which one is being described.

A website is for the people who do not know you yet. Its job is to explain what you do, make you credible, and give someone a way to start a conversation. It is the cheapest of the three, it is measured in weeks, and for a great many businesses it is honestly the whole answer.

A system is for the people already inside the company. It is where stock, invoices, customers, purchasing and payroll stop living in parallel files and start agreeing with each other. Nobody outside the business ever sees it, and it is usually where the money is quietly going.

An app earns its cost when the relationship repeats: a customer who orders, books, tracks or pays every week, or a field team working away from a desk. If the interaction happens twice a year, a good mobile site does the same job for a fraction of the price, and nothing has to be installed.

Most of what we are called in to correct is a category error rather than a technical one - an app built where a website was needed, or a website polished while the warehouse still ran on paper. We would rather spend the first call sorting that out, including when the answer is the cheap one.

Support

Launch is where the maintenance starts

Software is not a building. Nothing about it stays still after you move in.

There is a moment in every project where the thing goes live and everybody exhales. It is the right moment to celebrate and the wrong moment to stop paying attention, because the ground under a live product keeps moving even when nobody touches the code.

Operating systems update twice a year and withdraw things they used to permit. Browsers change defaults. A payment provider rotates an endpoint. A certificate expires. A phone ships with a screen shape nobody designed for. None of these is anyone's fault, and all of them arrive on a schedule somebody else sets.

The business moves too. The team finds the three screens they use forty times a day and the two features nobody has ever opened. Volume grows past what the first design assumed. A new branch works slightly differently. A product that cannot absorb any of that is finished in the narrow sense and dying in the useful one.

So a handover includes the unglamorous apparatus: training for the whole team, a warranty period, a named person to call, monitoring that tells us before your customer does, and backups we restore on a schedule. After that, maintenance is an arrangement rather than a favour - a regular rhythm of updates, fixes and small improvements.

The alternative is the pattern we keep being called in to rescue. A system that worked on launch day, was never touched, and two years on cannot be updated without being rewritten. That rewrite costs several times what the upkeep would have.

Design

Working code is the floor, not the finish

Every feature you paid for is a feature somebody has to find. Most of the software we replace failed there, not in the logic.

A system can be entirely correct and still fail. The calculations are right, the integrations hold, the data is where it should be, and the team still keeps a spreadsheet on the side, because the software asks for eleven clicks to do the thing they do forty times a day.

The same applies to anything a customer touches. An app that wants a registration form, a verification code and a profile photo before it will show a single price gets deleted on the walk back to the car. Nobody files that as a bug. It arrives later as a number nobody can explain.

So we design the path before the screens. What is this person here to do, what is the shortest honest route to it, and what can be removed altogether. The screens are then built around that path rather than around the database tables, which is what happens by default when nobody is watching.

Two practical consequences follow. Interfaces have to hold their shape across the devices people actually own, from an ageing Android in a warehouse to whatever launched last month, without anybody maintaining a second design. And Arabic has to be a first-class layout rather than a mirrored afterthought: right to left, the numerals and dates a reader expects, and type that does not clip its own marks.

None of this is decoration. It is the difference between a system the company uses and a system the company works around, and the second is how the spreadsheets come back.

Let's scope your project.

Tell us how your business needs to operate. We'll send a clear, no-obligation quote.