Result preparation feature designed and planned befor implementing

This commit is contained in:
AG
2025-10-11 15:38:07 +03:00
parent d4b1b1af01
commit 42303b1fc3
9 changed files with 521 additions and 1 deletions

View File

@@ -5,6 +5,8 @@ Auto-generated from all feature plans. Last updated: 2025-10-09
## Active Technologies
- Node.js (LTS), TypeScript 5.x (001-people-tend-to)
- Browser Local Storage (Primary store for session state). The backend is stateless. (001-people-tend-to)
- TypeScript (v5.x) (002-result-preparation-refactoring)
- In-memory for session data (no persistent storage) (002-result-preparation-refactoring)
## Project Structure
```
@@ -19,7 +21,7 @@ npm test [ONLY COMMANDS FOR ACTIVE TECHNOLOGIES][ONLY COMMANDS FOR ACTIVE TECHNO
Node.js (LTS), TypeScript 5.x: Follow standard conventions
## Recent Changes
- 001-people-tend-to: Added Node.js (LTS), TypeScript 5.x
- 002-result-preparation-refactoring: Added TypeScript (v5.x)
- 001-people-tend-to: Added Node.js (LTS), TypeScript 5.x
- 001-people-tend-to: Added Node.js (LTS), TypeScript 5.x

View File

@@ -0,0 +1,34 @@
# Specification Quality Checklist: Result Preparation Refactoring
**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2025-10-11
**Feature**: [Link to spec.md]
## Content Quality
- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed
## Requirement Completeness
- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified
## Feature Readiness
- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification
## Notes
- Items marked incomplete require spec updates before `/speckit.clarify` or `/speckit.plan`

View File

@@ -0,0 +1,90 @@
openapi: 3.0.0
info:
title: Anonymous Desire Aggregator API
version: 2.0.0
description: API for facilitating real-time, private, anonymous decision-making sessions.
paths:
/sessions:
post:
summary: Get a new unique session ID
operationId: createSession
responses:
'201':
description: Session ID created successfully.
content:
application/json:
schema:
type: object
properties:
sessionId:
type: string
format: uuid
description: The unique ID for the session. Clients will use this to join the WebSocket channel.
/sessions/{sessionId}/analyze:
post:
summary: Trigger the semantic analysis for a session
operationId: triggerAnalysis
parameters:
- name: sessionId
in: path
required: true
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
allDesires:
type: array
description: A complete list of all desire sets from all participants, collected by the client.
items:
type: object
properties:
wants:
type: array
items:
type: string
accepts:
type: array
items:
type: string
noGoes:
type: array
items:
type: string
responses:
'202':
description: Analysis has been successfully triggered. Results will be broadcast over the WebSocket.
'404':
description: Session not found.
# WebSocket Protocol (/sessions/{sessionId})
# The primary communication for this application is via WebSockets. The backend acts as a message relay and orchestrator.
#
# Client-to-Server Messages:
#
# - type: 'SHARE_STATE'
# payload: { session: Session } # Client sends its entire session object to sync with others.
#
# - type: 'SUBMIT_DESIRES'
# payload: { desireSet: DesireSet } # A single user submits their desires.
#
# Server-to-Client Messages:
#
# - type: 'USER_JOINED'
# payload: { participantId: string }
#
# - type: 'STATE_UPDATE'
# payload: { session: Session } # Broadcasts the latest session state to all clients.
#
# - type: 'ANALYSIS_COMPLETE'
# payload: { decision: Decision } # Broadcasts the final results.
#
# - type: 'SESSION_LOCKED'
# payload: {}

View File

@@ -0,0 +1,46 @@
# Data Model: Result Preparation Refactoring
**Date**: 2025-10-11
**Feature**: Result Preparation Refactoring
This document defines the data structures used in the feature.
## Entities
### DesireSet
Represents a single user's submission.
| Field | Type | Description |
|---|---|---|
| participantId | string | The unique identifier for the participant. |
| wants | string[] | A list of things the participant wants. |
| accepts | string[] | A list of things the participant is willing to accept. |
| noGoes | string[] | A list of things the participant does not want. |
### Session
Represents a single session where users submit their desires.
| Field | Type | Description |
|---|---|---|
| sessionId | string | The unique identifier for the session. |
| state | SessionState | The current state of the session (`SETUP`, `GATHERING`, `HARMONIZING`, `FINAL`, `ERROR`). |
| expectedResponses | number | The number of participants expected to submit their desires. |
| submittedCount | number | The number of participants who have submitted their desires. |
| responses | Map<string, DesireSet> | A map of participant IDs to their submitted `DesireSet`. |
| clients | Map<string, WebSocket> | A map of client IDs to their WebSocket connections. |
| finalResult | Decision \| null | The final categorized result of the session. |
| topic | string \| null | The topic of the session. |
### Decision
Represents the final categorized result of the analysis.
| Field | Type | Description |
|---|---|---|
| goTos | string[] | A list of items that all participants want. |
| alsoGoods | string[] | A list of items that some participants want and others accept. |
| considerables | string[] | A list of items that are wanted or accepted by some participants. |
| noGoes | string[] | A list of items that at least one participant does not want. |
| needsDiscussion | string[] | A list of items with conflicting desires. |

View File

@@ -0,0 +1,73 @@
# Implementation Plan: Result Preparation Refactoring
**Branch**: `002-result-preparation-refactoring` | **Date**: 2025-10-11 | **Spec**: [spec.md](spec.md)
**Input**: Feature specification from `/specs/002-result-preparation-refactoring/spec.md`
## Summary
This plan outlines the refactoring of the result preparation mechanism. The current system groups similar desires but does not categorize them into the required `Go-to`, `Also good`, `Considerable`, `No-goes`, and `Needs discussion` categories. This refactoring will replace the existing desire grouping logic in the `LLMService` with a more sophisticated analysis that aligns with the feature specification. The frontend will be updated to correctly display these new categories.
## Technical Context
**Language/Version**: TypeScript (v5.x)
**Primary Dependencies**:
- **Backend**: Node.js, Express, ws (WebSockets), @google/generative-ai
- **Frontend**: React, Material-UI, WebSockets
**Storage**: In-memory for session data (no persistent storage)
**Testing**: Jest
**Target Platform**: Web Browser
**Project Type**: Web Application (Frontend + Backend)
**Performance Goals**: Real-time updates for session state changes. LLM analysis should complete within a reasonable time frame (e.g., < 10 seconds).
**Constraints**: The solution must integrate with the existing WebSocket-based communication.
**Scale/Scope**: Sessions support up to 20 participants.
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
- **I. Defined Technology Stack**: PASS (Node.js, React)
- **II. UI/UX Consistency**: PASS (Material-UI is used)
- **III. Container-First Development**: PASS (Docker is used)
- **IV. Test-Driven Development (TDD)**: PASS (Tests exist and will be added)
- **V. API-First Design**: PASS (Backend and frontend are decoupled)
## Project Structure
### Documentation (this feature)
```
specs/002-result-preparation-refactoring/
├── plan.md # This file (/speckit.plan command output)
├── research.md # Phase 0 output (/speckit.plan command)
├── data-model.md # Phase 1 output (/speckit.plan command)
├── quickstart.md # Phase 1 output (/speckit.plan command)
├── contracts/ # Phase 1 output (/speckit.plan command)
└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
```
### Source Code (repository root)
```
backend/
├── src/
│ ├── services/
│ │ └── LLMService.ts
│ └── ws/
│ └── index.ts
└── tests/
frontend/
├── src/
│ ├── components/
│ │ └── ResultsDisplay.tsx
│ ├── hooks/
│ │ └── useSession.ts
│ └── pages/
│ └── SessionPage.tsx
└── tests/
```
**Structure Decision**: The existing project structure will be used. The primary changes will be in the `backend/src/services/LLMService.ts` and `backend/src/ws/index.ts` for the backend, and `frontend/src/components/ResultsDisplay.tsx` for the frontend.
## Complexity Tracking
No violations to the constitution were identified.

View File

@@ -0,0 +1,47 @@
# Quickstart: Result Preparation Refactoring
**Date**: 2025-10-11
**Feature**: Result Preparation Refactoring
This document provides instructions on how to run and test the refactored result preparation feature.
## Running the Application
1. **Start the backend**:
```bash
cd backend
npm install
npm start
```
2. **Start the frontend**:
```bash
cd frontend
npm install
npm start
```
3. Open a web browser and navigate to `http://localhost:3000`.
## Testing the Feature
1. **Create a session**: Click on the "Create Session" button. This will generate a unique session URL.
2. **Share the session URL**: Share the URL with another person (or open it in a new incognito window to simulate another user).
3. **Set up the session**: As the session creator, set the topic and the number of expected responses.
4. **Submit desires**: Each participant should fill out the desire form and submit it.
5. **View the results**: Once all participants have submitted their desires, the system will automatically analyze them and display the categorized results.
### Example Test Case
- **Participant 1**:
- **Wants**: "Pizza"
- **Accepts**: "Pasta"
- **Doesn't Want**: "Salad"
- **Participant 2**:
- **Wants**: "Pizza"
- **Accepts**: "Pasta"
- **Doesn't Want**: "Tacos"
### Expected Result
- **Go-to**: ["Pizza"]
- **Also good**: ["Pasta"]
- **No-goes**: ["Salad", "Tacos"]

