# User Stories for P2P Chat Application > **Reference:** [webrtc.org](https://webrtc.org) The following user stories describe a peer-to-peer chat and voice application (Discord-like) built with **Electron** and **Angular** (using RxJS and NgRx) with a local SQLite store (via SQL.js). A central server only provides a directory of active rooms and users; all message and audio/video data is exchanged directly between peers (no port forwarding needed). Stories are grouped by role and include acceptance criteria and technical notes. --- ## Regular User ### Search and Join Chat Server **User Story:** As a Regular User, I want to search for available chat servers (rooms) by name or topic so that I can find and join active communities. **Acceptance Criteria:** - A search input allows queries against the central directory of servers. - Matching servers are returned and listed with details (name, current user count, etc.). - I can select a server from the list and send a join request. - If the server exists and is active, I am connected to that server's peer network. - Error is shown if the server is not found or unavailable. **Technical Notes:** - Use Angular's `HttpClient` to call the central REST API (e.g. `GET /servers?search={query}`), which returns an Observable. - Use RxJS operators (e.g. `debounceTime`) to handle user input. - Use Angular components/forms for the search UI and display results. Use `async` pipe in templates for Observables. - Store search results and selected server info in an NgRx store or Angular Signals to manage state and reactively update UI. --- ### Create Chatroom (Become Host) **User Story:** As a Regular User, I want to create a new chatroom so that I can start my own voice/text server; I should automatically become the room's host. **Acceptance Criteria:** - I can create a named room; the central server registers the new room. - I join the newly created room and see myself listed as the host/owner. - The host can set an optional password or topic for the room. - Other users searching for rooms see this new room available. - If I disconnect without others online, the room is removed from the server directory. **Technical Notes:** - Use Angular forms to input room details and NgRx actions to handle creation. Dispatch an action that posts to the central server API (e.g. `POST /servers`) and upon success updates the local store. - In the NgRx state, mark the creator as `host: true`. Follow NgRx best practices (immutable state, action-driven updates). - No code style notes here beyond following lint rules (e.g. `prefer const`, `no var`, 2-space indent). - After creation, initiate the P2P mesh: the host opens listening sockets (WebRTC or TCP sockets) and waits for peers (see "P2P Connectivity" story). --- ### Join Existing Chatroom **User Story:** As a Regular User, I want to join an existing chatroom so that I can participate in it. **Acceptance Criteria:** - I can select an available room and request to join. - The host is notified of my request and (if approved) I connect to the room. - If no approval step, I immediately join and synchronize chat history and participants. - Upon joining, I receive the current chat history (text and possibly voice stream) from one or more peers. **Technical Notes:** - Use Angular Router or services to handle navigation/joining logic. - When joining, use a WebRTC signaling channel (via the central server or direct peer signaling) to exchange ICE candidates (STUN/TURN). - Once connected, use WebRTC DataChannels for chat data and Streams for audio/video. - On the host side, use NgRx Effects to handle incoming join events and broadcast initial state (messages and user list) to new peer. --- ### Send, Edit, Delete, and React to Messages **User Story:** As a Regular User, I want to send text messages, and edit or delete my own messages (and react to any message), so that I can communicate effectively and correct mistakes. **Acceptance Criteria:** - I can type and send a chat message, which is immediately delivered to all peers. - I can edit or delete any of my own previously sent messages; these edits/deletions update on all peers in real time. - I can react (e.g. add emoji) to any message; reactions are displayed next to the message for all users. - All message operations (send/edit/delete/react) are performed instantly (optimistic UI) and confirmed or synchronized with peers. - Deleted messages are removed from the UI for all users. **Technical Notes:** - Use WebRTC `RTCDataChannel` (via a library like `simple-peer` or native API) for sending JSON-encoded message events between peers. Data channels provide reliable, ordered delivery for text. - Maintain a local message store (NgRx store or Signals) that holds all chat messages and reactions. Update the store immutably and broadcast updates to other peers. - Persist messages locally using SQL.js: run SQLite in-memory and after significant changes call `db.export()` to save state (or write to a file via Electron). On join, import/export to synchronize history (SQL.js can load an existing `Uint8Array` DB). - Implement send/edit/delete/react actions and reducers/effects in NgRx. Ensure all reducers treat state immutably and use NgRx Effects for any asynchronous broadcasts. - Follow lint rules for event handlers and functions (`no-unused-vars`, consistent naming). --- ### Voice Chat (Push-to-Talk) **User Story:** As a Regular User, I want to join a voice channel within the chatroom so that I can talk to other participants (e.g. using push-to-talk or a switch). **Acceptance Criteria:** - I can enable my microphone and connect to the voice channel. - Other users hear my voice with low latency, and I hear theirs. - Only one person needs to be host; no central server relaying audio. - If I mute or leave, others no longer hear me. - Voice quality adapts to network (e.g. uses Opus codec). **Technical Notes:** - Use WebRTC MediaStreams for audio: call `navigator.mediaDevices.getUserMedia({ audio: true })` to capture microphone audio. Add this audio track to the peer connection. - On receiving side, use a `