Skip to content

🛰️ InterPoll on GenosDB — complete migration, unified (P2P · no servers)#25

Open
estebanrfp wants to merge 17 commits into
Interpoll1:masterfrom
estebanrfp:master
Open

🛰️ InterPoll on GenosDB — complete migration, unified (P2P · no servers)#25
estebanrfp wants to merge 17 commits into
Interpoll1:masterfrom
estebanrfp:master

Conversation

@estebanrfp

Copy link
Copy Markdown

This consolidates the whole InterPoll-on-GenosDB rebuild into a single branch — master as one clean source of truth: the migration, the UI pass and the deploy fix, unified. It supersedes #21 (which tracked an earlier branch); everything from it, plus the later work, now lives here in one place.

What it is: a clean-room rebuild of InterPoll on GenosDB — same Vue 3 + Ionic + Pinia UI, only the data/identity/P2P layer swapped. Browser-to-browser, no servers, signed by default.

By the numbers: runtime deps 28→16 (P2P stack 13→1 = genosdb) · services ~40→21 · source ~46k→23k LOC (−50%) · relay servers 3→0 · zero Gun/IPFS/libp2p · ~116 KB gzip data layer.

What "unified" includes:

  • the full migration — identity, polls/posts/comments, communities, chat, trust, signed-action chain, search, network status
  • the UI pass — dark-mode elevation, shared card-shell, full-width layout (your design identity untouched, only execution)
  • the deploy fix — netlify.toml: the prod build uses absolute asset paths and is an SPA, so it needs serving from the web root + an index.html fallback. One file, validated on a live deploy.

Verified live: https://interpoll-genosdb.netlify.app · https://estebanrfp.github.io/interpoll-genosdb/ — full UI, P2P sync across peers, no servers.

No strings: adopt it, cherry-pick from it, or take it as a parallel edition — whatever fits. Happy to keep contributing via PRs.

estebanrfp and others added 17 commits June 9, 2026 00:29
Rebuilds the entire data/identity/sync layer on GenosDB:
- one dependency instead of the ~30-dep Gun/IPFS/libp2p stack; zero relay servers
- signed-by-default operations; per-identity signed votes with derived, race-free tallies
- Security Manager identity (WebAuthn/BIP39) with open-participation RBAC
- HLC-ordered integrity log, OPFS persistence, GenosRTC P2P sync (verified peer-to-peer)
- ~46k -> ~23k LOC, 40 -> 21 services, vitest suite green

A friendly contribution/showcase; original project & credit: theEndless11/decentralised.
See WHY-GENOSDB.md for the full rationale and measured contrast.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… support

GenosDB ships a self-contained dist/ (gdb entry + its sm/genosrtc/… plugins)
and resolves those plugins at runtime via new URL('./*.min.js', import.meta.url).
Bundling split + hashed them across assets2/, so nested siblings (sm-acls,
sm-gov) were never emitted → 404 in production builds.

