# Amygdal > Amygdal is a software development and custom AI development company specialising in healthcare. We design and build custom AI, RAG systems, AI in healthcare, AI and software for BIM, and mobile and web apps. Offices in Sarajevo (Bosnia and Herzegovina), Delaware (USA) and Doha (Qatar); serving the United Kingdom, Germany, Switzerland, Qatar and the USA. Every page listed here is canonical on www.amygdal.com. Articles and case studies are written in English; service pages are also published in German and Arabic. # Services ## Custom AI Development URL: https://www.amygdal.com/services/custom-ai-development Off-the-shelf AI gets you a demo. Custom AI gets you a system that knows your data, fits the way your team works and keeps working after launch. We design, build and run AI features and agents end to end — and we start by finding the place where AI actually changes a decision. ### What we offer - **AI strategy & discovery**: We map where AI changes an outcome, size the effort honestly and validate the riskiest assumption with a focused proof of concept before anyone commits to a roadmap. - **LLM features & copilots**: Summarisation, extraction, classification and assistants built into your product, with prompts, evaluations and fallbacks under version control. - **AI agents & automation**: Agents that call your APIs, follow your business rules and hand off to a human when they should — with guardrails, logging and cost limits. - **Machine learning models**: Predictive models, recommendations and computer vision trained on your data, when a classic model beats a language model. - **Private & self-hosted models**: Open-weight models running in your cloud or region when data cannot leave it, including EU and Gulf hosting. - **MLOps & monitoring**: Evaluation suites, drift monitoring, tracing and retraining pipelines, so quality is measured rather than assumed. ### Use cases - Document and email processing that routes work automatically - Support and sales assistants grounded in your own content - Forecasting and anomaly detection on operational data - Image and video analysis for inspection or cataloguing - Internal copilots for analysts, engineers and operations teams ### FAQ **How long does a custom AI project take?** A proof of concept usually takes two to six weeks. Taking it to production — integration, evaluation, security review and monitoring — typically adds one to three months, depending on your systems and data. **Do we need a lot of data to start?** Often not. Many LLM features work with your existing documents and a well-built evaluation set. Where a trained model is needed, we assess data quality in discovery and tell you plainly whether it is enough. **Which models do you use?** Whatever fits the job and your constraints: hosted models from OpenAI, Anthropic or Google, open-weight models such as Llama or Mistral, or classic machine learning. We design so the model can be swapped later. **Can the AI run inside our own cloud?** Yes. We deploy on AWS, Azure or Google Cloud in the region you need, including EU and Middle East regions, and can use self-hosted models when data must stay in your environment. ## RAG Development URL: https://www.amygdal.com/services/rag-development Retrieval-augmented generation lets a language model answer from your knowledge — contracts, manuals, tickets, BIM models, clinical guidelines — instead of from memory. The hard part is not the demo; it is retrieval quality, permissions and knowing when the answer is wrong. That is the part we engineer. ### What we offer - **Ingestion pipelines**: Connectors for file shares, wikis, databases and APIs, with parsing for PDFs, tables and scans, sensible chunking and incremental re-indexing. - **Hybrid search & reranking**: Vector and keyword search combined, then reranked, so exact terms like part numbers and names are found as reliably as concepts. - **Citations & guardrails**: Every answer links to the passages it used. When the sources do not support an answer, the system says so instead of guessing. - **Access control**: Document permissions enforced at retrieval time, so people only get answers built from content they are allowed to read. - **Evaluation**: A test set of real questions scored on retrieval and answer quality, run on every change to prompts, models or chunking. - **Chat, search & API surfaces**: Delivered as an assistant, a search experience, a Slack or Teams bot, or an API your other systems call. ### Use cases - Internal knowledge assistants for policies, processes and wikis - Customer support answers grounded in product documentation - Contract, tender and compliance document review - Natural-language questions over BIM and engineering data - Clinical guideline and protocol lookup for care teams ### FAQ **What is RAG development?** RAG development is building systems where a language model first retrieves relevant passages from your own data and then answers using them. It keeps answers current and traceable without retraining a model. **Which vector database do you use?** It depends on scale and your stack. PostgreSQL with pgvector covers many projects; Elasticsearch, OpenSearch or Weaviate suit larger or search-heavy ones. We pick what you can operate. **How do you stop hallucinations?** You reduce them rather than eliminate them: better retrieval, answers constrained to cited sources, refusal when evidence is missing, and an evaluation set that catches regressions before users do. **Can RAG respect our document permissions?** Yes. We carry permissions from the source systems into the index and filter at query time, so the model never sees content the user cannot access. ## AI in Healthcare URL: https://www.amygdal.com/services/ai-in-healthcare Healthcare AI succeeds when it fits a clinical workflow and earns trust. We build AI into healthcare products and operations with privacy, accuracy and human oversight designed in from the first sprint — not bolted on before an audit. ### What we offer - **Clinical documentation AI**: Summaries, coding suggestions and structured extraction from notes, letters and reports, reviewed by a clinician before anything is filed. - **Triage & decision support**: Risk scores and prioritisation that explain their reasoning, so care teams can see why a case was flagged. - **Remote patient monitoring**: Apps and platforms that connect devices and wearables, detect meaningful changes and alert the right person. - **Patient-facing apps**: Mobile and web apps for engagement, coaching and follow-up, with AI that personalises without overstepping. - **Medical knowledge assistants**: RAG assistants over guidelines, protocols and formularies, citing the source for every answer. - **Compliance by design**: Data minimisation, encryption, audit trails and in-region hosting, aligned with GDPR, HIPAA and the EU AI Act. ### Use cases - Discharge letter and referral summarisation - Symptom intake and appointment routing - Wearable data analysis for chronic care and fitness - Care-home and senior-care matching platforms - Operational forecasting for beds, staff and supplies ### FAQ **Is your healthcare AI HIPAA and GDPR compliant?** We design systems to meet HIPAA and GDPR requirements — data minimisation, encryption, access control, audit logging and data processing agreements — and work with your compliance team on certification where it applies. **Do you build software as a medical device?** We build decision-support and workflow tools and can work within a regulated SaMD process alongside your quality and regulatory team. We are clear early about which side of that line a feature sits. **Where is patient data hosted?** In the region you require — for example EU data centres for German and Swiss providers, or Gulf regions for Qatar — and models can be self-hosted so data never leaves your environment. **Which healthcare products have you worked on?** Our healthcare and wellbeing work includes the Ealthiness fitness and health app and engineering for A Place For Mom, a senior-care platform in the United States. ## AI & Software for BIM URL: https://www.amygdal.com/services/ai-for-bim BIM models hold a huge amount of structured information that most teams can only reach through specialist tools. We build software and AI that get that information out — checking models automatically, classifying elements, feeding cost and planning systems, and letting people ask questions of a model in plain language. ### What we offer - **IFC & Revit data pipelines**: Extract geometry, properties and relationships from IFC files and Revit models into databases your other systems can use. - **Automated model checking**: Rule-based and AI-assisted checks for naming, classification, missing properties and standards compliance, with clear reports. - **Element classification**: Machine learning that maps elements to classification systems and cost codes, reducing hours of manual tagging. - **Quantity takeoff & estimating**: Quantities derived from the model and connected to cost data, so estimates update when the design does. - **BIM assistants**: RAG and agent-based assistants that answer questions about a model, its specifications and related documents. - **Web model viewers & portals**: Browser-based 3D viewers and project portals for clients and site teams who don't have BIM licences. ### Use cases - Checking models against BIM execution plans before handover - Automating property and classification enrichment - Linking model elements to schedules, costs and documents - Answering site-team questions from the model on mobile - Building dashboards on top of BIM data for owners and operators ### FAQ **Which BIM formats do you work with?** IFC is our default because it is open, and we work with Revit and other Autodesk data through their APIs. We can also process related documents such as specifications and schedules. **Where does AI help most in BIM?** In the repetitive, rules-heavy work: classifying elements, checking model quality, extracting quantities and answering questions across models and documents. Design judgement stays with people. **Can you integrate with our existing BIM tools?** Yes. We build plugins, APIs and data pipelines around the tools your teams already use rather than asking them to switch. **Do you work with construction firms in Germany, Switzerland and the UK?** Yes — those markets have strong BIM mandates and standards, and we work remotely with teams there in English and German. ## Software Development URL: https://www.amygdal.com/services/software-development We are a software development company for teams that need working software, not just code. One senior team covers product discovery, design, engineering, QA and the AI work — so decisions are made once and delivery stays predictable. ### What we offer - **Product discovery**: Workshops, user flows and a scoped plan that turns an idea into a backlog you can estimate and fund. - **UX/UI design**: Clickable prototypes and a design system your developers can build from without guesswork. - **Backend & APIs**: Robust services in Node.js, NestJS or Python, with PostgreSQL, Redis and search where they are needed. - **Web & mobile apps**: Next.js web apps and React Native mobile apps sharing one TypeScript codebase where it makes sense. - **QA & test automation**: Automated tests and release pipelines so each release is boring in the best way. - **Dedicated teams**: A team that works as part of yours, in your time zone overlap, with your tools and rituals. ### Use cases - New products and MVPs for funded startups - Replacing spreadsheets and legacy tools with custom platforms - Extending in-house teams with senior engineers - Rescuing and stabilising projects that have stalled - Adding AI features to existing software ### FAQ **How do you price software development?** Most projects run on time and materials with a fixed monthly team, which keeps scope flexible. For well-defined phases such as discovery or an MVP we can agree a fixed price. **Do you work with companies in the UK, Germany, Switzerland and Qatar?** Yes. Our European team overlaps fully with UK and Central European working hours and largely with the Gulf, and we work in English, German and Arabic. **Who owns the code?** You do. Code, designs and documentation are yours from day one, in your repositories. **How quickly can a team start?** Usually within two to three weeks of agreeing scope, starting with a short discovery phase. ## Custom Software Development URL: https://www.amygdal.com/services/custom-software-development When off-the-shelf tools force your team into workarounds, custom software pays for itself. We build bespoke platforms, portals and internal tools — integrated with the systems you already run and designed to be maintained for years. ### What we offer - **Bespoke platforms**: Multi-tenant SaaS, marketplaces and client portals with roles, billing and audit built in. - **Internal tools**: Back-office applications that replace spreadsheets and email chains with clear workflows. - **Integrations**: Connections to ERPs, CRMs, HR, payment and messaging systems, with queues and retries that survive outages. - **Legacy modernisation**: Incremental migration from ageing systems to a modern stack, without a risky big-bang cutover. - **Workflow automation**: Documents, approvals and notifications automated — with AI where it removes manual reading or typing. - **Long-term support**: Monitoring, security updates and a roadmap after launch, from the team that built it. ### Use cases - Recruiting, HR and timesheet platforms - Dealer and sales tools for automotive groups - Pricing and comparison engines - Community and membership platforms - Data and analytics portals for financial services ### FAQ **When is custom software worth it?** When the process is core to how you compete, when off-the-shelf tools need heavy workarounds, or when integration costs exceed the licence. We will tell you if an existing product is the better buy. **Can you work with our existing systems?** Yes. Most of our custom software sits alongside ERPs, CRMs and in-house services; we design integrations early because that is where projects usually slip. **What does custom software development cost?** It depends on scope. After a short discovery we give a range and a phased plan, so the first release delivers value before the full budget is spent. **What happens after launch?** We offer ongoing support and development, or a documented handover to your in-house team. ## Mobile App Development URL: https://www.amygdal.com/services/mobile-app-development We design and build mobile apps people keep on their home screen. Using React Native and Expo, one team ships native-quality apps to both stores — with offline support, payments, notifications and the device features your product needs. ### What we offer - **Product & UX design**: Flows and interfaces designed for thumbs and short attention spans, tested as prototypes first. - **Cross-platform apps**: React Native and Expo apps for iOS and Android from one TypeScript codebase. - **Native capabilities**: Camera, NFC, widgets, biometrics, health data and background tasks, with native modules where needed. - **Backends & sync**: Supabase, NestJS or serverless backends with offline-first sync and real-time updates. - **Payments & subscriptions**: In-app purchases, Stripe and RevenueCat, with paywalls you can experiment with. - **Release & growth**: App Store and Google Play submissions, over-the-air updates, analytics and crash reporting. ### Use cases - Consumer apps with subscriptions - Health, fitness and wellbeing apps - Field and sales apps for enterprise teams - Companion apps for hardware and IoT - Networking and community apps ### FAQ **Native or cross-platform?** For most products React Native with Expo gives native performance and one codebase. We recommend fully native Swift or Kotlin when an app depends heavily on platform-specific features. **How long does it take to build a mobile app?** A focused first version typically takes three to five months, including design, development, testing and store review. **Do you handle App Store and Google Play submission?** Yes — accounts, builds, review notes, privacy labels and release management. **Can you take over an existing app?** Yes. We start with a code and architecture review, then stabilise and continue development. ## Web Development URL: https://www.amygdal.com/services/web-development From SaaS dashboards to multilingual marketing sites, we build for the web with Next.js, React and TypeScript. Fast by default, accessible, easy to rank — and structured so your team can keep shipping after we hand over. ### What we offer - **Web applications**: Dashboards, portals and SaaS products with real-time data, roles and solid state management. - **Marketing sites**: Fast sites with a CMS, structured data and analytics, built to convert. - **Multilingual & RTL**: Internationalised sites with hreflang, localised SEO and right-to-left layouts for Arabic. - **Performance & Core Web Vitals**: Server rendering, image optimisation and caching tuned until the numbers are green. - **Accessibility**: Semantic markup, keyboard support and contrast checks against WCAG 2.2 AA. - **APIs & integrations**: Auth, payments, search and third-party services connected cleanly behind your front end. ### Use cases - SaaS products and customer portals - Multi-country sites for the UK, DACH and the Gulf - E-commerce and price comparison - Community and social platforms - Internal dashboards over operational data ### FAQ **Why Next.js?** It gives server rendering, static generation and API routes in one framework, which means fast pages, good SEO and less infrastructure to run. **Can you build multilingual websites with Arabic?** Yes — including right-to-left layouts, Arabic typography and localised SEO with hreflang for each market. **Do you work with a CMS?** Yes. We use headless CMSs such as Sanity, Contentful or Strapi so your team can edit content without a developer. **Will the site be fast?** We set performance budgets at the start and test Core Web Vitals before launch. # Work ## Cardly — Mobile app · Networking URL: https://www.amygdal.com/projects/cardly Live product: https://www.usecardly.app/ Case study: https://www.amygdal.com/blog/cardly-case-study Stack: React Native, Expo, TypeScript, Supabase, PostgreSQL, Stripe, Astro, Railway Cardly replaces the paper business card. You make your card once, then hand it over as a link or a QR code — it opens in any browser, so the other person needs nothing installed. Change your job title and every card you have ever shared updates with it. We built the mobile app with React Native and Expo on top of Supabase: on-device card scanning with AI parsing for hard layouts, contacts with notes, tags and reminders, home-screen widgets, wallet passes, offline mode, company accounts with Stripe billing, and a companion web app and marketing site on Astro. ## Digital Arrow — Recruiting + HR platform URL: https://www.amygdal.com/projects/digital-arrow Live product: https://digital-arrow.agency/ Case study: https://www.amygdal.com/blog/digital-arrow-case-study Stack: Node.js, NestJS, PostgreSQL, Redis, MinIO, Elasticsearch, Browserless, Prisma, Next.js, React, Tailwind, shadcn/ui, Slack, Jira Digital Arrow brings recruiting and HR into a single workspace — from posting a role and building candidate CVs to running asynchronous video interviews with AI scoring, managing timesheets, contracts, time-off, and client invoices. We architected a scalable backend with NestJS and PostgreSQL, added full-text candidate search with Elasticsearch, media handling via MinIO, and headless document/PDF generation with Browserless — including online signatures for contracts. ## Ealthiness — Healthcare · AI health app URL: https://www.amygdal.com/projects/ealthiness Live product: https://ealthiness.app/ Case study: https://www.amygdal.com/blog/ealthiness-case-study Stack: React Native, Expo, React, React Router, TanStack Query, NestJS, MongoDB, Mongoose, Redis, Weaviate, Gemini, OpenAI, Ollama, Stripe, AWS S3, Railway Ealthiness turns everyday signals — mood, sleep, meals, fasting, steps, runs and workouts — into personal guidance. Users log their day in the mobile app, chat with an AI trainer by text or voice, and follow diet, fitness and therapy plans set up with their care team. We built the whole product: an Expo and React Native app, a NestJS API on MongoDB with Redis job queues, and an admin portal where coaches, doctors and psychologists manage patients, sessions and plans for companies and hospitals. The AI trainer runs on Gemini with fallback providers, uses a Weaviate vector store for context, and handles speech-to-text and text-to-speech for voice conversations. Subscriptions run through Stripe, and the platform deploys on Railway. ## Sumus — AI · Product discovery URL: https://www.amygdal.com/projects/sumus Live product: https://www.sumus.co/ Case study: https://www.amygdal.com/blog/sumus-ai-esg-case-study Stack: React Native, React, Next.js, NestJS, REST API, Shopify, Redis, PostgreSQL, MinIO, Railway, NextAuth, Stripe, Ollama, OpenAI, Tailwind, shadcn/ui, TanStack Query Sumus helps shoppers decide what to buy. Scan a barcode — or a photo — and Sumus breaks the product down: what is inside, how each ingredient scores on safety and quality, where it is available nearby, and what the community has to say about it. We built the AI tool behind it: product recognition from a scan, the scoring engine that combines expert rules, public data and community patterns into one clear score, and the location and community layers around it. Scores are independent — brands cannot pay to change them. The result turns a label nobody reads into a decision a shopper can make in seconds. ## Cannaleo — Healthcare · Telemedicine URL: https://www.amygdal.com/projects/cannaleo Live product: https://cannaleo.de/ Stack: Kotlin, Spring Boot, PostgreSQL, Next.js, React, TypeScript, Tailwind, TanStack Query, Turborepo, AWS S3, Vercel Cannaleo GmbH builds software for medical-cannabis therapy in Germany. The Cannaleo Portal brings patients, doctors, practices and pharmacies into one regulated flow: a patient submits a therapy request and questionnaire, books a doctor, joins a video consultation and receives a prescription that is sent to a pharmacy that has the medicine in stock. We built the portal as three Next.js apps — patient, doctor and admin — on a Kotlin and Spring Boot API with PostgreSQL and PostGIS. It handles appointments and availability, repeat-prescription requests, pharmacy stock search, qualified electronic signatures, video consultations, payments and transactional email, with document storage on S3. ## UK Water & Gas Connections — Utilities · Connections platform URL: https://www.amygdal.com/projects/uk-utilities-connections Stack: React, Vite, React Router, Tailwind, TypeScript, Hono, Drizzle, PostgreSQL, AWS Lambda, API Gateway, AWS RDS, AWS Cognito, AWS SQS, SST, Terraform Getting a new water or gas connection in the UK means applications, site details, fees, quotes and payments that move between the customer and the network operator. We built one platform that runs that whole process for several UK water and gas networks, each as its own tenant. Customers apply and track progress in a client portal; staff work cases in an admin portal with a configurable workflow engine, a form builder with 30+ field types, a fee calculator and a quote generator. Scheduled jobs chase payments, surveys and expiring quotes against SLAs, and the platform integrates with SAP, payment providers, GIS mapping and the contact centre. The backend is Hono on AWS Lambda with PostgreSQL (a schema per tenant), Cognito sign-in, SQS queues and SES email. We first built the infrastructure with SST and later migrated it to Terraform. ## Customer CRM on Google Cloud — CRM · Google Cloud URL: https://www.amygdal.com/projects/customer-crm Stack: React, React Router, TanStack Query, TypeScript, NestJS, Firestore, Google Cloud, Cloud Run, Cloud Functions, Pub/Sub, Cloud Logging, Terraform Support and operations teams for a subscription product with around 3 million customers needed one place to look up a customer and act on their account. We built that CRM: customers, subscriptions, transactions and refunds, notes and activity history, with roles, permissions and an audit trail of who changed what. The API is NestJS on Cloud Run over Firestore, with Pub/Sub and Cloud Functions handling events between services and Cloud Logging for traceability. The React front end uses React Router and TanStack Query, and all infrastructure is defined in Terraform. ## AloAlo eSIM — Travel · Mobile app URL: https://www.amygdal.com/projects/aloalo Live product: https://aloalo.one/ Stack: React Native, Expo, NestJS, Prisma, PostgreSQL, Stripe, TanStack Start, Tailwind, Railway AloAlo is our own travel eSIM product. Travellers pick a destination, compare data plans and buy one in a couple of taps; the eSIM is provisioned through a carrier partner API and installed straight onto the phone, so there is no physical SIM and no roaming bill. We built the iOS and Android app with React Native and Expo, a NestJS and Prisma backend that handles plan catalogues, orders and Stripe payments, a TanStack Start admin panel for operations, and a fast marketing site — all deployed on Railway. ## AISell — E-commerce · AI platform URL: https://www.amygdal.com/projects/aisell Live product: https://aisell.store/ Stack: Next.js, React, Tailwind, Hono, Prisma, PostgreSQL, MongoDB, Redis, OpenAI, Stripe, Expo AISell is our own product for the shift from search to AI assistants. Merchants connect their catalogue, AISell structures it so AI platforms can discover the products, and shoppers can find and buy through a chat-based assistant instead of browsing a website. We built the platform end to end: a Hono backend with PostgreSQL and MongoDB, background jobs on Redis queues, LLM pipelines for product understanding and conversational search, Stripe checkout, a Next.js storefront localised into five languages including right-to-left Arabic, and an Expo mobile app. ## REI Print Mail — PropTech · SaaS platform URL: https://www.amygdal.com/projects/reiprintmail Live product: https://reiprintmail.com/ Stack: NestJS, Prisma, PostgreSQL, Supabase, Snowflake, Qwik, Vue, Python, FastAPI, Stripe REI Print Mail helps real-estate investors in the United States find motivated sellers and reach them by mail. Customers build lists of property records, design letter campaigns, and order printed mail that is generated, tracked and delivered for them; the companion REI Smart Data app lets them query property data directly. Our engineers worked across the platform: NestJS services in a Turborepo monorepo, PostgreSQL and Snowflake for property data, PDF letter generation with tracking codes, Stripe billing, a Qwik marketing and ordering front end, a Vue data app, and Python FastAPI data services. ## Adriatic ERP — ERP · Integrations URL: https://www.amygdal.com/projects/adriatic-erp Live product: https://adriaticsystems.ba/ Stack: Python, Frappe, ERPNext Adriatic Systems offers a cloud ERP tailored to companies in Bosnia and Herzegovina, where invoices must be fiscalised and accounting follows a national chart of accounts. We built the localisation layer that makes ERPNext work under those rules. On the Frappe framework we developed an integration with certified fiscal devices so retail receipts and invoices are fiscalised automatically, an importer for the standard Bosnian chart of accounts, and modules for wholesale price calculation and other local requirements. ## Dorfleben — Community social network URL: https://www.amygdal.com/projects/dorfleben Live product: https://dorfleben.de/ Stack: Node.js, Next.js, React, React Native, AWS, S3, SageMaker, Ollama, Weaviate, Redis, PostgreSQL, Algolia, Drizzle, Tailwind, TanStack Query, shadcn/ui, WebSockets Dorfleben is a community platform for towns and villages across Germany, bringing local administration, clubs, church, school, and daycare together in one place. Residents discover events, join groups, and stay connected with the people and organizations around them. We built the community app end to end — web and mobile (React and React Native) on a Node.js backend — with AI-powered search and recommendations (Weaviate, SageMaker, Ollama), instant discovery through Algolia, and realtime updates over WebSockets. The platform makes it effortless for an entire community to organize and communicate, and its success has become a model that other towns look to when they want to bring local life online. ## Zilius — Healthcare · Care coordination URL: https://www.amygdal.com/projects/zilius Live product: https://www.zilius.ai/ Stack: React, TypeScript, Apollo GraphQL, Ant Design, Node.js, Express, GraphQL, MongoDB, AWS Cognito, AWS S3, AWS Zilius helps hospital care teams follow cardiac patients — after bypass surgery or a coronary intervention — once they leave the hospital, so readmissions are caught and acted on early. We worked on the platform end to end: data views for patients, physicians, facilities and admission events with search, filters and CSV export; monthly readmission alerts; ingestion of HL7 ADT messages from a regional health information exchange; and data uploads and reporting. Each hospital runs its own isolated deployment on AWS, with Cognito sign-in and a GraphQL API over MongoDB. ## Profil Klett — IZZI — Education · Digital learning URL: https://www.amygdal.com/projects/profil-klett Live product: https://izzi.digital/ Stack: PHP, Symfony, Vue, Nuxt, Angular, MySQL, Redis, RabbitMQ Profil Klett is a Croatian school publisher, and IZZI is its digital learning platform: a bookshelf of digital textbooks, classrooms for teachers, family accounts so parents can follow their children, leaderboards, and quizzes generated by learning outcome and difficulty. We worked across the platform — the Symfony API, the Vue and Nuxt bookshelf apps, the Angular authoring tool and the shared theme — and on localisation for new markets, on a Docker stack with MySQL, Redis and RabbitMQ. ## BYOD — Hospitality · Operations platform URL: https://www.amygdal.com/projects/byod Live product: https://byod.ai/ Stack: React, TypeScript, TanStack Query, Flutter BYOD (Bring Your Own Data) gives restaurant and hospitality operators one view of their business. Managers schedule staff and handle shift trades, pick-ups and availability; compare labour against sales and predicted hours; and watch a live situation room that pulls together sales, schedules, events and other signals. We built the web platform — scheduling, employees, labour analytics, the situation room and guest-facing modules — and a Flutter mobile app for staff with checklists, a logbook and to-dos. ## Hurree — Martech · Analytics SaaS URL: https://www.amygdal.com/projects/hurree Live product: https://www.hurree.co/ Stack: React, TypeScript, Tailwind, MUI, Python, Django, PostgreSQL, Redis, Azure Functions, Azure, Stripe Hurree brings the numbers a team cares about into one dashboard. Teams connect tools such as HubSpot, Google Analytics, Google Ads, Facebook, LinkedIn, Mailchimp, Klaviyo, Shopify and Stripe, then build dashboards from widgets and share live snapshots. We built the platform's core: a Django REST API with PostgreSQL, background workers on Redis, scheduled data syncs running on Azure Functions, a React dashboard app with charts and performance thresholds, Stripe subscriptions with trials, and an internal admin analytics app. ## A Place For Mom — Healthcare platform URL: https://www.amygdal.com/projects/aplaceformom Live product: https://www.aplaceformom.com/ Stack: Next.js, React, Node.js, MongoDB, Mongoose, AWS Lambda, AWS SQS, AWS SNS, AWS S3, AWS EC2, Tailwind, MUI, Slack, Jira, Linear A Place for Mom is one of the largest senior-care referral services in the United States, helping families find the right assisted living, memory care, and home care through a trusted network of thousands of providers. The platform serves 300,000+ customers across the country. We delivered the healthcare service side of the product — a high-scale platform on Next.js and Node.js with MongoDB, using event-driven AWS infrastructure (Lambda, SQS, SNS, S3, EC2) to stay fast and reliable under heavy, nationwide load. Every interaction is designed to support families at a difficult moment: clear guidance, trusted matches, and expert advice that help them make confident decisions about their loved ones' care. ## History.com — Streaming · QA automation URL: https://www.amygdal.com/projects/history Live product: https://www.history.com/ Stack: Appium, WebdriverIO, Mocha, Oclif History is A+E's streaming home for History Channel content across TV platforms, with History Vault as its subscription service. We built automated end-to-end tests for both apps on Amazon Fire TV, Android TV and Apple TV. The suites cover browsing, search, shows and seasons, live TV, the video player, sign-in with TV providers, and the History Vault registration and subscription flows — run on real devices with Appium and WebdriverIO, and driven by a custom Oclif CLI. ## A+E Global Media — Media · QA automation URL: https://www.amygdal.com/projects/aegm Live product: https://www.aegm.com/ Stack: Appium, WebdriverIO, Mocha, Oclif A+E Global Media runs some of the best-known TV brands, and each one ships its own streaming app on every living-room platform. We built one shared test suite for the TV Everywhere apps of History, History Vault, A&E, Lifetime and FYI on Amazon Fire TV, Android TV and Apple TV. The suite covers free and subscription experiences — browsing, search, shows and seasons, live TV, the player, Continue Watching, sign-in through TV providers and voice prompts — and runs on real devices with Appium and WebdriverIO. A custom Oclif CLI drives the runs, CI pulls test builds automatically, and reports with screen recordings go to the team after every run. ## Srovnejto — Price comparison URL: https://www.amygdal.com/projects/srovnejto Live product: https://www.srovnejto.cz/ Stack: .NET, Vue, Nuxt, PostgreSQL, Azure Database, Azure Redis, Azure Messaging, Socket.io Srovnejto.cz helps consumers in the Czech Republic navigate and compare a wide range of products and services — from energy and utilities to insurance and financial products. We worked across a .NET backend and a Vue/Nuxt frontend on Azure (managed database, Redis, and messaging), with realtime updates over Socket.io. ## Volkswagen — Automotive · Cloud solution URL: https://www.amygdal.com/projects/volkswagen Live product: https://www.volkswagen.com/ Stack: React, React Context, Tailwind, .NET, REST API, Azure, AI models Volkswagen Group is one of the world's largest automotive manufacturers, home to brands including Volkswagen, Audi, Porsche, and Škoda, with operations and customers across the globe. For VW Group we delivered a cloud solution powering financial-services and car-configurator support tooling — scalable, resilient infrastructure that serves clients worldwide and keeps critical automotive services running smoothly. It's software built for scale and reliability, supporting the day-to-day operations of a global automotive leader. ## Škoda Auto — Automotive · Sales tool URL: https://www.amygdal.com/projects/skoda Live product: https://www.skoda-auto.com/ Stack: React, React Context, Tailwind, .NET, REST API, Azure, Messaging services Škoda Auto is one of Europe's oldest and best-known car manufacturers and a core brand of the Volkswagen Group, selling vehicles in more than a hundred markets worldwide. For Škoda we built a sales tool that supports the dealer and customer journey — helping teams configure, present, and move vehicles through the sales process with a fast, modern interface. The work sits within the wider VW Group ecosystem we support, bringing a consistent, reliable digital experience to Škoda's sales operations across markets. ## Oppinly — Product design URL: https://www.amygdal.com/projects/oppinly Stack: Next.js, React, NestJS, Tailwind, shadcn/ui, TanStack Query, TanStack Table, Railway We designed the product experience for Oppinly — from concept and flows to a polished, ready-to-build interface. ## Tradefeedr — Fintech · Data analytics URL: https://www.amygdal.com/projects/tradefeedr Live product: https://www.tradefeedr.com/ Stack: React, Next.js, Tailwind, shadcn/ui, TanStack Query, TanStack Table, Python, FastAPI Tradefeedr is a data-analytics platform for the institutional trading community — banks, hedge funds, and asset managers — that unifies fragmented trading data into a single, shared source of truth for analyzing execution quality and performance. We contributed to the data-analytic tool that makes this possible: connecting and normalizing data from many venues and counterparties, then surfacing the analytics that help institutions understand and improve how they trade. The outcome is clarity in a notoriously complex domain — turning scattered trading data into insight that teams across the industry can rely on. ## Bratislava.sk — Government · City portal URL: https://www.amygdal.com/projects/bratislava Live product: https://bratislava.sk/ Bratislava.sk is the official website of the capital city of Slovakia. Residents use it to find city services, transport and environment information, news, the official notice board and elections information. We built the website for the city. ## Visit Bratislava — Tourism · Multilingual website URL: https://www.amygdal.com/projects/visitbratislava Live product: https://www.visitbratislava.com/ Visit Bratislava is the city's official tourism site. Visitors plan trips by length, browse events and experiences, find food and drink, and learn about the Bratislava CARD, in English, German, Slovak, Hungarian and Italian. We built the website. ## Rite-Hite — Industrial · Web platform URL: https://www.amygdal.com/projects/ritehite Live product: https://www.ritehite.com/ Rite-Hite designs and manufactures loading dock equipment, industrial doors, safety barriers and climate-control systems for warehouses and plants worldwide. We worked on Rite-Hite's web platform. ## Strawberry Export ERP — Agriculture · Mobile ERP URL: https://www.amygdal.com/projects/strawberry-erp Stack: React Native, Zebra scanners A business that imports and exports strawberries needs every movement of fruit recorded as it happens, not typed in later. We built an ERP app in React Native that runs on Zebra handheld scanners, so staff scan goods straight into import and export records on the warehouse floor. # Articles ## Healthcare Software Development in Europe: GDPR, MDR and the AI Act URL: https://www.amygdal.com/blog/healthcare-software-development-europe Published: 2026-10-13 · Category: Healthcare · Tags: Healthcare, Europe, GDPR, EU AI Act, MDR, DiGA Europe stacks several regimes on top of GDPR. Here is how MDR, the AI Act, the European Health Data Space, DiGA and DTAC shape healthcare software in 2026. Building healthcare software for Europe means meeting several regimes at once. GDPR sets the baseline for health data. The Medical Device Regulation decides whether your software is a regulated device. The AI Act adds a high-risk regime for medical AI. The European Health Data Space sets new requirements for EHR systems. National routes such as Germany's DiGA and England's DTAC decide whether health systems will pay for or adopt your product. This guide summarises our research into what each of these means for a software team in 2026. We build for clients in Germany, Switzerland and the UK. It is engineering guidance, not legal advice. For the cross-market view, see our [healthcare page](https://www.amygdal.com/healthcare). ### GDPR: special-category data from the first sprint Under [GDPR](https://eur-lex.europa.eu/eli/reg/2016/679/oj), health data is special-category data. You need an Article 9 condition on top of an Article 6 lawful basis, a DPIA for large-scale processing (Article 35), and data protection by design and by default (Article 25). In engineering terms: - **Minimise per feature.** List the exact fields each feature and model needs, and send nothing more. - **Pseudonymise where the task allows.** Pseudonymised data is still personal data under GDPR, but pseudonymisation is a recognised safeguard. - **Host in the EU or Switzerland** and keep a register of sub-processors, including model providers and observability tools. - **Make rights self-service** where possible: access, export, correction and erasure. Switzerland runs its own regime. The revised [Federal Act on Data Protection](https://www.fedlex.admin.ch/eli/cc/2022/491/en), in force since 1 September 2023, treats health, genetic and biometric data as sensitive and introduces privacy by design and impact assessments. It is close to GDPR in approach, but the details differ. ### MDR rule 11: is your software a medical device? Under the [Medical Device Regulation (EU) 2017/745](https://eur-lex.europa.eu/eli/reg/2017/745/oj), software with a medical intended purpose is a medical device, and Annex VIII Rule 11 sets its class. Software that provides information used to take diagnostic or therapeutic decisions is **class IIa** at minimum. It is **IIb** if those decisions could cause serious deterioration or surgical intervention, and **III** if they could cause death or irreversible deterioration. Class IIa and above need a notified body. MDCG 2019-11 is the main [guidance on qualification and classification](https://health.ec.europa.eu/medical-devices-sector/new-regulations/guidance-mdcg-endorsed-documents-and-other-guidance_en). Intended purpose drives everything, so we settle it in discovery. A symptom-tracking diary and a tool that recommends a dose may share most of their code, but they are regulated very differently. Where the product is a device, we use an IEC 62304-style software lifecycle and ISO 14971 risk management from the first sprint. ### The EU AI Act: new dates for high-risk medical AI Under the [AI Act](https://eur-lex.europa.eu/eli/reg/2024/1689/oj), AI that is a medical device, or a safety component of one, and that requires third-party conformity assessment is **high-risk**. That brings risk management, data governance, technical documentation, automatic logging, transparency, human oversight, accuracy and robustness requirements. Prohibited practices have applied since February 2025. The timeline has changed. The [Digital Omnibus on AI, Regulation (EU) 2026/1744](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=OJ:L_202601744), entered into force on 27 July 2026. It moved high-risk obligations to **2 December 2027** for Annex III systems and **2 August 2028** for AI in products covered by Annex I legislation, which includes medical devices. The extra time is useful, but it doesn't change what needs to be built: dataset provenance, versioned models, evaluation and bias reports, human-in-the-loop interfaces and logs. Teams that build these in now won't have to reconstruct them later. Our post on [HIPAA- and GDPR-compliant AI](https://www.amygdal.com/blog/hipaa-gdpr-compliant-ai-healthcare) covers the practices in detail. ### The European Health Data Space The [European Health Data Space Regulation (EU) 2025/327](https://health.ec.europa.eu/ehealth-digital-health-and-care/european-health-data-space-regulation-ehds_en) entered into force on 26 March 2025 and applies in phases: - **March 2027:** deadline for the Commission's key implementing acts. - **March 2029:** cross-border exchange of the first priority categories (patient summaries, ePrescriptions/eDispensations), and secondary-use rules for most categories. - **March 2031:** the second group (medical images, lab results, hospital discharge reports). - **March 2035:** third countries and international organisations can apply to join HealthData@EU for secondary use. For anyone building EHR systems or modules, the EHDS adds pre- and post-market requirements for interoperability and logging. Choosing HL7 FHIR and structured, coded data now is the cheapest way to prepare. ### National routes: Germany's DiGA and England's DTAC **Germany.** Under the [DiGA procedure](https://verwaltung.bund.de/leistungsverzeichnis/EN/leistung/99005058019000), digital health applications can be prescribed and reimbursed under statutory health insurance after BfArM review. Key points from the official description: - A DiGA must be a medical device in **class I, IIa or IIb**. - BfArM usually decides within **three months**, extendable by up to three more in justified cases. - **Provisional listing** gives up to 12 months to prove a positive care effect, extendable by a further 12 in exceptional cases. - Applicants must show data protection, information security (including **ISO 27001** ISMS evidence and remediated penetration-test findings) and interoperability. **England.** NHS buyers assess products against the Digital Technology Assessment Criteria, which cover clinical safety, data protection, technical security, interoperability and usability and accessibility. NHS England [published a refreshed DTAC form](https://innovation.nhs.uk/news/updated-nhs-england-digital-technology-assessment-criteria-dtac-form-and-guidance/) on 4 March 2026 with 25% fewer questions, and full transition was due by 6 April 2026. Clinical safety evidence comes from [DCB0129](https://www.digitalregulations.innovation.nhs.uk/regulations-and-guidance-for-developers/all-developers-guidance/complying-with-nhs-digital-clinical-risk-management-standards/), which requires a clinical safety officer, a hazard log and a safety case from the manufacturer, while deploying organisations follow DCB0160. ### Mistakes we see most often - **Classifying late.** Teams build a 'wellness' app, add a recommendation feature, and only then find they have a class IIa device needing a notified body. - **Treating the DPIA as paperwork.** Its findings should change the design, for example by dropping fields, shortening retention or moving processing in-region. - **Ignoring the observability stack.** Error trackers and log platforms can capture full payloads, including health data, outside the agreed region. - **One market at a time.** Building for Germany first and then retrofitting NHS or Swiss requirements costs more than designing for the shared core (GDPR, FHIR, clinical risk management) from the start. ### How we build healthcare software for Europe 1. **Intended purpose and classification first.** Decide on MDR Rule 11 and AI Act status in discovery, and record the reasoning. 2. **EU or Swiss hosting** with a sub-processor register, data-transfer documentation and retention schedules that cover logs. 3. **FHIR-first interoperability** with national profiles where they exist, so EHDS, DiGA and NHS integrations don't require rewrites. 4. **Evidence as a by-product of delivery.** The DPIA, hazard log, test reports and penetration-test results are updated with each release. 5. **AI with oversight built in:** sources and uncertainty shown to the user, overrides recorded, models and prompts versioned and evaluated. We bring consumer-health product experience from [Ealthiness](https://www.amygdal.com/projects/ealthiness), a mobile fitness and wellbeing app we designed and built, and large-scale platform engineering from our work for [A Place For Mom](https://www.amygdal.com/projects/aplaceformom). For DiGA-ready apps or NHS-facing tools, see our [AI in healthcare](https://www.amygdal.com/services/ai-in-healthcare) and [mobile app development](https://www.amygdal.com/services/mobile-app-development) services, or [contact us](https://www.amygdal.com/contact). ### FAQ **When do EU AI Act high-risk rules apply to medical AI?** Since the Digital Omnibus on AI (Regulation (EU) 2026/1744), high-risk obligations for AI in products covered by Annex I legislation, which includes medical devices, apply from 2 August 2028. Standalone Annex III high-risk systems follow from 2 December 2027. **Is health software automatically a medical device under MDR?** No. It depends on intended purpose. Software with a medical purpose, such as informing diagnosis or treatment decisions, is a device and under Rule 11 is usually class IIa or higher. Wellness, administrative and booking software is generally not. **What does a DiGA need to get listed in Germany?** It must be a CE-marked medical device in class I, IIa or IIb, meet data protection, security (including ISO 27001 evidence) and interoperability requirements, and show a positive care effect, which can be done during a provisional listing of up to 12 months. ## A Lightweight AI Governance Model for Growing Companies URL: https://www.amygdal.com/blog/internal-ai-governance-framework Published: 2026-10-07 · Category: AI · Tags: AI governance, AI adoption, Strategy, Risk Your teams are already using AI. Governance is how you keep that safe and useful without creating a committee that blocks everything. In most companies, AI adoption did not start with a strategy. It started with individuals: someone pasting a contract into a chatbot, a developer trying a coding assistant, a marketing team generating drafts. By the time leadership asks what the AI policy is, dozens of tools are already in use and some product features already depend on models. Governance is often pictured as a heavy committee that slows everything down. It does not need to be. For a growing company, a lightweight model that fits on a few pages can reduce real risks while making it easier, not harder, for teams to use AI well. The aim is not to slow adoption. Companies that put a clear, proportionate framework in place tend to adopt AI faster, because teams know which tools they can use and what review a new idea will need. Uncertainty, not governance, is what usually holds people back. ### Start with an inventory You cannot govern what you cannot see. Build a simple register of every AI use in the company, whether in internal tools or customer-facing features. For each entry, record: - What it does and which team uses it. - Which tool or model it relies on, and under which contract. - What data goes into it, especially personal, confidential or customer data. - Who or what is affected by its output. - Who owns it. A spreadsheet is fine to begin with. The value is in having it at all, and in keeping it current. Ask teams to add entries themselves through a short form, and make clear that registering a tool is not a request for permission. People report what they use when reporting carries no penalty. Review the list quarterly and remove what is no longer in use. ### Sort uses by risk Not every use deserves the same scrutiny. A three-tier approach works for most organisations: 1. **Low risk**: personal productivity with non-sensitive data, such as drafting, summarising public material or brainstorming. Approved tools, basic guidance, no review. 2. **Medium risk**: internal workflows using company or customer data, or output that is published externally. Named owner, approved tool with suitable data terms, periodic checks. 3. **High risk**: AI that influences decisions about people (hiring, credit, health, access to services) or acts autonomously in customer-facing systems. Formal review, evaluation, human oversight and documentation. If you serve European users, align the high tier with the categories in the EU AI Act. Our [practical reading of the AI Act](https://www.amygdal.com/blog/eu-ai-act-for-product-teams) explains how those categories map onto product work. Data classification makes the tiers easier to apply. If the company already labels information as public, internal, confidential or restricted, map each label to the tools and uses allowed for it. Staff then have a simple rule: check the label, check the list. ### Approve tools, not just rules A policy that only says what people must not do will be ignored. Give teams approved tools with enterprise data terms, single sign-on and clear guidance on what data may be used where. When the sanctioned option is easy and good, unsanctioned use falls away on its own. Review new tool requests quickly; a request that waits weeks for an answer is a request that gets solved some other way. Keep a short list of uses the company will not pursue at all, such as entering restricted customer data into consumer chat tools, or fully automated decisions about employees. A few clear red lines are easier to remember than a long policy, and they remove the need to debate the same requests repeatedly. ### Owners and a small review group Every medium- and high-risk use needs a named owner who is accountable for how it behaves. Add a small review group, typically someone from engineering, security or data protection, legal and the relevant business area, that looks at high-risk uses before launch and whenever they change significantly. Keep the group small and the turnaround short. Its job is to make good launches possible, not to prevent launches. #### Vendors and contracts Many AI risks arrive through suppliers rather than internal projects. When buying software, ask whether it uses AI, which models it relies on, where data is processed, whether your data is used for training and how the vendor evaluates quality. Add these questions to standard procurement checklists so they are asked every time, not only when someone remembers. ### Evaluate and monitor For AI that is built into products or important workflows, governance depends on engineering practice. The essentials are the same ones we apply on every project: - An evaluation set for each feature, rerun on every model or prompt change. - Logging of inputs, outputs and model versions, with retention aligned to data protection rules. - Monitoring for quality drift, cost and incidents, with an owner who reviews the numbers. - A clear route for users and staff to report problems, and a process to act on reports. Our guide to [testing models on your own data](https://www.amygdal.com/blog/how-to-evaluate-llms-for-your-product) describes how to build those evaluation sets. Plan for incidents as well. Decide in advance what counts as an AI incident, such as a data leak through a tool, a harmful output reaching a customer or a decision made on a clearly wrong result, who is told, and how the affected system is paused. Treat it like any other operational incident, with a short review afterwards and changes that prevent a repeat. ### Train people on judgement Short, practical training does more than a long policy document. Show people real examples: what can go wrong when confidential data goes into the wrong tool, how models produce confident errors, and why a human should check anything that leaves the company. Revisit the guidance as tools change, which they will, frequently. #### Keep it proportionate Review the framework itself once or twice a year. If low-risk uses are waiting on approvals, loosen the process. If incidents keep coming from one area, tighten it there. Good governance changes with the company and the tools; a policy written once and left alone quickly stops matching how people actually work. ### Need help putting AI governance in place? We help companies adopt AI with the engineering practices that make governance workable. See our [custom AI development](https://www.amygdal.com/services/custom-ai-development) service, or [get in touch](https://www.amygdal.com/contact) to discuss your AI roadmap. ### FAQ **Does a mid-sized company need an AI governance framework?** Yes, but a light one. An inventory of AI uses, risk tiers, approved tools, named owners and a small review group for high-risk uses covers most of what matters without slowing teams down. **What should an AI usage policy include?** Which tools are approved, what data may be used with each, which uses need review, who owns each AI system, and how people report problems. Pair it with short practical training rather than relying on the document alone. **Who should own AI governance in a company?** Each AI use needs its own accountable owner. Oversight typically sits with a small cross-functional group drawing on engineering, security or data protection, legal and the business, with a clear executive sponsor. ## Custom Software Development: A Practical Buyer's Guide URL: https://www.amygdal.com/blog/custom-software-development-guide Published: 2026-10-01 · Category: Engineering · Tags: Custom software, Buying software, Nearshore, Outsourcing Commissioning custom software for the first time? A plain guide to build vs buy, discovery, pricing models, team shape and what a good software company hands over. Commissioning custom software is a significant decision, and most people only make it a few times in their career. Proposals from different vendors are hard to compare, the terminology is unfamiliar and the risks are not obvious until something goes wrong. This guide is written from the other side of the table. We are a software development company with offices in Delaware, Sarajevo and Doha, working with clients in the UK, Germany, Switzerland and Qatar. Here is what we would want a client to know before choosing any partner, including us. ### Build or buy? The cheapest software is software you do not have to build. Before commissioning custom software development, check honestly whether an existing product would do the job. A rough guide: - **Buy** when the process is standard (accounting, payroll, basic CRM), when an off-the-shelf tool covers most of your needs, and when the process is not what differentiates you. - **Build** when the software is the product you sell, when it encodes a process that gives you an edge, when you need integrations no vendor offers, or when licence costs at your scale exceed the cost of owning it. - **Combine** in many cases: buy the commodity parts and build the layer that connects them and carries your specific logic. A good partner will tell you when not to build. If a vendor never questions whether you need custom software, treat that as a signal. ### Start with discovery, not a quote Any fixed quote produced from a two-page brief is a guess. A short paid discovery phase, typically a few weeks, turns that guess into a plan. It should produce: 1. A clear statement of the problem, the users and how success will be measured. 2. A prioritised scope, separating what is needed for a first release from what can wait. 3. Key user flows and wireframes or a clickable prototype for the riskiest parts. 4. A proposed architecture and technology choice, with reasons. 5. A delivery plan with milestones and a realistic budget range. Discovery is also the cheapest moment to find out whether you work well with a team. If communication is difficult during discovery, it will not improve during delivery. ### Fixed price or time and materials? **Fixed price** works when scope is genuinely well defined and unlikely to change: a clearly specified integration, a migration, a small tool. The vendor carries the estimation risk and prices it in, and any change goes through a change request. **Time and materials** works better for products that will evolve as you learn from users, which describes most new software. You pay for the team's time and keep control of priorities. The risk is open-ended spending, which you manage with a budget cap, fortnightly demos, a visible backlog and the right to stop at any milestone. A common, sensible pattern is fixed-price discovery followed by time-and-materials delivery in agreed phases. ### What a good team looks like The size of the team matters less than its shape. For a typical web or mobile product, a capable core team includes a product or delivery lead who owns communication and priorities, a designer for at least the early phases, two to four engineers covering frontend, backend and mobile as needed, and QA built into the process rather than bolted on at the end. Ask who will actually work on your project, and whether those people stay for its duration. Senior names in the pitch who disappear after kick-off are a common source of disappointment. ### Nearshore delivery for the UK, Germany and Switzerland Our engineering hub in Sarajevo works in Central European Time, the same time zone as Germany and Switzerland and one hour ahead of the UK. In practice that means full overlap for daily stand-ups, workshops and quick calls, which is the main advantage of nearshore over far-offshore delivery. Travel for kick-offs and workshops is a short flight. We have delivered for clients in these markets, including a community platform for towns across Germany ([Dorfleben](https://www.amygdal.com/projects/dorfleben)) and work within the Volkswagen Group ecosystem for [Volkswagen](https://www.amygdal.com/projects/volkswagen) and [Škoda](https://www.amygdal.com/projects/skoda). Clients in Germany and Switzerland often have specific expectations around data protection and documentation; GDPR-aware design and clear written handover are part of how we work by default. ### Working with clients in Qatar and the Gulf Our office in Doha supports clients in Qatar and the wider Gulf. Projects there often bring requirements that should be raised in discovery rather than discovered late: Arabic and English interfaces with proper right-to-left layouts, local data residency or hosting preferences, integration with local payment providers and government systems, and a working week that differs from Europe's. With a team on the ground in Doha and engineering in Europe, time-zone overlap is good, and in-person workshops are straightforward to arrange. ### What you should own at the end Whoever you choose, make sure the contract and the working practice give you everything needed to continue without them. A good software development company hands over: - **Source code** in a repository you own, from day one, not at the end. - **Infrastructure and accounts** (cloud, app stores, domains, third-party services) registered to your organisation. - **Documentation:** architecture overview, setup instructions, deployment process and key decisions. - **Automated tests and a CI/CD pipeline**, so another team can change the code safely. - **Clear intellectual property terms** assigning the work to you. - **A handover period** with your in-house team or a new vendor, if you choose to move on. ### Red flags when choosing a vendor Most failed software projects show warning signs early. Be cautious if a vendor: - Gives a confident fixed price for a large product without discovery. - Cannot name the people who will work on your project. - Keeps the code in their own repository until final payment. - Offers no regular demos of working software, only status reports. - Agrees with every requirement and never pushes back on scope. ### Talk to us If you are weighing up a custom software project, we are happy to give you an honest view, including when buying is the better option. Read about our [custom software development](https://www.amygdal.com/services/custom-software-development) service, see what [custom AI development](https://www.amygdal.com/blog/custom-ai-development) can add, or [contact us](https://www.amygdal.com/contact) to arrange a call. ### FAQ **How much does custom software development cost?** It depends on scope, platforms and team size. A short paid discovery phase is the most reliable way to get a realistic budget range rather than a guess based on a brief. **Is nearshore development from Europe a good fit for UK, German and Swiss companies?** Usually, yes. Our Sarajevo team works in Central European Time, giving full overlap with Germany and Switzerland and near-full overlap with the UK, with short travel for in-person workshops. **Who owns the code when the project ends?** You should. Insist on code in a repository you own from day one, infrastructure in your name, clear IP assignment, documentation and a handover period in the contract. ## AI in BIM: Practical Uses for Building Information Models URL: https://www.amygdal.com/blog/ai-in-bim Published: 2026-09-22 · Category: AI · Tags: BIM, AEC, IFC, RAG, Automation BIM models hold enormous amounts of structured data that teams rarely have time to use. Where AI genuinely helps, from model checking to asking a model questions in plain language. Building Information Modeling (BIM) has turned design and construction data into something structured: walls, doors, ducts and beams with types, properties, quantities and relationships. In theory, that makes BIM ideal for automation. In practice, much of the checking, classification and reporting on BIM models is still done by hand, by skilled people who would rather be designing. We have worked on AI and software development for BIM, and the pattern we see is consistent: the useful applications of **AI in BIM** are not about generating buildings. They are about reading models faster, catching problems earlier and making model data accessible to people who do not use authoring tools. Here is where AI helps, and what it takes to make it reliable. ### Getting the data out: IFC and Revit extraction Everything starts with data extraction. Open formats such as IFC can be parsed with libraries like IfcOpenShell; Revit data is usually accessed through the Revit API or exported to IFC or a structured format. The goal is a clean, queryable representation of elements, their properties, spatial structure (site, building, storey, space) and relationships. This step is unglamorous and decisive. Models from different firms and tools use properties inconsistently, leave fields empty, or put key information in free-text names. A good extraction pipeline normalises units, maps custom property sets to a common schema and records where each value came from, so later steps can be traced back to the source model. ```python import ifcopenshell import ifcopenshell.util.element as util model = ifcopenshell.open("project.ifc") rows = [] for el in model.by_type("IfcBuildingElement"): psets = util.get_psets(el) rows.append({ "guid": el.GlobalId, "ifc_class": el.is_a(), "name": el.Name, "storey": getattr(util.get_container(el), "Name", None), "type": getattr(util.get_type(el), "Name", None), "properties": psets, }) ``` ### Classifying elements Many workflows depend on elements being classified correctly — against Uniclass, OmniClass, a national standard or a client's own cost codes. In real models, classification fields are often missing or wrong. Machine learning and language models can suggest classifications from an element's IFC class, type name, family, properties and geometry, with a confidence score. The practical design is to auto-apply only high-confidence suggestions, queue the rest for review, and learn from the corrections. That turns a tedious manual pass into a focused review of the genuinely ambiguous cases. ### Automated model checking Model checking verifies that a model meets requirements: required properties present, naming conventions followed, elements on the right storeys, fire ratings set where needed, information requirements met at each project stage. Rule-based checking is well established and should remain the backbone, because rules are explainable and repeatable. AI adds value at the edges. Language models can help translate written requirements — employer's information requirements, specifications, standards — into draft machine-checkable rules for an expert to confirm. They can also explain failures in plain language and group hundreds of individual issues into a short list of underlying causes. ### Clash triage Clash detection tools are good at finding geometric intersections and poor at telling you which ones matter. A federated model can produce thousands of clashes, most of them duplicates, tolerances or acceptable overlaps such as insulation around a pipe. Teams spend hours sorting them before coordination meetings. - **Group related clashes** that share a root cause, such as one duct run hitting a series of beams. - **Filter likely non-issues** based on element types, disciplines and overlap size, using the team's past decisions as training signal. - **Prioritise** by discipline, location and construction sequence, so the meeting starts with what blocks work soonest. - **Draft issue descriptions** in a standard format such as BCF for a coordinator to review and assign. The coordinator still decides. The AI reduces the pile they have to look at. ### Quantity takeoff Quantities can be read directly from well-modelled elements, but takeoff often stalls on inconsistent modelling: walls split oddly, slabs modelled as generic objects, missing material layers. AI-assisted classification and data cleaning make automated takeoff usable on real models, and anomaly detection can flag quantities that look wrong compared with similar elements or previous revisions. Results should always be traceable to element IDs so estimators can check them. ### Asking a BIM model questions in plain language Project managers, owners and facility teams rarely open authoring tools, yet they constantly need answers from the model: how many fire doors are on level 3, which rooms lack a specified finish, what changed between revisions. A natural-language interface built with retrieval-augmented generation makes those answers available to them. The architecture that works combines two kinds of retrieval. Structured questions — counts, filters, sums — are translated into queries over the extracted element database, so numbers come from the data, not from the model's guesswork. Document-style questions — specifications, standards, meeting notes linked to the model — use a [RAG pipeline](https://www.amygdal.com/blog/rag-development-guide) with citations. In both cases the answer links back to the specific elements or documents, so users can verify it in the viewer. ### Fitting into existing BIM workflows Design teams already work in Revit, Archicad, Navisworks, Solibri and common data environments, and they will not adopt a separate tool for every task. The AI features that get used are the ones that appear where people already work: a plugin panel in the authoring tool, issues pushed into the existing issue tracker in BCF format, a report generated into the common data environment, or a simple web viewer for stakeholders who do not have authoring licences. Model size and confidentiality also shape the architecture. Federated models can be large, and project data is often commercially sensitive or subject to client security requirements, so processing frequently needs to run in the client's own cloud tenancy or on-premises, with open models where hosted ones are not acceptable. ### Making AI for BIM reliable 1. Invest in extraction and normalisation first; every later step depends on it. 2. Keep rules for what can be expressed as rules, and use AI for ambiguity, language and prioritisation. 3. Show confidence and keep a human review step for anything that affects design, cost or safety. 4. Trace every output to element GUIDs and model revisions. 5. Evaluate on real project models from several firms, not one clean sample. ### Working with Amygdal on BIM Amygdal has delivered AI and software development for BIM, with engineering teams serving clients in the UK, Germany, Switzerland and Qatar. Our [AI for BIM](https://www.amygdal.com/services/ai-for-bim) service covers data extraction, classification, model checking, clash triage and natural-language querying, built on the same practice as our [custom software development](https://www.amygdal.com/services/custom-software-development) work. [Contact us](https://www.amygdal.com/contact) to talk about your models and workflows. ### FAQ **How is AI used in BIM?** Mainly to read and organise model data faster: extracting data from IFC and Revit, classifying elements, supporting model checking, triaging clashes, cleaning data for quantity takeoff and answering questions about the model in plain language. **Can AI replace rule-based BIM model checking?** No, and it should not. Rules are explainable and repeatable. AI works best alongside them: drafting rules from written requirements, explaining failures and grouping issues into root causes. **Can I ask questions about a BIM model in natural language?** Yes. A well-built system translates structured questions into queries over extracted model data and uses retrieval for document questions, linking every answer back to the specific elements or documents. ## Building Cardly: React Native, Expo and Supabase URL: https://www.amygdal.com/blog/cardly-case-study Published: 2026-09-22 · Category: Case study · Tags: React Native, Expo, Supabase, Astro, Stripe, Mobile Cardly replaces the paper business card with one you never reprint. Here is how we built the mobile app, the scanner, the widgets and the web side. Cardly is a digital business card app. You make your card once, hand it over as a link or a QR code, and the person on the other end opens it in whatever browser they already have — no app, no account. When you change jobs, every card you have ever shared updates with you. The other half of the product is the reverse direction: scan someone else's card, and Cardly reads it, tidies it and files it with a note about where you met. We designed and built Cardly ourselves, which makes it a useful case study: every decision below was ours to make and ours to live with. This post walks through the product, the architecture, and the handful of choices that mattered most. ### The product in one paragraph The core loop has three steps: make your card, hand it over, keep the contact. Around that loop sit the features that make it a working tool rather than a toy: - **Sharing by link and QR** — the receiver needs nothing installed. Because a card is a plain web URL, the same link also works anywhere a URL does, including an NFC tag. - **Scanning cards back** — point the camera at a paper card, a QR code or an email signature, and the fields are extracted and saved. - **Contacts that stay findable** — notes, tags and follow-up reminders on every person you meet. - **A home-screen widget** that puts your QR code one tap away on iOS and Android. - **Companies and teams** — one company pays, invites people by email, and its members get Pro with the company design on their cards. - **Offline support, light and dark themes**, Apple Wallet and Google Wallet passes, and data export. ### Architecture: Expo app, Supabase backend The mobile app is **React Native with Expo** (SDK 54, React Native 0.81) and Expo Router for file-based navigation. State lives in Zustand, forms use React Hook Form with Zod validation, and i18next handles translations. We chose Expo because it lets a small team ship to both stores from one codebase while still dropping into native code where it matters — and on Cardly it mattered in three places: text recognition, wallet passes and widgets. The backend is **Supabase**: Postgres with row-level security on every user-owned table, Supabase Auth (email, Apple and Google sign-in), Storage for images, and Edge Functions for anything that needs a secret — billing webhooks, company invites, wallet pass generation, account deletion and CRM sync. The schema is managed as plain SQL migrations, and we made sure the whole database can be rebuilt from those migrations alone. That sounds like housekeeping, but it is what makes a staging environment trustworthy. Row-level security did a lot of the heavy lifting. A public card has to be readable by anyone with the link, while the owner's contacts, notes and imported address book must be readable by nobody else. Expressing that in the database, rather than in API code, means there is one place to get it right. ### Native edges: scanning, widgets and wallets #### Scanning: on-device first, AI as the upgrade Card scanning is where most apps in this category disappoint, so we spent real time on it. The first pass runs **on the phone**: we wrote a small Expo native module that uses Apple Vision on iOS and Google ML Kit text recognition on Android. One photo can contain several cards; the app splits them and offers each one as a separate contact. A rules-based parser then maps the raw text to name, role, company, email, phone, website and address. On-device OCR is fast and private, but real business cards are messy: vertical layouts, two languages, logos that read as text. For those, a Supabase Edge Function sends the text (or the photo) to a small Claude model and gets structured fields back. If the AI step is not configured or fails, the app keeps its own result. That fallback order — device first, model second, never block the user — is the pattern we recommend for most [custom AI development](https://www.amygdal.com/services/custom-ai-development) inside mobile apps. #### Widgets, wallets and offline The widget exists for one moment: somebody asks for your details and you have a drink in your other hand. On iOS it is a native WidgetKit extension written in Swift, added to the Expo project as an Apple target, reading the card from a shared App Group. On Android it is built with react-native-android-widget. Both render the QR code locally so the widget works without a network. Wallet passes were similar. Apple's review process flags binaries that link PassKit unnecessarily, so pass generation happens server-side in an Edge Function and the app only hands the finished pass to the system. Offline support is a cache of your cards and contacts in AsyncStorage, with a connectivity check that treats a captive-portal hotel Wi-Fi as offline rather than trying, failing and only then falling back. ### One Astro repo, two websites The web side is a single **Astro** project with Tailwind, deployed as two Railway services: the marketing site at www.usecardly.app and the signed-in web app at app.usecardly.app. The split exists for a concrete reason. A Supabase session lives in localStorage, which is per-origin; serving account pages from both hosts would mean two sessions and two places to sign in. So the product gets its own origin, and every emailed auth link and company invite points there. Both sites build from the same pages. A small post-build script keeps the half that belongs to each target and writes redirects for the other half, and all links go through two helpers so they resolve correctly in development, on www and on app. Shared header, footer, design tokens and Supabase client stay in one place instead of drifting as copies. ### Payments and team billing Cardly is free for one card, with a Pro subscription for more. Payments run on **Stripe**: the Stripe payment sheet in the app (card, Apple Pay, Google Pay), Stripe Checkout on the web, and Stripe's billing portal for managing or cancelling. Webhooks update subscription state in Postgres, and the subscription belongs to the account, so it follows the user to every device. Company plans are bought on the web, where a finance team expects an invoice rather than a purchase on somebody's phone. Seats are counted from the moment an invite goes out, and invitees get Pro as soon as they accept. The store review process shaped this more than anything else: clear pricing, auto-renewal wording, in-app account deletion that removes every row the user owns, and a written explanation of how imported contacts are stored and protected. ### What we would tell another team 1. Make the receiving side need nothing. A link that opens in any browser beats any amount of in-app polish. 2. Put authorisation in the database. Row-level security is easier to audit than scattered API checks. 3. Run AI as an upgrade path, not a dependency. On-device first, model second, user never blocked. 4. Budget for native edges. Expo covers most of the app, but widgets, wallet passes and OCR each needed native work. 5. Read the store guidelines before designing payments, not after the first rejection. ### Building something similar? Cardly is the kind of product we enjoy building: a focused mobile app with a real backend, native edges and a web side that has to agree with it. If you are planning one, see our [mobile app development](https://www.amygdal.com/services/mobile-app-development) service, read [how we build React Native apps](https://www.amygdal.com/blog/building-great-react-native-apps), or [get in touch](https://www.amygdal.com/contact). ### FAQ **What is Cardly built with?** The mobile app is React Native with Expo and Expo Router. The backend is Supabase (Postgres, Auth, Storage, Edge Functions), payments run on Stripe, and the marketing site and web app are built with Astro and Tailwind. **Does the person receiving a Cardly card need the app?** No. A card is shared as a web link or QR code and opens in any browser, without an account or anything installed. **How does Cardly read paper business cards?** Text is first recognised on the phone using Apple Vision on iOS and ML Kit on Android. For difficult layouts, an Edge Function can send the text or photo to an AI model that returns structured contact fields. ## Healthcare Software Development in the USA: HIPAA, FHIR and AI URL: https://www.amygdal.com/blog/healthcare-software-development-usa Published: 2026-09-15 · Category: Healthcare · Tags: Healthcare, USA, HIPAA, FHIR, AI, FDA HIPAA is only the start. A practical map of the US rules that shape healthcare software in 2026, from FHIR mandates to FDA's view of clinical AI. The US is the largest digital-health market, and its rules come from several directions at once. HIPAA governs providers, payers and their vendors. The FTC and states cover consumer health apps that fall outside HIPAA. ASTP/ONC and CMS are pushing standard FHIR APIs and penalising information blocking. FDA decides when clinical software, including AI, is a medical device. This guide summarises our research into the rules a US healthcare software team should design for in 2026. It draws on our own work, including engineering for the senior-care platform [A Place For Mom](https://www.amygdal.com/projects/aplaceformom). It is engineering guidance, not legal advice. The cross-market overview is on our [healthcare page](https://www.amygdal.com/healthcare). ### HIPAA: know whether you are in scope HIPAA applies to covered entities (providers, health plans and clearinghouses) and to their business associates. The [Security Rule](https://www.hhs.gov/hipaa/for-professionals/security/index.html) requires administrative, physical and technical safeguards for electronic PHI. The [Breach Notification Rule](https://www.hhs.gov/hipaa/for-professionals/breach-notification/index.html) requires notice without unreasonable delay and no later than 60 days after discovery. Two points matter for architecture: - **Your cloud provider is a business associate.** [HHS guidance](https://www.hhs.gov/hipaa/for-professionals/special-topics/cloud-computing/index.html) says a provider that stores or processes ePHI is a business associate even without the encryption key. You need a BAA, and you must stay within the services it covers. - **Every vendor in the data path counts**, including logging, error tracking, email, analytics and AI model APIs. If PHI could reach a vendor, it needs a BAA or the PHI needs to be removed first. The Security Rule is also changing. HHS [proposed its first major rewrite](https://www.federalregister.gov/documents/2025/01/06/2024-30983/hipaa-security-rule-to-strengthen-the-cybersecurity-of-electronic-protected-health-information) on 6 January 2025. Among other changes, it would make encryption, multi-factor authentication and network segmentation mandatory. [Reporting in 2026](https://www.fiercehealthcare.com/health-tech/feds-push-back-hipaa-security-rule-overhaul-july-2027) indicates final action has slipped, and the current rule stays in force. We already build to the proposed baseline, because it is good practice and it avoids rework later. ### Outside HIPAA: FTC and state health-data laws Many consumer health and wellness apps are not covered by HIPAA, and that does not leave them unregulated. The FTC [amended its Health Breach Notification Rule](https://www.ftc.gov/legal-library/browse/rules/health-breach-notification-rule) in 2024 to cover health apps and similar technologies, and unauthorised disclosures, such as sharing data with advertising platforms, count as breaches. States are adding their own rules. Washington's [My Health My Data Act](https://atg.wa.gov/protecting-washingtonians-personal-health-data-and-privacy), in force since March 31, 2024 for regulated entities, protects consumer health data outside HIPAA, including data from wearables. For consumer products such as a fitness or wellbeing app (see [Ealthiness](https://www.amygdal.com/projects/ealthiness), which we built), this means: - **No tracking pixels or third-party SDKs that receive health data** unless the user has explicitly authorised it. - **A consumer health data privacy notice** where state law requires one, plus consent flows that are specific and revocable. - **Breach runbooks** that cover the FTC and state notification paths, not only HIPAA. ### Interoperability: FHIR APIs and information blocking Federal policy now requires standard APIs. The ONC [HTI-1 final rule](https://healthit.gov/regulations/hti-rules/hti-1-final-rule/) made USCDI v3 the baseline for certified health IT as of 1 January 2026 and added transparency requirements for decision support interventions. The [CMS Interoperability and Prior Authorization final rule](https://www.cms.gov/newsroom/fact-sheets/cms-interoperability-and-prior-authorization-final-rule-cms-0057-f) requires impacted payers to build FHIR-based APIs, including Patient Access, Provider Access, Payer-to-Payer and Prior Authorization APIs, with compliance dates generally beginning on 1 January 2027. The other side of this is enforcement. Under the 21st Century Cures Act, information blocking is prohibited, and a 2024 HHS rule set [disincentives for providers](https://healthit.gov/sites/default/files/2024-06/Disincentives_Final_Rule.pdf) found to have committed it. Policy is still moving: in December 2025 ASTP/ONC [proposed the HTI-5 rule](https://www.hhs.gov/press-room/hhs-proposes-hti-5-rule.html), which would remove or revise many certification criteria and update the information-blocking regulations. We track it, but we design to the stable core: **HL7 FHIR R4, US Core profiles and SMART on FHIR authorization**. ### Clinical AI and the FDA The first question for any clinical AI feature is whether it is a medical device. FDA's [Clinical Decision Support Software guidance](https://www.fda.gov/regulatory-information/search-fda-guidance-documents/clinical-decision-support-software), revised in January 2026, sets out how it applies the 21st Century Cures Act criteria that exclude some CDS from device regulation. Features that analyse medical images or signals, or that drive time-critical decisions without letting the clinician review the basis, are much more likely to be devices. For AI that is a device, FDA has published lifecycle expectations. Its December 2024 [final guidance on predetermined change control plans](https://www.fda.gov/medical-devices/cdrh-new-news-and-updates/webinar-final-guidance-marketing-submission-recommendations-predetermined-change-control-plan) lets manufacturers pre-authorise planned model updates. Its January 2025 [draft guidance on AI-enabled device software functions](https://www.fda.gov/regulatory-information/search-fda-guidance-documents/artificial-intelligence-enabled-device-software-functions-lifecycle-management-and-marketing) covers data management, model description, validation, performance monitoring and cybersecurity. Our engineering response: 1. Classify each AI feature against the CDS criteria **before** design, and record the reasoning. 2. Keep the clinician in control: show the inputs and basis for every suggestion, and log overrides. 3. Version datasets, models and prompts, and keep evaluation reports, so a later submission does not mean reconstructing history. 4. Monitor performance in production and treat drift as an incident. Our [AI in healthcare](https://www.amygdal.com/services/ai-in-healthcare) service and our guide to [HIPAA- and GDPR-compliant AI](https://www.amygdal.com/blog/hipaa-gdpr-compliant-ai-healthcare) go deeper on de-identification, hosting and audit trails. ### Minimum necessary, audit trails and de-identification Three HIPAA ideas shape day-to-day engineering more than any others. First, the **minimum necessary** standard: each role, service and API scope should see only the PHI it needs. Second, **auditability**: every access to a record should be attributable to a person or service, timestamped and stored where application admins cannot quietly edit it. Third, **de-identification**: development, testing, analytics and many AI features can run on de-identified data, which takes them out of HIPAA's scope altogether when done by HIPAA's defined methods. In practice we build role-based access with attribute checks for sensitive record types, write an append-only access log separate from application logs, and run a de-identification step before data reaches lower environments or model prompts. Engineers work with synthetic or de-identified data by default, and production access is time-limited and logged. ### How we build for the US market - **US regions, HIPAA-eligible services and a signed BAA** for every component that touches PHI, including AI providers. - **Security to the proposed baseline:** encryption everywhere, MFA, segmentation, asset inventory and regular vulnerability testing. - **FHIR-first integrations** with US Core and SMART on FHIR, with scopes kept to the minimum necessary. - **Event-driven, observable infrastructure** that holds up under nationwide traffic. That was the brief for our work on A Place For Mom, built on Next.js, Node.js and AWS Lambda, SQS and SNS. - **Privacy-safe product analytics** that never send PHI or consumer health data to ad tech. If you are planning a US healthcare product, from a patient app to an EHR-integrated AI assistant, our [mobile](https://www.amygdal.com/services/mobile-app-development) and AI teams can help you scope it. [Get in touch](https://www.amygdal.com/contact). ### FAQ **Does every health app need to be HIPAA compliant?** No. HIPAA applies to covered entities and their business associates. Many direct-to-consumer health apps fall outside it, but they may be covered by the FTC Health Breach Notification Rule and state laws such as Washington's My Health My Data Act. **Can we use cloud AI services with PHI?** Only if the provider signs a business associate agreement that covers the specific services you use, and you configure them so prompts and outputs are not retained or used for training. Otherwise, de-identify the data first or host the model yourself. **Is our clinical AI feature regulated by the FDA?** It depends on its function. FDA's Clinical Decision Support guidance explains which CDS functions are excluded from device regulation. Image or signal analysis, and outputs a clinician cannot independently review, point towards device status. Classify early and document the reasoning. ## How We Structure NestJS, Prisma and PostgreSQL Backends URL: https://www.amygdal.com/blog/nestjs-prisma-postgresql-architecture Published: 2026-08-19 · Category: Engineering · Tags: NestJS, Prisma, PostgreSQL, Redis, Elasticsearch Our default backend stack is NestJS on PostgreSQL, with Redis for queues and caching and Elasticsearch for search. Here is how we structure it and why. For most products we build, the backend is **NestJS** on **PostgreSQL**, with **Redis** for caching and background jobs and **Elasticsearch** when search matters. Where we use an ORM on that stack, it is usually **Prisma**. It is a deliberately unexciting stack: typed end to end, well documented and easy to hire for. This post walks through how we structure these backends, using two real projects as reference points. [Digital Arrow](https://www.amygdal.com/projects/digital-arrow), a recruiting and HR platform, runs on NestJS, PostgreSQL, Prisma, Redis, Elasticsearch, MinIO and Browserless. [Ealthiness](https://www.amygdal.com/projects/ealthiness), an AI health app, uses NestJS, MongoDB, Redis job queues and a Weaviate vector store behind a React Native client. ### Modules follow the domain NestJS gives you modules, and the most important architectural decision is how you draw them. We organise by business domain, not technical layer. On a platform like Digital Arrow, that means modules along the lines of jobs, candidates, interviews, timesheets, contracts and invoicing, rather than one big 'services' folder. - Each module owns its **controllers, services, DTOs and tests**. - Modules expose a small public service; other modules call that service, not each other's database tables directly. - Cross-cutting concerns (auth guards, logging, error filters, config) live in a shared core module. - Validation happens at the edge with DTOs, so services can trust their inputs. This gives you a **modular monolith**: one deployable application with clear internal boundaries. It scales horizontally without trouble, and if one module later needs to become its own service, the boundary is already there. ### Prisma and PostgreSQL: schema as the source of truth With Prisma, the schema file is the single source of truth for the data model, and the generated client gives typed queries throughout the codebase. A renamed column breaks the build rather than a production request. Our conventions: 1. **Every schema change is a migration**, committed with the code that needs it and reviewed like any other change. 2. **Migrations run automatically in CI/CD** before the new version starts serving traffic, never by hand against production. 3. **Destructive changes are split** into expand and contract steps: add the new column, backfill, switch reads, then drop the old one in a later release. 4. **Indexes are added for real query patterns**, checked with the query plan, not guessed in advance. 5. **Raw SQL is allowed** where Prisma is awkward, such as complex reporting queries, and kept inside the owning module. PostgreSQL does a lot of work for us beyond plain tables: constraints and foreign keys enforce integrity, JSONB holds genuinely flexible data, and transactions keep multi-step operations consistent, for example creating a contract and its signature request together. ### Redis for caching and queues Anything slow, unreliable or not needed for the immediate response goes into a background queue. We use Redis-backed queues (BullMQ, through the NestJS integration) for emails, notifications, search indexing, webhook delivery, media processing and document generation. On Digital Arrow, generating contract and CV PDFs with headless Chrome through Browserless is a good example: it is too slow and resource-hungry to run inside an API request, so it runs as a job, and the user is notified when the document is ready. Media such as interview videos is stored in MinIO, S3-compatible object storage, rather than on the API servers. ```ts @Processor("documents") export class DocumentsProcessor extends WorkerHost { constructor(private readonly pdf: PdfService) { super(); } async process(job: Job<{ contractId: string }>) { const file = await this.pdf.renderContract(job.data.contractId); await this.pdf.store(job.data.contractId, file); } } ``` Jobs are idempotent, so a retry never produces a duplicate email or document, and failed jobs are visible in monitoring rather than disappearing silently. Redis also holds short-lived cache entries and rate-limit counters. ### Elasticsearch for search, PostgreSQL for truth PostgreSQL full-text search goes a long way, but once users expect fuzzy matching, relevance ranking, facets and fast filtering across large text fields, a dedicated search engine earns its place. Digital Arrow uses Elasticsearch for full-text candidate search across CVs and profiles. The rule we follow is simple: **PostgreSQL is the source of truth, Elasticsearch is a derived index**. Writes go to the database; a queue job then updates the search index. If the index is ever lost or the mapping changes, we rebuild it from the database. That keeps search fast without ever risking data integrity. ### Testing that catches real problems Our testing is weighted towards the places bugs actually occur: - **Unit tests** for pure business rules: pricing, permissions, state transitions. - **Integration tests** that run services against a real PostgreSQL database in a container, because mocked ORMs hide the bugs that matter. - **End-to-end API tests** for critical flows such as sign-up, payments and document signing. - **Migration checks in CI**, applying every migration to a fresh database to make sure the history is consistent. ### API design and documentation Most of our backends serve a Next.js web app and often a React Native client. We generate an OpenAPI description from the NestJS controllers and DTOs, and use it to produce typed clients for the frontends. That keeps web, mobile and backend in agreement about every field, and it gives partners and future team members accurate API documentation for free. We version deliberately. Additive changes, such as new optional fields or new endpoints, ship freely. Breaking changes get a new endpoint or version and a deprecation period, which matters most when mobile users may be several app versions behind. ### Authentication and permissions Most of our platforms serve several kinds of user. Digital Arrow, for example, covers recruiters, candidates and client companies, each seeing different data. We handle this with NestJS guards that check both who the user is and what they are allowed to do on the specific resource, not just their role. Permission logic lives in one place per module and is covered by unit tests, because permission bugs are among the most damaging and least visible failures a multi-tenant system can have. Every query that touches tenant data is scoped by the tenant identifier at the service layer, so a missing filter in a controller cannot leak another company's records. ### Operations and observability The API runs stateless, so it scales by adding instances. Configuration comes from the environment, secrets never live in the repository, and health checks cover the database, Redis and search. Structured logs carry a request ID through the API and into any jobs it triggers, which makes tracing a problem across the system straightforward. For more on scaling this kind of service, see [how to scale a Node.js application](https://www.amygdal.com/blog/scaling-nodejs-applications). ### Building your backend with us If you are starting a new platform or need an existing NestJS backend reviewed, we are happy to talk through your architecture. See our [web development](https://www.amygdal.com/services/web-development) service, read the [Digital Arrow case study](https://www.amygdal.com/blog/digital-arrow-case-study), or [contact us](https://www.amygdal.com/contact). ### FAQ **Why use NestJS instead of plain Express?** NestJS adds modules, dependency injection, validation and testing conventions on top of Node.js. For a growing team and codebase, that structure keeps the backend consistent and easier to change. **How do you run Prisma migrations safely in production?** Migrations are committed with the code, applied automatically in CI/CD before the new release serves traffic, and destructive changes are split into expand-and-contract steps across releases. **When do you add Elasticsearch to a PostgreSQL backend?** When users need fuzzy matching, relevance ranking or facets across large text fields. PostgreSQL stays the source of truth, and the search index is rebuilt from it when needed. ## Healthcare Software Development in Qatar: An Engineering Guide URL: https://www.amygdal.com/blog/healthcare-software-development-qatar Published: 2026-08-18 · Category: Healthcare · Tags: Healthcare, Qatar, Digital health, Data protection, AI Qatar's health system is centrally planned, already digitised and investing in AI. Here is what a software team has to design for before writing the first line of code. Qatar is a distinctive place to build healthcare software. The system is largely public and centrally planned, the main providers already share a clinical record, and the country has in-country hyperscale cloud. Privacy law also treats health data as a special category that needs regulator permission before you process it. If you plan for these facts, delivery goes smoothly. If you discover them halfway through, they stall the project. This guide summarises research our team did into the Qatari digital-health landscape and what it means for engineering decisions. We run an office in Doha, and this is the checklist we use. It is engineering guidance, not legal advice. For the full picture across all three of our markets, see our [healthcare specialization](https://www.amygdal.com/healthcare). ### The strategic context: Health for All 2024–2030 The Ministry of Public Health's third [National Health Strategy 2024–2030](https://www.qna.org.qa/en/News-Area/News/2024-09/18/0053-moph-launches-online-platform-presenting-third-national-health-strategy), titled 'Health for All', has three pillars: improved population health and wellbeing, excellence in service delivery and patient experience, and health-system efficiency and resilience. Each pillar points to a type of software: - **Population health:** prevention, chronic-condition and engagement programmes that run continuously, not only at visits. - **Service delivery and patient experience:** patient portals, booking, remote follow-up and bilingual Arabic/English apps that patients actually use. - **Efficiency and resilience:** integration, analytics and automation that reduce manual work between institutions. Commentary in the local press has also linked the strategy to [expected growth in the medical-devices and digital-health devices sector](https://thepeninsulaqatar.com/article/10/11/2024/national-health-strategy-likely-to-drive-growth-in-medical-devices-sector). For product teams, that suggests demand for connected devices and the software around them. ### An already-digitised system: integrate, don't duplicate Hamad Medical Corporation runs Oracle Cerner as its clinical information system. According to [HMC](https://hamad.qa/EN/news/2023/June/Pages/Integration-of-Oracle-Cerner-Electronic-Health-Record-Across-Hamad-Medical-Corporation.aspx), the system has supported integrated care across the public sector since 2012, links to Primary Health Care Corporation facilities, and was integrated with Qatar Biobank in 2023. A new product therefore rarely starts on a blank page. Usually it has to fit around an established system of record. In practice we scope integration in discovery. We work out which system owns each piece of data, what interfaces exist, which party approves access, and what the new product must never store itself. Our default is HL7 FHIR resources for any new interfaces, with clear mapping documentation wherever older formats are involved. ### PDPPL: health data is 'special nature' data Qatar's [Personal Data Privacy Protection Law, Law No. 13 of 2016](https://ncsa.gov.qa/en/pages/personal-data-privacy-personal-data-privacy-protection-law), is administered by the National Cyber Security Agency. Health data is 'personal data of a special nature', and processing it requires prior permission from the regulator. The regulator's guidelines, summarised by [Clyde & Co](https://www.clydeco.com/en/insights/2021/03/new-regulatory-guidelines-on-the-qatar-persona-1), add obligations that change how a project is planned: - **A data privacy impact assessment** before new processing of special-nature data. - **Records of processing activities**, kept up to date by trained staff. - **Privacy by design**, embedded from the design stage through the product lifecycle. - **Breach notification within 72 hours** to the regulator and affected individuals. - **Fines of up to QAR 5,000,000** for non-compliance. The engineering consequence is simple. The data map, DPIA and permission application are work items on the delivery plan from week one. Consent capture, withdrawal, access, correction and erasure become product features with acceptance criteria, not text in a privacy policy. ### Hosting health data in Qatar In-country hosting is practical. Microsoft [opened an Azure datacenter region in Qatar](https://news.microsoft.com/en-xm/2022/08/31/microsoft-opens-first-global-datacenter-region-in-qatar-bringing-new-opportunities-for-a-cloud-first-economy/) in 2022, and Google Cloud [launched its Doha region](https://www.googlecloudpresscorner.com/2023-05-22-Google-Cloud-Opens-New-Cloud-Region-in-Doha) in 2023. For health products we default to hosting production data, backups and logs in Qatar, and we document every flow that leaves the country, including email, push notifications, error tracking and AI model calls. AI providers need particular care. If a feature calls a hosted model, check where inference runs, whether prompts are retained, and whether the data could be used for training. Where those answers are unclear, an open-weight model hosted in your own Qatari cloud account is often the cleaner option. ### A realistic delivery sequence Healthcare projects in Qatar rarely go wrong because of code. They go wrong because approvals, integrations and data decisions come up late. The sequence we use puts those items at the front: 1. **Weeks 1–2: discovery.** Map users, workflows, systems of record and every category of personal data. Flag special-nature data and any cross-border flow. 2. **Weeks 2–4: privacy and integration groundwork.** Draft the DPIA, prepare the permission application and agree interface access with each system owner. 3. **Build in thin slices.** Ship one complete workflow end to end, including audit logging, consent and Arabic/English UI, before adding more scope. 4. **Shadow mode for any AI.** Run models alongside clinicians on real cases and measure agreement before outputs reach users. 5. **Go-live with runbooks.** Incident response, breach notification and access reviews are rehearsed before launch, not written afterwards. Exact timings depend on the institution and the data involved. The order matters more than the dates: approvals and integration access are usually on the critical path, so they start first. ### AI in Qatari healthcare: already in national programmes AI is already in production in Qatar. Since June 2024, PHCC has used [Lunit INSIGHT MMG in its Screen for Life breast-screening programme](https://lunit.io/en/company/news/lunits-ai-solution-enhances-qatars-national-breast-cancer-screening-program), where two radiologists read each mammogram with reference to the AI's results. That is the model we recommend for clinical AI: it supports a professional and does not replace one. Research governance is also active. In late 2024 MOPH ran its [National Health Research Ethics Workshop on AI in health research](https://www.qna.org.qa/en/News-Area/News/2024-12/01/0057-moph-discusses-ethics-of-use-of-artificial-intelligence-in-health-research) with the NCSA, Qatar University and HBKU. If an AI feature depends on research datasets, plan for ethics review alongside the privacy work. Our [AI in healthcare](https://www.amygdal.com/services/ai-in-healthcare) service covers how we scope, evaluate and monitor these systems. ### How we build healthcare software for Qatar 1. **Discovery with the data map first.** Identify systems of record, data owners, special-nature data and every cross-border flow before estimating anything. 2. **In-country hosting by default**, with encryption in transit and at rest, role-based access and an append-only audit log of every read and write of health records. 3. **Consent and rights as features.** Granular consent, simple withdrawal, and self-service access and correction where the use case allows. 4. **Bilingual from day one.** Arabic and English with full RTL support in web and [mobile apps](https://www.amygdal.com/services/mobile-app-development), tested with real users. 5. **Clinical AI with a human in the loop.** Show sources and uncertainty, record overrides, and evaluate against local data before going live. Our consumer health experience includes [Ealthiness](https://www.amygdal.com/projects/ealthiness), a mobile fitness and wellbeing companion we designed and built end to end, covering guided exercises, live run tracking, mood graphs and activity insights. We have also done engineering for the US senior-care platform [A Place For Mom](https://www.amygdal.com/projects/aplaceformom). With a team in Doha, workshops and acceptance testing run in the local time zone. To discuss a project, [contact us](https://www.amygdal.com/contact). ### FAQ **Do we need permission to process health data in Qatar?** Yes. Under Law No. 13 of 2016 (PDPPL), health data is personal data of a special nature, and processing it requires prior permission from the regulator. The guidelines also expect a data privacy impact assessment before new processing of this kind. **Can healthcare data be hosted inside Qatar?** Yes. Microsoft Azure has had a Qatar region since 2022 and Google Cloud has had a Doha region since 2023. We host production data, backups and logs in-country by default and document any flow that leaves Qatar. **How quickly must a data breach be reported in Qatar?** The PDPPL regulatory guidelines require notification to the regulator and affected individuals within 72 hours. Build detection, triage and notification runbooks before launch, not after an incident. ## ESG Data and AI: Building Sustainability Features That Last URL: https://www.amygdal.com/blog/esg-data-and-ai-sustainability-features Published: 2026-08-12 · Category: Product · Tags: Sustainability, ESG, AI, Data Sustainability data is messy, incomplete and increasingly scrutinised. AI helps make sense of it, if the product is honest about what the data can say. Customers, investors and regulators increasingly want to know the environmental and social footprint of what they buy and fund. That has created demand for product features that surface ESG information: sustainability scores on products, supplier comparisons, impact dashboards. AI is well suited to part of this work, especially turning scattered, unstructured information into something comparable. It is also an area where trust is fragile. A score that cannot be explained, or a claim that overstates the evidence, can damage the brand it was meant to help. Here is how we approach building sustainability features with AI. It helps to separate three questions that are often blurred together: what data exists, how trustworthy it is, and how it should be presented. AI can help with the first two. The third is a product decision that should be made deliberately, with input from people who understand both the domain and the audience. ### The data problem comes first ESG information arrives in every format imaginable: supplier spreadsheets, certification documents, sustainability reports, product labels, public databases and self-declared claims. Coverage is uneven, definitions differ and some of it is out of date. Before any model is involved, a product needs to know where each data point came from and how reliable it is. - Record the **source** and **date** of every data point, and keep them visible to users who want to check. - Distinguish **verified** data, such as third-party certifications, from **self-declared** and **estimated** values. - Normalise units and definitions explicitly, and document the choices. - Treat missing data as missing, not as zero or average. Provenance is not just good practice; it is what lets you correct mistakes. When a supplier updates a certification or a source turns out to be wrong, you need to find every score and comparison that used the old value and recalculate it. Without lineage, that becomes a manual investigation. ### Where AI helps 1. **Extraction.** Reading certificates, reports and product pages and pulling out structured fields such as materials, origin and certifications. 2. **Recognition.** Identifying a product from a photo or scan so the right record can be retrieved. 3. **Matching.** Linking the same product or supplier across sources that name it differently. 4. **Explanation.** Turning a structured score into a plain-language summary a shopper or analyst can understand. Notice what is not on the list: inventing values. A model should never fill a gap with a plausible-sounding number. If an estimate is used, it must come from a documented method and be labelled as an estimate. #### Keep humans in the extraction loop Extraction models make mistakes, especially on poorly scanned documents and unusual layouts. Route low-confidence extractions to a reviewer, and sample high-confidence ones for spot checks. Track error rates by document type and source; a single supplier format that is consistently misread can skew many scores at once. ### Example: Sumus [Sumus](https://www.amygdal.com/projects/sumus) is an AI product-discovery engine for fashion. A shopper scans a garment and sees its ingredients, quality, safety and availability alongside an ESG footprint, then compares sustainability across brands. We built the AI tool behind it: the scanning and recognition pipeline, the ESG scoring engine and the brand-comparison layer. The full story is in our [Sumus case study](https://www.amygdal.com/blog/sumus-ai-esg-case-study). Users rarely need every detail, but they need to know the details exist. A short line such as how this score is calculated, linking to the method and sources, does more for credibility than a longer marketing description of the product's sustainability credentials. ### Scoring that people can trust A single number is attractive for users and dangerous for credibility. A few principles keep scores defensible: - Publish the **method**: which factors count, how they are weighted and where the data comes from. - Show the **breakdown** behind the headline score, not just the total. - Show **confidence**: a score based on verified data should look different from one based on estimates. - Keep the scoring logic **deterministic** and versioned. Use models to gather and structure inputs, not to decide the score itself. - Recalculate when data or method changes, and keep history so past scores can be explained. Explanations generated by a model need the same care as the score. Constrain them to the data behind the score and the published method, so the summary cannot claim more than the evidence supports. A template with model-filled fields is often safer than free generation for this reason. ### Avoiding greenwashing by accident Rules on environmental claims are tightening in several markets, including the EU and the UK, with growing scrutiny of vague terms like eco-friendly or green without evidence. Products that display sustainability information should avoid generic claims, make comparisons on a like-for-like basis and keep the evidence behind every statement. Check the current requirements in each market with legal advice; the engineering task is to make sure every claim in the interface can be traced back to its data. Be cautious with comparisons. Two products scored on different amounts of verified data are not directly comparable, even if both scores are shown on the same scale. Indicate data coverage next to any comparison, and consider withholding a comparison entirely when coverage is too thin to support it. ### Architecture in brief A typical setup separates ingestion (connectors and document processing), a normalised data store with provenance, a versioned scoring service, and the user-facing application. AI components sit mainly in ingestion and explanation. That separation means you can improve extraction or swap a model without changing how scores are calculated, and audit each layer independently. #### Measuring whether it helps Decide early what success means for the product. For a consumer tool it might be how often users compare options or change their choice after seeing a score. For a business tool it might be time saved collecting supplier data or the share of a catalogue with verified information. These measures keep the team focused on usefulness rather than on producing more scores. ### Building a sustainability product? We build AI products that handle messy real-world data carefully. Learn about our [custom AI development](https://www.amygdal.com/services/custom-ai-development) service, or [contact us](https://www.amygdal.com/contact) to talk about your ESG or sustainability feature. ### FAQ **Can AI calculate an ESG score?** AI is best used to gather, extract and structure the inputs. The score itself should come from a documented, versioned and deterministic method, so it can be explained and reproduced when someone asks how it was calculated. **How should a product handle missing sustainability data?** Show it as missing. Never treat gaps as zero or fill them with model-generated guesses. If you use estimates, base them on a documented method and label them clearly as estimates. **How do we avoid greenwashing in a sustainability app?** Avoid vague claims, compare like with like, show the method and data source behind every score, and keep evidence for each statement. Check current rules on environmental claims in each market with legal counsel. ## LLM Agents in Production: Tools, Guardrails and Evaluation URL: https://www.amygdal.com/blog/ai-agents-in-production Published: 2026-08-05 · Category: AI · Tags: AI agents, LLM, Guardrails, Observability Agents that call tools and take actions are powerful and fragile. The engineering practices that keep them safe, measurable and affordable in production. An LLM agent is a model that can decide to call tools — search a database, create a ticket, send an email, update a record — observe the result, and continue until a task is done. That ability to act is what makes agents useful, and it is also what makes them risky. A chatbot that gives a wrong answer is embarrassing. An agent that takes a wrong action can cost money, leak data or corrupt records. Running **AI agents in production** is mostly ordinary software engineering applied carefully: narrow interfaces, permissions, tests, logs and budgets. Here is how we approach it. ### Do you need an agent at all? Many problems described as agentic are better solved with a fixed workflow: a sequence of steps where the model fills in specific parts, such as classifying a request or extracting fields. Workflows are easier to test, cheaper to run and more predictable. Reach for an open-ended agent only when the path genuinely varies from case to case and cannot be enumerated in advance. Often the right design is a workflow with one or two agentic steps inside it. ### Design tools like a public API Tools are the agent's interface to your systems, and their design matters more than the prompt. Good tools are narrow, well named, strictly typed and safe to call twice: - **Prefer specific tools over general ones.** `refund_order(order_id, amount)` is safer than `run_sql(query)`. - **Validate every argument** on the server, never trusting the model's output. Reject and explain, so the agent can correct itself. - **Return compact, structured results.** Large raw payloads waste context and confuse the model. - **Make actions idempotent** where possible, so a retry does not create a duplicate payment or ticket. - **Separate read and write tools**, and put the write tools behind stronger checks. ### Guardrails and permissions An agent should never have more access than the user it is acting for. Pass the user's identity through to every tool call and enforce permissions in the tool, not in the prompt. Prompts can be overridden — including by text the agent reads from a web page, email or document. That is prompt injection, and the only reliable defence is limiting what a manipulated agent could do. ```typescript const tools = { lookupOrder: readTool(async ({ orderId }, ctx) => orders.findForUser(orderId, ctx.user)), issueRefund: writeTool( async ({ orderId, amount }, ctx) => { const order = await orders.findForUser(orderId, ctx.user); if (amount > order.total) throw new ToolError("Amount exceeds order total"); return refunds.create({ orderId, amount, requestedBy: ctx.user.id }); }, { requiresApproval: (args) => args.amount > 100 }, ), }; ``` Other guardrails worth building in: a maximum number of steps per task, a spending limit per run, human approval above a risk threshold, allow-lists for external domains, and output checks before anything is sent to a customer. ### Evaluating agents Agents are harder to evaluate than single prompts because there are many paths to an outcome. We evaluate at three levels: 1. **Tool level** — given a situation, does the agent choose the right tool with valid arguments? 2. **Task level** — across a set of realistic scenarios, does it reach the correct end state? Check the state of the system, not just the final message. 3. **Safety level** — adversarial cases: injected instructions in retrieved content, requests outside the user's permissions, ambiguous requests that should trigger a clarifying question. Run scenarios against a sandboxed copy of your systems, several times each, because agent behaviour varies between runs. Track success rate, steps taken and cost per task, and re-run the suite whenever prompts, tools or models change. ### Observability When an agent goes wrong in production, you need to see exactly what it saw and did. Trace every run end to end: the input, each model call with its prompt and response, each tool call with arguments and results, timings and token counts. Link traces to the user and the business object involved so support teams can answer “why did this happen?” without engineering help. Sample traces regularly for review, and turn failures into new evaluation cases. ### Cost control Agents can loop, and loops are expensive. Set hard limits on steps and tokens per task. Use a smaller, cheaper model for routing and simple steps, and a stronger one only where reasoning is needed. Cache stable context such as system prompts and tool definitions where your provider supports it. Trim tool outputs to the fields the agent needs. And measure cost per successful task, not per call — a cheaper model that fails more often may cost more overall. ### Memory and state Agents that work across long tasks or multiple sessions need somewhere to keep state, and that is another place where ordinary engineering beats cleverness. Store task progress, decisions and intermediate results in your own database with a clear schema, rather than relying on an ever-growing conversation history. It makes runs resumable after a failure, keeps the context window small, and lets you inspect exactly what the agent believed at each step. Be deliberate about long-term memory. Remembering a user's preferences can be helpful; silently accumulating personal data in a memory store is a privacy problem. Decide what is stored, for how long, and how a user can see or delete it, exactly as you would for any other feature. Treat external content the same way. Anything an agent reads from a web page, an inbound email or an uploaded file should be stored and passed along as data, clearly separated from instructions, and never promoted into memory without a check. Otherwise a single malicious document can influence every future run. ### Rolling agents out Start with read-only agents that research and draft, with a person taking the action. Add write actions one at a time, with approval steps, and remove approvals only when the evidence supports it. This staged approach is the same one we recommend for any [custom AI development](https://www.amygdal.com/blog/custom-ai-development) project, and it works especially well for agents. ### Building agents with Amygdal We design and build agentic systems, tool integrations and the evaluation and observability around them for clients in the UK, Germany, Switzerland and Qatar. Many agents also depend on good retrieval, covered in our [RAG development guide](https://www.amygdal.com/blog/rag-development-guide). See our [custom AI development](https://www.amygdal.com/services/custom-ai-development) service or [contact us](https://www.amygdal.com/contact) to talk through your use case. ### FAQ **What is the difference between an AI agent and a chatbot?** A chatbot generates replies. An agent can also call tools — query systems, create records, send messages — and decide its next step based on the results, which makes it more capable and more in need of guardrails. **How do you protect AI agents from prompt injection?** Assume the agent can be manipulated by content it reads, and limit the damage: enforce user permissions inside tools, keep write tools narrow, require approval for risky actions, and restrict external access. **How do you control the cost of LLM agents?** Set step and token limits per task, route simple steps to smaller models, cache stable context, trim tool outputs, and track cost per successful task rather than per model call. ## BIM Software Development: IFC, Revit APIs and Web Viewers URL: https://www.amygdal.com/blog/bim-software-development Published: 2026-07-14 · Category: Engineering · Tags: BIM, IFC, Revit, AI, AEC IFC parsing, Revit add-ins, browser model viewers and data pipelines — what building software for BIM involves, and where AI earns its place. Building Information Modelling has moved most of the construction industry's knowledge into digital models, but the software around those models is often a patchwork: desktop authoring tools, exported spreadsheets, and a lot of manual checking. Much of the value in BIM software development is in the gaps — getting model data out, checking it, connecting it to other systems and showing it to people who do not have a Revit licence. We have done AI and software development for BIM, and this guide is a practical overview of the main building blocks, the tools we reach for, and where AI genuinely helps. ### IFC: the open format you will end up parsing IFC (Industry Foundation Classes) is the open, vendor-neutral schema for exchanging building models. Whatever authoring tool a project uses, IFC is usually how models move between disciplines and into anything you build. Working with it well means understanding a few things that surprise newcomers: - **It is a graph, not a table.** Elements, property sets, spatial structure and relationships are linked entities. Flattening too early loses meaning. - **Schema versions differ.** IFC2x3 and IFC4 are both common in the wild, and exporters interpret them differently. - **Property sets vary by author.** Standard Psets are only part of the story; most projects carry custom properties that matter to the client. - **Geometry is expensive.** Parsing semantics is fast; tessellating geometry for display or clash checks is where time and memory go. For server-side work, IfcOpenShell is the mainstay for Python pipelines. In JavaScript, web-ifc (from the That Open Company ecosystem) parses IFC in WebAssembly in both Node.js and the browser. ```python import ifcopenshell import ifcopenshell.util.element as el model = ifcopenshell.open("model.ifc") for wall in model.by_type("IfcWall"): psets = el.get_psets(wall) fire = psets.get("Pset_WallCommon", {}).get("FireRating") print(wall.GlobalId, wall.Name, fire) ``` ### Revit and Autodesk APIs When a workflow lives inside Revit, the Revit API is the way in. Add-ins are written in C# against .NET and run inside the desktop application, which gives full access to the model but ties you to Revit's threading model, transactions and release cycle. Each yearly Revit version is a compatibility check. Keep add-ins thin. The Revit-specific code should read from and write to the model; validation rules, classification logic and anything you might want to run elsewhere belongs in a separate library or service. That way the same rules can run inside Revit for a designer and in a cloud pipeline for a whole portfolio of models. For cloud workflows, Autodesk Platform Services (formerly Forge) provides model derivative translation, data management, and Design Automation, which runs Revit and other engines headlessly in the cloud. The trade-off is familiar: desktop add-ins are closest to how designers work, cloud APIs are easier to scale and integrate. Many good systems use both — an add-in for in-context actions, a cloud pipeline for everything batch. ### Web-based model viewers Most people who need to see a model — clients, site teams, facility managers — will never open an authoring tool. A web viewer brings the model to them. The main open options we work with: - **That Open Engine (formerly IFC.js)** — built on web-ifc and Three.js, good for loading IFC directly in the browser and building custom tools on top. - **xeokit** — a WebGL SDK designed for large models, with strong performance on big federated scenes and a precompiled model format. - **Autodesk Viewer** — the natural choice when models already live in Autodesk Platform Services. For anything beyond a small model, convert IFC on the server into an optimised format and stream that to the browser, rather than parsing raw IFC on the client. Users notice load time long before they notice anything else. A modern [web development](https://www.amygdal.com/services/web-development) stack around the viewer — search, filters, issue tracking, property panels — is usually where most of the product work is. ### Model data pipelines The highest-value BIM software is often invisible: pipelines that pull model data out on every revision, validate it and push it somewhere useful. A typical pipeline looks like this: 1. Ingest a new model revision from a common data environment or upload. 2. Parse elements, properties and spatial structure into a relational or document store. 3. Run rule-based checks — required properties, naming conventions, classification codes. 4. Diff against the previous revision to show what changed. 5. Publish results to dashboards, cost tools or facility management systems. Storing extracted data in PostgreSQL alongside the original files keeps queries fast and makes revision history straightforward. Geometry-heavy work runs in background workers so uploads never block on it. Two things make these pipelines trustworthy. First, stable identity: IFC GlobalIds are what let you say an element changed rather than was deleted and recreated, so pipelines should check that exporters preserve them between revisions. Second, rules written as data, not code — a list of required properties per element type that a BIM manager can read and change — so the checks reflect the project's standards rather than a developer's interpretation of them. ### Where AI fits in BIM AI is useful in BIM where the work is reading, classifying and searching — and much less useful where exact geometry or code compliance is at stake. The areas where we have seen it help: - **Classification and mapping** — suggesting classification codes or mapping inconsistent property names to a standard, with a person confirming. - **Natural-language querying** — asking a model "which fire doors on level 3 are missing a rating?" and translating that into a structured query over extracted data. - **Document retrieval** — connecting specifications, standards and project documents to model elements using [RAG](https://www.amygdal.com/services/rag-development). - **Data quality triage** — ranking which issues in a large model are most likely to matter. The rule we follow: AI suggests, deterministic checks verify, and a person approves anything that affects design or compliance. We cover this in more detail in [AI in BIM](https://www.amygdal.com/blog/ai-in-bim). ### Working with us on BIM BIM software development sits between construction knowledge and ordinary good engineering. If you need IFC pipelines, a Revit add-in, a web viewer or AI on top of model data, see our [AI for BIM](https://www.amygdal.com/services/ai-for-bim) service or [contact us](https://www.amygdal.com/contact). ### FAQ **What is the best way to parse IFC files?** IfcOpenShell is the standard choice for Python pipelines. In JavaScript, web-ifc parses IFC in WebAssembly in both Node.js and the browser. **Should I use That Open Engine or xeokit for a web BIM viewer?** That Open Engine is a good fit for custom IFC tools built on Three.js. xeokit is strong for very large federated models. For big models, convert on the server and stream an optimised format either way. **Can AI check BIM models for code compliance?** AI can help classify elements, search documents and triage issues, but compliance checks should be deterministic rules, with a qualified person approving the results. ## Building Integrations and Plugins for SaaS Marketplaces URL: https://www.amygdal.com/blog/building-saas-marketplace-integrations Published: 2026-06-24 · Category: Product · Tags: Integrations, SaaS, APIs, Product strategy An integration listed in a well-known marketplace can bring users to your product. Building one that survives API changes and review processes takes some care. Most business software does not live on its own. Customers expect it to connect to the tools they already use: their chat app, project tracker, e-commerce platform, payments and accounting. For a product company, integrations are both a retention feature and a distribution channel. A listing in a popular marketplace puts your product in front of people who are already looking for a solution. Integrations also have a reputation for becoming a maintenance burden. Third-party APIs change, tokens expire, webhooks arrive twice or not at all. This post covers how we plan and build integrations that hold up over time. Talk to customers before choosing which platform to integrate with first. Ask which tools they use daily and where they currently copy data by hand. The integration that removes the most manual copying is usually the one that gets used, whatever the marketplace's size. ### Decide what the integration is for Start with the job, not the API. Is the integration meant to bring data into your product, push your product's output somewhere else, or let users act on your product without leaving another tool? A notification bot, a two-way sync and an embedded app inside another platform are very different projects in scope and risk. Two-way sync in particular is far harder than it looks, because conflicts and deletions have to be handled on both sides. It is also worth deciding early whether you are building one integration or an integration capability. If your roadmap includes several, the shared parts (connection management, credential storage, retries, logging, a settings screen for customers) should be designed once. Teams that build their first three integrations independently usually end up rewriting all three. ### The building blocks - **Authentication.** OAuth flows, token storage encrypted at rest, refresh handling and a clear path for users to reconnect when access is revoked. - **Webhooks.** Signature verification, idempotent handlers (the same event may arrive more than once) and a queue so slow processing never causes the sender to time out. - **Rate limits.** Respect the provider's limits with backoff and batching, and design so a burst from one customer cannot exhaust shared quota. - **Data mapping.** An explicit, versioned mapping between their model and yours, with sensible handling of fields that do not exist on one side. - **Observability.** Per-customer logs of sync runs and failures, so support can answer why something did not appear without involving an engineer. #### Design for failure Every external API will fail at some point: timeouts, outages, expired credentials, unexpected payloads. A robust integration treats failure as normal. Retries use exponential backoff with limits. Failed events go to a dead-letter queue that someone can inspect and replay. A periodic reconciliation job compares records on both sides and repairs drift caused by missed webhooks. And users see a clear status, such as connected, syncing or needs attention, rather than silently stale data. ### Examples from our projects Integrations show up in most of what we build. [Sumus](https://www.amygdal.com/projects/sumus), an AI product-discovery engine for fashion, includes Shopify in its stack alongside a NestJS backend. [Digital Arrow](https://www.amygdal.com/projects/digital-arrow), the HR and recruiting platform we architected, lists Slack and Jira among its technologies and uses Browserless for headless document generation, including online contract signatures. In each case the integration code is isolated behind its own module, so a change in a third-party API touches one place. Security reviewers on the customer side will ask how tokens are stored, who can access them and what happens if your service is compromised. Keep credentials encrypted with keys managed separately from the database, scope them to the minimum needed and make revocation immediate. Document this once and reuse the answer in every security questionnaire. ### Getting through marketplace review Most marketplaces review apps before listing them, and the requirements tend to look similar: 1. Request only the permissions you actually use, and explain why each one is needed. 2. Publish a privacy policy and terms that describe exactly what data you access and store. 3. Provide a test account and clear instructions for reviewers. 4. Handle uninstall cleanly, including deleting stored data where the platform requires it. 5. Meet the platform's design and accessibility guidelines for any embedded interface. Build these into the plan from the start. Retrofitting minimal permissions and data deletion after a rejection costs more than designing for them. #### Treat the listing as a product A marketplace listing is a sales page. Clear screenshots, a short explanation of what the integration does, setup instructions and a support contact all affect how many people install it. Track installs, activation (users who complete setup) and retention separately; a high install count with low activation usually points to a confusing setup flow rather than a lack of interest. Version your own side of the integration too. When you change how data is mapped, existing customers should not see records suddenly change shape. Migrate them deliberately, with a note in the changelog, and keep the previous mapping available until everyone has moved. ### Plan for maintenance An integration is a long-term commitment. Subscribe to the provider's developer changelog, run automated tests against their sandbox on a schedule, and alert on rising error rates per integration. Budget time every quarter for API version upgrades. If you offer several integrations, a shared internal framework for auth, retries and logging pays for itself quickly. Finally, give customers control. Let them choose what syncs, pause the integration without losing configuration and see a history of what changed. Customers trust integrations they can understand, and they disconnect the ones that surprise them. ### Adding AI to an integration Many recent marketplace apps use AI to do something useful with another product's data, such as summarising time entries, classifying tickets or drafting reports. The same rules apply as for any AI feature: be explicit about what data is sent to which model, evaluate output quality, and let users review results before anything is written back to their system. Our post on [choosing between an agent and a workflow](https://www.amygdal.com/blog/ai-agent-vs-workflow-automation) helps decide how much autonomy such a feature should have. ### Need an integration built? We build integrations, plugins and the platforms around them. See our [web development](https://www.amygdal.com/services/web-development) service, or [get in touch](https://www.amygdal.com/contact) to discuss what you want to connect. ### FAQ **How long does it take to build a SaaS integration?** A one-way notification or data push can be quick. A two-way sync or an embedded marketplace app takes considerably longer, because of conflict handling, review requirements and testing. Scope depends heavily on the provider's API. **How do you handle webhooks reliably?** Verify signatures, acknowledge quickly and process events from a queue, make handlers idempotent because events can be delivered more than once, and reconcile periodically in case an event is missed. **What do marketplaces check before approving an app?** Typically minimal permissions with a clear justification, a privacy policy, clean uninstall and data deletion, a working test account for reviewers and compliance with the platform's design guidelines. ## What an AI Consultancy Should Actually Deliver URL: https://www.amygdal.com/blog/ai-consultancy-agency Published: 2026-06-17 · Category: AI · Tags: AI consultancy, Strategy, Delivery An AI consultancy is worth hiring when it leaves you with working software and a team that understands it. What to expect at each stage, and what to be wary of. “AI consultancy” can mean anything from a slide deck to a shipped product. Plenty of organisations have paid for an AI strategy that identified dozens of opportunities and delivered none of them. The gap between advice and working software is where most of the value is lost. At Amygdal, an AI consultancy engagement means we help you find where AI creates real value, then design, build and integrate it into production. We are a software company that implements AI, so the strategy is grounded in what can actually be shipped. Here is what we think any AI consultancy should deliver, whoever you hire. ### 1. Opportunity discovery tied to decisions A good AI consultancy starts by finding the opportunity, not the model. The useful question is where in your business AI would change a decision, save meaningful time, or enable a product you cannot offer today. That means interviews with the people doing the work, a look at the systems and data involved, and an honest assessment of value against effort. The deliverable should be a short, ranked list of use cases, each with the decision it affects, the data it needs, the main risk, and how success would be measured. If the list is long and vague, the discovery was not finished. ### 2. A proof of concept on the riskiest assumption Most AI projects die between a demo and a dependable product. The way to de-risk that is a focused proof of concept that tests the hardest assumption against real data. Can the system extract the right fields from your actual documents? Does retrieval find the correct policy clause? Is accuracy good enough in the cases that matter? A proof of concept should produce evidence and a clear go or no-go recommendation in weeks. Be wary of one that produces a polished interface over a curated dataset — it proves the demo works, not the product. ### 3. Production software, not a handover document This is where pure advisory firms step back and where the real work starts. Production AI is mostly software engineering: data pipelines, APIs, permissions, a usable interface, error handling, guardrails, monitoring and tests, integrated with the systems people already use. LLM and RAG features, computer vision, predictive analytics and recommendations all need the same treatment. Our project history reflects that mix. On [Sumus](https://www.amygdal.com/projects/sumus) we built the AI tool behind a fashion product-discovery engine — recognition, ESG scoring and brand comparison. On [Digital Arrow](https://www.amygdal.com/projects/digital-arrow), an HR and recruiting platform, asynchronous video interviews with AI scoring sit inside a much larger product of timesheets, contracts and invoicing. In both cases the AI only works because the software around it does. ### 4. Evaluation and operations you can see You should leave an engagement knowing how well the system works and how you will know if that changes. Concretely, an AI consultancy should hand over: - **An evaluation set** of real examples with expected outcomes, and the results of running the system against it. - **A regression process** that re-runs evaluation whenever prompts, models or data change. - **Monitoring** for quality, latency, cost and usage, with alerts that someone owns. - **Guardrails** appropriate to the risk: input validation, output checks, refusal behaviour and human review where needed. - **A record of decisions**: which models, why, where data is processed, and what was tried and rejected. ### 5. Knowledge transfer, not dependency A good partner accelerates you and leaves your team more capable. That means working in your repositories and infrastructure where possible, pairing with your engineers, documenting the system as it is built, and agreeing in advance how ownership transfers. If the engagement is structured so that only the consultancy can change the system, ask why. ### What a typical engagement looks like Engagements vary, but a sensible shape is short discovery, a time-boxed proof of concept, then a production phase with regular releases. Discovery and the proof of concept are usually measured in weeks and have a clear exit point: if the evidence is weak, you stop with a useful finding and a modest bill rather than a half-built system. During the production phase, expect to see working software early and often — a release every week or two that real users can try — rather than a long build followed by a reveal. Expect the consultancy to raise risks plainly: data that is not good enough, an integration that will take longer than planned, a use case that is not delivering. Those conversations are uncomfortable, but they are the main reason to work with experienced people. A partner who only ever reports good news is not managing the project; they are managing you. Finally, expect clarity on ownership from the first contract: your code, your prompts, your evaluation sets and your data, in your accounts. ### When to hire an AI consultancy Hire one when you know AI could help but do not have the in-house depth to choose the right approach, avoid expensive mistakes and ship it safely. That is especially true in regulated or high-stakes contexts such as [healthcare](https://www.amygdal.com/blog/implementing-ai-in-healthcare) and finance, and when AI will be part of a customer-facing product rather than an internal tool. You probably do not need one if the need is covered by AI features in tools you already own, or if you have an experienced team that simply needs more hands — in that case, a development partner is a better fit than a consultancy. ### Questions to ask a prospective AI partner 1. Which AI systems have you put into production, and who maintains them now? 2. How do you evaluate quality before and after launch? 3. What would make you recommend we not build this? 4. Where will our data be processed, and by which providers? 5. How does ownership of code, prompts and evaluation sets transfer to us? ### Talk to us Amygdal works as an AI consultancy and development partner for clients in the UK, Germany, Switzerland and Qatar. Our [custom AI development](https://www.amygdal.com/services/custom-ai-development) service takes you from discovery to production, and our guide to [custom AI development vs off-the-shelf tools](https://www.amygdal.com/blog/custom-ai-development) covers how to decide what to build. [Get in touch](https://www.amygdal.com/contact) to start with a discovery conversation. ### FAQ **What is the difference between an AI consultancy and an AI development company?** A pure consultancy advises; a development company builds. Amygdal does both: we set the AI strategy and then implement it in production, so the advice is grounded in what actually ships. **How do you start an AI project without wasting budget?** With opportunity discovery and a focused proof of concept on the riskiest assumption. That produces evidence quickly and tells you whether to invest further before you commit to a full build. **Can an AI consultancy integrate AI into our existing product?** Yes, and that is most of our work: adding LLM and RAG features, predictive analytics or computer vision to existing systems, with the data plumbing, evaluation and monitoring to make them reliable. ## Mobile App Engineering: What It Is and Why It Matters URL: https://www.amygdal.com/blog/mobile-app-engineering Published: 2026-06-10 · Category: Mobile · Tags: Mobile, iOS, Android, Architecture, Testing Anyone can assemble screens. Mobile app engineering is the discipline that keeps an app fast, secure and maintainable as it grows from launch to its third year. Anyone can assemble screens. **Mobile app engineering** is what makes an app fast, secure, reliable and maintainable as it grows. It is the difference between a prototype that impresses in a demo and a product that thousands of people open every day without thinking about it. When clients compare mobile app development proposals, they mostly see feature lists and timelines. The engineering is harder to see, and it is what determines whether the app is still pleasant to work on in its third year. This post explains what that engineering consists of. ### Architecture before features Apps built screen by screen tend to work well for six months and then become hard to change. Good mobile engineering starts with structure: - **Clear separation of concerns:** UI components, data fetching and business rules live in predictable places. - **A deliberate approach to state:** server data in a caching layer such as TanStack Query, local UI state kept local. - **Typed API contracts** shared with the backend, so mismatches are caught at build time. - **A design system** of reusable components and tokens, which keeps iOS and Android consistent and speeds up new screens. - **Modular features** that can be developed and tested in isolation. None of this is glamorous. All of it is what allows a team to keep shipping quickly once the app has fifty screens instead of five. ### Performance users can feel Users notice jank, slow startup and laggy scrolling immediately, even if they cannot name it. Mobile engineering treats performance as a requirement, not a polish phase. That means virtualised lists, animations that run on the UI thread, correctly sized and cached images, a lean startup path and profiling on mid-range devices rather than flagship phones. In React Native specifically, it also means knowing when to write a native module; we go deeper on that in [building great React Native apps](https://www.amygdal.com/blog/building-great-react-native-apps). ### Security on a device you do not control A mobile app runs on hardware you do not own, and its binary can be inspected. That changes the security model: 1. Never ship secrets in the app bundle. Anything in the binary should be considered public. 2. Store tokens in the platform's secure storage (Keychain on iOS, Keystore on Android), not plain async storage. 3. Enforce every permission check on the server; the client is only a convenience. 4. Handle payments and subscriptions through the platform stores or a proven provider. On [Ealthiness](https://www.amygdal.com/projects/ealthiness), subscriptions run through Stripe. 5. Request only the device permissions you need, at the moment you need them, with a clear explanation. ### Testing at the right levels Mobile testing is often skipped because it is awkward. We aim for a balanced set: unit tests for business logic, component tests for important UI states, and a small number of end-to-end tests that cover the flows that must never break, such as sign-up, login and payment. Device fragmentation matters too. Our team built cross-platform automated testing for A&E's [History.com](https://www.amygdal.com/projects/history) apps on Amazon Fire TV, Android TV and Apple TV using Appium and WebdriverIO on real devices, driven by a custom CLI. The lesson carries over to phones: automated tests on real device profiles catch problems that manual checks on one phone will miss. ### Releases and life after launch Shipping a mobile app is different from deploying a website. Store review adds delay, users stay on old versions for months, and a bad release cannot simply be reverted. Engineering for this means: - CI/CD that produces signed builds for TestFlight and the Play internal track on every merge. - Staged rollouts and, where appropriate, over-the-air updates for JavaScript-only fixes. - Crash and performance monitoring in place before public launch. - Backward-compatible APIs and a minimum-version check for the rare breaking change. - Feature flags to turn off a problematic feature without a new store release. ### Cross-platform without compromise For most products, React Native lets one team keep iOS and Android in sync at lower cost than two native teams. We have used it across consumer apps such as Ealthiness and community platforms such as [Dorfleben](https://www.amygdal.com/projects/dorfleben), which serves towns across Germany on web and mobile. Fully native development still makes sense for apps dominated by heavy graphics or deep platform features. Choosing well is itself part of the engineering. ### Accessibility and localisation Two areas that are cheap to design in and expensive to retrofit are accessibility and localisation. Accessibility means proper labels for screen readers, sufficient contrast, support for larger text sizes and touch targets that are easy to hit. Beyond being the right thing to do, it increasingly matters for public-sector and enterprise buyers in the UK and the EU. Localisation means keeping every user-facing string out of the code from the start, formatting dates, numbers and currencies by locale, and testing layouts with longer languages such as German. For clients in Qatar and the wider Gulf, it also means designing for Arabic and right-to-left layouts, which affects navigation, icons and animations, not just text. ### Questions to ask a mobile partner If you are evaluating a mobile app development company, these questions reveal more about engineering quality than a portfolio of screenshots: 1. How do you structure state and data fetching, and why? 2. Which devices do you profile performance on? 3. What runs automatically on every pull request? 4. How do you handle users on old app versions when the API changes? 5. Who owns the app store accounts, signing keys and repositories? Clear, specific answers suggest a team that has maintained apps after launch, not just built them. Ask to see how a recent app was maintained, not just how it was launched. Release notes, crash trends and how quickly issues were fixed tell you far more about a team's engineering than a polished launch video. Good partners will happily walk you through that history. ### Working with us If you are planning a new app, or your current one has become slow or risky to change, we can help with architecture reviews, performance work, test automation or a full build. See our [mobile app development](https://www.amygdal.com/services/mobile-app-development) service or [contact us](https://www.amygdal.com/contact). ### FAQ **How is mobile app engineering different from mobile app development?** Development often means building features. Engineering means building them with the architecture, performance, security, testing and release process that keep the app reliable and maintainable. **Is one codebase for iOS and Android reliable?** Yes, with React Native used well: share most code and write native modules for performance-critical or platform-specific features. It keeps both platforms in sync at lower cost. **How do you keep a mobile app stable as it grows?** A modular architecture, typed APIs, automated tests on the critical flows, crash monitoring, staged rollouts and feature flags, so new features do not degrade the app. ## Sumus: AI Product Discovery for Sustainable Fashion URL: https://www.amygdal.com/blog/sumus-ai-esg-case-study Published: 2026-06-02 · Category: Case study · Tags: AI, ESG, NestJS, Next.js, Ollama, OpenAI Scan a garment, see its ESG footprint, compare brands. A look at the AI pipeline we built for Sumus and the decisions that kept it honest. Sumus is an AI product-discovery engine for fashion. A shopper scans a garment and Sumus shows its ingredients, quality, safety and availability alongside an ESG footprint, then lets them compare sustainability across brands side by side. The aim is to put information about materials, ethics and environmental impact in front of people at the moment they are deciding. We built the AI tool behind that experience: the scanning and recognition pipeline, the ESG scoring engine and the brand-comparison layer. This post explains how those pieces fit together and why we made the choices we did. ### The stack Sumus runs on a **NestJS** REST API with **PostgreSQL** and Redis, MinIO for images and files, and a **Next.js** web app alongside a **React Native** mobile app, deployed on Railway. Shopify integration connects product catalogues, and Stripe and NextAuth cover payments and authentication. For models, we used both **Ollama** for self-hosted open models and **OpenAI** for hosted ones. The web and mobile clients talk to the same API, and the AI pipeline sits behind it rather than inside either client. That keeps model choice, prompts and scoring rules on the server, where they can change without an app release, and it means a shopper gets the same answer whether they scan on their phone or look a product up on the web. ### From a scan to a product The first job is recognition: given a photo or a scanned label, which product is this? That breaks down into a pipeline rather than a single model call: 1. **Capture** — the image goes to object storage and the request gets an ID, so every step after it is traceable. 2. **Extract** — read what is on the label or tag: brand, composition, care and origin text. 3. **Match** — resolve that to a known product or product family in the catalogue, including those coming in from Shopify. 4. **Enrich** — attach what is known about materials, manufacturing and brand practices. 5. **Score and explain** — compute the ESG view and the plain-language summary the shopper sees. Splitting the work this way means each step can be tested, measured and improved on its own. When a result is wrong, you can see which step got it wrong, which is the difference between a prototype and something a team can maintain. Each step should also report how confident it is. A clean label that matches one catalogue product goes straight through. A blurry photo or an ambiguous match is better shown to the shopper as a short list of candidates to pick from, rather than a confident wrong answer. Results for products that have already been resolved are cached, so repeat scans of popular items are fast and cost nothing in model calls. ### Scoring is rules, explanation is AI The most important design decision was where **not** to use a language model. ESG scores have to be consistent: the same garment must get the same score today and next month, and two shoppers comparing brands must be comparing like with like. A language model asked to "rate the sustainability" of a product will not give you that. So the scoring engine is deterministic. It takes structured inputs — material composition, certifications, origin, brand-level data — and applies defined weights. Models do the parts they are good at: reading messy label text, matching products, and turning a score breakdown into a short explanation a shopper understands in seconds. Every explanation is generated from the score's actual inputs, so the words cannot drift from the number. Scoring rules also need versioning. When the weighting changes — because better data becomes available or the methodology is refined — each stored score should record which version produced it. That makes it possible to re-score the catalogue deliberately and to explain why a product's score moved, instead of numbers shifting silently underneath users. ### Why both Ollama and OpenAI Running both self-hosted and hosted models is a pragmatic choice, not an ideological one. High-volume, well-defined tasks such as extraction and classification are good candidates for smaller open models served through Ollama, where cost is predictable and data stays on infrastructure we control. Harder reasoning and generation tasks can go to hosted models where quality justifies the cost. Keeping both behind one internal interface means a task can move between them as models improve, without touching the rest of the system. It also makes evaluation straightforward: run the same labelled test set through two models and compare, before switching anything in production. ### Comparison that does not mislead Brand comparison is where sustainability products most easily become misleading. Data coverage is uneven: some brands publish detailed supply-chain information and others publish almost nothing. A comparison that quietly fills gaps with guesses rewards the brands that disclose least. We designed the comparison layer to make coverage visible. Missing data is shown as missing, not as an average, and the shopper can see which parts of a score rest on verified inputs. It is a less tidy interface, and a more honest one. The same applies to sources. Each ESG input carries where it came from — a certification, a brand disclosure, a product label — so that when a brand updates its information, the affected scores can be recalculated and the change is traceable. For a product whose whole value is trust, being able to answer "where does this number come from?" matters more than any individual feature. ### Lessons for AI product teams - Build a pipeline of small, testable steps rather than one large prompt. - Keep anything that must be consistent — scores, prices, eligibility — in deterministic code. - Use models to read and explain, and generate explanations from the real inputs. - Put self-hosted and hosted models behind one interface so you can switch per task. - Show missing data as missing. ### Building an AI product? Sumus is a good example of [AI development](https://www.amygdal.com/services/custom-ai-development) where the model is one part of a larger system. If your product depends on retrieving and explaining structured knowledge, our [RAG development guide](https://www.amygdal.com/blog/rag-development-guide) is a good next read. See the [Sumus project](https://www.amygdal.com/projects/sumus), or [get in touch](https://www.amygdal.com/contact). ### FAQ **What did Amygdal build for Sumus?** We built the AI tool: the garment scanning and recognition pipeline, the ESG scoring engine and the brand-comparison layer, on a NestJS and PostgreSQL backend with Next.js and React Native clients. **Does a language model calculate the ESG score?** No. Scoring is deterministic and rules-based so results stay consistent. Models extract information from labels, match products and write the plain-language explanation. **Why use Ollama and OpenAI together?** Self-hosted open models via Ollama suit high-volume, well-defined tasks with predictable cost, while hosted models handle harder tasks. One interface lets each task use the right model. ## Machine Learning for Prioritisation in Healthcare Services URL: https://www.amygdal.com/blog/machine-learning-prioritisation-healthcare Published: 2026-05-13 · Category: Healthcare · Tags: Healthcare, Machine learning, Triage, Human in the loop Some of the safest, most useful AI in healthcare does not diagnose anything. It helps busy teams decide which request, referral or patient to look at next. Discussions of AI in healthcare often jump straight to diagnosis: a model reading scans or predicting disease. Those applications are important, and they are also among the most heavily regulated and hardest to validate. A quieter category often delivers value sooner: **prioritisation**. Healthcare teams face queues everywhere, from referrals and inbound enquiries to messages, follow-ups and care requests. Deciding what to look at first is a real problem that machine learning can help with. This post describes how we approach prioritisation systems in healthcare settings: what to predict, how to keep clinicians and staff in control, and what to measure. Prioritisation also fits how healthcare teams already work. Staff sort queues all day using experience and informal rules. A model that makes that sorting faster and more consistent supports their judgement rather than replacing it, which matters for adoption as much as for safety. ### Rank, do not decide The central design choice is that the model orders work; people make decisions. A prioritisation model suggests which items in a queue probably need attention sooner and explains why. A nurse, coordinator or advisor still reviews each item. This keeps the human accountable, makes errors recoverable and is usually a far easier conversation with clinical governance than a system that acts on its own. Whether a given system counts as a medical device depends on its intended purpose and on local regulation, so involve regulatory advice early. Our post on [implementing AI in healthcare safely](https://www.amygdal.com/blog/implementing-ai-in-healthcare) covers that process in more depth. Start by observing how the queue is handled today. Watch experienced staff sort their work and ask what they look for. Their implicit rules are often a strong baseline, and some of them can be implemented directly as rules before any model is trained. The model then has to beat that baseline to earn its place. ### Choosing what to predict A model is only as useful as its target. Good targets are concrete, observable and agreed with the people who will use the output: - Likelihood that a request will need escalation to a clinician. - Likelihood that a case is time-sensitive, based on how similar cases were handled historically. - Likelihood that a family or patient will drop out of a process without contact. - Expected complexity, so cases can be routed to the right level of expertise. Be careful with historical labels. If past prioritisation was inconsistent or biased, a model trained on it will learn the same patterns. Review the data with clinicians before training anything. Agree on the cost of each kind of error with clinicians before training. Ranking an urgent case too low is usually far worse than ranking a routine case too high, and the model's thresholds and evaluation should reflect that imbalance rather than treating all mistakes as equal. ### Often, simpler models are better For tabular data such as request type, timings, history and structured answers, gradient-boosted trees or logistic regression frequently perform as well as anything more complex, and they are easier to explain and validate. Language models are useful for turning free-text messages into structured signals first. The best systems often combine the two: an LLM extracts features from text, a simple, well-understood model produces the score. #### Validate before anyone relies on it Before a prioritisation model influences real queues, run it in **shadow mode**: it scores live items, but staff do not see the scores. Compare its ranking with what actually happened, and with how experienced staff prioritised the same items. This shows how the model performs on current data, without any risk to patients, and gives clinicians concrete evidence to review rather than a promise. When it does go live, start with a limited group of users and a defined review period. Agree in advance which results would lead you to pause, adjust or stop the rollout. ### Designing the interface around the score 1. Show the **reason** for a high priority, such as the phrases or factors that drove it, not just a number. 2. Let staff **override** the order with one action, and record the override as feedback. 3. Keep a **safety net**: rules for clearly urgent signals that bypass the model entirely. 4. Never hide low-priority items. Everything stays visible; the model only changes the order. 5. Make the system's **limits** clear in the interface, so nobody treats it as a diagnosis. Training matters too. Staff who understand what the score means, and what it does not mean, use it better. A short session with real examples of correct and incorrect rankings, and clear guidance on when to override, does more for safe use than any amount of documentation. ### Measuring what matters Accuracy on a test set is necessary but not sufficient. Before launch, evaluate performance across patient groups to detect uneven error rates. After launch, track operational outcomes agreed with the team, such as time to first contact for urgent cases, override rates and missed escalations. A rising override rate is an early sign that the model or the underlying population has drifted. Data protection runs through all of this. Health data is special-category data under GDPR and protected health information under HIPAA in the United States, which shapes where data is stored, who can see it and how long logs are kept. Getting these decisions right early is far cheaper than retrofitting them after launch. #### Plan for drift Healthcare services change: new referral routes, seasonal demand, updated forms, different patient populations. Each change can shift what the model sees. Monitor input distributions as well as outcomes, schedule periodic revalidation with the clinical team, and keep a documented process for retraining and redeploying the model, including who signs off on a new version. ### Context from our healthcare work Healthcare services operate under heavy, uneven load. On [A Place For Mom](https://www.amygdal.com/projects/aplaceformom), a US senior-care platform serving more than 300,000 customers, we delivered the healthcare service side on Next.js and Node.js with event-driven AWS infrastructure built to stay reliable under nationwide demand. Any prioritisation layer in a service like that has to be as dependable as the platform beneath it. ### Exploring AI for your healthcare service? We build healthcare software and AI with privacy and human oversight designed in. Read about our [AI in healthcare](https://www.amygdal.com/services/ai-in-healthcare) service, see our [healthcare work](https://www.amygdal.com/healthcare), or [contact us](https://www.amygdal.com/contact). ### FAQ **Is an AI triage or prioritisation tool a medical device?** It depends on its intended purpose and the regulations in your market. Tools that inform clinical decisions about individual patients may qualify. Seek regulatory advice early and design the intended purpose deliberately. **What kind of model works best for prioritising healthcare requests?** Often a simple, explainable model such as gradient-boosted trees on structured data, sometimes combined with a language model that extracts signals from free text. Simpler models are easier to validate and explain to clinicians. **How do you keep clinicians in control of AI prioritisation?** The model only orders the queue; people make decisions. Show reasons for each score, allow one-click overrides, keep rule-based safety nets for urgent signals and never hide low-priority items. ## Building HIPAA- and GDPR-Compliant AI for Healthcare URL: https://www.amygdal.com/blog/hipaa-gdpr-compliant-ai-healthcare Published: 2026-05-06 · Category: Healthcare · Tags: HIPAA, GDPR, EU AI Act, Healthcare, Security Compliance is a design input, not a final review. The architectural decisions that make healthcare AI defensible under HIPAA, GDPR and the EU AI Act. Building AI for healthcare means working with some of the most protected data that exists. In the US, HIPAA governs protected health information. In the UK and EU, GDPR treats health data as a special category requiring an explicit legal basis and extra safeguards. Switzerland's revised Federal Act on Data Protection and Qatar's personal data protection law add their own requirements. On top of this, the EU AI Act introduces obligations for AI systems based on their risk. None of this makes healthcare AI impractical. It means compliance has to shape the architecture from the first week. This post covers the decisions we make on every healthcare AI project. It is engineering guidance, not legal advice — every project should involve your data protection officer and legal counsel. ### Data minimisation: the cheapest control there is The safest data is data you never collect. For each AI feature, write down exactly which fields the model needs to do its job, and send nothing else. A model summarising a referral letter may not need the patient's name, address or insurance number. A model forecasting appointment no-shows may need history, but not diagnosis. Minimisation also applies to retention. Decide how long prompts, outputs and logs are kept, and delete on schedule. Logs are a common blind spot: a well-meaning debug log can quietly become the largest store of patient data in the system. ### De-identification and pseudonymisation Where a task can be done without identifying the patient, remove identifiers before data reaches the model. Under HIPAA, de-identification follows defined methods. Under GDPR, pseudonymised data is still personal data, but pseudonymisation is a recognised safeguard that reduces risk. Practical techniques include: - **Replacing direct identifiers with tokens** before text is sent to a model, and re-inserting them only in the final, access-controlled view. - **Detecting identifiers in free text** — names, dates, addresses, record numbers — with a dedicated step, then reviewing samples to check what it misses. - **Generalising quasi-identifiers** such as exact dates of birth or rare conditions that could identify someone in combination. - **Using synthetic or de-identified data** for development and testing, so engineers do not need access to real records. ### Hosting in-region and choosing model providers Where data is processed matters as much as how. For UK and EU patients, that usually means hosting in the UK or EU and checking every sub-processor, including the model provider. For US healthcare clients, any vendor handling protected health information needs a business associate agreement. Swiss and Qatari clients often have their own residency expectations. In practice there are three options: a major cloud provider's model service in a specific region under a suitable agreement; an open model hosted in your own cloud account; or an on-premises deployment. Each has trade-offs in capability, cost and operational effort. The important thing is to make the choice explicitly and document it, and to confirm that prompts and outputs are not retained or used for training by the provider. ### Audit trails and access control Every AI-assisted action in a clinical setting should be reconstructable: who requested it, what data was used, which model and prompt version ran, what it returned, and what the human did next. That record supports incident investigation, patient requests and regulatory review. Keep it tamper-evident and separate from application logs. Access control applies to AI as much as to any other feature. If a retrieval system searches clinical documents, it must respect the same permissions as the source system, filtering at query time — a pattern we describe in our [RAG development guide](https://www.amygdal.com/blog/rag-development-guide). ### Human in the loop, by design For anything that influences care, the AI should support a professional, not replace one. That has concrete design consequences: output is presented as a suggestion with its sources and reasoning; the clinician confirms, edits or rejects it; overrides are easy and recorded; and the system makes its uncertainty visible rather than hiding it behind confident prose. GDPR also gives individuals rights around solely automated decisions with significant effects, which human review helps address. ### EU AI Act awareness The EU AI Act classifies AI systems by risk. Many healthcare uses — particularly AI that is part of a regulated medical device — fall into the high-risk category, which brings requirements around risk management, data governance, technical documentation, logging, transparency, human oversight, accuracy and robustness. Obligations are being phased in over several years, so check the current timeline for your use case. The useful observation for engineering teams is that the practices described above — documented data sources, versioned models and prompts, evaluation reports, logging and human oversight — are exactly the evidence the Act expects. Building them in from the start is far cheaper than reconstructing them later. ### Vendor and sub-processor due diligence A modern AI system involves several third parties: a cloud host, a model provider, perhaps a vector database service, an observability tool and an email or messaging provider. Each one that touches personal data is a processor or sub-processor and needs to be listed, assessed and covered by an agreement. Observability and error-tracking tools are frequently overlooked, yet they can capture full prompts and responses. Keep a simple register of every service, what data it receives, where it processes that data and under which agreement. Review it whenever a new tool is added or a provider changes its terms. This register is also one of the first documents a hospital procurement or information governance team will ask to see. ### A compliance checklist for healthcare AI 1. Identify the legal basis and the applicable regimes: HIPAA, UK/EU GDPR, Swiss FADP, Qatari law, medical device rules, EU AI Act. 2. Run a data protection impact assessment before building. 3. Define the minimum data per feature and a retention schedule, including logs. 4. De-identify or pseudonymise wherever the task allows. 5. Choose hosting region and model provider explicitly; sign the right agreements. 6. Enforce source-system permissions inside retrieval. 7. Record a full audit trail of AI-assisted actions. 8. Design human review, overrides and visible uncertainty into the interface. 9. Version models, prompts and evaluation results; re-test on every change. ### How Amygdal can help We build healthcare software and AI with privacy as a design input, for clients in the UK, Germany, Switzerland, Qatar and the US. See our [AI in healthcare](https://www.amygdal.com/services/ai-in-healthcare) service and our broader guide to [implementing AI in healthcare](https://www.amygdal.com/blog/implementing-ai-in-healthcare), or [contact us](https://www.amygdal.com/contact) to discuss your project. ### FAQ **Can we use large language models with patient data under GDPR?** Yes, with an appropriate legal basis, a data protection impact assessment, data minimisation, a suitable hosting region and provider agreements that prevent retention or training on your data. Pseudonymisation further reduces risk. **Does the EU AI Act apply to healthcare AI?** Often, yes. AI that forms part of a regulated medical device is generally treated as high-risk, with requirements for documentation, logging, human oversight and accuracy. Obligations are phased in, so check the timeline for your case. **Is de-identified data outside the scope of HIPAA and GDPR?** Data properly de-identified under HIPAA's methods is outside HIPAA. Under GDPR, only truly anonymous data is out of scope; pseudonymised data is still personal data, though pseudonymisation counts as a safeguard. ## Scaling Your MVP After a Seed Round: What to Do First URL: https://www.amygdal.com/blog/scaling-mvp-after-seed Published: 2026-05-06 · Category: Product · Tags: Startups, Seed, Scaling, Engineering teams A seed round changes the engineering job. The MVP proved the idea; now it has to handle real users, real load and a bigger team without stalling. A seed round changes the job. Before it, the goal was to prove that something works. After it, the goal is to turn that proof into a product that handles real users, real load and a growing team, while showing the kind of progress that leads to the next round. This is the phase where we see startups lose the most time, usually by trying to do everything at once: rebuild the backend, launch three new features and double the team in the same quarter. Here is the sequence we recommend instead. ### Weeks one to four: get an honest picture Before deciding what to change, find out what you have. We usually start a post-seed engagement with a short technical review covering: - **Usage data:** which flows users actually rely on, where they drop off and what they never touch. - **Reliability:** error rates, slow endpoints, crash reports and anything that pages someone at night. - **Architecture:** the data model, how the app is deployed, what is tested and what is held together by hope. - **Security basics:** secrets management, access control, backups and dependency hygiene. - **Team workflow:** how code gets from a branch to production and how long that takes. The output is a short, prioritised list, not a hundred-page report. Its purpose is to stop the team from arguing about opinions and start working from evidence. ### Harden what users already rely on Post-seed, the priority is usually not more features. It is making the flows people already use fast and dependable. Early adopters forgive rough edges; the next cohort of users will not. Reliability is what turns early traction into retention, and retention is what the next round will be judged on. Practically, that means fixing the top errors from monitoring, adding tests around the core paths and anything involving money, improving performance on the screens people use daily, and closing the obvious security gaps. ### Pay down the debt that is actually in the way Every MVP has technical debt; that is normal and often correct. The mistake is treating all of it as urgent. We sort debt into three buckets: 1. **Blocking:** debt that is slowing down the features on your roadmap or causing incidents. Fix this now. 2. **Compounding:** debt that will get more expensive with every new user or engineer, such as a weak data model or missing CI. Schedule this soon. 3. **Cosmetic:** code that is untidy but stable. Leave it until you are already working in that area. If the MVP was built on reasonable foundations, most of this work is additive: caching, background queues, observability, a better-indexed database. If it cut deeper corners, we replace parts surgically, one module at a time behind stable interfaces, rather than pausing the roadmap for a full rewrite. We cover how to avoid this situation in the first place in [MVP to scale](https://www.amygdal.com/blog/mvp-to-scale). ### Grow the team without slowing it down Seed money buys engineers, but adding people to an unstructured codebase can make a team slower. Before hiring heavily, put in the structure that lets more people ship in parallel: - A CI/CD pipeline where every pull request is type-checked, tested and previewed automatically. - Clear module boundaries so two engineers rarely need to change the same files. - Typed API contracts between frontend, mobile and backend. - A small design system so UI work does not reinvent buttons on every screen. - Written conventions and a short onboarding guide, so a new hire is productive within days. Hiring also takes longer than founders expect. A dedicated external team can keep momentum while you recruit, and a good partner will plan from the start to hand work over to your in-house engineers rather than create a dependency. Nearshore teams in Europe, such as ours in Sarajevo, overlap fully with UK and German working hours, which makes this kind of blended setup straightforward. ### Spend the runway on evidence Runway is finite. The temptation post-seed is to build the product you imagine having at Series A. The better approach is to invest in the parts of the product that real usage has justified, measure the effect and repeat. The goal is the metrics your next round depends on, not a perfect codebase. ### Mobile and web at the same time Many seed-stage products start on one platform and face pressure to add another: a web dashboard for the mobile app, or an app for the web product. The mistake is to build the second platform as a separate project with its own logic. We keep business rules on the server, share TypeScript types and validation across clients, and use React Native for mobile so the same team can work across platforms. That way, adding a platform is mostly interface work rather than reimplementing the product a second time, and the two stay consistent as the roadmap moves. ### Signs the plan is working It helps to agree in advance what progress looks like, so the team is not judged on lines of code or story points. Useful signals in the months after a seed round include: - Fewer production incidents and faster recovery when they happen. - Shorter time from a merged pull request to production. - New engineers shipping their first change within their first week. - Core flows getting faster or more reliable, measured rather than felt. - Product experiments shipping on a regular rhythm, with results feeding the roadmap. If those indicators are improving, the engineering investment is paying off, even if the codebase still has rough corners. If they are not, the plan needs revisiting before more budget goes in. It is also worth reviewing the plan with investors and the wider team every quarter. Priorities shift quickly after a round, and an engineering roadmap that was right in month one can be wrong by month four. A short, honest review keeps effort pointed at what the business needs next. ### How we help post-seed teams We work with post-seed startups as a full product team or alongside existing engineers: technical reviews, hardening, architecture work and feature delivery. Learn more about our [software development](https://www.amygdal.com/services/software-development) service or [contact us](https://www.amygdal.com/contact) to talk about where your product is now. ### FAQ **We raised a seed round on our MVP. What should we do first?** Get an honest picture of usage, reliability and architecture, then harden the flows users already rely on. Reliability and evidence usually come before new features. **Do we need to rebuild our MVP to scale after seed?** Usually not. Scaling is mostly additive: caching, queues, observability and a better data layer. Where deep corners were cut, replace modules one at a time rather than starting over. **How do we grow the engineering team without slowing down?** Add structure first: CI/CD, clear module boundaries, typed APIs, a design system and written conventions. An external team can keep momentum while you hire. ## Ealthiness: Building an AI Health App in React Native URL: https://www.amygdal.com/blog/ealthiness-case-study Published: 2026-04-21 · Updated: 2026-10-17 · Category: Case study · Tags: React Native, Expo, NestJS, AI, Health, Mobile Mood, sleep, meals and movement in one app, an AI trainer you can talk to, and coaches, doctors and psychologists behind it. How Ealthiness is built. Ealthiness started as a fitness companion and grew into an AI-powered health app. People log the signals of an ordinary day — mood, sleep, meals, fasting, steps, runs and workouts — and get guidance back from an AI trainer and from a care team of coaches, doctors and psychologists. Companies and hospitals can bring it to their people as a programme. We built the whole product: the mobile app, the API, the AI layer and the admin portal the care team works in. This post covers how it fits together and the decisions that mattered. ### The stack - **Mobile:** React Native with Expo and Expo Router, Stripe for in-app payments, Mapbox for routes and push notifications. - **API:** NestJS on MongoDB through Mongoose, with Redis-backed job queues for anything slow, S3 for files and SendGrid for email. Sign-in uses JWT with Google and Facebook login. - **AI:** Gemini as the primary model with fallback providers, a Weaviate vector store for context, and speech-to-text and text-to-speech for voice conversations. - **Admin portal:** React Router with TanStack Query and shadcn/ui, with role-based permissions. - **Hosting:** Docker images deployed on Railway. We chose React Native for the usual reasons — one team, one codebase, both stores — and Expo because nothing in the app needed us to leave it. Our general approach is in [building great React Native apps](https://www.amygdal.com/blog/building-great-react-native-apps). ### Logging that people keep doing The app tracks many things: mood history, a sleep tracker, a meal and food log with diet plans, fasting windows, steps, runs and guided exercises. Each is only useful if people keep logging, so every check-in is designed to take seconds, and the app shows the signals side by side over time so a user can see for themselves how a week of better sleep lines up with how they felt. MongoDB suits this data well. Each log type has its own shape and changes as the product learns, and documents let us add a field to a meal entry or a therapy session without a migration across the whole system. ### An AI trainer you can talk to The AI trainer is the centre of the app. Users ask it questions by text or by voice, and it answers with the user's own history in view: recent logs, plans and goals are retrieved from a Weaviate vector store and passed to the model as context, so advice is about this person rather than people in general. Two decisions shaped it. First, no single provider is a dependency: Gemini handles conversations, and the service can fall back to other providers if a call fails. Second, voice is first-class. Speech is transcribed, answered and read back, which matters for an app people use mid-workout or while cooking. The trainer guides; it does not diagnose. Anything that needs a professional belongs to the care team, which is the other half of the product. ### A care team behind the app Coaches, doctors and psychologists work in the admin portal. They manage patients and coach groups, set up diet, fitness and therapy plans, run sessions and follow progress. Companies and hospitals sit above them, so an employer or clinic can run Ealthiness for its own people. With that many roles, permissions have to be explicit. Each role sees only what it needs — a coach sees their own clients, a psychologist their own sessions — and the rules live on the server, not in the UI. Health data is sensitive, and the safest design is one where the API refuses what the screen should never have asked for. ### Work that happens in the background Transcription, AI calls, embeddings and notifications are all slower than a normal API request. They run as jobs on Redis-backed queues, so the app stays responsive and a slow model call never blocks a user saving their dinner. ### What we would repeat 1. Make logging take seconds, or it stops happening. 2. Give the AI the user's own context through retrieval instead of hoping a general model guesses well. 3. Never depend on a single AI provider for a core feature. 4. Put a human care team next to the AI, and keep the AI on the guidance side of the line. 5. Enforce role-based access on the server from day one. ### Building a health product? Our [AI in healthcare](https://www.amygdal.com/services/ai-in-healthcare) and [mobile app development](https://www.amygdal.com/services/mobile-app-development) teams build products like Ealthiness, from the first prototype to store release and the backend behind it. See the [Ealthiness project](https://www.amygdal.com/projects/ealthiness) or [contact us](https://www.amygdal.com/contact). ### FAQ **What is Ealthiness built with?** React Native and Expo for the mobile app, a NestJS API on MongoDB with Redis job queues, Gemini with fallback providers and a Weaviate vector store for the AI trainer, an admin portal in React Router, Stripe for payments, deployed on Railway. **How does the Ealthiness AI trainer personalise its answers?** It retrieves the user's recent logs, plans and goals from a vector store and gives them to the model as context, so answers are based on that person's own data. **Does the AI replace doctors or coaches?** No. The AI trainer gives everyday guidance; coaches, doctors and psychologists in the care team handle plans, sessions and anything that needs a professional. ## AI Agent, Workflow or Script? Choosing the Right Automation URL: https://www.amygdal.com/blog/ai-agent-vs-workflow-automation Published: 2026-04-08 · Category: AI · Tags: AI agents, Automation, Business process, Strategy The word agent now covers everything from a cron job to an autonomous system. Naming what you actually need saves money and avoids fragile software. Ask five vendors what an AI agent is and you will get five answers. The term is now applied to chatbots, scheduled scripts, workflow tools with a language model in one step, and genuinely autonomous systems that plan and act on their own. For a business deciding what to build, that vagueness is expensive. It leads to complex, unpredictable software where a simple, reliable one would have done. This post offers a plain way to separate the options, and a rule we use with clients: choose the least autonomous design that solves the problem. Most real systems mix all three. A customer onboarding process might use plain integration code to create accounts, a model to read uploaded documents, and nothing agent-like at all. Naming each part correctly is what lets you test and price it correctly. ### Three levels of automation - **Scripts and rules.** Deterministic code: if this, then that. Every step is written by an engineer. Cheap, fast, testable and completely predictable. - **Workflows with AI steps.** A fixed sequence defined in code, where one or more steps call a model, for example to classify an email, extract fields from a PDF or draft a reply. The path is fixed; only the content of certain steps is generated. - **Agents.** A model decides which steps to take, in which order, using tools you give it, and loops until it judges the goal is met. The path itself is generated at run time. Each level adds flexibility and removes predictability. The right choice depends on how much variation the task really has. The distinction is not academic. It decides how you test the system, how you explain its decisions to customers or auditors, how much each run costs and what happens when something goes wrong. A workflow fails at a known step; an agent can fail in ways nobody anticipated, because it chose a path nobody designed. ### When a script is enough If the inputs are structured and the rules can be written down, write them down. Moving data between systems, sending reminders, generating documents from templates and syncing records do not need a model at all. Adding one makes the system slower, more expensive and harder to test without making it better. Much of what is marketed as AI automation is, underneath, this kind of integration work. ### When a workflow with AI steps fits This is where most of the value sits for most businesses. The process is known, but some steps involve unstructured input that rules cannot handle well: free-text emails, scanned documents, CVs, support tickets. A model handles those steps; ordinary code handles everything else. On [Digital Arrow](https://www.amygdal.com/projects/digital-arrow), an HR and recruiting platform we built, the hiring lifecycle is a defined process (post a role, collect candidates, interview, contract, timesheets, invoices) and AI is used for specific steps such as scoring asynchronous video interviews. The structure stays predictable; the model does the part that needs judgement on unstructured input. #### Making AI steps reliable A model inside a workflow should be treated like any other component with an error rate. Constrain its output to a schema, validate the result in code, and route low-confidence or invalid outputs to a person instead of passing them on. Measure accuracy per step against real examples. When a step is reliable enough, reduce human review for it; when it is not, the rest of the process keeps working while the uncertain cases wait for a person. ### When an agent is justified Agents make sense when the path genuinely varies from case to case and enumerating it in advance would be impractical: open-ended research tasks, investigating an incident across several systems, or helping a user complete a goal that could take many different routes. Even then, we constrain them heavily. Our post on [LLM agents in production](https://www.amygdal.com/blog/ai-agents-in-production) covers the guardrails in detail. A useful middle ground is the **constrained agent**: the model chooses among a small set of tools, within a limited number of steps, inside a workflow that fixes the start and end points and requires approval before anything irreversible happens. This captures much of the flexibility of an agent while keeping the system testable. ### Questions to ask before you build 1. Can a domain expert write the steps down? If yes, start with a workflow. 2. Which steps involve unstructured input? Those are candidates for a model. 3. What happens if a step is wrong? The higher the cost of a mistake, the less autonomy you want. 4. Does a human need to approve the outcome? Design that checkpoint in from the start. 5. How will you test it? If you cannot describe a test, you are not ready to automate it. 6. What is the volume? A process run ten times a month may not justify automation at all. Cost deserves a line of its own. A workflow step that calls a model once has a predictable price per run. An agent that loops until it is satisfied can call a model dozens of times for one task, and the number varies. Set budgets and step limits, and track the cost per completed task, not just per call. ### A practical migration path We usually recommend starting at the simplest level and promoting steps only when there is evidence they need it. Map the current process with the people who run it. Automate the deterministic parts first, which often delivers most of the time saving. Add model-powered steps where unstructured input is the bottleneck, with evaluation sets to measure accuracy. Consider an agent only for the parts that remain genuinely open-ended, and keep a human in the loop until the data shows it is safe to step back. This approach also produces a system your team can understand and maintain, which matters more over the years than how impressive the first demo looked. #### Signs you chose too much autonomy - Runs of the same task take very different paths and costs. - Nobody can explain why a particular outcome happened. - Testing relies on watching it work rather than on repeatable cases. - Most of the agent's runs follow the same few steps anyway, which means a workflow would do. ### Automating a process? We build automation at every level, from integrations to AI workflows and constrained agents. Explore our [custom AI development](https://www.amygdal.com/services/custom-ai-development) service, or [talk to us](https://www.amygdal.com/contact) about the process you want to automate. ### FAQ **What is the difference between an AI agent and an AI workflow?** In a workflow, the sequence of steps is fixed in code and a model handles specific steps. In an agent, the model decides which steps to take and in what order. Workflows are more predictable; agents are more flexible. **Do we need an AI agent to automate our business processes?** Usually not. Most business processes can be written down, so a workflow with AI steps where needed is cheaper, faster and easier to test. Agents are best kept for tasks whose path genuinely varies case by case. **How do we keep automated AI decisions safe?** Limit autonomy to what the task needs, add human approval where mistakes are costly, measure accuracy with evaluation sets and log every decision so it can be reviewed later. ## How to Implement AI in Healthcare Safely URL: https://www.amygdal.com/blog/implementing-ai-in-healthcare Published: 2026-03-25 · Category: Healthcare · Tags: Healthcare, AI, Compliance, Product AI in healthcare succeeds on trust, not model size. A practical approach to choosing use cases, protecting data, validating output and fitting AI into clinical workflows. Implementing **AI in healthcare** is less about the model and more about trust. Clinicians need to believe the output, patients need to know their data is safe, and the organisation needs to know it can defend every decision the system influences. A model that scores well in a notebook but does not fit the way a ward, clinic or care team works will be ignored, or worse, relied on when it should not be. This is how we approach healthcare AI projects, from choosing the use case to getting a first version into real use. ### Start with the workflow, not the model The best healthcare AI disappears into an existing workflow. Before choosing a model we map who acts on the output — a nurse, a triage coordinator, a care adviser, a patient — and what decision it changes. That decides almost everything downstream: how fast the result must arrive, how much explanation it needs, where it appears on screen, and what happens if it is wrong. An alert that a clinician cannot trust or act on is worse than no alert at all, because it adds noise to an already crowded day. So we look for use cases where the action is clear and the cost of a mistake is understood: - **Administrative load** — summarising notes, drafting referral letters, coding and categorising documents for review. - **Prioritisation** — flagging records or messages that need attention sooner, with a human making the final call. - **Remote monitoring** — turning device and wearable data into trends and exceptions instead of raw readings. - **Patient-facing guidance** — helping people navigate services, prepare for appointments or stay engaged between visits, within clearly defined limits. - **Search over clinical and operational knowledge** — protocols, policies and guidelines, answered with citations. ### Privacy and accuracy are the product Health data is among the most sensitive and regulated data there is. We design HIPAA- and GDPR-aware from day one: collect the minimum data needed, encrypt it in transit and at rest, keep a full audit trail, and agree where data is processed and stored before a line of code is written. We cover the regulatory side in more depth in our guide to [HIPAA- and GDPR-compliant AI](https://www.amygdal.com/blog/hipaa-gdpr-compliant-ai-healthcare). Accuracy needs the same rigour. Aggregate accuracy hides the cases that matter. We validate against realistic edge cases — rare conditions, incomplete records, unusual phrasing, different patient groups — and report performance for each. For anything that touches clinical decisions we favour explainable outputs and human-in-the-loop review, so a clinician stays in control and can see why the system said what it said. ### Integration is where projects succeed or stall Healthcare software rarely starts from a blank page. AI has to read from and write to electronic health records, scheduling systems, device platforms and messaging tools, often through standards such as HL7 FHIR or vendor APIs with their own constraints. Planning that integration early avoids the common outcome where a useful model sits in a separate tool nobody opens. Scale and reliability matter too. On [A Place For Mom](https://www.amygdal.com/projects/aplaceformom), a US senior-care platform serving 300,000+ customers, we delivered the healthcare service side on Next.js and Node.js with event-driven AWS infrastructure. Platforms like that show how much of healthcare technology is dependable plumbing — queues, retries, monitoring — that any AI feature has to sit on top of. ### What we build Our healthcare work covers remote patient monitoring that connects wearables and devices to records, machine learning that spots patterns across large datasets for earlier detection, telehealth with privacy-compliant video, and wellness apps that keep people engaged between visits. [Ealthiness](https://www.amygdal.com/projects/ealthiness), a mobile health and fitness companion we designed and built end to end, pairs guided exercises, live run tracking and mood and activity insights with the data plumbing behind them — the same foundations that AI-driven insights depend on. ### Integrate, then iterate AI in healthcare earns trust over time. Rather than launching a broad system and hoping, we follow a staged path: 1. **Define the decision and the measure.** Agree what improvement looks like — time saved, response times, missed follow-ups — before building. 2. **Run in shadow mode.** Let the system produce output that clinicians see alongside their normal process but do not act on, and compare. 3. **Launch narrowly.** One team, one pathway, one type of request, with clear escalation routes. 4. **Monitor continuously.** Track quality, overrides and complaints, and review a sample of outputs regularly with clinical staff. 5. **Expand on evidence.** Widen scope only when the data supports it. This is slower than a big-bang launch on paper. In practice it is faster, because it avoids the pilot that never leaves the pilot stage. ### Measuring whether it worked Healthcare organisations are right to be sceptical of AI claims, so measurement has to be built in rather than added at the end. Agree the baseline before launch: how long a task takes today, how many messages wait more than a day, how often follow-ups are missed. Then measure the same things after launch, with the same definitions. Track how often clinicians accept, edit or reject the AI's output, and read the edits — they are the most direct feedback you will get. A high override rate is not necessarily a failure; it may show the system is surfacing cases worth a second look. But a rate that stays high, or overrides concentrated in one patient group or one type of request, tells you where the model or the workflow needs work. Share these results with the clinical team regularly. Trust grows when people can see the evidence, including the parts that are not yet good enough. ### Common mistakes to avoid - Choosing a use case because the technology is interesting rather than because someone needs it. - Treating compliance as a review at the end instead of a design input. - Measuring only overall accuracy and missing failures in specific patient groups. - Leaving no clear owner for the system once the project team moves on. ### Working with Amygdal on healthcare AI We are a software development company that builds healthcare and AI products for clients in the UK, Germany, Switzerland, Qatar and the US. Our [AI in healthcare](https://www.amygdal.com/services/ai-in-healthcare) service covers use-case discovery, compliant architecture, model validation and integration. If you are considering a healthcare AI project, [start with a conversation](https://www.amygdal.com/contact) about the workflow you want to change. ### FAQ **Is AI in healthcare safe and compliant?** It can be, when privacy and validation are designed in from the start. That means minimising and encrypting data, keeping audit trails, validating against edge cases, and keeping a human in the loop for anything clinical. **What healthcare AI use cases are best to start with?** Ones with a clear action and understood risk: reducing administrative work, prioritising messages or records for human review, summarising remote monitoring data, and searching clinical guidance with citations. **How do you start an AI healthcare project?** By mapping the workflow and the decision the AI will change, agreeing how success is measured, then building a narrow first version that runs in shadow mode before going live with one team. ## From MVP to Scale: Building a Product You Won't Rewrite URL: https://www.amygdal.com/blog/mvp-to-scale Published: 2026-03-25 · Category: Product · Tags: MVP, Startups, Product, Architecture An MVP should test your riskiest assumption quickly, but the code that proves the idea should also be the code you grow. Here is how we balance the two. The trick with an MVP is building the smallest thing that proves your idea, without writing code you have to throw away the moment it works. Founders tend to hear two contradictory pieces of advice: move fast and accept mess, or build it properly from day one. Both are partly right, and both fail when applied without judgement. Here is how we approach MVP development at Amygdal: cut scope aggressively, but keep the foundations clean, so that success means adding to the product rather than starting again. ### Start from the riskiest assumption An MVP is not a smaller version of the whole product. It is a test of the thing you are least sure about. For one founder that is whether users will pay; for another, whether a technical approach works at all; for a third, whether two sides of a marketplace will both show up. In discovery we ask founders to rank their assumptions by how fatal they would be if wrong, then design the MVP around the top one or two. Everything that does not help test them goes onto a later list. This is the single most effective way to shorten timelines, and it is a product decision rather than an engineering one. ### Where to cut, and where not to Speed and quality are not opposites if you are clear about which corners are safe to cut. Our rough rule: - **Safe to cut:** admin panels (use the database or a simple internal tool), edge-case settings, multiple pricing tiers, polished onboarding, most integrations, internationalisation, and features for user types you have not yet met. - **Not safe to cut:** a sensible data model, authentication done properly, typed code, automated deployment, basic tests around money and permissions, and analytics. The items in the second list are cheap to do at the start and expensive to retrofit. A bad data model in particular will tax every feature you build afterwards. Skipping them does not make an MVP faster in any meaningful sense; it just moves the cost to the worst possible moment. ### Choose foundations you can grow on We build most MVPs on a stack we know will carry the product well beyond validation: TypeScript across the board, Next.js or React Native for the client, NestJS or a lean Node.js service for the API, and PostgreSQL for data. It is not exotic, and that is the point. Hiring is easier, documentation is plentiful and the path to scale is well understood. We also deploy to managed platforms early. A product that can be deployed in one command from day one keeps the feedback loop short, and it avoids the classic situation where the MVP only runs on a single developer's laptop. ### Instrument from day one An MVP's job is to produce evidence. If you cannot see what users actually do, you have built a demo, not an experiment. Before launch we agree with the founder on the handful of events that matter, such as sign-up, activation, the core action and payment, and wire them into analytics along with error monitoring. That evidence is what tells you whether to double down, pivot or stop, and it is what investors will ask about. Retrofitting analytics after launch means losing the most informative weeks of data you will ever get. ### Scaling the parts that earned it Once traction is real, scaling should be deliberate. We look at where users actually spend time and where the system strains, then invest there first. In practice that tends to mean: 1. Hardening the core flows: error handling, edge cases and performance on real devices and networks. 2. Adding infrastructure as it becomes necessary: caching, background queues, search and observability. 3. Building the admin and support tooling that was skipped, now that you know what operations really need. 4. Expanding the team, with the structure (design system, CI/CD, module boundaries) that lets more people work in parallel. Because the foundations were sound, each of these steps adds to the MVP rather than replacing it. If you have just raised on the back of your MVP, our follow-up post on [scaling an MVP after a seed round](https://www.amygdal.com/blog/scaling-mvp-after-seed) goes into that phase in more depth. ### Working with an outside team on an MVP Many founders build their first version with an external software development company, and that can work very well if a few things are agreed up front. The founder should own the repository, cloud accounts and app store accounts from the first day. Demos of working software should happen every week or two, not just at the end. And the team should write down the main architectural decisions as they make them, so a future in-house engineer can understand why things are the way they are. Equally important is a shared definition of done for the MVP itself: the specific evidence that will count as validation. Without it, MVPs drift into full products, budgets stretch and the original question never gets a clear answer. ### Choosing the right platform for the MVP A common early question is whether to start with web, mobile or both. Our default advice is to start where your riskiest assumption is cheapest to test. For many B2B products that is a web app, which is faster to iterate on and needs no store review. For consumer products built around daily habits, location or the camera, a mobile app may be the only honest test of the idea. Building both from the start roughly doubles the surface you have to maintain while you are still learning what the product is. Where mobile is needed, React Native lets one team cover iOS and Android, and a shared TypeScript codebase means the web app and API can reuse types and validation. That keeps a small team productive without locking you into a platform choice you might regret. ### When a rewrite is actually justified Sometimes the honest answer is that a prototype should be replaced: it was built in a no-code tool that cannot support the product's needs, or the data model encodes an assumption that turned out to be wrong. Even then, we prefer a staged replacement, moving one area at a time behind the same interface, over a big-bang rewrite that freezes product work for months. ### Building your MVP with us We work with founders from first scoping through launch and scale. If you have an idea to validate or an MVP that needs a stronger foundation, have a look at our [custom software development](https://www.amygdal.com/services/custom-software-development) service and [get in touch](https://www.amygdal.com/contact). ### FAQ **How long does it take to build an MVP?** Typically a few weeks to a couple of months, depending on the assumption being tested and the platforms involved. Keeping scope tight is the main lever for keeping timelines short. **Will we have to rebuild the MVP when it grows?** Not if the foundations are sound. Keep the data model, auth, typing and deployment solid while cutting features, and growth becomes additive rather than a rewrite. **What should never be cut from an MVP?** A sensible data model, proper authentication, automated deployment, basic tests around money and permissions, and analytics. They are cheap to do early and expensive to add later. ## Digital Arrow: Building an HR and Recruiting Platform URL: https://www.amygdal.com/blog/digital-arrow-case-study Published: 2026-03-10 · Category: Case study · Tags: NestJS, PostgreSQL, Elasticsearch, Next.js, HR tech One workspace for the hiring lifecycle: CVs, async video interviews, timesheets, contracts and invoices. Here is how the platform is put together. Digital Arrow brings recruiting and HR into one workspace. A company posts a role, builds candidate CVs, runs asynchronous video interviews, and once someone is hired, handles their timesheets, time-off, contracts and client invoices in the same place. Most teams stitch this together from four or five tools; Digital Arrow is the attempt to make it one. We architected and built the platform. This post covers how it is structured and the engineering decisions behind the parts that are harder than they look: search, video, documents and signatures. ### The shape of the platform The backend is **Node.js with NestJS**, backed by **PostgreSQL** through Prisma. The frontend is **Next.js and React** with Tailwind and shadcn/ui. Around that core sit four supporting services, each chosen for one job: - **Elasticsearch** for full-text candidate and CV search. - **MinIO** as S3-compatible object storage for CVs, video answers and generated documents. - **Browserless** for headless-browser PDF generation — CVs, contracts and invoices. - **Redis** for caching, queues and short-lived state. NestJS suits this kind of product because the domain is wide. Jobs, applicants, interviews, timesheets, contracts and invoices are separate modules with their own services and controllers, but they share auth, permissions and a single database. NestJS's module system keeps those boundaries visible without forcing a microservice split the team does not need yet. We wrote more about that pattern in [NestJS, Prisma and PostgreSQL architecture](https://www.amygdal.com/blog/nestjs-prisma-postgresql-architecture). The other early decision was multi-tenancy. Several companies use the same platform, and recruiters, hiring managers, candidates and contractors all see different slices of the same records. Every query is scoped to a company, and role checks live in guards that run before any controller code. Getting that into the foundation in week one is far cheaper than retrofitting it after the first customer asks why they can see someone else's applicant. ### Postgres as the source of truth, Elasticsearch for search Candidate data is relational: a candidate has applications, applications belong to jobs, jobs belong to companies, and permissions follow that chain. That belongs in PostgreSQL. Searching that data the way a recruiter wants to — free text across skills, past roles and CV content, with typos and partial matches — is a different problem, and Postgres full-text search runs out of road quickly. So Postgres stays the source of truth and Elasticsearch holds a denormalised search document per candidate. Writes go to Postgres first; an indexing step updates Elasticsearch after. The rule we hold to is simple: if the two ever disagree, Postgres wins, and the index can be rebuilt from it at any time. Search results return IDs, and the detail view always reads from Postgres, so permissions are enforced in one place. CVs arrive in every format imaginable, so text extraction belongs in a background job rather than inside the upload request. The recruiter sees the upload succeed immediately, and the candidate becomes searchable a moment later. Queueing that work through Redis also gives retries for free when a file is slow or malformed. ### Async video interviews Asynchronous interviews let a recruiter send a set of questions and let candidates record answers when it suits them. It removes scheduling from the first round, which matters when candidates and hiring managers are in different time zones. The engineering work is mostly about the media path. Candidates record in the browser, uploads go directly to object storage rather than through the API server, and the platform keeps metadata — question, attempt, duration, status — in Postgres. Reviewers watch answers in sequence and leave structured feedback. The platform also supports **video requests**, where a recruiter asks for a short follow-up clip outside a formal interview. Video files should never be public. Playback goes through short-lived signed URLs issued by the API after a permission check, so a link copied out of the browser stops working within minutes. Candidates can see what they submitted, reviewers can see what they are assigned, and nobody else can see anything. For a product that stores people's faces and voices, that is the minimum. On top of that sits AI-assisted scoring of interview answers. We treat it as an aid to the reviewer, not a decision-maker: it summarises and highlights, and a person decides. In hiring, that is both the responsible position and, in several of the markets we work in, increasingly a regulatory expectation. ### Documents, PDFs and online signatures HR runs on documents: formatted CVs to send to clients, employment and contractor agreements, invoices. We render these as HTML templates and turn them into PDFs with **Browserless**, a hosted headless Chrome. Using a real browser engine means the same templates and CSS the team already knows produce the PDF, rather than a separate PDF layout language that only one person understands. Contracts add **online signatures**. The signing flow records who signed, when, and against which exact version of the document, and the signed PDF is stored immutably in object storage. Once signed, a document is never regenerated from its template — the template might have changed since. PDF rendering belongs in a queue too. A headless browser is a heavy dependency, and generating a batch of CVs or month-end invoices synchronously would tie up API workers. The better shape is for the API to record a job, a worker to render the document through Browserless and store it, and the user to be notified when it is ready. ### Timesheets, time-off and invoicing After hiring, the platform tracks time. Timesheet entries roll up into invoices for clients, and time-off requests flow through approval. The lesson here is the one every billing system teaches: store the inputs, not just the totals. An invoice keeps a reference to the exact timesheet entries it was built from, so a disputed line can be traced back to the hours behind it. The same thinking applies to time-off. Balances are best calculated from the history of requests and approvals rather than stored as a single number someone can edit, so the answer to "why do I have four days left?" is always a list, not a guess. ### What carried the project 1. One relational source of truth, with search as a rebuildable projection. 2. Media uploaded straight to object storage, never streamed through the API. 3. HTML-to-PDF with a real browser, so documents use the same skills as the rest of the frontend. 4. Signed documents stored as immutable files, separate from their templates. 5. AI that assists reviewers rather than replacing their judgement. ### Planning an HR or workflow platform? Platforms like Digital Arrow are mostly [custom software development](https://www.amygdal.com/services/custom-software-development): a wide domain, several data stores and a lot of document handling. See the [Digital Arrow project page](https://www.amygdal.com/projects/digital-arrow) for more, or [talk to us](https://www.amygdal.com/contact) about yours. ### FAQ **What tech stack does Digital Arrow use?** NestJS on Node.js with PostgreSQL and Prisma, Next.js and React on the frontend, Elasticsearch for search, MinIO for file storage, Browserless for PDF generation and Redis for caching and queues. **Why use Elasticsearch alongside PostgreSQL?** PostgreSQL holds the relational data and permissions. Elasticsearch handles fuzzy, full-text candidate search. The index is a projection that can be rebuilt from Postgres at any time. **Does the AI decide which candidates move forward?** No. AI scoring summarises and highlights interview answers to help reviewers, but a person makes the hiring decision. ## Open-Weight LLMs: When Self-Hosting Makes Sense URL: https://www.amygdal.com/blog/self-hosting-open-weight-llms Published: 2026-03-04 · Category: AI · Tags: LLM, Open source, Infrastructure, Privacy Open-weight models have become good enough for many production tasks. Whether you should run one yourself depends on data, volume and your team. Two years ago the choice was simple: if you wanted a capable language model, you called a commercial API. Today, open-weight models that you can download and run yourself are good enough for a large share of production tasks, from classification and extraction to summarisation and retrieval-augmented answers. That opens a real decision for product teams. Running your own model brings privacy and control, but it also brings infrastructure, monitoring and upgrades that an API provider would otherwise handle. Here is how we think through the trade-off with clients. ### Reasons to self-host - **Data residency and confidentiality.** Sensitive data never leaves infrastructure you control, which simplifies conversations with security teams and regulators, particularly in healthcare, finance and the public sector. - **Predictable cost at volume.** For steady, high-volume workloads, paying for compute can work out cheaper than paying per token. For spiky or low-volume use, it usually does not. - **Control over versions.** The model only changes when you decide to change it, so behaviour stays stable between your own evaluations. - **Customisation.** Open weights can be fine-tuned or adapted for narrow tasks in ways a hosted API may not allow. - **Offline or edge use.** Some products need inference where there is no reliable connection. There is also a softer benefit: independence from a single vendor's roadmap. Hosted models are retired, repriced and changed on the provider's schedule. An open model you run yourself stays available for as long as you need it, which matters for products with long support commitments or regulated validation processes. ### Reasons not to The strongest hosted models are still ahead on the hardest reasoning tasks. If your feature needs that level of capability, a smaller open model will disappoint. Self-hosting also means you now operate GPU infrastructure: capacity planning, autoscaling, cold starts, driver and runtime updates, security patching and on-call. For a small team with modest volume, that operational load often outweighs the benefits. Be realistic about the total cost too. A comparison that sets per-token prices against the hourly price of a GPU leaves out engineering time, idle capacity outside peak hours, redundancy for failover and the cost of keeping up with new model releases. Model the whole picture across a year before deciding. ### A hybrid is often the answer Most of the systems we build do not choose one side. They route each task to the most appropriate model: 1. A small self-hosted model handles high-volume, low-complexity work such as tagging, routing and embedding. 2. Sensitive steps, such as processing personal data, run on infrastructure you control. 3. Hard, low-volume reasoning tasks go to a hosted frontier model, with personal data removed first where possible. 4. A common interface sits in front of all of them, so switching a task between models is a configuration change. Our [Sumus](https://www.amygdal.com/projects/sumus) work is an example of mixing providers: the AI product-discovery engine we built uses both Ollama and OpenAI. On [Dorfleben](https://www.amygdal.com/projects/dorfleben), a community platform for German towns, AI-powered search and recommendations draw on Weaviate, SageMaker and Ollama. The routing logic itself should be simple and visible. A configuration file that says which task goes to which model, with a fallback for each, is easier to reason about than clever dynamic routing. It also makes cost reports straightforward, because each task's spend can be attributed to a specific model. ### What running a model really involves Downloading a model and running it on a laptop takes minutes. Running it reliably for users takes more: - **Serving** with a runtime suited to production traffic, with batching and streaming. - **Hardware sizing** based on model size, quantisation, context length and concurrent users. - **Autoscaling and queuing** so traffic spikes degrade gracefully instead of timing out. - **Monitoring** of latency, throughput, error rates and output quality, not just whether the server is up. - **An evaluation set** rerun before every model upgrade, as with any AI feature. - **Security**: network isolation, access control and logging that respects data protection rules. #### Smaller models, sharper tasks One reason self-hosting has become practical is that many production tasks do not need a very large model. A smaller model, sometimes fine-tuned on a few thousand examples from your own domain, can match a much larger general model on a narrow task such as classifying support tickets or extracting fields from invoices. It is also faster and cheaper to serve. The evaluation set decides whether that holds for your case; assumptions do not. Embedding models are an especially good candidate. They are small, run efficiently on modest hardware, and are called very often in search and retrieval systems, so moving them in-house can reduce both cost and data exposure. Plan the upgrade path from the start. New open models appear frequently, and moving to a better one should be a matter of running the evaluation set, comparing results and switching configuration, not a re-architecture. Keep the serving layer generic enough that a different model family can be dropped in, and keep the previous model available for a quick rollback. ### Licences matter Open-weight does not always mean open-source in the traditional sense. Model licences vary: some are permissive, others restrict commercial use, user numbers or particular applications. Read the licence for the exact model version you plan to deploy, and record it alongside the model in your inventory. Keep the licence check repeatable. When you upgrade to a newer version of the same model family, the terms may have changed, so treat a licence review as part of every model upgrade rather than a one-off task. ### A simple way to decide Start with a hosted API to prove the feature is worth building. Build your evaluation set while you do. Once you know the task, the volume and the quality bar, test one or two open models against that set. If they meet the bar and the privacy or cost case is real, move that task in-house. If not, you have lost very little. We go deeper into the build-or-buy side of this in [custom AI development vs off-the-shelf tools](https://www.amygdal.com/blog/custom-ai-development). ### Talk to us We design AI systems that use hosted and self-hosted models where each makes sense. See our [custom AI development](https://www.amygdal.com/services/custom-ai-development) service or [contact us](https://www.amygdal.com/contact) to discuss your requirements. ### FAQ **Is a self-hosted LLM cheaper than an API?** Sometimes. For steady, high-volume workloads, compute can cost less than per-token pricing. For low or spiky volume, hosted APIs are usually cheaper once you include infrastructure and engineering time. **Are open-weight models good enough for production?** For many tasks, yes, including classification, extraction, summarisation and retrieval-based answers. The strongest hosted models still lead on complex reasoning, so test candidates against your own evaluation set. **Can we use open-weight models commercially?** Often, but licences differ. Some are permissive, others limit commercial use or scale. Check the licence of the specific model version you deploy and keep a record of it. ## Custom AI Development vs Off-the-Shelf AI Tools URL: https://www.amygdal.com/blog/custom-ai-development Published: 2026-02-18 · Category: AI · Tags: Custom AI, Strategy, MLOps, Proof of concept Off-the-shelf AI tools solve common problems well. Custom AI earns its cost when the value sits in your data, your workflow or your product. Here is how to tell the difference. Most organisations now have access to capable AI through tools they already pay for: chat assistants, AI features inside their CRM, transcription in their meeting software. So the question we hear most often is not whether to use AI, but whether to build something of their own or keep buying. The honest answer is that off-the-shelf tools are the right choice more often than vendors of **custom AI development** like to admit. But there is a clear set of situations where building pays off, and a reliable way to run the project when it does. ### When off-the-shelf AI is enough Buy when the problem is generic and the tool already fits the way people work. Drafting emails, summarising meetings, general research, translating internal documents, or answering questions over a small, shared folder — these are well served by existing products. They are cheaper to start, someone else maintains them, and you can switch later. The warning signs that you are outgrowing a tool are usually practical: people copy data in and out of it by hand, it cannot see the systems that hold the real answer, its output needs heavy correction, or your compliance team cannot sign off on where the data goes. ### When custom AI development is worth it - **The value is in your data.** Your records, documents, transactions or sensor history are what make the answer useful, and no generic product has access to them in the right shape. - **AI is part of your product.** If customers will use the feature, you need control over its behaviour, latency, cost, branding and roadmap. - **The workflow is specific.** The AI must act inside your systems — create the ticket, update the record, route the case — not just produce text. - **Regulation or data residency rules out SaaS.** Healthcare, finance and public-sector clients often need data to stay in a specific region or on their own infrastructure. - **Unit costs matter at scale.** A per-seat tool can become more expensive than a tailored system once usage grows. A useful example is [Sumus](https://www.amygdal.com/projects/sumus), an AI product-discovery engine for fashion. A shopper scans a garment and sees its ESG footprint, then compares sustainability across brands. No off-the-shelf tool does that; the AI is the product. We built the scanning and recognition pipeline, the ESG scoring engine and the brand-comparison layer. ### How a custom AI project runs Custom AI projects fail most often between a promising demo and a dependable system. We structure the work to surface the hard problems early, in four stages. #### 1. Discovery We map the decision or task the AI will change, who acts on the output, and what good looks like. We look at the actual data — its quality, volume, access rules and gaps — and collect real examples that become the evaluation set. Discovery ends with a clear statement of the riskiest assumption and a recommendation, which sometimes is to buy a tool instead. #### 2. Proof of concept A proof of concept tests that riskiest assumption against real data, not a curated sample. Can the model extract the fields accurately enough? Does retrieval find the right passage? Is latency acceptable? The output is evidence and an estimate, not a polished UI. It should take weeks, not months. #### 3. Production build This is mostly software engineering: data pipelines, APIs, authentication and permissions, a usable interface, error handling, guardrails, logging and tests. It is also where integration happens — connecting to the CRM, ERP, document store or mobile app the users already have. Teams that treat AI as a model problem tend to underestimate this stage. #### 4. MLOps and iteration Once live, the system needs monitoring for quality, cost and drift; a regression suite that runs whenever prompts, models or data change; a way for users to flag bad output; and a clear owner. Model providers update and deprecate models regularly, so plan for that from the start. ### What custom AI costs to run The build is only part of the cost. A custom AI system has running costs that off-the-shelf tools hide inside a subscription: model usage billed per token or per request, hosting for vector stores and pipelines, monitoring, and the engineering time to keep everything current as models and data change. None of these are reasons not to build, but they should be estimated during discovery, alongside the expected benefit. A useful habit is to model cost per completed task — per document processed, per question answered, per case routed — and compare it with the current manual cost and with the per-seat price of the alternative tool. That comparison often settles the build-versus-buy question more clearly than any feature list. It also gives the team a number to watch after launch, so cost increases from heavier usage or a model change are noticed early rather than at the end of the quarter. ### Questions to ask before you commit 1. What specific decision or task changes, and how will we measure whether it improved? 2. Do we have the data, and the right to use it for this purpose? 3. What happens when the AI is wrong, and who catches it? 4. Where must the data and the model run, legally and contractually? 5. Who will own and maintain the system after launch? If you cannot answer the first question, it is too early to build. If you can answer all five, a focused proof of concept is usually the right next step. ### Hybrid is often the right answer Build versus buy is rarely all or nothing. Most custom AI systems we ship use hosted models from major providers or open models for the heavy lifting, and put the custom work where it matters: data pipelines, retrieval, workflow integration, evaluation and the user experience. For document-heavy problems, a well-engineered [RAG system](https://www.amygdal.com/blog/rag-development-guide) is frequently the core of the solution. ### Working with Amygdal Amygdal is an AI development company with offices in Delaware, Sarajevo and Doha, working with clients in the UK, Germany, Switzerland and Qatar. Our [custom AI development](https://www.amygdal.com/services/custom-ai-development) service runs from discovery through production and ongoing operation, built on the same engineering practice as our [custom software development](https://www.amygdal.com/services/custom-software-development) work. If you are deciding whether to build, [talk to us](https://www.amygdal.com/contact) — we will tell you if a tool you already own would do the job. ### FAQ **How long does a custom AI project take?** Discovery and a proof of concept typically take a few weeks. A production build depends on integrations and scope; most of the effort goes into data pipelines, integration and evaluation rather than the model itself. **Do we need our own model for custom AI development?** Rarely. Most custom AI systems use existing hosted or open models and put the custom work into data, retrieval, workflow integration and evaluation. Training or fine-tuning is reserved for cases where it measurably helps. **What is MLOps and why does it matter after launch?** MLOps is the practice of monitoring, testing and updating AI systems in production. It catches quality drift, controls cost and makes model upgrades safe, so the system stays reliable rather than degrading quietly. ## How to Scale a Node.js Application Without a Rewrite URL: https://www.amygdal.com/blog/scaling-nodejs-applications Published: 2026-02-18 · Category: Engineering · Tags: Node.js, Backend, Scalability, Redis, PostgreSQL Most Node.js scaling problems are not Node problems. Here is the order we work through when an API starts slowing down under real traffic. Node.js scales well when you respect its strengths and avoid its traps. It is excellent at I/O-heavy, high-concurrency workloads, which describes most web APIs. It is poor at long CPU-bound work on the main thread. Nearly every scaling problem we are asked to fix comes back to one of a handful of causes, and very few of them are solved by simply buying a bigger server. This is the order we work through when a Node.js backend starts struggling, drawn from projects ranging from early-stage products to high-traffic platforms such as [A Place For Mom](https://www.amygdal.com/projects/aplaceformom), where we built on Node.js with event-driven AWS infrastructure (Lambda, SQS, SNS) for a service used by more than 300,000 customers. ### 1. Measure before you change anything You cannot scale what you cannot see. Before touching code, we make sure the service has structured logs, request metrics (latency percentiles, not just averages), distributed tracing across services and the database, and event loop lag monitoring. With that in place, the bottleneck usually announces itself. A realistic load test against a staging environment then tells you where it breaks and at roughly what level of traffic. That is far cheaper than finding out in production. ### 2. Keep the event loop free Node runs your JavaScript on a single thread. If one request spends 300 milliseconds parsing a huge JSON payload, resizing an image or generating a PDF, every other request waits. Common culprits are synchronous crypto, large JSON serialisation, regex on untrusted input and in-process report generation. - Move CPU-heavy work to **worker threads** or, better, to a **background queue** processed by separate workers. - **Stream** large files and responses instead of buffering them in memory. - Paginate everything that can grow, so no endpoint ever returns an unbounded result. - Watch event loop lag as a first-class metric and alert on it. ### 3. Run stateless and scale horizontally Once the event loop is healthy, a Node.js API should be stateless: no sessions in memory, no files written to local disk, no in-process caches that must stay consistent across instances. Sessions go to Redis or signed tokens, uploads go to object storage such as S3 or MinIO, and shared state lives in the database. Stateless services scale by adding instances behind a load balancer, whether that means more containers, more pods or a managed platform scaling on CPU and request count. This is the simplest, most reliable form of scaling, and it only works if the earlier steps are done. ### 4. Cache deliberately The fastest request is one that never reaches your database. We layer caching from the outside in: HTTP caching and a CDN for public responses, **Redis** for hot data and computed results, and occasionally a short-lived in-memory cache for values that are safe to be slightly stale. The hard part is invalidation. We prefer explicit cache keys tied to the entity that changed, short TTLs where correctness allows, and avoiding caches entirely for data that must always be fresh, such as balances or permissions. ```ts async function getProfile(id: string) { const key = `profile:${id}`; const cached = await redis.get(key); if (cached) return JSON.parse(cached); const profile = await db.profile.findUnique({ where: { id } }); await redis.set(key, JSON.stringify(profile), "EX", 300); return profile; } // On update: write to the database, then delete the key. await redis.del(`profile:${id}`); ``` ### 5. The database is usually the real bottleneck Most 'Node does not scale' complaints turn out to be database problems. The usual fixes, roughly in order of effort: 1. **Add the missing indexes** for the queries you actually run, confirmed with the query plan. 2. **Remove N+1 queries**, which ORMs make easy to write by accident. 3. **Use connection pooling** sized to the database, not to the number of Node instances multiplied by an arbitrary default. 4. **Move slow or non-urgent work off the request path** into queues: emails, exports, webhooks, search indexing and AI calls. 5. **Add read replicas** for read-heavy workloads once the above is done. 6. **Revisit the data model** only when access patterns have clearly outgrown it. ### Event-driven work at higher scale As traffic grows, more of the system benefits from being asynchronous. Instead of one request doing five things in sequence, the API records what happened and publishes an event; independent consumers send the email, update the search index, notify a partner system and refresh analytics. Each consumer can scale, fail and retry on its own without slowing the user's request. On AWS this is often SQS and SNS with Lambda or container workers, which is the pattern used on A Place For Mom. On smaller stacks, Redis-backed queues give most of the same benefit with less infrastructure. The important design rules are the same either way: make consumers idempotent, keep messages small and versioned, and monitor queue depth so a backlog is noticed before users feel it. ### 6. Split services only when there is a reason Microservices are an organisational tool as much as a technical one. A well-structured modular monolith, for example a NestJS application with clear module boundaries, will carry most products a long way. We extract a service when a part of the system has genuinely different scaling, deployment or ownership needs, such as a media pipeline or a search indexer, not because the architecture diagram looks more impressive. We describe this structure in more detail in our post on [NestJS, Prisma and PostgreSQL architecture](https://www.amygdal.com/blog/nestjs-prisma-postgresql-architecture). ### A scaling checklist before launch If you are preparing for a launch, a marketing push or an investor demo, this short list catches most of the problems we see in production: - Event loop lag, p95 latency and error rate are on a dashboard someone actually looks at. - Every list endpoint is paginated and every query behind it has an index. - Emails, exports, webhooks and third-party calls run in a queue, with retries and a dead-letter view. - The API is stateless and can run as two or more instances without code changes. - Timeouts are set on every outbound HTTP call, so a slow partner API cannot exhaust your connections. - A load test has been run against staging at a multiple of expected peak traffic. None of these items is difficult on its own. The value is in doing all of them before traffic arrives, rather than discovering the missing one during an incident. ### Getting help scaling your backend If your Node.js API is slowing down, or you want it reviewed before a launch or funding round, we can run a focused performance and architecture review and then fix what we find. See our [software development](https://www.amygdal.com/services/software-development) service or [contact us](https://www.amygdal.com/contact) to talk it through. ### FAQ **Can Node.js handle high traffic?** Yes. Node is well suited to I/O-heavy, high-concurrency workloads. Scaling comes from running it stateless and horizontally, caching sensibly, keeping CPU work off the event loop and tuning the database. **What is the most common Node.js scaling mistake?** Blocking the event loop with CPU-heavy work, and treating the database as an afterthought. Move heavy and asynchronous work to queues and design the data layer for your real access patterns. **Do we need microservices to scale Node.js?** Usually not. A modular monolith scales horizontally very well. Extract services only when a component has clearly different scaling, deployment or ownership needs. ## AI Coding Assistants in a Delivery Team: An Honest View URL: https://www.amygdal.com/blog/ai-coding-assistants-in-delivery-teams Published: 2026-02-04 · Category: Engineering · Tags: AI, Developer productivity, Code quality, Process AI tools write a lot of code now. Whether that makes a team faster depends on review, tests and how clearly the work was defined in the first place. Every few months a new tool is introduced as the thing that will replace software engineers. The demos are impressive: a ticket goes in, a pull request comes out. Clients reasonably ask whether this means software should now cost a fraction of what it did, and whether they need an engineering team at all. We use AI assistants every day at Amygdal, so our answer comes from practice rather than from a press release. They have changed how we work. They have not removed the need for engineers who understand the system, and in some situations they make that understanding more important, not less. ### Where assistants genuinely save time - **Boilerplate and scaffolding**: endpoints, forms, data mappers, migrations and tests that follow an established pattern in the codebase. - **Reading unfamiliar code**: summarising a module or explaining a library faster than searching documentation. - **Small, well-specified changes**: renaming across files, adding a field end to end, updating call sites after an API change. - **Test drafting**: proposing cases, including edge cases, that an engineer then reviews and trims. - **First drafts of scripts and one-off tools** where the stakes are low and the output is easy to check. In these areas, a competent engineer with a good assistant moves noticeably faster. The common thread is that the task is clear and the result is easy to verify. The productivity gain is real but uneven. Experienced engineers working in a codebase they know benefit most, because they can judge output instantly. Engineers new to a codebase benefit less, because they cannot yet tell good suggestions from plausible ones. ### Where they cost time instead The picture changes when the work is ambiguous or the consequences are subtle. Assistants produce code that looks finished. If nobody fully understands it, the cost shows up later as bugs, inconsistent patterns and duplicated logic. - **Architecture and data modelling**, where the right answer depends on context the model does not have. - **Concurrency, transactions and security**, where plausible code can be dangerously wrong. - **Large autonomous changes** that touch many files at once and are hard to review properly. - **Vague tickets.** An agent given an unclear task will confidently build the wrong thing. There is also a quieter cost. When an assistant writes a function that already exists elsewhere in the codebase, slightly differently, the codebase grows two ways of doing the same thing. Over months that inconsistency makes every later change slower. Good review catches it; rushed review lets it accumulate. ### Autonomous agents: useful, with supervision Agentic tools that plan, edit files, run tests and iterate are a real step forward. We use them for well-bounded tasks inside a branch, with a test suite that tells them when they are wrong. We do not hand them open-ended features and merge the result. The quality of what an agent produces tracks closely with the quality of the tests and specification it is given, which is an argument for investing in both. #### Making the codebase agent-friendly The same things that help a new engineer help an AI tool: clear module boundaries, consistent naming, typed interfaces, a fast test suite and a short document describing conventions. We now treat a concise contributor guide in each repository as part of the deliverable, because both humans and assistants read it. Teams that invest here find that generated code fits in with far less correction. A fast feedback loop matters just as much. If tests take twenty minutes, an agent iterating against them is slow and expensive; if they take one minute, it can try, fail and fix several times while the engineer reviews something else. ### Review is now the bottleneck When code is cheap to write, reading it carefully becomes the scarce skill. Our working rules reflect that: 1. The engineer who opens a pull request owns every line in it, whoever or whatever typed it. 2. Pull requests stay small enough to review properly, even if an assistant could produce more. 3. Generated code must follow the existing conventions of the codebase, not whatever the model prefers. 4. Tests are required, and a human checks that they test meaningful behaviour rather than the implementation. 5. Secrets, customer data and confidential code go only to tools approved for them. We also keep a clear line on data. Client code and data are only used with tools whose terms the client has agreed to, and some clients require that no external AI tool sees their repository at all. In those cases we either work without assistants or use a model hosted inside the client's environment. That decision is made at the start of a project, not discovered halfway through. ### What this means for buying software AI assistance does reduce the time spent typing code, and good teams pass some of that saving on. But typing was never most of the cost of software. Understanding the problem, making good design decisions, integrating with real systems, testing and running the product in production still take experienced people. Be wary of proposals that promise a complete product in days because an AI will write it; ask who will review, test and maintain it. Our [custom software development guide](https://www.amygdal.com/blog/custom-software-development-guide) covers the questions worth asking any partner. #### How we measure the effect We judge AI tooling by delivery outcomes rather than lines of code: cycle time from ticket to production, defect rates after release, time spent in review and how often work is reopened. Lines of code produced is a misleading measure; an assistant can raise it while making the product worse. When a tool improves the outcomes, we keep it. When it only increases output, we look harder at how it is being used. ### Skills that matter more now The engineers who get the most from these tools are the ones who were already good: they write clear specifications, design clean boundaries, think in tests and read code critically. Junior engineers benefit too, but only with strong review, otherwise they learn to accept output they cannot explain. ### Working with us Our teams use AI tooling where it helps and keep experienced engineers accountable for every change. Learn more about our [software development](https://www.amygdal.com/services/software-development) service, or [get in touch](https://www.amygdal.com/contact) to discuss a project. ### FAQ **Can an AI agent build a complete application on its own?** It can build a prototype. A production application needs design decisions, integrations, security review, testing and ongoing maintenance that still require experienced engineers who understand the whole system. **Do AI coding assistants make software cheaper?** They reduce the time spent writing routine code, which lowers some costs. Most of the cost of software is in understanding requirements, design, integration, testing and operations, which AI speeds up far less. **Is AI-generated code safe to use in production?** Only after the same review and testing as any other code. The risk is not the source of the code but code that nobody understands. Keep pull requests small and make an engineer accountable for every line. ## Next.js for Enterprise Web Development: A Practical Guide URL: https://www.amygdal.com/blog/nextjs-enterprise-web-development Published: 2026-01-27 · Category: Engineering · Tags: Next.js, React, i18n, SEO, Performance Rendering choices, multi-country i18n with Arabic RTL, SEO, performance and auth — how we approach Next.js for enterprise sites. Next.js has become a default choice for enterprise web development, and for good reason: it lets one React codebase serve static marketing pages, personalised dashboards and API routes, with control over how each page is rendered. But the defaults only get you so far. Enterprise sites serving several countries have to get rendering, internationalisation, SEO, performance and authentication right together. We build Next.js sites and applications for clients across the UK, the DACH region and the Gulf, and this guide covers the decisions that matter most in that context. ### Choose rendering per route, not per project With the App Router, rendering is decided per route and even per component. The useful question is not "SSR or static?" but "how fresh does this page need to be, and is it the same for everyone?" - **Static generation** for marketing, product and content pages that are the same for every visitor. Fast, cheap, and easy to cache at the edge. - **Incremental or on-demand revalidation** for content from a CMS that changes a few times a day. Rebuild the page when the content changes, not on every request. - **Dynamic rendering** for pages that depend on the user or the request — account areas, pricing that varies by contract, search results. - **Client components** only where interaction requires them. Server components by default keep JavaScript bundles small. Getting this wrong is expensive in both directions: dynamic rendering for pages that never change wastes server time, and static pages for personalised content leak data or show stale prices. Write the decision down. A short table in the repository listing each route group, its rendering mode, its revalidation trigger and who owns the content saves a surprising number of arguments later, and makes caching bugs much easier to reason about when they happen. ### Internationalisation for UK, DACH and the Gulf Multi-country sites are rarely just translation. British English, German, Swiss German conventions and Arabic differ in currency, dates, legal pages and sometimes in what you can say about a product. We structure routes with a locale segment, keep translations in typed message files, and treat locale as data the whole app can read. Arabic adds **right-to-left layout**. Setting the dir attribute on the html element is the start, not the end. Use CSS logical properties (margin-inline-start rather than margin-left) everywhere so layouts mirror automatically, check icons that imply direction, and test real Arabic content — it is often longer or shorter than the English source and breaks layouts in different places. Font choice matters too; pick an Arabic typeface designed to sit alongside your Latin one. Decide early how locales map to URLs. Path prefixes such as /en-gb, /de-ch and /ar on one domain are simplest to operate and share authority across markets; country domains suit organisations with separate legal entities or brands per market. Either works, but changing it after launch means redirects for every page. And do not auto-redirect visitors purely by IP address — offer a suggestion instead, so search engine crawlers and travelling users can still reach every version. ```tsx export default async function LocaleLayout({ children, params }) { const { locale } = await params; const dir = locale === "ar" ? "rtl" : "ltr"; return ( {children} ); } ``` ### SEO across countries Search engines need to understand which page serves which market. The essentials for a multi-country Next.js site: 1. **hreflang alternates** on every localised page, including an x-default, generated from the same route config as the pages themselves. 2. **Canonical URLs** that point to the page's own locale, never to the English version. 3. **Localised metadata** — titles and descriptions written for each market, not machine-translated afterthoughts. 4. **Per-locale sitemaps** generated at build time from the route list. 5. **Structured data** (Organization, Article, FAQPage) rendered on the server so it is present in the initial HTML. Next.js's Metadata API makes most of this declarative, which is the main reason to use it over hand-written head tags: one source of truth, generated per locale. For the German-speaking market in particular, check legal requirements alongside SEO: an Impressum, a privacy policy that reflects the actual tracking on the page, and a consent banner that genuinely blocks analytics until the visitor agrees. These are content and engineering problems at the same time, and they are easier to build in than to bolt on. ### Performance as a budget, not a phase Core Web Vitals affect both rankings and conversion, and enterprise sites tend to lose performance gradually — one tag manager script, one carousel, one oversized hero image at a time. We set budgets early and check them in CI. - Use next/image with explicit sizes, and serve AVIF or WebP. - Self-host fonts with next/font to avoid layout shift and extra connections. - Load third-party scripts with the right strategy, and question every one of them. - Keep client components small; move data fetching to the server. - Cache at the edge for global audiences — a visitor in Doha should not wait on a server in Frankfurt for a static page. ### Authentication and access Enterprise sites usually need single sign-on: Microsoft Entra ID, Okta or another OIDC provider for staff, and often a separate identity flow for customers. Auth.js (NextAuth) covers most providers. Whatever library you choose, the rules are the same: keep sessions in secure, HTTP-only cookies, check authorisation on the server in every route handler and server action — not only in middleware — and never rely on hiding a link as access control. Separate the public site from the authenticated application where it makes sense. Marketing pages benefit from aggressive caching; account pages must never be cached for the wrong user. Keeping them in distinct route groups, with caching headers set deliberately for each, prevents the worst class of enterprise web bug: one customer seeing another customer's data. For larger systems, Next.js often sits in front of a dedicated backend. We frequently pair it with NestJS, which we describe in [NestJS, Prisma and PostgreSQL architecture](https://www.amygdal.com/blog/nestjs-prisma-postgresql-architecture). Next.js handles rendering and the user session; the backend owns business rules and data. ### Need an enterprise Next.js build? As a software development company working across the UK, Germany, Switzerland and Qatar, we build multilingual Next.js platforms with these foundations from the start. See our [web development](https://www.amygdal.com/services/web-development) service, our [custom software development guide](https://www.amygdal.com/blog/custom-software-development-guide), or [contact us](https://www.amygdal.com/contact). ### FAQ **Is Next.js a good choice for enterprise websites?** Yes. It supports static, revalidated and dynamic rendering per route, has built-in metadata and image optimisation, and scales from marketing sites to authenticated applications in one codebase. **How do you support Arabic RTL in Next.js?** Set lang and dir on the html element per locale, use CSS logical properties so layouts mirror automatically, check directional icons, choose a suitable Arabic font and test with real Arabic content. **How should hreflang be handled on a multi-country Next.js site?** Generate hreflang alternates and canonicals from the same route configuration as the pages, include an x-default, and publish per-locale sitemaps so search engines can map each page to its market. ## RAG Development: Building Retrieval That Holds Up in Production URL: https://www.amygdal.com/blog/rag-development-guide Published: 2026-01-14 · Category: AI · Tags: RAG, LLM, Search, Evaluation Retrieval-augmented generation is easy to demo and hard to run. Here is how we design RAG systems that stay accurate, secure and affordable once real users arrive. Retrieval-augmented generation (RAG) is the most common way to make a large language model answer questions about your own documents, tickets, contracts or product data. The idea is simple: find the relevant passages, put them in the prompt, and ask the model to answer from them. A working prototype takes an afternoon. Getting the same system to answer correctly for thousands of users, over messy data, with permissions and a budget, is a different job. This guide covers the decisions that matter in **RAG development** once you move past the demo — the same checklist we work through on client projects. ### Start with the questions, not the vector database Before choosing a model or a store, collect 50–100 real questions your users ask, along with where the answer lives. This set becomes your evaluation baseline, and it tells you a lot about the shape of the problem. Are questions mostly factual lookups, comparisons across documents, or summaries? Do they reference product codes and IDs that semantic search handles badly? Are some documents confidential to certain teams? Each answer changes the architecture. ### Chunking: where most quality problems begin Chunking decides what the retriever can find. Fixed-size chunks of a few hundred tokens are a fine starting point, but they break tables, split procedures in half and strip away the heading that gave a paragraph its meaning. In practice we: - **Chunk along document structure** — headings, sections, list items, table rows — and fall back to size limits only when a section is too long. - **Carry context into every chunk**: document title, section path, date and source system, so a chunk still makes sense on its own. - **Use modest overlap** between neighbouring chunks so a sentence that straddles a boundary is not lost. - **Treat tables and PDFs as a separate parsing problem.** Poor extraction upstream cannot be fixed by a better model downstream. ### Embeddings and hybrid search Dense embeddings are good at meaning and bad at exact strings. A user searching for an error code, a SKU or a clause number needs keyword matching. That is why most production RAG systems we build use **hybrid search**: a vector index for semantic similarity plus a lexical index (BM25 or similar) for exact terms, with results merged by a method such as reciprocal rank fusion. Pick an embedding model that handles the languages you actually have — for clients across Germany, Switzerland and Qatar that often means German, French and Arabic alongside English — and version it. Changing the embedding model means re-embedding the corpus, so record which model produced each vector. On [Dorfleben](https://www.amygdal.com/projects/dorfleben), a community platform for towns across Germany, AI-powered search and recommendations ran on Weaviate with models served through SageMaker and Ollama, which is a good example of matching the retrieval stack to the content and language of the users. ### Reranking and the context window Retrieval should cast a wide net — say the top 30–50 candidates — and a reranker should choose the handful that go into the prompt. Cross-encoder rerankers read the question and the passage together, so they are much better at judging relevance than embedding similarity alone. Sending fewer, better passages to the model reduces cost, latency and the chance of the model latching onto an irrelevant one. ```typescript async function retrieve(query: string, user: User) { const filter = { tenantId: user.tenantId, groups: user.groups }; const [semantic, keyword] = await Promise.all([ vectorIndex.search(await embed(query), { topK: 40, filter }), keywordIndex.search(query, { topK: 40, filter }), ]); const candidates = reciprocalRankFusion([semantic, keyword]); const ranked = await rerank(query, candidates); return ranked.slice(0, 6); // only the best passages reach the prompt } ``` Note that the permission filter is applied inside both searches, not after. That detail matters more than any model choice. ### Access control, citations and refusals A RAG system must never retrieve a document the user could not open themselves. Store access metadata with every chunk, sync it from the source system, and filter at query time. Post-filtering the answer is too late: the model has already read the restricted text. Every answer should cite its sources with links back to the original document and section. Citations let users verify, let your team debug, and give the model a reason to stay grounded. Equally important is a clear instruction — and a tested behaviour — for saying “I could not find this” when retrieval comes back empty or weak. A confident wrong answer does far more damage than an honest gap. ### Evaluation: measure retrieval and generation separately When a RAG answer is wrong, the cause is usually retrieval: the right passage never reached the model. So evaluate the two stages separately: 1. **Retrieval quality** — for each question in your test set, did the expected source appear in the top results? Track recall and rank. 2. **Answer faithfulness** — is every claim in the answer supported by the retrieved passages? 3. **Answer usefulness** — does it actually address the question? Use human review on a sample, supported by an LLM judge for scale. 4. **Regression runs** — re-run the suite on every change to chunking, prompts, models or data pipelines, and block releases that make it worse. Log real queries in production (with appropriate privacy controls), sample the failures each week and add them to the test set. The evaluation set should grow with the product. ### Keeping the index fresh Stale data is a quiet failure mode. If a policy changes and the old version stays in the index, the system will cite it with confidence. Connect ingestion to the source systems through change events or scheduled syncs, delete chunks when documents are removed or permissions change, and show the last-updated date next to each citation so users can judge for themselves. Monitor ingestion like any other pipeline: failed documents, parsing errors and sync lag should raise alerts, not wait for a user complaint. ### Keeping cost and latency under control RAG costs come from embedding, storage, reranking and generation. The levers are practical: cache embeddings and frequent answers, keep prompts short by sending fewer, better chunks, route simple questions to a smaller model, and stream responses so users see progress. Incremental indexing — only re-embedding documents that changed — keeps ingestion cheap as the corpus grows. For sensitive data, self-hosted open models (we have used Ollama in production work, for example on [Sumus](https://www.amygdal.com/projects/sumus)) can keep inference inside your own infrastructure. ### Building RAG with Amygdal We are a software development company that builds AI into real products for clients in the UK, Germany, Switzerland and Qatar. Our [RAG development](https://www.amygdal.com/services/rag-development) work covers ingestion pipelines, hybrid retrieval, evaluation suites, permissions and the operations around them. If you are weighing whether RAG or a broader [custom AI development](https://www.amygdal.com/blog/custom-ai-development) project fits your problem, [get in touch](https://www.amygdal.com/contact) and we will look at your data and questions with you. ### FAQ **What is RAG development?** RAG development is the engineering of systems that retrieve relevant passages from your own data and give them to a language model to answer from. It covers parsing, chunking, embeddings, search, reranking, prompting, permissions and evaluation. **Is RAG better than fine-tuning a model?** For answering questions about documents that change, usually yes. RAG keeps knowledge in a searchable index you can update and cite. Fine-tuning is better for teaching style, format or a narrow task, and the two can be combined. **How do you stop a RAG system leaking confidential documents?** Store access metadata with every chunk, sync it from the source system, and filter inside the search query itself so restricted text never reaches the model. Then test it with users who have different permissions. ## Building Great React Native Apps with Expo in 2026 URL: https://www.amygdal.com/blog/building-great-react-native-apps Published: 2026-01-14 · Category: Mobile · Tags: React Native, Expo, Mobile, Performance React Native with Expo is a sensible default for most mobile products in 2026. Here is how we structure, optimise and ship apps that feel native on iOS and Android. React Native lets one team ship a single codebase to iOS and Android without the app feeling like a compromise, provided it is built with care. In 2026 the combination of React Native and **Expo** is, for most products we see, the sensible default: the tooling is mature, the native layer is accessible when you need it, and over-the-air updates make iteration fast. This post describes how we approach React Native work at Amygdal: the architecture we start with, where performance actually goes wrong, how we handle unreliable networks, and the release process that keeps apps stable after launch. It is the longer version of an answer we give often in discovery calls. ### Why Expo is the default now A few years ago, teams treated Expo as a starter kit to be ejected from later. That is no longer how it works. With development builds, config plugins and EAS for building and submitting, you can keep the managed workflow and still add custom native modules. You get a consistent build pipeline, predictable upgrades and a much shorter path from a pull request to an installable build on a tester's phone. Our [Ealthiness](https://www.amygdal.com/projects/ealthiness) app, an AI health companion with workouts, run tracking, mood and sleep logs and an AI trainer, is built on React Native and Expo with a NestJS, MongoDB and Redis backend. Subscriptions run through Stripe. None of that required leaving the Expo ecosystem. ### Architecture: boring on purpose The architecture that survives six months of feature requests is rarely clever. It is consistent. Our starting structure looks like this: - **Feature folders**, not type folders. Each feature owns its screens, hooks, API calls and tests, so changes stay local. - **Server state in TanStack Query**, local UI state in components or a small store. Most apps do not need a global state library for data that lives on the server. - **Typed API clients** generated from the backend contract, so a renamed field fails the build instead of crashing in production. - **A small design system** of primitives (text, buttons, inputs, spacing tokens) used everywhere, which keeps both platforms visually consistent. - **File-based routing** with Expo Router, so deep links and navigation structure are explicit and easy to reason about. The point is that a new engineer can open the repository and find where things live within an hour. That matters more to long-term velocity than any individual library choice. ### Performance is a design decision Janky lists and slow startup are what make cross-platform apps feel cheap. In our experience the causes are usually predictable, and they are almost never React Native itself: 1. **Lists that render everything.** Use a virtualised list (FlashList or a well-configured FlatList), stable keys and memoised row components. 2. **Re-renders cascading from the top.** Keep state close to where it is used and avoid passing new object or function references on every render. 3. **Animations on the JS thread.** Run gestures and animations with Reanimated so they stay smooth even when the JS thread is busy. 4. **Heavy images.** Serve correctly sized images, cache them, and avoid decoding large assets on screens that scroll. 5. **Bloated startup.** Defer non-critical work, lazy-load rarely used screens and keep the initial bundle lean. We profile on mid-range Android devices, not the newest iPhone on a developer's desk. If it is smooth there, it will be smooth for nearly everyone. ### Offline and unreliable networks Mobile users move between Wi-Fi, patchy 4G and no signal at all. An app that shows a spinner every time the network blips feels broken. Our default is **cache-first reads** with TanStack Query's persisted cache, so the last known data appears instantly and refreshes in the background. For writes, the question is how much the product needs. Simple cases use optimistic updates with a retry. Apps where users create data offline, such as logging a workout mid-run, need a local queue that replays mutations when connectivity returns, plus a clear conflict strategy on the server. We decide this early, because retrofitting offline writes into an app designed for always-on networking is expensive. ### Dropping to native where it counts React Native shares most code across platforms, but some features deserve native treatment: background location for run tracking, camera pipelines, Bluetooth peripherals, health data integrations and complex gestures. With Expo modules, writing a focused native module in Swift or Kotlin is a contained task rather than an architectural shift. The craft is knowing which screens need it and keeping that native surface small and well-tested. ### Releases that do not scare anyone A reliable app is mostly a reliable release process. Ours includes: - CI that type-checks, lints and runs tests on every pull request. - EAS builds for internal testers on every merge to the main branch, distributed through TestFlight and the Play internal track. - Over-the-air updates for JavaScript-only fixes, with a staged rollout and a rollback path. - Crash and performance monitoring wired in before the first public release, not after the first bad review. - A versioning policy so the backend can support older app versions that users have not updated yet. That last point is often forgotten. Unlike a website, you cannot force every user onto the latest build, so API changes need to stay backward compatible or be gated behind a minimum-version check. ### Auth, payments and the backend contract A mobile app is only as good as the API behind it. We design the backend contract alongside the app rather than after it: endpoints shaped around screens where that saves round trips, pagination everywhere a list can grow, and explicit error codes the app can translate into helpful messages instead of generic failure toasts. Authentication deserves the same care. Tokens live in secure storage, refresh happens silently in the background, and the app handles an expired session gracefully rather than dropping the user on a blank screen. For subscriptions, we use the platform stores through a provider such as RevenueCat so that receipts, renewals, refunds and cross-platform entitlements are handled correctly. Building that logic yourself is possible, but it is rarely where a product team should spend its time. #### Testing what matters We do not chase coverage numbers. Business rules get unit tests, important components get tests for their loading, empty and error states, and a short list of end-to-end flows such as sign-up, login and purchase run automatically before every release. That combination catches most regressions without slowing the team down. ### Working with us on React Native If you are planning a new app or inheriting one that has grown hard to change, we can help with architecture reviews, performance work or a full build. Read more about our [mobile app development](https://www.amygdal.com/services/mobile-app-development) service, see how we think about [mobile app engineering](https://www.amygdal.com/blog/mobile-app-engineering) more broadly, or [get in touch](https://www.amygdal.com/contact) to talk through your product. ### FAQ **Is React Native with Expo good enough for a production app in 2026?** Yes. With development builds, config plugins and EAS, Expo supports custom native code while keeping a consistent build and release pipeline. Most products never need to leave it. **Should we choose React Native or fully native?** React Native is usually better value when you want iOS and Android in sync from one team. Fully native makes sense for apps dominated by heavy graphics or deep platform-specific work. **How do you keep a React Native app fast?** Virtualised lists, state kept close to where it is used, animations on the UI thread with Reanimated, properly sized images and a lean startup path, all profiled on mid-range Android devices. ## How to Choose an LLM: Testing Models on Your Own Data URL: https://www.amygdal.com/blog/how-to-evaluate-llms-for-your-product Published: 2026-01-07 · Category: AI · Tags: LLM, Evaluation, AI, Model selection Benchmarks tell you which model is good in general. Your product needs to know which one is good at your task, at your cost, on your data. A new language model is announced almost every week, each with a chart showing it ahead on some benchmark. For a team building a product, those charts answer the wrong question. You do not need the best model in general. You need the model that does your task well enough, at a cost and speed your product can sustain, and that keeps doing so when the provider ships an update. The only reliable way to find that model is to test candidates on your own data. This post describes how we set up those comparisons for clients, from building the evaluation set to running side-by-side tests in production. The cost of choosing badly is rarely dramatic. It shows up as a feature that is slightly too slow, slightly too expensive or slightly too unreliable to roll out more widely, and a team that cannot say whether a different model would fix it. An evaluation process answers that question in days rather than leaving it to opinion. ### Why public benchmarks mislead Benchmarks measure broad capabilities on fixed datasets. Your workload is narrower and messier: domain vocabulary, specific output formats, documents in several languages, users who phrase things badly. A model that leads on general reasoning can still struggle with your extraction schema, and a smaller, cheaper model can be entirely adequate for classification. Benchmark data may also have leaked into training sets, which inflates scores without improving real-world behaviour. ### Build an evaluation set first Everything rests on a set of test cases that represent what the system will actually see. It does not need to be large to be useful; a well-chosen set of a hundred or two examples beats thousands of random ones. - **Real inputs.** Pull from production logs, support tickets or documents, anonymised where needed. - **Known good outputs** or clear grading criteria for each case, written by people who understand the domain. - **Hard cases on purpose.** Ambiguous requests, missing information, long inputs, other languages, attempts to make the model misbehave. - **Tagged by category**, so you can see that a model is strong on summaries but weak on tables rather than just reading one average. Write the evaluation set before you look at any model's output. If you build it after seeing what a favourite model does well, the set will quietly favour that model. Keep a held-out portion that you do not use while tuning prompts, so you have an honest final check. ### Decide how you will grade Grading is where most evaluations get sloppy. Match the method to the task: 1. **Exact or programmatic checks** for structured output: valid JSON, correct fields, values that match a reference. 2. **Reference comparison** for extraction and classification, scored automatically. 3. **Model-graded rubrics** for open-ended answers, with a separate model scoring against written criteria. Spot-check those grades by hand; graders have biases too. 4. **Human review** for a sample of cases, especially anything customer-facing or high-stakes. Record cost per request and latency alongside quality. A model that is slightly better but three times slower may be the wrong choice for an interactive feature and the right one for an overnight batch job. #### Prompts are part of the comparison Different models respond differently to the same prompt. A prompt written and polished for one model can make another look worse than it is. Give each serious candidate a fair round of prompt adjustment against the development portion of the set, then compare them on the held-out portion. Otherwise you are measuring your prompt, not the model. Also run each case more than once. Model output varies between runs, even at low temperature, and a model that is right four times out of five on a case behaves very differently in production from one that is right every time. ### Compare offline, then test online Offline evaluation narrows the field to two or three candidates. It cannot tell you how real users respond. For that, run an **online comparison**: route a share of live traffic to each candidate and measure what matters for the product, such as task completion, edits users make to generated text, thumbs up or down, escalations to a human, or conversion. Keep everything else constant. If you change the prompt and the model at the same time, you will not know which one moved the metric. Log the model version and prompt version with every request, so results can be sliced cleanly afterwards. Decide in advance what result would make you switch. For example: the challenger must match quality within a small margin on every category and reduce cost or latency meaningfully. Writing the rule down before the test prevents the team from reading whatever it hoped for into the numbers afterwards. ### Design for switching Whatever you choose today will not be your choice in a year. Put a thin abstraction between your application and the model provider, keep prompts in versioned configuration rather than scattered through code, and rerun the evaluation set whenever a provider updates a model. That turns a model change from a risky migration into a routine pull request. For retrieval-based systems, evaluate retrieval and generation separately; many quality problems blamed on the model are actually search problems. We cover that in our [RAG development guide](https://www.amygdal.com/blog/rag-development-guide). #### Watch the operational details - **Context window and long inputs**: test with your longest realistic documents, not just typical ones. - **Structured output support**: some models follow a JSON schema far more reliably than others. - **Data terms and region**: confirm where data is processed and whether it may be retained. - **Rate limits and availability**: check quotas against your expected peak traffic. - **Deprecation policy**: know how much notice the provider gives before retiring a model version. ### What a good outcome looks like At the end of a model selection exercise you should have a written comparison with quality scores by category, cost and latency per request, a recommended default, a fallback provider and an evaluation set that keeps running in CI. That is worth more than any leaderboard position. ### Need help choosing? We run model evaluations as part of [custom AI development](https://www.amygdal.com/services/custom-ai-development) projects, and we are happy to help you set up your own. [Contact us](https://www.amygdal.com/contact) to talk about your use case. ### FAQ **How many test cases do I need to evaluate an LLM?** Fewer than most people think. A carefully chosen set of one to two hundred cases that covers your real categories and hard edge cases is usually enough to separate candidates. Grow it as you find new failure modes in production. **Can one LLM grade another LLM's answers?** Yes, for open-ended outputs, using a clear written rubric. It is fast and scales well, but graders have their own biases, so check a sample of grades by hand and use programmatic checks wherever the output is structured. **Should we A/B test models in production?** Once offline evaluation has narrowed the field, yes. Live traffic shows how real users respond. Change only one variable at a time and log the model and prompt version with every request so the results are clean. ## The EU AI Act for Product Teams: A Practical Reading URL: https://www.amygdal.com/blog/eu-ai-act-for-product-teams Published: 2025-12-03 · Category: AI · Tags: AI governance, Regulation, EU, Compliance The EU AI Act is now part of building software for European users. Here is a practical reading for product and engineering teams, not lawyers. The EU AI Act is the first broad law that regulates artificial intelligence by what it is used for rather than by how it is built. If you sell software with AI features to customers in the European Union, or your system's output is used there, it applies to you, including companies based in the UK, Switzerland or Qatar. This is a practical reading for product managers and engineers. It is not legal advice, and the obligations are being phased in over several years with guidance still being published, so check the current timeline with your counsel. What we can offer is how the Act maps onto everyday product and engineering decisions. ### The core idea: risk depends on use The Act sorts AI systems into tiers based on the harm they could cause in a given context. The same underlying model can sit in different tiers depending on what you do with it. - **Prohibited practices.** A short list of uses that are banned outright, such as certain forms of manipulative techniques, social scoring and some biometric uses. - **High-risk systems.** AI used in sensitive areas listed in the Act, for example employment and recruiting decisions, access to education, credit scoring, certain medical devices and critical infrastructure. These carry the heaviest obligations. - **Transparency obligations.** Systems that interact with people or generate content, such as chatbots and generated media, must make that clear to users. - **Minimal risk.** Most AI features, such as spam filters, search ranking or writing aids, have no specific new obligations beyond existing law. There are also separate rules for providers of general-purpose AI models. Most product companies use those models rather than train them, so their obligations come from how they deploy the model, not from the model itself. ### Step one: map your AI features Before anyone debates obligations, list every place AI is used in your product and internal tools. For each one, write down what it does, who it affects, what decision it influences and whether a human reviews the output. You will usually find that most features are minimal risk, one or two need transparency notices, and occasionally one touches a high-risk area. Recruiting is a common example. A feature that ranks or filters job candidates is the kind of use the Act lists as high-risk. When we built AI scoring for asynchronous video interviews on [Digital Arrow](https://www.amygdal.com/projects/digital-arrow), a recruiting and HR platform, the design question was not just whether the model worked but how recruiters stay in control of the decision. The same mapping exercise often reveals AI that nobody thought of as a feature: a vendor tool with built-in scoring, a support platform that drafts replies, an analytics add-on that predicts churn. Under the Act, deploying a third-party system still carries obligations for the deployer, so these belong on the list too. ### What high-risk obligations look like in practice If a feature does fall into the high-risk category, the obligations translate into engineering work you would recognise: 1. **Risk management** across the lifecycle, documented and revisited when the system changes. 2. **Data governance**: knowing where training and evaluation data came from, and checking it for relevance and bias. 3. **Technical documentation** describing the system, its purpose, its limits and how it was tested. 4. **Logging** so that outputs can be traced after the fact. 5. **Human oversight** designed into the workflow, so a person can understand, override or stop the system. 6. **Accuracy, robustness and security** measured and maintained, not assumed. None of this is exotic. It is what a well-run AI project should have anyway. The difference is that it must now be written down and kept current. #### Provider or deployer? The Act distinguishes between providers, who develop an AI system or place it on the market under their own name, and deployers, who use one in their operations. A company that builds an AI feature into its own software product and sells it is usually acting as a provider for that feature. A company using a third-party AI tool internally is usually a deployer. The obligations differ, so work out which role you play for each entry on your list before deciding what applies. If you substantially modify a third-party system, or put your name on it, your role can shift towards provider. That is worth knowing before you fine-tune or rebrand a vendor model. ### Transparency is a design task For the much larger group of features with transparency duties, the work is mostly in the interface. Users should know when they are talking to an AI system rather than a person, and generated content should be identifiable as such where the Act requires it. Good product teams were already doing this because it builds trust. Clear labels, an easy route to a human and honest descriptions of what the assistant can and cannot do are the practical answer. ### Engineering habits that make compliance cheaper - Keep an **evaluation set** for every AI feature and record results for each model or prompt change. - Log prompts, retrieved context, model versions and outputs, with retention rules that respect GDPR. - Version prompts and configuration like code, so you can say exactly what was running on a given date. - Make human review a real step with its own interface, not a checkbox. - Write a short model card for each feature: purpose, data, known limits, owner. These habits overlap heavily with what we describe in [LLM agents in production](https://www.amygdal.com/blog/ai-agents-in-production). Teams that already evaluate and log properly will find the Act adds paperwork rather than new engineering. #### Where to start this quarter - Complete the inventory of AI features and third-party AI tools. - Classify each one by risk tier and by your role as provider or deployer. - Add AI disclosure to every interface where users talk to or receive content from a model. - Pick the highest-risk feature and bring its documentation, logging and oversight up to standard first. - Assign an owner who tracks guidance as it is published and updates the inventory. For companies selling into Germany or Switzerland, customers increasingly ask about AI Act readiness during procurement. Having the inventory and documentation ready shortens those conversations considerably. ### Building AI for European users? We design and build AI features with evaluation, logging and human oversight in from the start. Read about our [custom AI development](https://www.amygdal.com/services/custom-ai-development) work, or [contact us](https://www.amygdal.com/contact) to review an AI feature you are planning. ### FAQ **Does the EU AI Act apply to companies outside the EU?** Yes, in many cases. It applies to providers placing AI systems on the EU market and to systems whose output is used in the EU, regardless of where the company is based. Check your specific situation with legal counsel. **Is a customer support chatbot high-risk under the AI Act?** Usually not. A general support chatbot typically falls under transparency obligations: users must be told they are interacting with an AI system. It becomes more sensitive if it makes decisions in an area the Act lists as high-risk. **Do we need to change our model provider because of the AI Act?** Not necessarily. Obligations for deployers depend mainly on how you use the model. What matters is documenting your use case, evaluating outputs, logging decisions and designing human oversight where required. ## AI-Assisted Legacy Code Migration: What Actually Works URL: https://www.amygdal.com/blog/ai-assisted-legacy-code-migration Published: 2025-11-12 · Category: Engineering · Tags: Legacy modernisation, AI, Migration, Testing Language models can translate code quickly. Migrating a system safely is a different job. Here is how we combine the two without betting the business on it. Every company older than a few years has at least one system nobody wants to touch. It runs on a framework that stopped receiving updates, the people who wrote it have moved on, and every change takes three times longer than it should. Moving it onto a modern stack has always been expensive, mostly because someone has to read and rewrite every line by hand. Language models change part of that equation. They are fast at reading unfamiliar code and producing a plausible translation into another language or framework. The word that matters there is **plausible**. This post covers where AI genuinely helps in a migration, where it introduces risk, and the process we follow so that speed does not come at the cost of correctness. ### Translation is the easy part A migration is not a translation exercise. The hard parts of moving a legacy system are understanding what it actually does (which is often different from what the documentation says), preserving behaviour that users rely on without knowing it, and cutting over without downtime or data loss. Translating syntax is perhaps a fifth of the work. That is why teams who point a model at a repository and ask it to rewrite everything in TypeScript tend to end up with a codebase that compiles, looks tidy and behaves subtly differently. Rounding rules change. Date handling shifts by a timezone. An error that used to be swallowed now propagates. None of this is visible in a code review of the output alone. It also helps to be honest about why the system is being migrated. If the goal is to escape an unsupported runtime, a faithful port is the right target. If the goal is to change how the business works, a port is the wrong target and you are really looking at a rebuild with a migration path for data. Mixing the two goals in one project is one of the most common reasons modernisation work overruns. ### Where AI earns its place Used inside a disciplined process, models are genuinely useful at several stages: - **Code archaeology.** Summarising modules, tracing call paths and explaining what an undocumented function does. This shortens the discovery phase considerably. - **Generating characterisation tests.** Proposing test cases that pin down current behaviour, including edge cases a human might not think to check. - **Mechanical translation.** Converting data models, DTOs, validation rules and straightforward business logic module by module. - **Boilerplate on the new side.** Scaffolding controllers, repositories and API clients that follow the conventions of the target stack. - **Reviewing diffs.** Acting as a second reader that flags suspicious behaviour changes between old and new implementations. In each case a human engineer owns the result. The model drafts; the engineer verifies, corrects and commits. #### Give the model the right context Output quality depends heavily on what the model sees. Feeding it one file at a time produces code that ignores the conventions of the target codebase. We give it the relevant types, an example of an already-migrated module, the coding standards and the characterisation tests for the slice. The result needs far less correction, and reviewers can compare like with like. ### Tests first, translation second The single most important rule in any migration, AI-assisted or not, is that you need a way to prove the new system behaves like the old one. For legacy code that usually means writing **characterisation tests** before changing anything: tests that record what the system currently does, right or wrong, so you can detect any difference. 1. Identify the module boundaries and pick a first slice with clear inputs and outputs. 2. Capture real (anonymised) inputs from production logs or fixtures and record the old system's outputs. 3. Use a model to propose additional edge-case inputs, then record the old outputs for those too. 4. Translate the slice, with the model drafting and an engineer reviewing. 5. Run both implementations against the same inputs and diff the results. Investigate every mismatch. 6. Only when the diff is clean, or every difference is a deliberate fix, does the slice move forward. This sounds slow. In practice, AI makes the test-generation step much faster, which is exactly where manual migrations used to cut corners. ### Migrate in slices, not in one big bang We almost never recommend a full rewrite followed by a single cutover. The **strangler pattern** works better: put a routing layer in front of the old system, move one capability at a time to the new service, and send traffic to it gradually. If something goes wrong, you route back. The old system shrinks until it can be switched off. For data, the same principle applies. Run both stores in parallel for a period, reconcile them, and keep a rollback path until you are confident. We describe the backend patterns we tend to land on in [how we structure NestJS, Prisma and PostgreSQL backends](https://www.amygdal.com/blog/nestjs-prisma-postgresql-architecture). #### Choosing the first slice The first slice should be valuable enough to matter and small enough to finish in a few weeks. Good candidates are read-heavy capabilities with clear inputs and outputs, such as a pricing calculation, a report or a lookup API. Avoid starting with the module that writes to every table. A successful first slice proves the pipeline end to end: tests, translation, review, deployment, routing and rollback. Data deserves its own plan. Schema changes, encoding differences and years of inconsistent records surface during migration, not before. Profile the data early, write reconciliation checks that compare record counts and key totals between old and new stores, and rehearse the cutover on a copy of production data more than once. ### Risks to plan for - **Confident errors.** Models rarely say they are unsure. Treat every generated line as unreviewed until proven otherwise. - **Licensing and confidentiality.** Decide up front which code may be sent to which model provider, and consider a self-hosted model for sensitive repositories. - **Lost intent.** A faithful translation of a bad design is still a bad design. Use the migration to fix structure, but separate refactoring commits from behaviour changes. - **Hidden dependencies.** Cron jobs, stored procedures, shared database tables and file drops are easy to miss. Inventory them before you start. - **Team knowledge.** If the people who will run the new system did not take part in the migration, you have created a new legacy system. ### How to tell if it is working Good signals are boring ones: the behavioural diff stays clean, each slice ships to production on its own, incident rates do not rise during cutover, and engineers can make changes in the new code faster than they could in the old. If the team is debating why outputs differ late in the project, the tests came too late. ### Planning a migration? We help teams modernise systems they depend on, combining AI-assisted tooling with careful, test-led engineering. See our [custom software development](https://www.amygdal.com/services/custom-software-development) service, or [get in touch](https://www.amygdal.com/contact) to talk through the system you need to move. ### FAQ **Can AI rewrite a legacy application automatically?** It can draft a translation quickly, but not safely on its own. Models produce code that looks right and behaves slightly differently. A safe migration still needs characterisation tests, behavioural diffing and engineers who own every change. **What is the strangler pattern?** It is a way to replace a system gradually. A routing layer sits in front of the old application, and capabilities move one at a time to the new one. Traffic shifts as each piece is proven, and the old system is switched off at the end. **Is it safe to send proprietary code to an AI model?** That depends on your contracts and the provider's data terms. Many teams use enterprise agreements that exclude training on their data, or run an open-weight model on their own infrastructure for sensitive repositories. # Company FAQ **What does Amygdal do?** Amygdal is a software development company that helps teams design, build and implement AI. We ship mobile apps, web apps and custom software, and integrate AI — LLM/RAG features, computer vision, predictive analytics — into real products for global brands. **Is Amygdal an AI consultancy or a development company?** Both. We set the AI strategy and then build it in production, so the advice is grounded in what actually ships — not a slide deck. Most of our work ends in working software, not a report. **What is AI implementation, and how do you approach it?** AI implementation means putting AI to work inside a real product or workflow. We start by finding where AI changes a decision or unlocks value, validate the riskiest assumption with a focused proof of concept, then engineer it for production with data pipelines, evaluation, guardrails and MLOps. **Can you build a mobile app for iOS and Android?** Yes. We engineer iOS and Android apps — native and cross-platform (React Native) — with the architecture, performance, security, testing and release process that keep them fast and reliable as they scale. **Can you build our MVP?** Yes. We build MVPs lean and fast, focused on the riskiest assumption, on clean foundations so success doesn't mean a rewrite. We instrument them from day one so you learn what users actually do. **We raised a seed round — can you help us scale our MVP?** Yes. Post-seed, we harden the flows users rely on, add the infrastructure growth demands (caching, queues, observability, a better data layer), and put in the structure that lets a growing team ship in parallel — building on your MVP rather than rebuilding it. **What industries do you work in?** We have deep context in healthcare, construction and BIM, fintech and finance, retail and eCommerce, automotive and mobility, and startups — and we've delivered for global brands including VW Group, Skoda and History Channel. **Do you build RAG systems?** Yes. We build retrieval-augmented generation over documents, databases and BIM data — with hybrid search, reranking, citations, permission-aware retrieval and an evaluation set that catches regressions. **Do you work on AI and software for BIM?** Yes. We have built AI and software for Building Information Modeling: IFC and Revit data pipelines, automated model checking, element classification, quantity takeoff and assistants that answer questions about a model. **Which countries do you work with?** Mainly the United Kingdom, Germany, Switzerland and Qatar, as well as the United States. We work in English, German and Arabic, with full overlap with UK and Central European hours. **Which technologies do you use?** React, Next.js, Node.js, TypeScript, Python, Flutter and React Native, on AWS/DigitalOcean with PostgreSQL, Redis, Docker and Kubernetes — chosen per project, not by default. **How do we start a project with Amygdal?** Email us at info@amygdal.com. We'll scope the problem honestly, flag risks and opportunities, and propose a plan — from a focused MVP to a full build or AI integration. **Where is Amygdal based?** We're a remote-first studio with offices in Delaware (USA), Sarajevo (Bosnia and Herzegovina) and Doha (Qatar), serving clients globally. ## Languages and markets - English (Global): https://www.amygdal.com - English (United Kingdom): https://www.amygdal.com/uk - Deutsch (Deutschland): https://www.amygdal.com/de - Deutsch (Schweiz): https://www.amygdal.com/ch - العربية (قطر): https://www.amygdal.com/qa ## Contact - Email: info@amygdal.com - Phone: +1 740 990 2281 - Contact page: https://www.amygdal.com/contact - FAQ: https://www.amygdal.com/faq - LinkedIn: https://www.linkedin.com/company/amygdal/ - Instagram: https://www.instagram.com/amygdal.dev/ - X: https://twitter.com/AmygdalDev - Facebook: https://www.facebook.com/amygdal.dev/