mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-16 13:38:33 +00:00
feat: enforce singleton local node per instance (#1567)
Only one local node is allowed. Creating a second local returns 409, and the last local node cannot be deleted or converted to a remote type. Existing duplicate local nodes from older versions are preserved and can be cleaned up individually. Zero-local recovery auto-assigns the default flag. Frontend delete surfaces and the Add Node form respect the new invariant. Enforced in DatabaseService (addNode/updateNode/deleteNode guards) and routes (error translations). Legacy test fixtures use raw SQL helpers.
This commit is contained in:
@@ -288,7 +288,7 @@ export function NodeManager() {
|
||||
{resettingAnchor === nodeId ? 'Resetting...' : 'Reset anchor on peer'}
|
||||
</Button>
|
||||
)}
|
||||
{node && !node.is_default && (isAdmin || can('node:manage', 'node', String(nodeId))) && (
|
||||
{node && !node.is_default && nodes.filter(n => n.type === 'local').length > 1 && (isAdmin || can('node:manage', 'node', String(nodeId))) && (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
@@ -324,6 +324,7 @@ export function NodeManager() {
|
||||
<TableBody>
|
||||
{nodes.map((node) => {
|
||||
const canManageThis = isAdmin || can('node:manage', 'node', String(node.id));
|
||||
const isLastLocal = node.type === 'local' && nodes.filter(n => n.type === 'local').length <= 1;
|
||||
return (
|
||||
<TableRow key={node.id}>
|
||||
<TableCell>
|
||||
@@ -493,7 +494,7 @@ export function NodeManager() {
|
||||
</TooltipProvider>
|
||||
)}
|
||||
|
||||
{!node.is_default && canManageThis && (
|
||||
{!node.is_default && !isLastLocal && canManageThis && (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
|
||||
Reference in New Issue
Block a user