record progress for gifting meetings

This commit is contained in:
2026-02-18 20:04:14 -07:00
parent 3904e22f72
commit 877df0a0b4
2 changed files with 99 additions and 82 deletions

View File

@@ -29,43 +29,43 @@ We want to enhance this process such that the meeting can be an event where atte
_Note: Build and validate core matching algorithms before UI integration_
- [ ] Implement embedding generation function
- [ ] `generateEmbedding(text)` - call OpenAI API to generate embeddings
- [ ] Handle API keys via environment variables
- [ ] Error handling for API failures
- [ ] Unit tests with real profile descriptions
- [ ] Implement pure JavaScript vector math functions
- [ ] `dotProduct(vec1, vec2)` - multiply and sum vector components
- [ ] `magnitude(vec)` - calculate vector length
- [ ] `cosineSimilarity(vec1, vec2)` - measure similarity (0-1 scale)
- [ ] Unit tests for each function with known inputs/outputs
- [ ] Create test profiles with embeddings
- [ ] Profile 1: Sustainable agriculture focus
- [ ] Profile 2: Similar to Profile 1 (should match highly)
- [ ] Profile 3: Software/tech focus (different from 1 & 2)
- [ ] Profile 4: Community organizing (partial overlap with all)
- [ ] Generate real embeddings from descriptions using OpenAI API
- [ ] Verify embeddings are 1536-dimensional vectors
- [ ] Test similarity calculations
- [ ] Verify high similarity (>0.8) between similar profiles
- [ ] Verify low similarity (<0.5) between dissimilar profiles
- [ ] Verify medium similarity for partial overlaps
- [ ] Test with actual embedding vectors (1536 dimensions)
- [ ] Test basic pairing algorithm
- [ ] 4 people → 2 pairs (highest similarities)
- [ ] 6 people → 3 pairs
- [ ] 5 people → 2 pairs + 1 trio (group of 3)
- [ ] Verify pairs have higher similarity than non-pairs
- [ ] Test constraint handling
- [ ] Exclude specific pairs from matching
- [ ] Exclude individuals from matching pool
- [ ] Multiple rounds with no repeated pairs
- [ ] Test edge cases
- [ ] 2 people (minimum viable)
- [ ] 3 people (one trio)
- [ ] All identical profiles (any pairing is equally good)
- [ ] Empty/minimal profile handling
- [ ] Automated Testing
- [x] Implement embedding generation function
- [x] `generateEmbedding(text)` - call OpenAI API to generate embeddings
- [x] Handle API keys via environment variables
- [x] Error handling for API failures
- [x] Unit tests with real profile descriptions
- [x] Implement pure JavaScript vector math functions
- [x] `dotProduct(vec1, vec2)` - multiply and sum vector components
- [x] `magnitude(vec)` - calculate vector length
- [x] `cosineSimilarity(vec1, vec2)` - measure similarity (0-1 scale)
- [x] Unit tests for each function with known inputs/outputs
- [x] Create test profiles with embeddings
- [x] Profile 1: Sustainable agriculture focus
- [x] Profile 2: Similar to Profile 1 (should match highly)
- [x] Profile 3: Software/tech focus (different from 1 & 2)
- [x] Profile 4: Community organizing (partial overlap with all)
- [x] Generate real embeddings from descriptions using OpenAI API
- [x] Verify embeddings are 1536-dimensional vectors
- [x] Test similarity calculations
- [x] Verify high similarity (>0.8) between similar profiles
- [x] Verify low similarity (<0.5) between dissimilar profiles
- [x] Verify medium similarity for partial overlaps
- [x] Test with actual embedding vectors (1536 dimensions)
- [x] Test basic pairing algorithm
- [x] 4 people → 2 pairs (highest similarities)
- [x] 6 people → 3 pairs
- [x] 5 people → 2 pairs + 1 trio (group of 3) _Note: Changed to require even numbers_
- [x] Verify pairs have higher similarity than non-pairs
- [x] Test constraint handling
- [x] Exclude specific pairs from matching
- [x] Exclude individuals from matching pool
- [x] Multiple rounds with no repeated pairs
- [x] Test edge cases
- [x] 2 people (minimum viable)
- [x] 3 people (one trio) _Note: Changed to throw error for odd numbers_
- [x] All identical profiles (any pairing is equally good)
- [x] Empty/minimal profile handling
- [x] Automated Testing
**Validation:** All tests pass showing effective profile matching based on semantic similarity
@@ -138,20 +138,32 @@ npm run test:generate-embeddings
_Note: Profile storage already exists in endorser-ch partner-api as a simple text field_
Phase 1.1:
- [x] Allow users to create labels to attach to their contacts
- [x] The labels can be created on the edit-user screen
- [x] Show the labels on each user on the DID view contact-details screen
- [x] Show the labels at the top of the contacts page, and only show those contacts if the users clicks that label
Phase 1.2:
- [x] Create flag for permissioned profiles
- [x] Allow a back-end (endorser-ch) flag to tag individuals as always generating embedding vectors
- [x] Add an admin user array, set via environment variable or .env file
- [x] Add tests that only allow an admin to set the generateEmbeddings flag. Allow it for a user who has a profile and also for for a user that does not.
- [x] For any admin user, put a button on the DID view contact screen on the front-end (crowd-funder-pwa) that allows the admin user to tag the user DID to always generate embedding vectors
Phase 1.3:
- [ ] Verify existing profile field supports matching use case
- [ ] Confirm profile text field can hold interests, skills, and goals together
- [ ] Check field length limits are adequate for detailed descriptions
- [ ] Create simple profile creation/edit form
- [ ] Single text area for users to describe interests/skills/goals
- [ ] Character limit indicator (if applicable)
- [ ] Connect to existing partner-api endpoints
- [ ] Profile prompt on meeting join
- [ ] Check if attendee has matching-ready profile (has interests)
- [ ] Show profile creation/update modal if needed
- [ ] Allow skipping if not participating in matching
- [ ] Check if attendee has profile
- [ ] Show profile creation/update modal if needed, but allow them to cancel
- [ ] Image prompt on meeting join
- [ ] Show image creation/update modal if needed, but allow them to cancel
Phase 1.4:
- [ ] Display profiles to other attendees
- [ ] Basic read-only profile cards
- [ ] Fetch from partner-api.endorser.ch
- [ ] In the list of attendees, link to profile for each user if it's known
- [ ] Automated Testing
**Validation:** Attendees can see all attendee profiles after they join
@@ -161,22 +173,26 @@ _Note: Profile storage already exists in endorser-ch partner-api as a simple tex
### Phase 2: AI-Powered Profile Matching
**Goal:** Implement core semantic matching algorithm
- [ ] Set up AI/LLM integration
- [ ] Choose LLM provider (OpenAI, Anthropic, etc.)
- [ ] Configure API keys and rate limits
- [ ] Create embeddings service for profile text
- [X] Set up AI/LLM integration
- [X] Use OpenAI with the text-embedding-3-small model
- [X] Configure API keys and rate limits
- [X] Create embeddings service for profile text
- [X] Store in a new partner table named profile_embedding with the profile ID and with the embeddings as a comma-separated vector string
- [X] For anyone with the generateEmbeddings flag on their profile: call to OpenAI to get their embedding vector when the flag is set, and also when a profile with that flag is changed.
- [X] Allow blank value for embedding and hard-code their vector as the "data.empty.embedding" value from the test/embedding-empty-string.json file
- [ ] Implement matching algorithm
- [ ] Generate embeddings for each profile
- [X] Meeting organizer can trigger a pairing session
- [ ] Allow attendees to be excluded
- [ ] Calculate similarity scores between all pairs
- [ ] Create pairing algorithm (maximize total similarity)
- [ ] For an odd number, include 3 people in one of the groups
- [x] Pairing data is saved in the DB
- [x] Calculate similarity scores between all pairs
- [x] Create pairing algorithm (maximize total similarity)
- [ ] Create "do not pair" groups
- [ ] Basic matching endpoint
- [ ] POST endpoint for organizer to trigger matching
- [ ] Return list of pairs with similarity scores
- [ ] Simple results display
- [ ] Show matched pairs to attendees
- [ ] Assign numbers to each pair
- [x] POST endpoint for organizer to trigger matching
- [x] Return list of pairs with similarity scores
- [x] Simple results display
- [x] Show matched pairs to attendees
- [x] Assign numbers to each pair
- [ ] Automated Testing
**Validation:** Organizer can trigger matching, and all attendees can see AI-generated pairs with reasonable similarity
@@ -189,13 +205,13 @@ _Note: Profile storage already exists in endorser-ch partner-api as a simple tex
- [ ] Enhance organizer matching interface
- [ ] Visual display of pairs (cards, grid, or list)
- [ ] Show pair numbers prominently
- [ ] Display similarity reasoning (why these people matched)
- [ ] Create a new screen that lists all the attendees, along with their profile (if it's visible to the organizer) -- truncated, but allowed to be expanded
- [ ] Participant view of matches
- [ ] Show participants their assigned pair
- [x] Show participants their assigned pair
- [ ] Display partner's profile information
- [ ] Show pair number
- [x] Show pair number
- [ ] Real-time updates
- [ ] WebSocket or polling for match announcements
- [x] WebSocket or polling for match announcements
- [ ] Notify participants when matching is triggered
- [ ] Allow easy adding of notes onto the contact of the matched person
- [ ] Allow easy adding of an offer to the matched person
@@ -210,15 +226,14 @@ _Note: Profile storage already exists in endorser-ch partner-api as a simple tex
- [ ] Exclusion groups
- [ ] UI for organizer to select people
- [ ] Create "do not pair" groups
- [ ] Persist exclusion rules across rounds
- [ ] Exclude non-participants
- [ ] Option to mark organizer or others as excluded
- [ ] Ensure excluded people don't appear in matching pool
- [ ] Multiple matching rounds
- [ ] Track previous pairs in meeting state
- [ ] Constraint: don't repeat previous pairs
- [ ] Calculate when no more unique pairs possible
- [x] Track previous pairs in meeting state
- [x] Constraint: don't repeat previous pairs
- [x] Calculate when no more unique pairs possible
- [ ] Show organizer "rounds remaining" indicator
- [ ] Round history
- [ ] Store all previous rounds
@@ -233,13 +248,12 @@ _Note: Profile storage already exists in endorser-ch partner-api as a simple tex
### Phase 5: Post-Event Features and Polish
**Goal:** Enable long-term value and edge case handling
- [ ] Allow a back-end (endorser-ch) flag to mark users with admin permission, so they can tag individuals as always generating embedding vectors
- [ ] Post-event attendee list
- [ ] Persist attendee relationships after meeting deletion
- [ ] Create "past event" view showing all attendees
- [ ] Link to profiles even after event expires
- [ ] Meeting expiration handling
- [ ] Archive meeting data (don't delete attendee info)
- [ ] Maintain contact visibility permissions
- [ ] Archive meeting data on client side
- [ ] Analytics and insights
- [ ] Show match quality scores to organizer
- [ ] Track which pairs connected post-event
@@ -254,7 +268,7 @@ _Note: Profile storage already exists in endorser-ch partner-api as a simple tex
- [ ] Support for very small (2-3 people) or large (50+) groups
- [ ] Handle profile updates mid-matching
- [ ] Performance optimization
- [ ] Cache embeddings to avoid regeneration
- [x] Cache embeddings to avoid regeneration
- [ ] Optimize matching algorithm for large groups
- [ ] Add loading states and progress indicators
- [ ] Automated Testing
@@ -325,14 +339,3 @@ _Note: This is an optional enhancement that could significantly improve onboardi
- Start with greedy pairing (highest similarity pairs first)
- Could evolve to weighted bipartite matching for optimal global solution
- Need to handle constraints efficiently (exclusions, previous pairs)
**Data Model:**
- Profile: `{ userId, description: string, embedding: vector }` (description field already exists in partner-api)
- Meeting: extend to include `{ profileUserIds: string[], rounds: Round[], exclusionGroups: string[][] }`
- Round: `{ number: int, pairs: Pair[], timestamp: datetime }`
- Pair: `{ userIds: [string, string], similarityScore: float, pairNumber: int }`
**Privacy:**
- Attendees should consent to AI processing of their profiles
- Consider allowing profile visibility controls
- Meeting password security for sensitive gatherings is ensured by current features

View File

@@ -49,6 +49,20 @@
### Workshop Style (2-3 hours)
0. Preparation
- make flyer
- meeting goal?
Building a gifting society, in ways that fulfill us
Get us to where voluntary giving provides our basic needs
Getting more and more of our needs via gifts
Supporting more and more of our livelihoods via gifts
- Put out survey for their email (some contact for ID)
- Neil & I onboard people & invite them
- we gather the list of individuals and add to a group
- Send all profiles to get the embeddings & generate groups
- some people my come late, so gotta allow generation & pairing at event
- create handout
1. Welcome + ? (20 min)
- Ensure everyone has profile
4. App onboarding (30 min)