feat: Complete Step 3 & 4 - OAuth + SurrealDB schema
Step 3: ATproto OAuth + SurrealDB JWT - Implement database-backed OAuth state storage (lib/auth/oauth-state.ts) - Add session helpers for JWT decoding (lib/auth/session.ts) - Fix OAuth callback to properly handle state retrieval - Create /chat page displaying authenticated user handle - Configure headless mode for Magnitude testing Step 4: SurrealDB Schema & Permissions - Define JWT-based access control (HS512 algorithm) - Create user table with DID-based identity - Create node table with row-level security (users can only access their own data) - Create links_to relation table for graph edges - Define vector search index (1536 dimensions for gemini-embedding-001) - Add Docker Compose for local SurrealDB development 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
91
db/schema.surql
Normal file
91
db/schema.surql
Normal file
@@ -0,0 +1,91 @@
|
||||
-- --------------------------------------------------
|
||||
-- Ponderants :: SurrealDB Schema
|
||||
-- --------------------------------------------------
|
||||
|
||||
-- --------------------------------------------------
|
||||
-- Access Control (JWT)
|
||||
-- --------------------------------------------------
|
||||
|
||||
-- Define the JWT access method. This tells SurrealDB to trust
|
||||
-- JWTs signed by our Next.js backend using the HS512 algorithm
|
||||
-- and the secret key provided in the environment.
|
||||
-- (Note: DEFINE TOKEN is deprecated as of 2.x)
|
||||
DEFINE ACCESS app_jwt
|
||||
ON DATABASE
|
||||
TYPE JWT
|
||||
ALGORITHM HS512
|
||||
KEY $env.SURREALDB_JWT_SECRET;
|
||||
|
||||
-- --------------------------------------------------
|
||||
-- Table: user
|
||||
-- --------------------------------------------------
|
||||
|
||||
-- Stores basic user information, cached from ATproto.
|
||||
DEFINE TABLE user SCHEMAFULL;
|
||||
|
||||
-- The user's decentralized identifier (DID) is their primary key.
|
||||
DEFINE FIELD did ON TABLE user TYPE string
|
||||
ASSERT $value != NONE;
|
||||
|
||||
DEFINE FIELD handle ON TABLE user TYPE string;
|
||||
|
||||
-- Ensure DIDs are unique.
|
||||
DEFINE INDEX user_did_idx ON TABLE user COLUMNS did UNIQUE;
|
||||
|
||||
-- --------------------------------------------------
|
||||
-- Table: node
|
||||
-- --------------------------------------------------
|
||||
|
||||
-- Stores a single "thought node." This is the cache record for
|
||||
-- the com.ponderants.node lexicon.
|
||||
DEFINE TABLE node SCHEMAFULL
|
||||
-- THIS IS THE CORE SECURITY MODEL:
|
||||
-- Users can only perform actions on nodes where the
|
||||
-- node's 'user_did' field matches the 'did' claim
|
||||
-- from their validated JWT ('$token.did').
|
||||
PERMISSIONS
|
||||
FOR select, create, update, delete
|
||||
WHERE user_did = $token.did;
|
||||
|
||||
-- Foreign key linking to the user table (via DID).
|
||||
DEFINE FIELD user_did ON TABLE node TYPE string
|
||||
ASSERT $value != NONE;
|
||||
|
||||
-- The canonical URI of the record on the ATproto PDS.
|
||||
DEFINE FIELD atp_uri ON TABLE node TYPE string;
|
||||
|
||||
DEFINE FIELD title ON TABLE node TYPE string;
|
||||
DEFINE FIELD body ON TABLE node TYPE string;
|
||||
|
||||
-- The AI-generated vector embedding for the 'body'.
|
||||
-- We use array<number> for the vector.
|
||||
DEFINE FIELD embedding ON TABLE node TYPE array<number>;
|
||||
|
||||
-- The 3D coordinates calculated by UMAP.
|
||||
DEFINE FIELD coords_3d ON TABLE node TYPE array<number>
|
||||
-- Must be a 3-point array [x, y, z] or empty.
|
||||
ASSERT $value = NONE OR array::len($value) = 3;
|
||||
|
||||
-- Define the vector search index.
|
||||
-- We use MTREE (or HNSW) for high-performance k-NN search.
|
||||
-- The dimension (1536) MUST match the output of the
|
||||
-- 'gemini-embedding-001' model.
|
||||
DEFINE INDEX node_embedding_idx ON TABLE node FIELDS embedding MTREE DIMENSION 1536;
|
||||
|
||||
-- --------------------------------------------------
|
||||
-- Relation: links_to
|
||||
-- --------------------------------------------------
|
||||
|
||||
-- This is a graph edge table, relating (node)->(node).
|
||||
DEFINE TABLE links_to SCHEMAFULL
|
||||
-- Security for graph edges: A user can only create/view/delete
|
||||
-- links between two nodes that BOTH belong to them.
|
||||
PERMISSIONS
|
||||
FOR select, create, delete
|
||||
WHERE
|
||||
(SELECT user_did FROM $from) = $token.did
|
||||
AND
|
||||
(SELECT user_did FROM $to) = $token.did;
|
||||
|
||||
-- (No fields needed, it's a simple relation)
|
||||
-- Example usage: RELATE (node:1)-[links_to]->(node:2);
|
||||
Reference in New Issue
Block a user