OverviewFilesCommitsIssuesDocsReleasesPeers

pear-git commits / cb98eca

Fix group writes to use shared MetadataBase instead of local manager
handleCreateNamespace was writing to the local NamespaceManager (single-writer Hyperbee) instead of the GroupFacade (shared Autobase). Groups created on one server never replicated to peers. Now: create/update/delete/addRepo/removeRepo/addMember/removeMember all route through the shared MetadataBase when available. Local manager is fallback only when no shared registry exists. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cb98eca341af6578dda28942181ddefef86b061d
by plankatron <fleeky@gmail.com> · 2026-04-05T17:32:36.000Z

Changed files (2) +12 -22

lib/metadata-base.js +0 -1
……@@ -141,7 +141,6 @@ export class MetadataBase {
141141 break
142142
143143 case 'group':
144 console.log(`[Apply] group op: ${op.type} ${op.name || ''} from writer ${writer}`)
145144 await applyGroupOp(op, batch, base)
146145 break
147146
lib/routes/namespaces.js +12 -21
……@@ -68,14 +68,12 @@ async function getNamespace (server, name) {
6868}
6969
7070/**
71 * Write: route to the backend that owns the group
71 * Write: always prefer shared MetadataBase (replicates to peers).
72 * Fall back to local manager only if shared registry unavailable.
7273 */
7374async function getBackendFor (server, name) {
7475 const { namespaceManager, namespaceRegistry } = server.namespaceData
75 if (namespaceRegistry) {
76 const shared = await namespaceRegistry.get(name)
77 if (shared) return namespaceRegistry
78 }
76 if (namespaceRegistry) return namespaceRegistry
7977 return namespaceManager
8078}
8179
……@@ -305,7 +303,7 @@ async function handleGetNamespace (req, res, server) {
305303}
306304
307305async function handleCreateNamespace (req, res, server) {
308 const { namespaceManager } = server.namespaceData
306 const { namespaceManager, namespaceRegistry } = server.namespaceData
309307 try {
310308 const body = await readJson(req)
311309 const { name, type, displayName, description } = body
……@@ -315,7 +313,9 @@ async function handleCreateNamespace (req, res, server) {
315313 return
316314 }
317315
318 const result = await namespaceManager.create(name, type || 'group', {
316 // Write to shared MetadataBase when available (replicates to peers)
317 const backend = namespaceRegistry || namespaceManager
318 const result = await backend.create(name, type || 'group', {
319319 displayName,
320320 description
321321 })
……@@ -331,20 +331,11 @@ async function handleReconsolidate (req, res, server) {
331331 const { namespaceManager, namespaceRegistry } = server.namespaceData
332332 const { repos } = server.repoData
333333 try {
334 const results = { local: null, shared: null }
335
336 // Reconsolidate local groups
337 if (namespaceManager && namespaceManager.reconsolidateGroups) {
338 results.local = await namespaceManager.reconsolidateGroups(repos || [])
339 }
340
341 // Reconsolidate shared groups
342 if (namespaceRegistry && namespaceRegistry.reconsolidateGroups) {
343 results.shared = await namespaceRegistry.reconsolidateGroups(repos || [])
344 }
345
346 console.log('[Groups] Reconsolidated:', results)
347 json(res, { success: true, ...results })
334 // Prefer shared MetadataBase for reconsolidation (replicates to peers)
335 const backend = namespaceRegistry || namespaceManager
336 const result = await backend.reconsolidateGroups(repos || [])
337 console.log('[Groups] Reconsolidated:', result)
338 json(res, { success: true, ...result })
348339 } catch (err) {
349340 console.error('[API] Reconsolidate error:', err)
350341 json(res, { error: err.message }, 500)