View File

@@ -0,0 +1,53 @@
# Research: LLM-based Desire Categorization
**Date**: 2025-10-11
**Feature**: Result Preparation Refactoring
## Objective
To design a prompt for the Google Gemini LLM that takes a list of user desires (categorized as "wants", "accepts", and "no-goes") and returns a categorized list of `Go-to`, `Also good`, `Considerable`, `No-goes`, and `Needs discussion` items.
## Research & Findings
The core of the refactoring is to create a robust prompt that can handle the complex logic of categorizing desires. The prompt needs to instruct the LLM to perform the following steps:
1. **Identify Unique Desires**: The first step is to identify the unique desires across all participants. The current `LLMService` already does this, and this logic can be reused.
2. **Categorize Desires**: The main challenge is to categorize the unique desires based on the rules defined in the specification.
### Prompt Design
The following prompt is designed to be sent to the Gemini model. It includes the logic for categorization and the expected JSON output format.
```prompt
You are an AI assistant that analyzes and categorizes user desires from a session. Given a list of desire sets from multiple participants, your task is to categorize them into the following groups: "Go-to", "Also good", "Considerable", "No-goes", and "Needs discussion".
Here are the rules for categorization:
- "Go-to": Items that ALL participants want.
- "Also good": Items that at least one participant wants, and all other participants accept.
- "Considerable": Items that are wanted or accepted by some, but not all, participants, and are not "No-goes" for anyone.
- "No-goes": Items that at least ONE participant does not want. These items must be excluded from all other categories.
- "Needs discussion": Items where there is a direct conflict (e.g., one participant wants it, another does not want it).
The input will be a JSON object containing a list of desire sets. Each desire set has a participantId and three arrays of strings: "wants", "accepts", and "noGoes".
The output should be a JSON object with the following structure:
{
"goTo": ["item1", "item2"],
"alsoGood": ["item3"],
"considerable": ["item4"],
"noGoes": ["item5"],
"needsDiscussion": ["item6"]
}
Here is the input data:
[INPUT_JSON]
```
### Decision
The `LLMService` will be updated to use this new prompt. The `analyzeDesires` method will be refactored to take the desire sets as input and return the categorized result in the specified JSON format. The existing desire grouping logic will be replaced.
### Alternatives Considered
- **Rule-based System**: A purely rule-based system could be implemented to categorize the desires. However, this would be very complex to implement and maintain, especially when dealing with the nuances of natural language. Using an LLM simplifies this process significantly.
- **Multi-step LLM Chain**: A more complex approach would be to use multiple LLM calls to first group the desires, then categorize them. However, a single, well-defined prompt is more efficient and less prone to errors.

