Repository navigation
feat(boards): share boards by role and keep project settings per member - #9797
Open
joshistoast wants to merge 15 commits into
Open
joshistoast wants to merge 15 commits into
joshistoast wants to merge 15 commits into
Conversation
Replace board visibility, is_public and shared_boards with board_members and general_access, read through the query layer. Key projects by project_id across accounts, re-keying any shared id, and add per-member project_workspaces with a document schema floor. Clear an account's board project memberships when the account is deleted.
Add a board access service that grants viewer, contributor, editor and owner actions from membership and general access; routers, graph execution, workflow calls and upload events all ask it. Boards report general_access, my_role and allowed_actions, keep board_visibility as a deprecated alias, and answer 404 when unreadable and 403 when an action is not allowed. Drop the unused general_access index, and document the roles and the API changes.
…o their owner New draft projects mint project-<uuid> ids like every other client path; a create naming another account's id answers 409 and changes nothing. Origin-scoped queue reads (item ids, current, next, status) return a non-admin only their own items, keeping their query plans. Document global project ids and the queue scoping.
Projects read with the caller's workspace, which saves through its own revision-checked route and indexes its media separately. A document schema floor refuses clients that predate the split; deleting a project or account drops every member's workspace references. Document the content and workspace contract.
Layers, reference images, adjustments and workflow items take UUID-based ids from createItemId instead of a timestamp with a short random suffix.
…'s workspace Saves send the content (raising the document floor to 4) and then the caller's workspace, each at its own revision, and loads join the two halves back into one document. Drafts, recovery, conflicts, copies and duplicates track both halves, and the conflict banner names a settings-only conflict.
…settings .invk v3 writes project.json as content beside an optional workspace.json, behind a remembered "Include my settings for this project" option; v2 files still import, and newer schemas are refused from the manifest. Imports and duplicates create the content, then save the creator's settings, warning when that save fails. Groups the project halves module into the shared startup chunk, restoring the editor's request budget.
Boards shared with you list under Shared with me and admins' other-user boards under their own group; menus offer only what your role allows, with Access for owners. Results, uploads and moves never target a board you can only view: they go to the project inbox, and refused or revoked access refreshes the list with a notice.
…ttings in What's New Multi-user servers show a Share boards headline and the note that Public boards are now Everyone can contribute. Every server notes that layout, generation settings and prompt history stay each member's own in a project.
Board drag between projects is offered only on the caller's own boards their role lets them move. A refused archive restores the auto-add board only if the user has not chosen another since. The workspace reference query-plan check runs on SQLite only.
…haring-foundations
A board the caller can no longer open reads as gone when a project loads, as a deleted one does.
Board moves stay gated on the caller's role rather than board visibility: an owner can move a board whatever its general access.
Observe borrow-release wakeups directly and allow session GC to finish on busy runners. Give nested-loop failure cleanup a consistent integration-test deadline.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lays the foundations for sharing in 7.0, so that later collaboration work (members, share dialog, project grants, locks) does not need another data migration.
Board roles. Every board has an owner and a role per caller: Viewer, Contributor, Editor or Owner, with administrators overriding.
board_accessservice decides every board and item action. Routers, graph execution, workflow calls and upload events all use it.404; an action their role does not allow answers403.board_visibilityandshared_boardsbecomegeneral_access(Restricted / Everyone can view / Everyone can contribute) plus aboard_memberstable.BoardDTOreportsmy_role,allowed_actions,admin_overrideandgeneral_access.Global project ids. Project ids are unique across accounts. Queue reads by origin are scoped to the caller.
Per-member project settings. A project's content (name, canvas, workflows) is saved apart from each member's workspace (layout, widgets, generation settings, prompt history, selection, staging):
project_workspacestable andPUT /projects/{id}/workspace.invkv3:project.jsonis the content, with an optionalworkspace.jsonbehind Include my settings for this projectGallery board UI:
What's New: a "Share boards" headline (multi-user only) and notes on Public boards and per-member settings.
Builds on #9713.
Related Issues / Discussions
Fixes the board half of #9673. Workflow sharing is still listed under known bugs.
QA Instructions
Ran on this branch:
pnpm -C invokeai/frontend/webv2 check:release:ToastContrast(untouched here), can time out on a hover under a heavy full run; it passes 3/3 on its own.uv tool run ruff@0.11.2 check/format --checkon the 85 changed Python files: clean.uv run --no-sync python -m pytest -n 4: 13406 passed, 102 failed, 193 skipped. Each failure was traced to this machine, not this branch:tests/model_identification: the Git LFS fixtures are not fetched here.test_app_info.py(busy database): they fail only whilewebv2/distis built, because the UI's catch-all mount answers first. With the build moved aside, the file passes 36/36.test_16_channel_vae_loader,minimax_h3/test_text_encoder_checkpoint) fail the same way on feat(boards): boards belong to projects, with a Library tier and whole-project transfer #9713's branch.test_directory_install_rollback_race_preserves_both_source_artifacts) depends on the checkout filesystem's directory order. It passes 2/2 from a worktree of this branch, as on feat(boards): boards belong to projects, with a Library tier and whole-project transfer #9713's.test_ministral3_encoder_config,test_mistral_encoder_checkpoint_loader,test_ideogram4_diffusers_loader,test_migration_loader) ran out of/tmpquota here and pass when rerun.test_model_cache_ram_budget.py, caused by running with-p no:warnings; the file passes without it.No failing test is in a file this branch changes.
MySQL and MariaDB run the same suite in CI; the one query-plan check (SQLite's
EXPLAIN QUERY PLAN) is marked SQLite-only.Each migration has its own tests; board roles are migrated from 6.13- and alpha.1-shaped data (
test_migration_2026_10_10_{board_roles,global_project_ids,project_workspaces}.py).To try sharing in the browser against the mock backend:
node --input-type=module -e "import { startMockBackend } from './scripts/mock-backend.mjs'; await startMockBackend(9191, { profile: 'representative' });"frominvokeai/frontend/webv2INVOKEAI_DEV_BACKEND=http://127.0.0.1:9191 pnpm exec vite dev --port 5273curl -X POST -H 'content-type: application/json' -d '{"intermediatesCaller":"user","sharedBoards":true}' http://127.0.0.1:9191/__faults"multiuser-admin"instead of"user"gives the administrator view.POST /__board-accessrevokes access behind the page's back.Verified in the browser this way:
Review
Material findings from review were fixed before merge. Among them:
Remaining limits:
Compatibility / Rollout
Migrations: three linear migrations, after feat(boards): boards belong to projects, with a Library tier and whole-project transfer #9713's:
general_access,board_members;board_visibility/shared_boardsdropped)boards.project_id)project_workspacesplusminimum_document_schema_versionPrivate boards become Restricted, shared boards Everyone can view, and public boards Everyone can contribute.
API:
board_visibilityis kept as a deprecated alias derived fromgeneral_accessuntil 8.0; sending both is a422.board_visibility,shared_user_idsandboard_owner_id.project_idon boards is returned only to owners and administrators.openapi.jsonandschema.tsare regenerated.Clients:
412 document_schema_unsupported) and refuse.invkv3 files.Docs: the multi-user user and admin guides ("Upgrading to 7.0"), the projects and gallery guides, the API guide, the database-layer guide and known bugs are updated.
Checklist
What's Newcopy (if doing a release after this PR)