feat: allow partial domain removal and add conflict status

- Add partial domain removal functionality allowing users to remove their own claims and votes even when they're not the resolved claimant
- Add conflict status detection for domains where local peer has claim but another claimant won consensus
- Update UI to display conflict status with red badge
- Enhance API responses with detailed consensus information
- Update all documentation with new features

Changes:
- core/core.js: Add removeOwnClaimAndVotes() function for partial removal
- admin/routes/domains.js: Implement partial/full removal logic in /api/remove-domain
- admin/admin-backend/routes/domains.js: Same partial removal logic for backend routes
- plugins/sdk.js: Update removeDomain() to support partial removal
- admin/ui/config.js: Add conflict status badge and update postFetch
- admin/admin-frontend/ui/config.js: Add conflict status badge and fix status rendering
- admin/utils.js: Add conflict status to utility functions
- admin/admin-frontend/utils.js: Add conflict status to utility functions
- docs/CONSENSUS.md: Add conflict status to resolution states
- docs/README_LONGFORM.md: Add conflict status to consensus states
- docs/RESTAPI.md: Update /api/resolved-domains with new fields and examples
- docs/ARCHITECTURE.md: Document full vs partial removal modes
- docs/OPENAPI.yaml: Update Domain schema and add ConsensusState schema
This commit is contained in:
Raven Scott
2025-12-26 15:32:41 -05:00
parent ea1bcb569a
commit 480f99ae28
13 changed files with 234 additions and 61 deletions
+7 -5
View File
@@ -32,6 +32,7 @@ function getConsensusStatusBadge(status) {
const badges = {
'resolved': '<span class="px-2 py-1 bg-green-500 text-white rounded text-xs">Resolved</span>',
'tie': '<span class="px-2 py-1 bg-yellow-500 text-white rounded text-xs">Tie</span>',
'conflict': '<span class="px-2 py-1 bg-red-500 text-white rounded text-xs">Conflict</span>',
'insufficient_quorum': '<span class="px-2 py-1 bg-orange-500 text-white rounded text-xs">No Quorum</span>',
'no_claims': '<span class="px-2 py-1 bg-gray-500 text-white rounded text-xs">No Claims</span>',
'error': '<span class="px-2 py-1 bg-red-500 text-white rounded text-xs">Error</span>',
@@ -79,11 +80,11 @@ window.tabs = {
const tr = document.createElement('tr');
tr.className = 'border-b hover:bg-gray-50 dark:hover:bg-gray-700';
// Use consensus state from postFetch if available
// Use consensus status from postFetch (which may include 'conflict')
let consensusInfo = '';
if (item.consensusState) {
const consensusState = item.consensusState;
const statusBadge = getConsensusStatusBadge(consensusState.status);
const statusBadge = getConsensusStatusBadge(item.consensusStatus);
const voteInfo = Object.keys(consensusState.voteCounts || {}).length > 0
? ` (${Object.values(consensusState.voteCounts).reduce((a, b) => a + b, 0)} votes)`
: '';
@@ -113,9 +114,10 @@ window.tabs = {
if (item.consensusStatus === 'internal' || item.hash === 'internal' || item.hash === 'none') {
return { ...item, consensusStatus: 'internal' };
}
return {
...item,
consensusStatus: item.consensusState?.status || 'unknown'
// Use consensusStatus set by backend (including 'conflict'), fallback to consensusState status
return {
...item,
consensusStatus: item.consensusStatus || item.consensusState?.status || 'unknown'
};
});
}