GroupHome

GroupHome is a browser-first group coordination platform for organizations that want to move official work out of WhatsApp-style chat streams. It keeps chat secondary and makes structured objects first-class: announcements, events, RSVPs, tasks, polls, files, members, migration status, devices, notification preferences, and remote server aggregation.

What Is Implemented

  • FastAPI backend with SQLAlchemy and SQLite by default.
  • React/Vite/TypeScript frontend with mobile bottom navigation and desktop side navigation.
  • Accountless invite joining with hashed invite tokens and HttpOnly session cookies.
  • Prominent Chat entry point with messenger-style threads, left/right speech bubbles, author names, sent times, and configurable folding for short low-signal replies.
  • Chat composer that suggests structured follow-ups while typing and can manually create polls, events, tasks, announcements, invite links, or feedback notes from a conversation.
  • Group dashboards for important items, upcoming events, open actions, announcements, files, polls, tasks, and discussions.
  • Home dashboard sections: Needs me, Today / Upcoming, Changed since last visit, Official updates, Catch up.
  • Event RSVP, task completion, poll voting, local file upload/download, discussion threads.
  • Admin migration dashboard, QR-ready invite URL generation, reminder copy, legacy-channel status, read-only .txt chat archive import.
  • Recovery links in development mode, device pairing, device revocation, notification preferences, and passkey-shaped development provider.
  • Self-hosting seed protocol: /.well-known/group-platform.json, /api/sync, scoped connection codes, and remote cache aggregation.

Architecture

Browser / PWA
  -> React frontend
  -> FastAPI home server + group server
       -> SQLite/PostgreSQL-compatible SQLAlchemy models
       -> local file storage in development
       -> optional remote group servers through /api/sync

One server can act as a home server, a group server, or both. Remote aggregation is not federation: the home server uses a scoped server-side connection code to fetch structured objects from selected remote group servers.

Quick Start

cp .env.example .env
docker compose up --build

Open http://localhost:5173.

The compose backend runs seed data on startup. For local backend-only development:

cd backend
python -m app.db.seed
uvicorn app.main:app --reload
pytest

For frontend-only development:

cd frontend
npm install
npm run dev
npm run test
npm run build

Seed Demo

Seed data creates Anna Müller across:

  • FC Kreuzberg U12 Parents
  • Class 4B Parents
  • Tenant Association
  • Food Bank Volunteers

It includes missing RSVPs, a changed training location, assigned tasks, an open tenant poll, files requiring acknowledgement, official announcements, discussions, and migration state.

The seed command prints:

  • demo invite URL: http://localhost:5173/join/demo-fc-invite
  • demo remote connection code: demo-remote-sync-code

Invite Flow

Open /join/demo-fc-invite, enter a display name, and join without email, password, or native app install. After joining, the browser receives an HttpOnly session cookie and can immediately RSVP from the join page or group dashboard.

Chat On-Ramp

Open Chat from the bottom navigation or desktop side navigation. Chat is intentionally familiar: group threads, speech bubbles, names, and sent times. While typing, the composer suggests when the text looks like a poll, event, task, announcement, invite, or feedback item; the user must explicitly choose that structured chip before it creates the object. Short replies such as “ok” and “thanks” can be folded with the chat toggle.

Device Linking

Open Me -> Devices.

  1. Start a pairing code on the new device.
  2. Approve that code from an existing signed-in browser.
  3. Complete pairing on the new browser.
  4. Revoke stale devices from the device list.

Remote Aggregation Demo

Single-server demo:

  1. Open Me -> Servers.
  2. Create a connection code, or use seed code demo-remote-sync-code.
  3. Connect http://localhost:8000.
  4. Sync. Remote items appear on Home with remote source badges.

Two-server demo:

cd backend
DATABASE_URL=sqlite:///./remote.db SERVER_NAME="Club Server" SERVER_ORIGIN=http://localhost:8001 API_BASE_URL=http://localhost:8001/api FRONTEND_ORIGIN=http://localhost:5173 python -m app.db.seed
DATABASE_URL=sqlite:///./remote.db SERVER_NAME="Club Server" SERVER_ORIGIN=http://localhost:8001 API_BASE_URL=http://localhost:8001/api uvicorn app.main:app --port 8001

Then connect http://localhost:8001 from the main app with the remote server's printed connection code.

Security Notes

  • Invite, recovery, and remote connection codes are stored only as hashes.
  • Sessions use HttpOnly cookies. A readable CSRF cookie/header is wired for production mode; development mode keeps same-site cookie auth simple.
  • Remote connection codes are stored server-side in a development adapter field, not in browser localStorage.
  • File names are sanitized and upload size is limited.
  • Role checks protect invites, official announcements, member management, migration, and remote connection codes.

Known Limitations

  • SMTP is not configured; recovery links are logged/returned in development mode.
  • Passkeys use a pluggable development provider, not production WebAuthn.
  • Web push is a future adapter.
  • No full federation, native app, unofficial messenger bridge, or production E2EE.
  • File storage is local filesystem in development; production should use mounted storage or S3-compatible storage.
  • Remote writes generally open the source context; local RSVP write-through is implemented.

Roadmap

  • Harden production CSRF and secret management.
  • Add PostgreSQL compose profile and migrations.
  • Add richer archive parsing for WhatsApp .txt exports.
  • Add calendar export and optional web push.
  • Replace development passkey provider with full WebAuthn.
Description
No description provided
Readme AGPL-3.0 187 KiB
Languages
Python 61.5%
TypeScript 31.7%
CSS 5.6%
Shell 1%
HTML 0.1%