View File

@@ -0,0 +1,109 @@
# Feature Specification: Result Preparation Refactoring
**Feature Branch**: `002-result-preparation-refactoring`
**Created**: 2025-10-11
**Status**: Draft
**Input**: User description: "Users fill the response form with what they WANT, ACCEPT, and DO NOT WANT. Each field contains a text expressing user's desires. At least one of the fields is required. System checks each field for inner contradictions using an LLM. In case of contradictions, the system must ask the user to eliminate them. When all responses are received, the system initiates analysis and returns a result. The result is a cooperative decision prepared by an LLM based on everyone's opinions. The decision includes categories: `Go-to`, `Also good`, `Considerable`, `No-goes`, and `Needs discussion`."
## Clarifications
### Session 2025-10-11
- Q: How should the system handle the unavailability of the LLM service during a contradiction check? → A: A
- Q: How does the system know when all responses for a session have been received? → A: Existing function: session creator states the number of expected responses when creating a session.
- Q: What is the maximum number of participants a session should support? → A: Make it 20.
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Submit Desires (Priority: P1)
A user fills out a form with their desires (what they want, accept, and don't want) and submits it.
**Why this priority**: This is the core functionality for a user to input their desires.
**Independent Test**: A user can open the form, fill in at least one of the fields, and successfully submit it.
**Acceptance Scenarios**:
1. **Given** a user is on the desire submission page, **When** they fill in the "WANT" field and click submit, **Then** their submission is accepted.
2. **Given** a user is on the desire submission page, **When** they do not fill in any fields and click submit, **Then** they receive an error message.
---
### User Story 2 - Inner Contradiction Check (Priority: P1)
The system checks the user's submitted desires for internal contradictions within each category. If contradictions are found, the user is prompted to resolve them.
**Why this priority**: Ensures the quality and consistency of user input before the final analysis.
**Independent Test**: A user submits a desire set with a contradiction (e.g., "I want a dog" and "I don't want any pets" in the WANT field), and the system identifies the contradiction and prompts the user for correction.
**Acceptance Scenarios**:
1. **Given** a user has submitted a desire set with an internal contradiction, **When** the system processes the submission, **Then** the user is presented with a message indicating the contradiction and is asked to revise their submission.
2. **Given** a user has submitted a desire set with no internal contradictions, **When** the system processes the submission, **Then** the submission is accepted without any warnings.
---
### User Story 3 - Generate Cooperative Decision (Priority: P2)
After all users have submitted their non-contradictory desires, the system analyzes them and generates a cooperative decision with the categories: `Go-to`, `Also good`, `Considerable`, `No-goes`, and `Needs discussion`.
**Why this priority**: This is the final output of the feature and delivers the core value to the users.
**Independent Test**: Given a set of desire submissions from multiple users, the system can generate a categorized result.
**Acceptance Scenarios**:
1. **Given** all users have submitted their desires, **When** the analysis is triggered, **Then** a result is generated with the five specified categories.
2. **Given** a set of desires where all users want "A", **When** the analysis is run, **Then** "A" appears in the `Go-to` category.
3. **Given** user 1 wants "B" and user 2 accepts "B", **When** the analysis is run, **Then** "B" appears in the `Also good` category.
4. **Given** user 1 wants "C" and user 2 has no opinion on "C", **When** the analysis is run, **Then** "C" appears in the `Considerable` category.
5. **Given** user 1 does not want "D", **When** the analysis is run, **Then** "D" appears in the `No-goes` category and not in any other category.
6. **Given** user 1 wants "E" and user 2 does not want "E", **When** the analysis is run, **Then** "E" appears in the `Needs discussion` category.
### Edge Cases
- What happens if the LLM service is unavailable for contradiction checking? The system will display an error message and prevent the user from submitting their desires.
- How does the system handle a large number of participants in a session? A session will support a maximum of 20 participants.
- What happens if a user's input is very long? The system will enforce a character limit of 500 characters per desire field. The UI will display a character counter under each field. If the input exceeds this limit, the system will return an error message and prevent submission.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: The system MUST provide a form with three text fields: "What you WANT", "What you ACCEPT", and "What you DO NOT WANT".
- **FR-001a**: The UI MUST display a character counter under each of the three desire input fields.
- **FR-002**: The system MUST require at least one of the three fields to be filled.
- **FR-003**: The system MUST use an LLM to check for inner contradictions within each of the three fields of a user's submission.
- **FR-004**: If inner contradictions are found, the system MUST inform the user and ask them to revise their submission.
- **FR-005**: The system MUST be able to receive and store desire submissions from multiple users for a session.
- **FR-006**: The system MUST trigger the analysis process after all responses for a session are received.
- **FR-007**: The system MUST generate a result categorized into `Go-to`, `Also good`, `Considerable`, `No-goes`, and `Needs discussion`.
- **FR-008**: The `Go-to` category MUST contain items that all participants want and have no contradictions.
- **FR-009**: The `Also good` category MUST contain items that at least one participant wants and all other participants accept.
- **FR-010**: The `Considerable` category MUST contain items that are wanted or accepted by some, but not all, participants.
- **FR-011**: The `No-goes` category MUST contain items that at least one participant does not want. These items MUST be excluded from all other categories.
- **FR-012**: The `Needs discussion` category MUST contain items where contradictions are found between participants' desires.
- **FR-013**: The system MUST present the final categorized result to the users.
### Key Entities *(include if feature involves data)*
- **Desire Set**: A user's submission, containing three text fields: `want`, `accept`, `dont_want`.
- **Session**: A collection of `Desire Set`s from multiple users.
- **Result**: The categorized output of the analysis of a `Session`.
### Assumptions
- The LLM service for contradiction checking and result preparation is available and responsive.
- The number of participants in a session and the length of their inputs are within reasonable limits for the LLM to process effectively.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: 100% of user submissions are checked for inner contradictions.
- **SC-002**: The system correctly identifies and categorizes desires according to the rules in 100% of cases with no contradictions.
- **SC-003**: The system correctly identifies and categorizes desires into the "Needs discussion" category when contradictions exist between users.
- **SC-004**: Users can successfully submit their desires in under 1 minute.

View File

@@ -0,0 +1,66 @@
# Tasks for: Result Preparation Refactoring
**Feature**: `002-result-preparation-refactoring`
**Spec**: [spec.md](spec.md)
**Plan**: [plan.md](plan.md)
## Implementation Strategy
The implementation will be done in phases, focusing on refactoring the backend logic first, followed by the frontend updates. The backend and frontend tasks can be worked on in parallel.
**MVP Scope**: The Minimum Viable Product will include the refactored `LLMService` that can categorize desires and the updated `ResultsDisplay` component to show the new categories.
---
## Phase 1: Foundational Tasks (Backend Refactoring)
These tasks focus on updating the backend to handle the new desire categorization logic.
- **T001**: [Test] Create a new test file `backend/tests/LLMService.refactor.test.ts` to test the new desire categorization functionality.
- **T002**: [Backend] Refactor `backend/src/services/LLMService.ts` to replace the existing `analyzeDesires` method with one that uses the new prompt from `research.md` to categorize desires into `Go-to`, `Also good`, `Considerable`, `No-goes`, and `Needs discussion`.
- **T003**: [Backend] Update the WebSocket handler in `backend/src/ws/index.ts` to call the refactored `LLMService.analyzeDesires` method and broadcast the new `Decision` object to clients.
---
## Phase 2: User Story 1 & 2 - Desire Submission & Contradiction Check
**Goal**: A user can submit their desires, and the system checks for inner contradictions.
**Independent Test**: Submit a desire set with an inner contradiction (e.g., "I want a dog" and "I don't want any pets" in the same category) and verify that the system returns an error.
- **T004**: [Test] Add a test case to `backend/tests/LLMService.refactor.test.ts` for the inner contradiction check.
- **T005**: [Backend] Implement a new method `checkForInnerContradictions` in `backend/src/services/LLMService.ts` that uses an LLM to detect contradictions within a single desire set.
- **T006**: [Backend] Update the `SUBMIT_RESPONSE` message handler in `backend/src/ws/index.ts` to call `checkForInnerContradictions` before accepting a user's submission. If contradictions are found, send an error message back to the user.
- **T006a**: [Backend] In the `SUBMIT_RESPONSE` message handler in `backend/src/ws/index.ts`, add validation to ensure each desire field does not exceed 500 characters.
- **T006b**: [Frontend] [P] Update the `frontend/src/components/DesireForm.tsx` component to display a character counter under each input field.
---
## Phase 3: User Story 3 - Cooperative Decision (Frontend Refactoring)
**Goal**: The frontend can correctly display the categorized results from the refactored backend.
**Independent Test**: Given a set of desires from multiple users, the frontend correctly renders the `Go-to`, `Also good`, `Considerable`, `No-goes`, and `Needs discussion` categories.
- **T007**: [Frontend] [P] Update the `Decision` and related types in `frontend/src/hooks/useSession.ts` to match the new backend structure defined in `data-model.md`.
- **T008**: [Test] [P] Create a test file `frontend/src/components/ResultsDisplay.refactor.test.tsx` to test the updated `ResultsDisplay` component.
- **T009**: [Frontend] Refactor the `frontend/src/components/ResultsDisplay.tsx` component to display the new categories (`goTos`, `alsoGoods`, `considerables`, `noGoes`, `needsDiscussion`).
---
## Phase 4: Polish & Integration
- **T010**: Perform end-to-end testing of the entire workflow.
- **T011**: Clean up any old code related to the previous desire grouping logic.
- **T012**: Remove the old test files `backend/tests/llmService.test.ts` and `frontend/src/components/ResultsDisplay.test.tsx` after verifying the new tests provide adequate coverage.
- **T013**: [Test] Conduct performance testing to ensure that the desire submission process completes in under 1 minute as per SC-004.
---
## Dependencies
- **US1 & US2** are prerequisites for **US3**. The backend logic for contradiction checking and desire submission must be in place before the final results can be generated and displayed.
## Parallel Execution
- The backend tasks in **Phase 1 & 2** can be worked on in parallel with the frontend tasks in **Phase 3**.
- **Backend Team**: Can work on T001-T006.
- **Frontend Team**: Can work on T007-T009 using mock data until the backend is ready.