Custom software development
Backend services, data models, and business logic built to the specific rules of a domain rather than adapted from a generic product.
IT Engineering Services / Home
BOTTLECLOSET LTD designs, builds, and maintains software and cloud infrastructure for organisations that need systems to be understandable, testable, and durable — not merely finished.

BOTTLECLOSET LTD provides information technology services across the full life of a software system: analysis, architecture, implementation, verification, deployment, and ongoing maintenance. Work is delivered under written scope, tracked in shared tooling, and reviewed before it reaches a production environment.
The company works with organisations that already have technical constraints to respect — existing databases, integrations, compliance obligations, or platforms that cannot simply be replaced. Rather than proposing a rebuild by default, engagements begin by reading the system that exists and describing, in plain terms, what it does and where it is fragile.
Everything produced is intended to be maintainable by someone who was not present when it was written. That principle governs code structure, naming, test coverage, infrastructure definitions, and documentation alike.
Capabilities combine within a single engagement; a web application rarely arrives without infrastructure, integration, and test work alongside it.
Backend services, data models, and business logic built to the specific rules of a domain rather than adapted from a generic product.
Accessible, responsive interfaces with predictable state handling, clear routing, and server-rendered content where it benefits users.
Environment definitions kept in version control, repeatable deployments, and observability wired in from the first release.
Contract-first interfaces between applications, third-party platforms, and internal services, with explicit error and retry behaviour.
Layered automated checks plus exploratory testing, so regressions surface in a pipeline rather than in production.
Architecture review, technology selection, and written recommendations that name trade-offs instead of hiding them.
Custom development begins with the rules an organisation actually operates by: how records relate, which states are legal, who may act, and what must be auditable. Those rules are modelled explicitly in the data layer and in the service boundaries, so that invalid states are hard to create rather than merely discouraged by the interface.
Implementation proceeds in small, reviewable changes. Each unit of behaviour arrives with tests, and each release is traceable to the change that produced it.

04 / Web application engineering
Web applications are engineered from the routing model outward: every screen has an address, every address renders meaningful markup, and state that belongs in the URL lives there. Content that search engines and assistive technology need is present in the served HTML rather than assembled after the fact.
Layouts are responsive by construction, colour and type meet contrast requirements, and motion respects reduced-motion preferences.

Infrastructure work aims at reproducibility. Networks, compute, storage, and permissions are described in version-controlled definitions, so an environment can be recreated deliberately instead of reconstructed from recollection. Deployment runs through a pipeline that builds once, tests the artefact, and promotes it between environments.
Observability is part of the deliverable: structured logs, metrics, health checks, and alerts tied to conditions that matter operationally rather than to raw noise.
Integration work replaces manual transfer and brittle scripts with defined interfaces. Each connection states its payload shape, authentication method, failure modes, and retry policy in writing before it is implemented.
Schemas and versioning agreed up front so a change on either side is visible before it breaks.
Operations designed to tolerate repetition, so a retry cannot duplicate a record.
Checks that compare systems after transfer and report differences rather than assuming success.
Scheduled and event-driven workflows that remove repetitive manual steps from routine operations.

Testing is layered. Unit tests fix the behaviour of individual functions; integration tests exercise real boundaries such as databases and external interfaces; end-to-end tests confirm that the paths users depend on still work. Static analysis and type checking run on every change, and exploratory testing covers what automation cannot anticipate.
Defects are reproduced before they are fixed, and the reproduction becomes a permanent test so the same fault cannot return quietly.


Accounts, tokens, and service roles are scoped to the narrowest permission that allows the task.
Data crossing a boundary is validated against a schema before it reaches business logic.
Credentials live in managed secret storage, never in source control or client bundles.
Third-party packages are pinned, reviewed, and monitored for published advisories.
Access rules are tested as behaviour, including the paths that should be refused.
These practices reduce risk; no engineering practice can eliminate it, and none of the above should be read as a guarantee of regulatory compliance.
Read the existing system, capture constraints, and write down the objective in measurable terms.
Propose an architecture and data model, name the trade-offs, and agree the shape before building.
Implement in small increments, each reviewed, tested, and integrated continuously.
Run automated suites, exercise the interface manually, and confirm behaviour against the agreed scope.
Deploy through the pipeline, monitor behaviour, and fold findings into the next increment.
Communication is structured so that a stakeholder can tell what changed without attending a meeting. A shared backlog holds the agreed scope; progress updates state what was completed, what is in progress, and what is blocked; decisions are recorded with the reasoning and the alternatives that were rejected.
Where a request would compromise maintainability, security, or the agreed architecture, that is raised directly, with an alternative proposal rather than a refusal.


Engagements range from a focused piece of engineering work — an integration, a migration, a test suite — to the design and construction of a complete application and its supporting infrastructure. Scope is agreed in writing before work begins.
Work is broken into short delivery increments. Each increment has a defined objective, a reviewable output, and a demonstration of what changed. Priorities for the next increment are agreed at the end of the previous one.
Ownership and licensing of delivered work are set out in the engagement agreement. Repositories, environment definitions, and written documentation are handed over so the work can be maintained independently.
Through automated tests at unit, integration, and end-to-end levels, static analysis, peer code review, and exploratory testing of user-facing behaviour. Checks run in the pipeline on every change.
Security is treated as an engineering property: least-privilege access, validated inputs, encrypted transport, dependency monitoring, secret management, and reviews of authentication and authorisation logic.
Deployments are accompanied by monitoring, structured logging, and alerting so that behaviour in production is observable. Post-release support arrangements are agreed per engagement.
Technology selection follows the requirements of the system rather than a fixed stack. Commonly used tools are listed in the technology expertise section on this page.
A single written channel of record, a shared backlog, scheduled progress updates, and decision notes that capture what was chosen and why.
By email at [email protected]. A short description of the objective, current systems, constraints, and timing expectations is enough to start a useful conversation.
Describe the objective, the systems already in place, any constraints that must be respected, and your timing expectations. That is enough for a substantive first reply.