The business has outgrown its tools.
Off-the-shelf products cover most of the process, and spreadsheets, copy-paste, and workarounds cover the rest. The gaps are where errors and delays come from.
CUSTOM SOFTWARE DEVELOPMENT
We design and build the systems your business runs on: SaaS products, enterprise applications, internal platforms, marketplaces, and the APIs and backends behind them.
Off-the-shelf software makes you work its way. We start from how your business actually works, model it carefully, and engineer the architecture, data, security, and operations so the system keeps fitting as the business changes.
01 / WHY TEAMS CALL US
Most teams don’t need convincing that software could help. They need it to fit how the business works, and to keep fitting as it grows.
Off-the-shelf products cover most of the process, and spreadsheets, copy-paste, and workarounds cover the rest. The gaps are where errors and delays come from.
Code written to prove an idea is now carrying customers and revenue. There are no clear boundaries and few tests, so every change feels risky and slow.
Knowledge lives in one or two people’s heads. There is no architecture overview, no decision record, and onboarding a new engineer takes months.
Pages that were instant now take seconds, background jobs overlap, and nobody knows which part will break first when the next large customer arrives.
Deployments are manual, happen out of hours, and occasionally need a rollback nobody has rehearsed. So the team ships less often, in bigger and riskier batches.
The CRM, the billing system, and the database tell different stories. Integrations fail quietly, and someone reconciles them by hand at the end of the month.
02 / WHAT WE BUILD
Typical systems we design and build. Each one is shaped around your data, users, and constraints rather than a template.
Multi-tenant products with sign-up, onboarding, subscriptions, roles, and the admin tooling to run them as a business.
THE HARD PARTTenant isolation that holds in every query, export, cache key, and background job, not just the obvious screens.
Systems for complex, regulated, or high-stakes processes, with approval chains, SSO, and integration into the existing estate.
THE HARD PARTEncoding years of business rules without also encoding years of workarounds.
Shared capabilities other teams build on: identity, payments, notifications, documents, or an internal developer platform.
THE HARD PARTInterfaces stable enough for many teams to depend on while the platform keeps evolving underneath.
Two-sided platforms with listings, search, matching, payments, payouts, reviews, and trust and safety tooling.
THE HARD PARTMoving money between parties correctly, through refunds, disputes, partial payouts, and reconciliation.
Scheduling, dispatch, inventory, fulfilment, and field service: the software that coordinates people and physical work.
THE HARD PARTModeling real-world states and exceptions faithfully, so the system helps operations instead of becoming the bottleneck.
Operational and analytical views over your data, from live queues and SLAs to finance and management reporting.
THE HARD PARTNumbers everyone trusts: one definition per metric, visible freshness, and row-level access applied to every chart.
Self-service for customers and partners: accounts, orders, documents, payments, and support, connected to your back office.
THE HARD PARTExposing data from back-office systems that were never designed to be seen by customers, safely and quickly.
Public, partner, and internal APIs with clear contracts, authentication, rate limits, webhooks, and developer documentation.
THE HARD PARTEvolving the API without breaking integrations you don’t control and can’t see.
The services, workers, queues, and data stores behind web and mobile products, designed to be operated, not just deployed.
THE HARD PARTKeeping data consistent across components without distributed transactions, and recovering cleanly when one part fails.
Live dashboards, collaboration, tracking, messaging, and notifications that update the moment something changes.
THE HARD PARTOrdering, reconnection, and backpressure when thousands of clients are connected and the network is unreliable.
03 / REFERENCE ARCHITECTURE
Most systems we build share this shape. Choose a path to follow a real request across it, or select any component to see why it is there.
CLIENTS
EDGE
APPLICATION
MESSAGING
DATA
Traces, metrics, and structured logs from every hop, correlated by trace ID.
Secrets manager, least-privilege service identities, audit log, and dependency scanning.
Infrastructure as code, CI/CD, preview environments, and progressive rollout.
PATH · WRITE PATH
Clients layer
Field app for technicians. Works offline, queues changes locally, and syncs when a connection returns.
TYPICAL CHOICES
An illustrative field-service platform. We adapt the shape to your scale: many systems run happily as a single deployable with one database, and we add components only when there is a reason.
04 / ENGINEERING DISCIPLINES
Each discipline answers a question your business will eventually ask. Each one leaves an artifact you can review, not just a promise.
01 / ARCHITECTURE · THE QUESTION IT ANSWERS
We start with a modular monolith and split out services only where scaling, team ownership, or release cadence demands it. Quality attributes such as latency, availability, and recovery time are agreed as numbers before design begins.
YOU RECEIVEArchitecture overview, decision log, and quality-attribute targets
# ADR 0007: Start as a modular monolith
Status: Accepted
Context
Three teams, one domain, modest first-year load.
Decision
One deployable; one module per bounded context.
Modules call each other's public interfaces only.
No module reads another module's tables.
Consequences
+ one pipeline, simple local transactions
- boundaries must be enforced by tooling
Revisit when
a module needs independent scaling or releases.
02 / DOMAIN MODELING · THE QUESTION IT ANSWERS
We model the business with the people who run it, using event storming and real cases. Words that change meaning between departments mark the boundaries between contexts, and the rules that must always hold live inside aggregates.
YOU RECEIVEContext map, glossary, and a catalogue of aggregates and events
export class WorkOrder {
complete(by: TechnicianId, at: Instant) {
if (this.status !== "in_progress")
throw new InvalidTransition(this.status, "completed");
if (this.checklist.hasOpenRequiredItems())
throw new ChecklistIncomplete(this.id);
if (!this.assignees.includes(by))
throw new NotAssigned(by, this.id);
this.status = "completed";
return new WorkOrderCompleted(this.id, by, at);
}
}
03 / API DESIGN · THE QUESTION IT ANSWERS
Contracts are written and reviewed before implementation, then used to generate documentation, clients, and contract tests. Errors, pagination, and versioning behave the same way across every endpoint.
YOU RECEIVEVersioned API contracts, generated clients, and an API style guide
/v1/work-orders/{id}/complete:
post:
operationId: completeWorkOrder
x-permission: work_order:complete
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
responses:
'200': { $ref: '#/components/responses/WorkOrder' }
'409': { $ref: '#/components/responses/InvalidTransition' }
'422': { $ref: '#/components/responses/ValidationProblem' }
'429': { $ref: '#/components/responses/RateLimited' }
04 / DATABASE DESIGN · THE QUESTION IT ANSWERS
The database enforces what must always be true, not just the application. Indexes follow real access paths and are checked against query plans. Migrations run without downtime using an expand-and-contract sequence.
YOU RECEIVESchema and ER diagrams, migration policy, and data retention rules
CREATE TABLE work_orders (
id uuid PRIMARY KEY,
tenant_id uuid NOT NULL REFERENCES tenants (id),
site_id uuid NOT NULL REFERENCES sites (id),
status text NOT NULL CHECK (status IN
('requested','scheduled','in_progress','completed','cancelled')),
version int NOT NULL DEFAULT 0,
completed_at timestamptz,
CHECK (status <> 'completed' OR completed_at IS NOT NULL)
);
CREATE INDEX ON work_orders (tenant_id, status, site_id);
ALTER TABLE work_orders ENABLE ROW LEVEL SECURITY;
05 / SECURITY · THE QUESTION IT ANSWERS
Every feature that touches money, personal data, or permissions gets a threat model. Authorization is written as code and tested for every role. We use the OWASP ASVS as a checklist, and secrets never live in code or configuration files.
YOU RECEIVEThreat model, permission matrix, and an automated security test suite
export const policies = {
"work_order:complete": ({ actor, resource }) =>
actor.tenantId === resource.tenantId &&
(actor.role === "dispatcher" ||
(actor.role === "technician" &&
resource.assigneeIds.includes(actor.id))),
"invoice:void": ({ actor, resource }) =>
actor.tenantId === resource.tenantId &&
actor.role === "finance_admin",
} satisfies PolicyMap;
// Every policy has a test per role: authz/policies.test.ts
06 / SCALABILITY · THE QUESTION IT ANSWERS
We build a load model from real usage, test against it with production-sized data, and fix the actual bottleneck rather than scaling everything. Slow or spiky work moves to queues so it can’t take the interactive path down with it.
YOU RECEIVELoad model, repeatable load tests, and a capacity plan
export const options = {
scenarios: {
morning_peak: {
executor: "ramping-arrival-rate",
stages: [
{ target: 40, duration: "5m" }, // today's peak
{ target: 400, duration: "15m" }, // 10x headroom
],
},
},
thresholds: {
"http_req_duration{route:complete}": ["p(95)<300"],
http_req_failed: ["rate<0.001"],
},
};
07 / OBSERVABILITY · THE QUESTION IT ANSWERS
Traces follow a request through every service, queue, and query. Alerts fire on what users experience, measured against service level objectives, rather than on CPU graphs. Every alert links to a runbook.
YOU RECEIVETracing, dashboards, SLOs, alerts, and runbooks
slo: complete-work-order
journey: Technician completes a work order
indicator:
good: status < 500 and latency < 300ms
total: POST /v1/work-orders/*/complete
objective: 99.5% # rolling 28 days
alerts:
- burn_rate: 14.4 window: 1h action: page
- burn_rate: 6 window: 6h action: ticket
runbook: runbooks/work-orders.md#slow-completion
08 / TESTING · THE QUESTION IT ANSWERS
Many fast tests on the domain rules, integration tests against a real database, contract tests at every API boundary, and a small number of end-to-end tests on the journeys that matter most. All of them run on every change.
YOU RECEIVETest strategy and automated suites running in CI
Software testingdescribe("WorkOrder.complete", () => {
it("rejects open required checklist items", () => {
const order = aWorkOrder().inProgress()
.withChecklist([{ required: true, done: false }]);
expect(() => order.complete(tech, now))
.toThrow(ChecklistIncomplete);
});
it("completes exactly once", () => {
const order = aWorkOrder().inProgress().build();
order.complete(tech, now);
expect(() => order.complete(tech, now))
.toThrow(InvalidTransition);
});
});
09 / DEPLOYMENT · THE QUESTION IT ANSWERS
Infrastructure is code, every environment is reproducible, and every change reaches production through the same pipeline. Releases go out to a small share of traffic first and roll back automatically when the service level objectives say so.
YOU RECEIVECI/CD pipelines, infrastructure as code, and a release runbook
Cloud & DevOpsdeploy-production:
needs: [e2e-staging, migration-check]
environment: production
steps:
- run: ./deploy canary --weight 5
- run: ./verify slo complete-work-order --for 10m
- run: ./deploy promote --weight 100
- if: failure()
run: ./deploy rollback
10 / MAINTENANCE · THE QUESTION IT ANSWERS
Software is maintained, not finished. Dependencies are updated on a schedule, technical debt is tracked with its cost and paid down deliberately, and every incident review ends with a change to the system, not just a lesson.
YOU RECEIVEMaintenance plan, debt register, and handover documentation
Cadence
weekly dependency update PRs, CI-gated
monthly security patches, error-budget review
quarterly runtime and framework upgrades,
backup restore drill
yearly architecture review against real load
Debt register
DEBT-014 invoice PDFs rendered synchronously
cost: slows completion at peak
fix: move to worker queue (est. 3d)
05 / DOMAIN MODELING
Boundaries come from the business, not from the framework. Each context owns its language, rules, and data, and the others hear about its changes through events.
ILLUSTRATIVE DOMAIN · FIELD-SERVICE OPERATIONS
| # | Event | From → to | What happens next |
|---|---|---|---|
| 01 | SiteRegistered | Customers → Work orders | The site becomes available for new work orders, with its access notes. |
| 02 | WorkOrderRequested | Work orders → Scheduling | Scheduling proposes appointment slots using skills, location, and shift availability. |
| 03 | AppointmentConfirmed | Scheduling → Notifications | The customer receives a confirmation with the arrival window. |
| 04 | PartsRequired | Work orders → Inventory | Stock is reserved at the nearest location, or a shortage is raised. |
| 05 | WorkOrderCompleted | Work orders → Billing | An invoice is drafted from the contract’s rates and the parts used. |
| 06 | InvoiceIssued | Billing → Notifications | The invoice is sent to the customer’s billing contact. |
| 07 | InvoiceIssued | Billing → Accounting ERP | Posted to the ledger through an anti-corruption layer that translates our model into the ERP’s. |
| 08 | PaymentRequested | Billing → Payment provider | The provider is charged through an adapter, so its API never leaks into the billing model. |
Core contexts are where the business differentiates, so they get the most modeling effort. Generic ones are good candidates to buy rather than build. External systems sit behind anti-corruption layers, so their quirks stay at the edge.
06 / OBSERVABILITY
What happens in the 34 milliseconds after a technician taps “Complete”, and in the background work that follows once they have their answer.
TRACEPOST /v1/work-orders/{id}/complete
34 ms to response16 spans300 ms including background work
ON THE REQUEST PATH
AFTER THE RESPONSE · ASYNCHRONOUS
The event is written in the same transaction as the state change. A crash between the two can’t lose the event, or announce a change that never happened.
The client sends an idempotency key and consumers check event IDs, so a retried request or a redelivered message changes nothing twice.
PDF rendering and a slow email provider happen after the response. The technician waits for the work that matters, and nothing else.
07 / DELIVERY PIPELINE
Every change takes the same path to production. Each stage has a gate, and anything that fails a gate stops before it can reach a customer.
GATEApproved by a second engineer
GATEAny failure blocks the merge
GATEA broken contract blocks the merge
GATEAccepted where behavior changes
GATELong locks or breaking changes blocked
GATECritical journeys pass
GATEBudget burn triggers rollback
GATERelease noted in the changelog
If: error-budget burn during canary at stage 07
Automatic rollbackTraffic shifts back to the previous version within minutes. Migrations are expand-then-contract, so the old version still works with the new schema.
Previous version keeps serving
08 / CAPABILITIES
Each capability can stand alone, but production systems usually need most of them working together.
Sign-up, SSO with SAML and OIDC, MFA, service accounts, and role- or attribute-based permissions, tested for every role.
Tenant isolation in data, caches, files, and jobs, with per-tenant configuration, limits, and data export.
Plans, usage metering, invoicing, proration, dunning, and integration with payment providers and accounting.
Explicit states and transitions for orders, cases, and approvals, with timeouts, escalations, and a full history.
Full-text and faceted search, saved views, scheduled reports, and exports that respect permissions.
Uploads, virus scanning, previews, generated PDFs, e-signature integration, and retention policies.
Email, SMS, push, and in-app messages from versioned templates, with user preferences and delivery tracking.
Typed clients for third-party APIs, signed webhooks in both directions, retries, and reconciliation.
Who did what, when, and from where, recorded immutably for privileged actions and exposed to administrators.
Local-first data for mobile and field use, conflict resolution rules, and sync that survives poor connectivity.
Need the interface, the app, or the data layer specifically? Web development · Mobile app development · Data & integrations · AI development
09 / ENGINEERING APPROACH
How we choose when there is more than one reasonable answer, which in software is most of the time.
01
The software should model how your business really works.
02
Complexity has to earn its place.
03
Future engineers should know why, not just what.
04
Integration risk is cheapest to find early.
05
Testing and security are part of every change.
06
Your team should be able to own what we build.
Infrastructure, pipelines, and monitoring are delivered with our cloud and DevOps practice; connections to your systems with data and integrations.
10 / TECHNOLOGIES
We recommend a stack after discovery, based on your requirements, existing platforms, and team.
Chosen for your team’s skills and the problem, not fashion.
Web, mobile, and internal tools on a shared design system.
Boring, proven stores, used for what they are good at.
Reproducible environments in the cloud you already use.
Representative technologies; no official partnerships are implied. Explore our technology capabilities.
11 / PROCESS
Every stage ends with something you can review, so decisions are made on evidence rather than optimism.
Understand the business, its users, and its constraints. Map the current process and systems, and agree what success means in measurable terms.
OUTPUTProblem brief, success measures, and constraints
Model the domain with the people who run it, define the context boundaries, and make the significant architectural decisions on paper first.
OUTPUTContext map, architecture overview, first decision records
Build a thin slice through every layer, from interface to database, and deploy it to production through the real pipeline.
OUTPUTA deployed, observable end-to-end slice
Ship features in small vertical slices with tests, reviewed with you every iteration against the agreed outcomes.
OUTPUTWorking software at a regular cadence
Load tests, security review, failure drills, and data migration rehearsals before real users depend on the system.
OUTPUTRelease readiness report
Staged rollout with monitoring, alerts, and a rehearsed rollback. Data migrated and verified, support briefed.
OUTPUTProduction release and runbooks
Run, maintain, and extend the system with you, or hand it over to your team with documentation and pairing.
OUTPUTMaintenance plan and roadmap
See how this fits into our wider delivery process.
12 / RELEVANT WORK
Client case studies are published once they are approved. The work below consists of illustrative concepts, not delivered engagements or claimed results.
A design study for coordinated, observable workflows across the business systems an operations team depends on.
A design study for a mobile application that lets field technicians complete work without a reliable connection.
13 / WHY NEURALSHARKS
Commitments you can hold us to during an engagement.
NeuralSharks was founded by six software engineering partners. Senior engineers make the architectural decisions, write code, and stay involved through delivery.
About NeuralSharksDomain modeling, backend, interfaces, data, security, testing, and cloud operations in one team, so the parts are designed to work together.
All servicesAutomated tests, security checks, and release gates are planned from the first iteration by an in-house quality engineering discipline.
Test automationIf buying a product, extending your current system, or building less would serve you better, we will say so, with the reasoning written down.
Your repositories, your cloud accounts, mainstream technology, and documentation good enough for another team to take over.
Clear boundaries and tests make change cheap, so the system can follow the business as it learns.
Read: build for the next release14 / FAQ
If yours isn’t here, ask us directly. A straight answer is part of the service.
Buy where your needs are the same as everyone else’s, such as accounting, email, or payroll, and build where the software is how you compete or how your operations differ. Often the answer is a mix: products for generic capabilities, custom software for the core, and integrations between them. We will tell you when buying is the better option.
Usually a modular monolith first: one deployable with strict internal boundaries. It is faster to build, easier to operate, and keeps transactions simple. When a module needs independent scaling or its own release cadence, a clean boundary makes extracting it a contained piece of work rather than a rewrite.
Yes. We start with an assessment of the code, architecture, data, and operations, then usually modernize incrementally: add tests and observability, establish boundaries, and replace parts one at a time behind stable interfaces. Big-bang rewrites are rarely the safest option.
We recommend a stack after discovery, based on your requirements, your team’s skills, and your existing platforms. We prefer mainstream, well-supported technology, because it is easier to hire for and maintain long after we are gone.
You do. We work in your repositories and cloud accounts from the start, so there is never a handover of access at the end. Ownership terms are set out in the contract before work begins.
Security is part of design, not a final audit: threat models for sensitive features, tested authorization, secrets management, dependency scanning, and audit logs. We design to the controls your compliance obligations require and work with your auditors; we don’t claim certifications on your behalf.
We estimate after discovery, when the scope, integrations, and risks are understood. Discovery itself is a fixed, short engagement. Delivery is planned in increments, so you see working software early and can adjust scope based on what you learn.
Yes. We can lead the work, embed engineers in your team, or own a defined part of the system. We follow your conventions or help establish them, and plan knowledge transfer from the start.
We can operate and maintain the system, extend it, or hand it over to your team with documentation, runbooks, and pairing. Either way, maintenance is planned: dependency updates, monitoring, incident response, and regular architecture reviews.
START A PROJECT
Tell us what your business needs to do that its current software can’t, which systems are involved, and where the risk is. We’ll come back with questions, an honest view on build versus buy, and a sensible first milestone.