DESDEO 2.4.0
[2.4.0] - 14.4.2026
Core logic
Added
- Added CVXPY solver support with full integration into the problem/solver
stack (#466). - Updated
guess_best_solverto include CVXPY and to check for a valid Gurobi
license (#468).
Changed
- Updated gurobipy implementation: tensor constants can now be used without
errors (#464).
Fixed
- Fixed infinite loop in
dmitry_forest_problem_disc()(use relative path
instead of walking up to theDESDEOfolder), which also caused
conftest.pyto hang.
Web API
Added
- Added NAUTILUS Navigator endpoints
/initializeand/navigate, with
NautilusNavigatorInitializationStateandNautilusNavigatorNavigationState
states and unit tests. - Added constrained variant endpoint
POST /problem/{problem_id}/constrained_variantwithVariableFixing,
ConstrainedVariantRequest, andConstrainedVariantResponsemodels. - Added
is_temporaryandparent_problem_idfields toProblemDBfor
variant tracking. - Added site-selection endpoints
POST /site-selection/load_metadataand
POST /site-selection/map, backed by a newSiteSelectionMetaDataDB model
(follows theForestProblemMetaDatapattern). - Added E-NAUTILUS what-if simulation endpoint
POST /method/enautilus/simulate(ephemeral, no DB writes) with
ENautilusSimulateRequest/Response/StepResultmodels and a
deprioritizeflag for worst-case selection. - Added endpoint returning the list of DM users.
- Added
/add_new_dmendpoint (restricted to analyst/admin) and enabled
analysts/admins to create and manage problems and interactive sessions on
behalf of DMs. - Added
fetch_problem_with_role_checkand
fetch_interactive_session_with_role_checkhelpers inutils.pyfor
role-aware ownership bypass. - Added
?target_user_id=parameter onPOST /session/newfor analysts to
create sessions on behalf of DMs. - Added endpoint returning an HTTP exception based on an error code.
- Added tests for the constrained-variant endpoint, the site-selection
endpoint, and DM-user/problem-ownership behavior.
Changed
- Refactored NAUTILUS Navigator to follow the E-NAUTILUS patterns: replaced
legacy manual auth/problem loading withSessionContextGuard, moved
request/response models fromschemas/tomodels/asSQLModel, used
Problem.from_problemdb(), and walkedStateDB.parentfor session-scoped
parent-chain traversal. - Deleted
desdeo/api/schemas/(no longer needed after the model migration). - Session/problem listing endpoints now return all sessions/problems for
analysts (own only for DMs); empty lists return200 + []instead of404. - Problem action endpoints (delete, solver, JSON, representative sets) now
allow analyst access to any problem. - Simplified
DELETE /problem/{problem_id}: owners can delete any of their
problems. - Restricted
POST /add_new_dmto analyst/admin (was previously public). - Removed the legacy
/clinic/router,ClinicMapRequest/Responsemodels,
andclinic_map.pyin favor of the metadata-driven site-selection map. - Added
401and500login responses to the API/OpenAPI generator.
Fixed
- Fixed
SessionContextGuardHTTP status codes:404for missing resources,
403for ownership failures (previously400for both). - Fixed
InteractiveSessionBasemissingfrom_attributes=True, which caused
POST /session/newto return{}. - Fixed swapped arguments in
fetch_interactive_session(utils.py). - Fixed
test_delete_problem_unauthorizedandtest_constraint_variantto
expect the correct403/404status codes.
Web GUI
Added
- Added rudimentary Manage Users page (
/manage-users) for analysts and
admins to create DM and analyst accounts; route is server-side guarded and nav
visibility is role-based (auth store populated on topbar mount). - Added analyst/admin management of other users' interactive sessions and
problems: user filter dropdown (default "Myself"), Owner column/field, and
"Create for" / DM selectors on session and problem creation. - Added map metadata upload dialog on the Problems page (JSON file
upload); renamedclinic-map.sveltetosite-selection-map.sveltewhich
now accepts aproblem_idprop. - Added map interaction in E-NAUTILUS: click site markers to cycle
free → restricted → forced; multiple sites per city node are constrained
together; re-solve with RPM using E-NAUTILUS final objectives as aspiration
levels; constrained variant inherits the parent problem's solver metadata. - Added comparison bottom panel with tabbed Parallel Coordinates /
Comparison Table views; solution tab shows the constrained solution with
the original as a dashed comparison line; "Use this solution" accepts the
constrained result, "Reset" reverts to the original. - Added what-if scenario simulation in the Decision Journey view: "best"
(blue) and "worst" (red) buttons per objective, dashed-line overlays with
hollow-circle markers, and an actual-vs-what-if comparison table with
colored deltas. - Added catch-all proxy route
/api/[...path]that forwards browser API
calls throughevent.fetchsohandleFetchintercepts for cookie
injection and401/token-refresh handling. - Added generated Orval endpoints for NAUTILUS Navigator and enabled Orval
Zod body-schema generation. - Added login error display after unsuccessful login attempts.
Changed
- Replaced the hardcoded clinic map system with the new metadata-driven
site-selection map. - Unrolled tensor variables in RPM results for frontend compatibility
(e.g.sv→sv_1..sv_60). - Updated API client to use correct URLs for debug/deploy;
getUrlnow
returns a relative/api/<path>on the browser side, with a
http://localhost:8000fallback detected viatypeof window === 'undefined'
on the server side. - Removed client-side
401retry logic fromcustomFetch— now handled
server-side byhandleFetchvia the proxy; removed the dead Vite/api
proxy config fromvite.config.ts. - Replaced
$effectwith an explicitoninputhandler for clearing login
errors and removed a debugconsole.logfrom the login server action. - Default Decision Journey visualization pane height raised to 65% for more
chart room; selected iteration highlighted with a vertical band. - Regenerated Orval clients multiple times to pick up new endpoints.
Fixed
- Fixed various URL-resolving and access-token cookie issues affecting
deployment. - Fixed Orval import mismatches after regeneration
(getProblemProblemGetPost,addRepresentativeSolutionSet).
Documentation
Added
- Added a guide on how to deploy the fullstack on OpenShift using the
octool from a terminal.
Changed
- Updated deployment documentation and polished deployment files.
- Updated the
webuiREADME (including theAPI_BASE_URLfix).
Tooling, CI, and deployment
Added
- Added a
justfileand therust-justdependency —justis a
drop-in cross-platform replacement formakeand is available on PyPI. - Added a Python version of
run_fullstack.shso it runs on all
Python-compatible platforms. - Added a GitHub workflow for running the Web GUI tests with Vite.
- Added
secretsto.gitignore.
Changed
- Updated docs so that references to
make/Makefilenow point to
just/justfile. - Updated build and Dockerfiles; switched
npm citonpm installin
webui/Dockerfile. - General Rahti deployment testing and configuration updates.
Full Changelog: v2.3.0...v2.4.0