# Data Model: Afraid to Ask **Feature Branch**: `004-afraid-to-ask` | **Date**: 2025-10-13 | **Spec**: [../spec.md](D:\Coding\unisono\specs\004-afraid-to-ask\spec.md) **Input**: Feature specification from `/specs/004-afraid-to-ask/spec.md` ## Entities ### Session Represents a common session for multiple anonymous users. - **id**: Unique identifier for the session (string) ### Idea Represents an anonymous user's input within a session, which can be a "Want", "Accept", or "Afraid to Ask" idea. - **id**: Unique identifier for the idea (string) - **sessionId**: ID of the session to which the idea belongs (string, foreign key to Session.id) - **type**: Type of the idea (enum: `Want`, `Accept`, `AfraidToAsk`) - **content**: The raw text content of the idea (string). For `AfraidToAsk` ideas, this field will store the *encrypted* content. - **privacyStatus**: Indicates the visibility of the idea (enum: `Private`, `Public`). `AfraidToAsk` ideas start as `Private`. - **isCompliant**: (Boolean, optional) For `AfraidToAsk` ideas, indicates if it semantically complies with another user's "Want" or "Accept" idea within the *same session*. This is determined by the backend. - **createdAt**: Timestamp of when the idea was created (datetime) ## Relationships - **Session** 1:N **Idea**: A session can contain multiple ideas from different anonymous users. ## Data Flow for "Afraid to Ask" Ideas 1. **Client-side Encryption**: When an anonymous user submits an "Afraid to Ask" idea, the raw content is encrypted client-side using an ephemeral key derived from the current session. The *encrypted* content is then stored in the user's browser local storage. 2. **Server-side Processing (Ephemeral)**: When semantic comparison is required, the encrypted idea is sent to the backend via WebSocket, along with the `sessionId`. * The backend decrypts the idea in memory (using a server-managed key or derived from the `sessionId`). * Semantic comparison is performed using an LLM (Google Cloud Natural Language API) against other "Want" and "Accept" ideas within the *same session*. * The raw decrypted idea is immediately discarded from memory. * The server stores the *encrypted* idea and its `isCompliant` status (and other metadata) in an ephemeral session store or in-memory cache, tied to the `sessionId`. 3. **Session Termination**: Upon session termination (e.g., when all users leave the common session), all encrypted "Afraid to Ask" ideas and their associated metadata are purged from the server-side ephemeral storage. 4. **Result Display**: Only `Public` ideas (including `AfraidToAsk` ideas that have become `Public` due to compliance within the session) are sent to clients via WebSocket for display.