Merge NEXT: planning, generation map and portable configuration on top of the OIDC access model

NEXT predates the access work, so the identity layer follows master: access comes from
configured groups, instance administrators replace the site administration, and accounts are
created by SSO or by an administrator. Kept from NEXT: manual publication with the Review
changes panel and shared generator drafts, portable import/export (meguri/v2), the layered
generation map with binding provenance, JSM provider changes, contact/approval semantics and
the account-owned Person. Dropped: site administration, local sign-up, and the mandatory
unique email with its contact/account migrations. The manual-publication migration is
renumbered m_0010 after m_0009_access.

Accounts without an email still get a Person in every workspace they reach, a changed sign-in
email updates the account's person, and an account that loses access keeps its linked person so
schedules stay valid. Instance administrators may use Sync and shared drafts.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Aleksandr BogomiakovandClaude committed 2026-10-07 16:06:10 +01:00
commit 38105c65c2
57 files changed
+6890 -431

No files matched your search

+7
View File
@@ -63,8 +63,15 @@ fs.mkdirSync('test-results',{recursive:true});
await order(['Third','First','Second']);
await page.getByRole('button',{name:'Move Third down',exact:true}).click();await order(['First','Third','Second']);
await route('Second').getByRole('button',{name:'Edit',exact:true}).click();
await dialog().getByLabel('Field',{exact:true}).selectOption('priority');
await dialog().getByLabel('Operation',{exact:true}).selectOption('less-than');
await dialog().getByLabel('Value',{exact:true}).fill('P3');
await dialog().getByRole('checkbox',{name:'Not',exact:true}).check();
await page.screenshot({path:'test-results/routing-priority.png',fullPage:true});
assert.equal(await dialog().getByLabel('Position',{exact:true}).inputValue(),'3');
await dialog().getByLabel('Position',{exact:true}).selectOption('1');await save();await order(['Second','First','Third']);
assert.deepEqual((await state()).document.routes.find(r=>r.name==='Second').conditions,[{field:'priority',operation:'less-than',value:'P3',negate:true}]);
await page.getByRole('button',{name:'+ Routing rule',exact:true}).click();
await dialog().getByLabel('Rule name',{exact:true}).fill('Fourth');
await dialog().getByLabel('Position',{exact:true}).selectOption('2');await save();await order(['Second','Fourth','First','Third']);