docs: add Supabase integration report#53
Conversation
Covers product overview, use-cases for Supabase users, architecture diagram, database schema, step-by-step setup instructions, the memory system, and links to relevant docs. https://claude.ai/code/session_015ER1eiSHoNeyUaRgBz8n2F
There was a problem hiding this comment.
Pull request overview
This PR adds an INTEGRATION_REPORT.md file providing a comprehensive guide for Supabase integration with the Inworld Language Tutor app. The document covers the product overview, use-cases, architecture, database schema, setup instructions, and the memory system in detail.
Changes:
- Adds a new
INTEGRATION_REPORT.mdfile documenting the Supabase integration end-to-end. - Documents the dual-mode architecture (anonymous vs. authenticated), setup steps, and environment variable reference.
- Describes the memory system, including the semantic retrieval SQL query and memory types.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| │ memory-retrieval-node → calls match_memories() RPC │ | ||
| │ state-update-node → stores new memories │ |
There was a problem hiding this comment.
The architecture diagram attributes memory storage to state-update-node, but this is incorrect. Looking at the code, state-update-node only updates the connection state with the LLM's response (StateUpdateNode.process() in backend/src/graphs/nodes/state-update-node.ts). Memory storage is actually performed by MemoryProcessor via a callback set up in websocket-handler.ts (lines 181–201). The diagram entry state-update-node → stores new memories should be corrected to reflect that a background MemoryProcessor handles this responsibility.
| │ memory-retrieval-node → calls match_memories() RPC │ | |
| │ state-update-node → stores new memories │ | |
| │ memory-retrieval-node → calls match_memories() RPC│ | |
| │ background MemoryProcessor → stores new memories │ |
| FROM user_memories | ||
| WHERE user_id = $1 | ||
| AND embedding IS NOT NULL | ||
| AND embedding <=> query_embedding < (1 - 0.7) -- threshold |
There was a problem hiding this comment.
The SQL snippet in the Memory System section hardcodes the similarity threshold as 0.7, but the actual runtime value used by MemoryRetrievalNode is 0.5 (defined as MEMORY_SIMILARITY_THRESHOLD = 0.5 in backend/src/graphs/nodes/memory-retrieval-node.ts, line 26). The match_memories RPC function accepts the threshold as a parameter (match_threshold), and the node passes 0.5 at runtime. The comment -- threshold next to (1 - 0.7) is therefore misleading and does not reflect the actual behaviour of the application.
| AND embedding <=> query_embedding < (1 - 0.7) -- threshold | |
| AND embedding <=> query_embedding < (1 - 0.5) -- similarity threshold |
| | Table | Purpose | | ||
| |-------|---------| | ||
| | `user_preferences` | Stores the user's preferred target language | | ||
| | `conversations` | One row per conversation session, keyed by `(user_id, language_code)` | |
There was a problem hiding this comment.
The conversations table is described as "keyed by (user_id, language_code)", which implies a unique constraint. However, looking at the actual migration (supabase/migrations/20240108000000_initial_schema.sql), there is no UNIQUE constraint on (user_id, language_code) in the conversations table — a user can have multiple conversations in the same language. The wording "keyed by" is inaccurate and should be replaced with something like "filtered by" or simply "associated with".
| | `conversations` | One row per conversation session, keyed by `(user_id, language_code)` | | |
| | `conversations` | One row per conversation session, associated with `(user_id, language_code)` | |
Covers product overview, use-cases for Supabase users, architecture diagram, database schema, step-by-step setup instructions, the memory system, and links to relevant docs.
https://claude.ai/code/session_015ER1eiSHoNeyUaRgBz8n2F