WS8 PR F: firm model preferences

↗ view on GitHub · sloth-ninja · 2026-07-27 · e504926a

Add a third firm policy (memberModelPrefs) and firm model configuration
(default model + offered providers) on top of the #44 migration columns.

When a firm turns the policy OFF: members' personal model-preference writes
are gated (fixed 403), their stored prefs become inert (never deleted) and the
firm default governs server-side resolution, and the model pickers are filtered
to the firm's offered providers. Orgless self-hosters and policy-ON firms are
unchanged everywhere. All new columns read 42703-tolerantly; the gate and
resolver fail open on lookup error. No migration, no new env vars, no new deps.

Backend: organisations.ts (policy + modelConfig on membership,
getUserOrganisationModelContext, get/setOrganisationModelConfig,
normaliseModelConfig); llm/models.ts (MODEL_PROVIDERS, isSelectableModelId);
userSettings.ts + serializeProfile firm-aware resolution; requireMemberPolicy
gate on PATCH /user/profile (model fields only, admins not exempt); admin
PATCH /policies memberModelPrefs + GET/PATCH /admin/model-config with 400 on
unknown model/provider.

Frontend: mikeApi types + get/updateFirmModelConfig; firmPolicy helpers;
account/models neutral card under policy-off + offered-provider filtering;
ModelToggle offeredProviders prop (chat + tabular); firm-settings third policy
toggle + Model configuration card.

Tests: 295 backend vitest pass (24 files) incl. new userSettings.test.ts and
extended auth.policy/organisations/user.serialize/admin suites. Frontend tsc
clean; eslint no new problems on changed files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Repository Sloth-ninja/JessicaOSS
Author sloth-ninja <ezanahaddis@gmail.com>
Authored
Parents 51891a1d
Stats 19 files changed , +1380 , -23
Part of WS8 PR F: firm model preferences

Capture this commit into my fork

Download a Markdown prompt that tells Claude how to port this exact commit into your working tree. Run it via claude -p < capture-commit-e504926a.md from inside the repo you want the change in.

⬇ Download capture-commit-e504926a.md