Fix (per the official bundler docs' intent): serve GenosDB's dist intact from a
single location and load it without bundler involvement.
- gdbServices: dynamic import of `${BASE_URL}genosdb/index.js`
- vite.config: `genosdb-static` plugin — dev serves the folder from node_modules,
  build copies the whole folder verbatim into dist/genosdb/
- base path + router base via GH_PAGES env for GitHub Pages project sites
- router uses import.meta.env.BASE_URL so the subpath is inherited automatically

Verified on a static server replicating GitHub Pages (subpath + SPA 404.html):
app boots, Security Manager initialises, communities sync — zero 404s.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The authStore already exposed logout() but no UI wired it, so a returning user
with a persisted identity (SM silent-resume) had no way to switch/clear identity
without clearing browser storage by hand. Adds a 'Log out' item at the bottom of
the left nav, shown only while logged in; it calls auth.logout()
(db.sm.clearSecurity()), after which the OnboardingModal (gated on
!auth.isLoggedIn) reappears for re-login or recovery.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- README mermaid: show GenosDB as the hub (Security Manager, graph/OPFS, db.map
  and GenosRTC are its modules) instead of siblings of the browser.
- Bundler note (README, AGENTS.md, WHY-GENOSDB.md): describe the actual approach —
  GenosDB is served intact from a single folder via the genosdb-static plugin —
  not the stale optimizeDeps.exclude:['genosdb'] guidance.
- Cellular mesh: per the official genosrtc-cells docs it's 'Cells', cutting peer
  connections by orders of magnitude (~100x-1000x) vs a full mesh — corrected the
  inaccurate strict O(N^2)->O(N) claim in README, AGENTS.md and WHY-GENOSDB.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e open RBAC

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match upstream's public-domain dedication (theEndless11/decentralised adopted
The Unlicense), so this GenosDB build is unambiguously free to use, modify and
redistribute.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The dev server relied on a custom vite middleware (genosdb-static plugin) to
serve GenosDB's dist/ — fragile across environments, and the cause of the
404 / "Failed to fetch dynamically imported module: /genosdb/index.js" seen
when running pnpm dev (PR Interpoll1#21 feedback).

Now scripts/copy-genosdb.mjs copies node_modules/genosdb/dist into
public/genosdb before vite starts (dev and build), so Vite serves the folder
natively in dev and ships it verbatim in the build — same intact-folder
principle, zero custom server code. Fails fast with a clear message if
node_modules/genosdb is missing (pnpm install).

Verified in-browser: pnpm dev → /genosdb/index.js 200, app boots, no fetch
errors; GH_PAGES=1 pnpm build → dist/genosdb/ intact (13 modules), app boots.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
HomePage mounts underneath the identity gate, so its heavy init step called
UserService.getCurrentUser() before any identity existed and crashed on
currentUser.id ("Heavy init error … reading 'id'"). Worse, nothing re-ran the
step after login, so the chain log and background chat (DM notifications)
were never initialised in a fresh session.

- Extract the step into initUserScopedServices(): idempotent, no-ops without
  an identity, fired on mount AND by a watch on auth.isLoggedIn right after
  the user passes the gate; failures re-arm it for the next login.
- handleLogout tears down chat services and re-arms the init so a different
  identity starts clean.
- getCurrentUser() cache is now validated against the active address — after
  logout + new login it can no longer return the previous identity's profile.
- Chat init paths throw a clear error instead of TypeError when no identity.

Verified in-browser: no console errors pre-login; login fires chain+chat init
(sync-debug start/complete); logout → new identity re-inits cleanly.
95/95 tests pass; production build OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Dark mode set every surface token (bg, elevated, surface, strong, hover) to
pure #000000, so the page, cards and hover states were indistinguishable and
cards effectively invisible; light-mode shadows are invisible on black; muted
text (#70757f) fell below AA. The design language assumes elevation that the
dark theme never provided.

Rebuild the dark tokens only (no component/logic changes): a quiet near-black
indigo-cast elevation ramp (base -> surface -> strong -> hover), AA-legible
muted text, dark-appropriate shadows with a faint brand glow, and item/toolbar
backgrounds lifted off pure black so list rows aren't darker holes. InterPoll's
identity (indigo accent, rounded cards, calm) is unchanged — only its execution
is completed. Verified in-browser across Home/Create/Communities/Settings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Search, Profile, Settings and Chain Explorer dropped content straight into
<ion-content>, so it floated edge-to-edge on the ambient background and looked
unfinished next to the Home tabs (which use a centered, contained card layout).

Add a shared .page-shell (centered max-width column) + .page-panel (reuses the
surface-card look) and apply the existing design language consistently:
- Chain Explorer: centre its card.
- Profile: header + each section become panels; redundant dividers removed.
- Settings: each tab stacks its sections as spaced panels.
- Search: the search controls sit in a panel instead of floating.

No identity change — same indigo accent, rounded cards and calm; the app's own
card language is just applied everywhere instead of only on Home. 95/95 tests
pass; production build OK; verified in-browser across all four pages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Chain Explorer: add a calm empty state ("No blocks yet …") instead of a
  blank card when there are no blocks yet.
- Network (Resilience): centre it in the shared page-shell so it matches the
  other utility pages, and correct the scaling claim — "cutting peer
  connections by orders of magnitude versus a full mesh" instead of the
  inaccurate strict "O(N^2) to O(N)" (matches the GenosDB docs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Same data model, lighter forms — every optional decision now ships with a
sensible default and editing it is opt-in:

- Community: ONE name field — the c/ handle is derived automatically
  (lowercased, spaces -> underscores, live "Will live at c/x" preview), so
  users never learn slug format rules; description optional; default rules
  ("Be respectful", "No spam") collapsed behind "N rules · Customize"; the
  P2P banner is now a one-line note under the button.
- Poll: essentials panel (community, question, options) + settings collapsed
  behind a "7 days · single choice · Customize" summary (duration, multiple
  choice, early results, private/invites, description — all opt-in).
- Post: hero preamble removed, media block flattened to a single
  "Add image (optional)" action; fields and image sit side by side.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
One layout language for every page, using the existing card design instead of
a single narrow stack:

- Shared .page-shell widened (1140px; forms 1080px) + a reusable .form-grid
  (essentials 1.6fr | side panels 1fr, collapses under 900px).
- Profile: identity card beside the edit sections (1/3 + 2/3).
- Settings: sections flow as a responsive panel grid (auto-fit, 360px min).
- Home Communities tab: community cards in an auto-fill grid.
- Search: wider container; result cards distributed in a grid (state rows
  span full width).
- Chain Explorer: blocks flow two-up on wide screens; standalone pages
  (Claim/Vote/Receipt/Results/JoinPrivate/detail views/chat list) adopt the
  same shell so nothing renders edge-to-edge on the ambient background.

Pure presentation — no data or component logic changes. Verified at 1440px
and narrow widths, light and dark.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove the Cellular Mesh card — it presented GenosRTC's optional cells mode
as active, but InterPoll initialises with rtc: true (cells not enabled). The
Network page now shows exactly what runs: Nostr discovery, live connection
status and the peers in the room.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Vite production build uses absolute asset paths (/assets2/...) and loads the GenosDB runtime from /genosdb/*, so dist/ must be served from the web root; and as an SPA it needs an index.html fallback for deep-link refreshes. Without this, a Netlify deploy 404s on the bundles -> blank page. This config makes both work.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant