Changelog
All notable changes to Mole will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
Work merged after v1.1.0 and not yet cut into a release.
[1.1.0] - 2026-10-18
Released on 2026-10-18, published with one artifact per target: mole-linux,
mole-macos and mole-windows.exe. backend/pyproject.toml is the single source
of truth for the version, so main.py no longer needs editing when a release is
cut.
Added
- Bounds enforcement on
num_mutationsacross all three callers: the API returns400outside0..10, the CLI rejects out-of-range input, and the frontend validates before sending. MAX_MUTATIONS_PER_REQUEST = 10inbackend/src/main.py, answering a larger request with400rather than performing unbounded work.- Accessible labels for the two form inputs. Both had a sibling
<label>with nohtmlForand noidon the input, so neither had a programmatic accessible name. - A Coccinella Labs favicon, previously
/favicon.pngreturned404. - Cypress coverage for the frontend: accessibility, mutation input, image layout, result-grid layout, and unchanged-behaviour regression specs.
- A merge-queue ruleset for the default branch, with conversation resolution required before merge.
Fixed
- Validation errors are reported readably. FastAPI answers a schema violation
with
422and a list of error objects; the client only understood a stringdetail, so the real reason was replaced by the bare status code. - Empty and malformed mutation input no longer reaches the API. The field held a
number, so clearing it produced
NaN, which serialised tonulland was rejected with422. - The mutations input
minwas1while the API accepts0and answers withmutated=false. - Long SMILES values no longer overlap in the result panel. A two-column grid
whose items had no
min-w-0let unbroken SMILES tokens paint outside their track and collide with the neighbouring column. - Failed mutations are reported instead of being silently discarded.
- API failures state their cause rather than one generic message.
- RDKit warnings are muted only during candidate validation, where they are expected.
CIemits a valid sha tag onpull_requestevents.
Changed
- Frontend build moved from Create React App to Vite 8 with Tailwind CSS 4.
CRA hardcoded
tailwindcssinto its PostCSS pipeline and disabled project-level PostCSS config, so Tailwind 4 could not be adopted without replacing the build tooling. This resolves #93 and supersedes the dependabot bump in #91. - Frontend entry points moved to
.jsx, since Vite does not transform JSX in.jsfiles. - Frontend environment variables use the
VITE_prefix (VITE_BACKEND_URL,VITE_API_KEY), set as build arguments indocker-compose.yml. - The production frontend image runs
vite buildand servesdist. - The service version is resolved from
pyproject.toml, preferring installed distribution metadata. Previouslymain.pyhardcoded its own copy, soGET /healthcould report a version that differed from the packaged one. - The product was renamed to Mole and repository URLs updated.
- Release artifacts are named per target at
v1.1.0; assets up to and includingv1.0.0keep their existing names. - e2e tests run on pull requests and in the merge queue, on Node 22.
Two changes affect the repository rather than the application:
- A pre-commit hook fails when
CHANGELOG.mdanddocs/changelog.mddiffer. The two had already drifted by four entries, so the changelog published on the docs site was missing part of whatv1.0.0shipped. - A
promote-changelogworkflow rewrites theUnreleasedheading to a dated version heading and opens a pull request when a version tag is pushed, so the changelog no longer has to be edited by hand at release time.
Removed
- PostgreSQL, Redis and the Celery worker. None were on the request path,
and no module under
backend/srcreadDATABASE_URLor the Celery settings.src/tasks.pyheld a second copy of the mutation code that predated the failure-reporting fixes, and the worker never imported it, so it registered only Celery built-ins. react-router-dom, which was unused.- The CI step that ran
react-scripts test; there are no JavaScript unit tests. Cypress is the frontend suite. python-jose, along with refreshed vulnerable transitive dependencies.
Security
qs, reached only through@cypress/requestin the test runner, resolved to 6.16.1, above the patched line for CVE-2026-8723. Dependabot alert #69.
Known issues
- The API key is embedded in the client bundle.
VITE_API_KEYis inlined at build time, so anyone loading the page can read it. Unresolved and tracked separately.
[1.0.0] - 2025-12-28
The first tagged release. Entries below describe what shipped in 1.0.0 and are written against that tag; later changes are in Unreleased above.
Added
- Molecule generation.
POST /generate_moleculeproduces variants of a supplied SMILES string through random mutations of three types:substituent,bond_orderandatom_swap.mutation_typesoptionally restricts which are used. - A FastAPI service exposing
/generate_molecule,/healthand/docs, with/healthreporting service status and version. - A React web interface that submits a SMILES string, shows the generated molecule as a rendered image, and reports the mutation counters and molecular properties. Built with Create React App and Tailwind CSS.
- API key authentication on every endpoint, via a bearer token.
- A CLI, packaged as a standalone binary and installed under the
mol-platformcommand, for generating without the web interface. - A Docker Compose stack with the FastAPI backend, the frontend, an nginx reverse proxy in front of both, and PostgreSQL and Redis.
- A Celery worker and the
src/tasks.pymodule it loaded. - Tests: backend unit tests for molecule generation, backend e2e tests, and a Cypress frontend suite.
- Linting and hooks: Ruff for Python, with pre-commit configured in the repository.
- Documentation published through MkDocs Material, covering installation, configuration, the CLI, the API, testing and CI/CD.
- Environment configuration via
.env.example, and workflows updated to read theAPI_KEYsecret.
Fixed
- SMILES string manipulation was corrected to perform proper RDKit molecular editing rather than string substitution.
- Sanitisation was added so generated molecules are valid.
numpy.randomwas replaced with the standard libraryrandom, dropping a dependency that was not needed.- Docker dependencies and
PYTHONPATHwere corrected so the image builds. - npm vulnerabilities were resolved.
- Input validation was added across the request boundary.
Changed
- Python was pinned to 3.12 across all environments.
- Dependencies were updated for compatibility.
- Error messages and logging were made more informative.
Technical
- Type-safe random selection, and mutation logic organised into per-type strategies rather than one branching function.
- CI/CD running automated tests, with production containerisation.