Skip to content

Conversation

maparent
Copy link
Collaborator

@maparent maparent commented Oct 8, 2025

https://linear.app/discourse-graphs/issue/ENG-950/optimize-data-access-following-the-simulation

Summary by CodeRabbit

  • New Features

    • Space-scoped public views for accounts, spaces, documents, contents, and concepts.
    • New helpers to fetch schemas, instances, related concepts, authors, and linked documents/contents.
    • New embedding-backed content view and vector similarity matching for content search.
  • Security

    • Stronger per-space access helpers and updated policies enforcing ownership and space membership.
  • Improvements

    • Clearer error messages when creating a space.
    • Anonymous session signed out after password sign-in during space creation to avoid auth conflicts.

Copy link

linear bot commented Oct 8, 2025

Copy link

supabase bot commented Oct 8, 2025

Updates to Preview Branch (eng-950-optimize-data-access-following-the-simulation) ↗︎

Deployments Status Updated
Database Wed, 15 Oct 2025 00:16:04 UTC
Services Wed, 15 Oct 2025 00:16:04 UTC
APIs Wed, 15 Oct 2025 00:16:04 UTC

Tasks are run on every commit but only new migration files are pushed.
Close and reopen this PR if you want to apply changes from existing seed or migration files.

Tasks Status Updated
Configurations Wed, 15 Oct 2025 00:16:05 UTC
Migrations Wed, 15 Oct 2025 00:16:05 UTC
Seeding Wed, 15 Oct 2025 00:16:05 UTC
Edge Functions Wed, 15 Oct 2025 00:16:08 UTC

View logs for this Workflow Run ↗︎.
Learn more about Supabase for Git ↗︎.

@maparent
Copy link
Collaborator Author

maparent commented Oct 8, 2025

@CodeRabbit review

Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@maparent maparent force-pushed the eng-950-optimize-data-access-following-the-simulation branch from 9dc305e to 8b79fa1 Compare October 8, 2025 18:24
@maparent maparent changed the base branch from main to eng-898-create-database-query-functions-for-base-dg-queries October 8, 2025 18:24
@maparent
Copy link
Collaborator Author

maparent commented Oct 8, 2025

@CodeRabbit review again, I force-pushed and changed the base.

Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

@maparent: I'll perform a full review of the PR now that you've force-pushed and changed the base branch.

✅ Actions performed

Full review triggered.

Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

📝 Walkthrough

Walkthrough

Adds privacy-scoped my_* views/functions and accompanying FK/relationship typings; updates queries/types to target those views; implements RLS helper functions (is_my_account, my_account(), my_space_ids(), in_space, etc.); centralizes embedding view; improves error reporting in space creation and signs out anonymous user after sign-in.

Changes

Cohort / File(s) Summary
DB types & generated typings
packages/database/src/dbTypes.ts
Adds my_concepts/my_contents/my_documents views types and Relationships; adds new FKs (concept.represented_by_id, concept.schema_id, content.document_id, content.part_of_id, embedding.target_id); broadens several function arg types to accept unknown.
Query builders / client queries
packages/database/src/lib/queries.ts
Re-aliases joins and selects to use my_* views (e.g., Document→my_documents, Content→my_contents), updates inner join aliases and filtering paths to match view-backed relations; base source becomes my_concepts.
Client context helpers
packages/database/src/lib/contextFunctions.ts
Improves error handling in fetchOrCreateSpaceDirect: aggregates result2.error?.message and any error.context.body text (via Response.text()) into a richer failure message returned via asPostgrestFailure.
Edge function: create-space
packages/database/supabase/functions/create-space/index.ts
After successful password sign-in during space creation, signs out the anonymous user locally; minor formatting/OPTIONS reorder only.
DB migrations: security/views & helpers
packages/database/supabase/migrations/20251008131345_security_views.sql
Adds public helpers and views (renames/introduces is_my_account, adds my_account(), my_space_ids(), my_spaces, my_accounts, my_documents, my_contents, my_concepts), creates privacy-preserving views and STABLE SECURITY DEFINER functions for relation traversal and embedding matching; updates policies to use helpers.
DB schemas: account / policies
packages/database/supabase/schemas/account.sql, packages/database/supabase/schemas/access_token.sql
Reworks account access helpers/policies to use is_my_account / my_account() / my_space_ids(); updates RLS policies and access_token policy to call public.is_my_account(...).
DB schemas: concept/content APIs
packages/database/supabase/schemas/concept.sql, packages/database/supabase/schemas/content.sql
Adds my_concepts/my_contents/my_documents views; adds view-backed helper functions (schema_of_concept, instances_of_schema, concept_in_relations, concepts_of_relation, content_of_concept, document_of_content, author_of_content, author_of_concept); reintroduces concept_local_input type and _local_concept_to_db_concept.
Embedding surface
packages/database/supabase/schemas/embedding.sql
Adds my_contents_with_embedding_openai_text_embedding_3_small_1536 view and rewrites embedding match functions/queries to use that view (adjusts aliases and column references).
Misc: package script
packages/database/package.json
Adds bench script (tsx scripts/bench.mts).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant EdgeFn as create-space Edge Function
  participant Auth as Supabase Auth
  participant DB as DB (RLS + my_* helpers)

  Client->>EdgeFn: POST /create-space (credentials)
  EdgeFn->>Auth: signInWithPassword()
  Auth-->>EdgeFn: session (password user)
  rect rgb(220,240,255)
    note right of EdgeFn: create or fetch space via privacy views/functions
    EdgeFn->>DB: call my_account()/my_space_ids()/insert Space / SpaceAccess
    DB-->>EdgeFn: success or error
  end
  alt success
    EdgeFn->>Auth: signOut({ scope: "local" })
    EdgeFn-->>Client: 200 Created (space info)
  else failure
    EdgeFn->>DB: read error context body (if any)
    EdgeFn-->>Client: aggregated error message
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60–90 minutes

Possibly related PRs

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly summarizes the primary change by describing the refactoring of the concept query function and the introduction of security-scoped views to address RLS performance issues, which directly aligns with the pull request’s main objectives.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@maparent maparent force-pushed the eng-950-optimize-data-access-following-the-simulation branch from 8b79fa1 to 1f6d684 Compare October 8, 2025 18:26
@maparent maparent changed the title ENG-950 Optimize data access following the simulation ENG-950 Make the query function go through new security-aware aware views to avoid RLS slowdown Oct 8, 2025
@maparent
Copy link
Collaborator Author

maparent commented Oct 8, 2025

@CodeRabbit is this title more clear?

Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

Tip

For best results, initiate chat on the files or code changes.

@maparent: The current title "ENG-950 Optimize data access following the simulation" is partially clear, but the phrase "following the simulation" is ambiguous. It's unclear whether this means:

  • After running a simulation
  • In the context of a simulation feature
  • As a follow-up to simulation-related work

Based on the changes in this PR (security views, API renaming, expanded query capabilities), a clearer title might be:

Option 1: ENG-950 Refactor data access layer with security views
Option 2: ENG-950 Add security-scoped views and optimize concept queries
Option 3: ENG-950 Optimize data access with user-scoped views and enhanced queries

If "simulation" is important context from the linked issue, you could clarify it:
Option 4: ENG-950 Optimize post-simulation data access with security views

Which aspect of the changes would you like to emphasize in the title?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (6)
packages/database/src/lib/contextFunctions.ts (3)

106-107: Add error handling for Response body parsing.

The new Response(...).text() operation can throw if result2.error.context.body is not a valid BodyInit type. Consider wrapping this in a try-catch to prevent the error handler from itself throwing an error.

Apply this diff to add error handling:

-    if (result2.error?.context?.body)
-      error += await new Response(result2.error.context.body).text();
+    if (result2.error?.context?.body) {
+      try {
+        error += await new Response(result2.error.context.body).text();
+      } catch (e) {
+        error += " [Failed to parse error context body]";
+      }
+    }

108-108: Consider removing console.log in production.

The console.log might expose sensitive error details in production environments. Consider using a proper logging framework with appropriate log levels, or guard this with an environment check.


105-105: Redundant type cast.

The cast as string | undefined is redundant since result2.error?.message already produces string | undefined through optional chaining.

Apply this diff to simplify:

-    let error: string = (result2.error?.message as string | undefined) || "";
+    let error: string = result2.error?.message || "";
packages/database/supabase/functions/create-space/index.ts (1)

117-117: LGTM! Proper session cleanup.

The signOut({ scope: "local" }) call correctly cleans up the session created by the sign-in attempt used to check anonymous user existence. The scope: "local" parameter appropriately limits the sign-out to the current session without affecting other sessions.

Note: The signOut is called even when sign-in fails with invalid_credentials, but this is harmless as Supabase's signOut safely handles the absence of an active session.

Optional: Consider using admin API for user existence checks.

For better idiomaticity, consider refactoring to use supabase.auth.admin.listUsers({ filter: { email } }) or a similar admin method instead of signing in to check user existence. This would:

  • Avoid creating unnecessary sessions
  • Be more explicit about the intent
  • Eliminate the need for immediate sign-out

However, this refactor can be deferred as the current implementation is functional and the signOut addition properly addresses the session cleanup concern.

packages/database/supabase/schemas/account.sql (1)

189-193: Optional: LIMIT 1 in CTEs is redundant.

The WITH u AS (SELECT auth.uid() LIMIT 1) pattern includes an unnecessary LIMIT 1 since auth.uid() returns a single value. While not harmful, it adds noise.

Consider simplifying:

-    WITH u AS (SELECT auth.uid() LIMIT 1)
+    WITH u AS (SELECT auth.uid())

Also applies to: 202-205, 214-218

packages/database/src/lib/queries.ts (1)

153-153: Security-scoped queries via my_concepts view.

Switching from the Concept table to the my_concepts view ensures queries automatically respect user access permissions through the view's my_space_ids() filter.

Performance consideration: Views may impact query planning. If performance degrades, consider:

  • Ensuring indexes on Concept.space_id exist
  • Monitoring query execution plans
  • Potentially materializing views for read-heavy workloads
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5359f69 and 1f6d684.

📒 Files selected for processing (9)
  • packages/database/src/dbTypes.ts (11 hunks)
  • packages/database/src/lib/contextFunctions.ts (1 hunks)
  • packages/database/src/lib/queries.ts (4 hunks)
  • packages/database/supabase/functions/create-space/index.ts (2 hunks)
  • packages/database/supabase/migrations/20251008131345_security_views.sql (1 hunks)
  • packages/database/supabase/schemas/access_token.sql (1 hunks)
  • packages/database/supabase/schemas/account.sql (4 hunks)
  • packages/database/supabase/schemas/concept.sql (5 hunks)
  • packages/database/supabase/schemas/content.sql (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Supabase Preview
  • GitHub Check: Supabase Preview
  • GitHub Check: Supabase Preview
🔇 Additional comments (13)
packages/database/supabase/functions/create-space/index.ts (2)

197-210: LGTM! Improved code organization.

Moving the origin validation outside the OPTIONS block improves code organization by allowing the originIsAllowed variable to be reused for both the OPTIONS response and the success response at line 238. This reduces potential duplication and makes the flow clearer.


189-189: LGTM! Style improvement.

Adding the semicolon improves consistency with the codebase's style conventions.

packages/database/src/dbTypes.ts (1)

561-812: LGTM - Auto-generated types align with schema changes.

The new my_concepts, my_contents, and my_documents view definitions are correctly generated from the SQL schema, with appropriate nullable fields and relationship definitions.

packages/database/supabase/schemas/concept.sql (2)

149-240: Function overloading pattern is appropriate.

The overloaded functions for my_concepts view (e.g., schema_of_concept, content_of_concept, author_of_concept) provide a clean API for both direct table access and view-filtered access, maintaining backward compatibility while enabling security-scoped queries.


118-135: No changes needed: null my_space_ids() yields empty result as intended

packages/database/supabase/schemas/account.sql (1)

267-294: LGTM - Security views properly implement access control.

The my_spaces and my_accounts views correctly filter by user's accessible spaces using my_space_ids(), providing a clean security boundary for client queries.

packages/database/supabase/schemas/access_token.sql (1)

43-43: LGTM - Policy correctly updated to use is_my_account.

The change from my_account(platform_account_id) to is_my_account(platform_account_id) is semantically clearer and consistent with the account.sql refactoring.

packages/database/src/lib/queries.ts (2)

117-121: Correct use of PostgREST function relationship syntax.

The changes to Document:document_of_content and Content:content_of_concept properly leverage PostgREST's computed relationship feature, calling the SQL functions that return related rows.


177-177: Case change aligns with PostgREST embedded resource naming.

The change from content.source_local_id to Content.source_local_id (capital C) is consistent with PostgREST's naming convention where embedded resources use the relationship name defined in the query (line 121: Content:content_of_concept).

packages/database/supabase/schemas/content.sql (2)

73-84: LGTM - Views follow consistent security pattern.

The my_documents and my_contents views correctly filter by my_space_ids(), maintaining consistency with the security model introduced for concepts and accounts.

Note: These views are subject to the same NULL handling issue as my_concepts - ensure my_space_ids() returns an empty array instead of NULL when the user has no space access (see comment on account.sql line 209-219).

Also applies to: 177-192


194-214: Relationship functions properly implement one-to-one semantics.

The document_of_content and author_of_content functions correctly use ROWS 1 and STRICT STABLE attributes, providing efficient computed relationships for PostgREST queries.

packages/database/supabase/migrations/20251008131345_security_views.sql (2)

97-255: Migration structure is well-organized and idempotent.

The migration properly uses:

  • CREATE OR REPLACE for functions and views
  • DROP POLICY IF EXISTS before creating policies
  • Descriptive comments on functions

This ensures the migration can be safely re-applied if needed.


1-1: No external references to old my_account() All found calls are within schema definitions or migrations that this script renames or recreates. Migration handles every internal usage.

@maparent maparent changed the title ENG-950 Make the query function go through new security-aware aware views to avoid RLS slowdown ENG-950 Refactor the concept query function with new security-scoped views to avoid RLS slowdown Oct 8, 2025
@maparent
Copy link
Collaborator Author

maparent commented Oct 8, 2025

@CodeRabbit: views were introduced precisely because performance was dismal without them. They do impact performance, but in the right direction.
Surprisingly, the LIMIT 1 on uid also has a positive impact on performance, it's not just noise.

Copy link
Contributor

coderabbitai bot commented Oct 8, 2025

Tip

For best results, initiate chat on the files or code changes.

@maparent: Thank you for the clarification! I appreciate you explaining the performance motivation behind these changes. It's valuable to know that:

  1. The security views (my_concepts, my_contents, my_documents, etc.) were specifically introduced to solve performance issues with the previous approach
  2. The LIMIT 1 on auth.uid() queries provides measurable performance gains

This context helps understand why the PR shifts from direct table queries to view-based access patterns. The security benefits align nicely with the performance improvements.

🐰✨


✏️ Learnings added
Learnt from: maparent
URL: https://github.com/DiscourseGraphs/discourse-graph/pull/482

Timestamp: 2025-10-08T18:55:17.989Z
Learning: In the discourse-graph database schema, security views like `my_concepts`, `my_contents`, and `my_documents` were introduced to significantly improve query performance. Direct table access had dismal performance, while the view-based approach provides substantial performance gains.

Learnt from: maparent
URL: https://github.com/DiscourseGraphs/discourse-graph/pull/482

Timestamp: 2025-10-08T18:55:17.989Z
Learning: In PostgreSQL queries within the discourse-graph project, adding `LIMIT 1` to `auth.uid()` lookups provides positive performance impact and should be retained as an optimization technique.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@maparent maparent requested review from mdroidian and removed request for mdroidian October 8, 2025 18:55
@maparent maparent force-pushed the eng-950-optimize-data-access-following-the-simulation branch from 1ee631d to 129ace9 Compare October 8, 2025 19:00
@maparent maparent requested a review from mdroidian October 8, 2025 19:02
@maparent maparent force-pushed the eng-950-optimize-data-access-following-the-simulation branch from 129ace9 to 69d76f7 Compare October 8, 2025 19:12
@maparent maparent removed the request for review from mdroidian October 9, 2025 14:40
@maparent
Copy link
Collaborator Author

maparent commented Oct 9, 2025

Deciding to wait for review, there will be iterations before it's pushed.
In particular I want to have a good solution for embeddings views,
and I still want to check a few things wrt optimizing the basic (view-less) RLS functions.

@maparent maparent marked this pull request as draft October 9, 2025 14:43
@maparent maparent force-pushed the eng-898-create-database-query-functions-for-base-dg-queries branch from ac99941 to 71e4ccf Compare October 12, 2025 17:08
@maparent maparent force-pushed the eng-950-optimize-data-access-following-the-simulation branch from dd2c2d1 to 028406b Compare October 12, 2025 18:11
Base automatically changed from eng-898-create-database-query-functions-for-base-dg-queries to main October 12, 2025 23:29
@maparent maparent force-pushed the eng-950-optimize-data-access-following-the-simulation branch from 028406b to d567640 Compare October 12, 2025 23:47
@maparent maparent force-pushed the eng-950-optimize-data-access-following-the-simulation branch from 386276f to d7a302c Compare October 13, 2025 14:07
@maparent
Copy link
Collaborator Author

@CodeRabbit full review

Copy link
Contributor

coderabbitai bot commented Oct 14, 2025

✅ Actions performed

Full review triggered.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
packages/database/supabase/schemas/embedding.sql (2)

31-51: Scoped embedding view LGTM

Joins and my_space_ids scoping look correct; filtering out obsolete embeddings is good.

Minor: ensure an appropriate pgvector index (e.g., ivfflat on ContentEmbedding_openai_text_embedding_3_small_1536.vector) exists and is tuned for your K and probes to keep ORDER BY <=> LIMIT performant.


71-77: Threshold + ANN ordering may reduce index usage

The WHERE similarity > match_threshold can limit ANN index effectiveness. If you observe slow plans, consider:

  • relying on ORDER BY <=> LIMIT only, and applying the threshold in the caller; or
  • increasing LIMIT internally (e.g., 2–4x) then filtering by threshold.

This is optional and workload‑dependent.

Also applies to: 72-74, 76-76

packages/database/supabase/migrations/20251008131345_security_views.sql (2)

59-66: Prefer EXISTS over COUNT(...) > 0 in boolean helpers

Using EXISTS avoids full counts and can short‑circuit:

-CREATE OR REPLACE FUNCTION public.account_in_shared_space(p_account_id BIGINT) RETURNS boolean
+CREATE OR REPLACE FUNCTION public.account_in_shared_space(p_account_id BIGINT) RETURNS boolean
 STABLE SECURITY DEFINER
 SET search_path = ''
 LANGUAGE sql AS $$
-    SELECT count(sa.account_id) > 0 FROM public."SpaceAccess" AS sa
-    WHERE sa.account_id = p_account_id
-    AND sa.space_id = ANY(public.my_space_ids());
+    SELECT EXISTS (
+      SELECT 1
+      FROM public."SpaceAccess" AS sa
+      WHERE sa.account_id = p_account_id
+        AND sa.space_id = ANY(public.my_space_ids())
+    );
 $$;
 
-CREATE OR REPLACE FUNCTION public.unowned_account_in_shared_space(p_account_id BIGINT) RETURNS boolean
+CREATE OR REPLACE FUNCTION public.unowned_account_in_shared_space(p_account_id BIGINT) RETURNS boolean
 STABLE SECURITY DEFINER
 SET search_path = ''
 LANGUAGE sql AS $$
-    SELECT count(sa.account_id) > 0 FROM public."SpaceAccess" AS sa
-    JOIN public."PlatformAccount" AS pa ON (pa.id = sa.account_id)
-    WHERE sa.account_id = p_account_id
-    AND sa.space_id = ANY(public.my_space_ids())
-    AND pa.dg_account IS NULL;
+    SELECT EXISTS (
+      SELECT 1
+      FROM public."SpaceAccess" AS sa
+      JOIN public."PlatformAccount" AS pa ON (pa.id = sa.account_id)
+      WHERE sa.account_id = p_account_id
+        AND sa.space_id = ANY(public.my_space_ids())
+        AND pa.dg_account IS NULL
+    );
 $$;

Also applies to: 70-79


151-163: Duplication with schema files — centralize canonical definitions

These views/functions are also defined in schemas (content.sql, concept.sql, embedding.sql). Duplicated CREATE OR REPLACE across migrations and schema snapshots increases drift risk.

Action: keep canonical definitions in one place (prefer schemas); in migrations, only add transitional statements needed for live DB upgrades.

Also applies to: 164-180, 181-199, 201-286, 287-307, 309-363

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ffc313a and 2ae86d3.

📒 Files selected for processing (11)
  • packages/database/package.json (1 hunks)
  • packages/database/src/dbTypes.ts (18 hunks)
  • packages/database/src/lib/contextFunctions.ts (1 hunks)
  • packages/database/src/lib/queries.ts (3 hunks)
  • packages/database/supabase/functions/create-space/index.ts (2 hunks)
  • packages/database/supabase/migrations/20251008131345_security_views.sql (1 hunks)
  • packages/database/supabase/schemas/access_token.sql (1 hunks)
  • packages/database/supabase/schemas/account.sql (4 hunks)
  • packages/database/supabase/schemas/concept.sql (5 hunks)
  • packages/database/supabase/schemas/content.sql (2 hunks)
  • packages/database/supabase/schemas/embedding.sql (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-05-30T14:49:24.016Z
Learnt from: maparent
PR: DiscourseGraphs/discourse-graph#182
File: apps/website/app/utils/supabase/dbUtils.ts:22-28
Timestamp: 2025-05-30T14:49:24.016Z
Learning: In apps/website/app/utils/supabase/dbUtils.ts, expanding the KNOWN_EMBEDDINGS and DEFAULT_DIMENSIONS mappings to support additional embedding models requires corresponding database model changes (creating new embedding tables), which should be scoped as separate work from API route implementations.

Applied to files:

  • packages/database/supabase/schemas/embedding.sql
📚 Learning: 2025-05-20T14:04:19.632Z
Learnt from: maparent
PR: DiscourseGraphs/discourse-graph#165
File: packages/database/supabase/schemas/embedding.sql:66-95
Timestamp: 2025-05-20T14:04:19.632Z
Learning: In the `match_embeddings_for_subset_nodes` SQL function in packages/database/supabase/schemas/embedding.sql, the number of results is implicitly limited by the length of the input array parameter `p_subset_roam_uids` since the function filters content using `WHERE c.source_local_id = ANY(p_subset_roam_uids)`.

Applied to files:

  • packages/database/supabase/schemas/embedding.sql
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Supabase Preview
  • GitHub Check: Supabase Preview
🔇 Additional comments (16)
packages/database/supabase/functions/create-space/index.ts (3)

117-117: Good addition: Clean session management.

Signing out the anonymous session immediately after the sign-in check ensures clean session state before proceeding with admin operations. Since the function uses the service role key for subsequent operations, the anonymous session is not needed.

Based on learnings: This aligns with the broader shift toward explicit session-state management in authentication flows.


189-189: Minor: Formatting-only change.

The semicolon placement change is stylistic and doesn't affect functionality.


197-210: LGTM: OPTIONS handling reformatted.

The preflight request handling logic remains identical, just reformatted for clarity. The origin validation and CORS headers are unchanged.

packages/database/src/lib/queries.ts (5)

117-122: LGTM: Systematic refactor to security-scoped views.

The query composition correctly shifts from direct table references to the new my_* views:

  • Document:my_documents!document_id (line 118-119)
  • Content:my_contents!represented_by_id (line 121)

The foreign key references and !inner modifiers are preserved correctly.

Based on learnings: These security views significantly improve query performance versus direct table access with RLS.


124-124: LGTM: Author reference updated to my_accounts view.

The author alias now correctly references my_accounts!author_id!inner, consistent with the broader refactor to security-scoped views.


144-150: LGTM: Relation subnodes updated to use my_ views.*

The nested relation references are correctly updated:

  • Content:my_contents!represented_by_id!inner (lines 144-146)
  • author:my_accounts!author_id!inner (line 149)

These maintain the same query semantics while using the security-scoped views.


155-155: Critical change: Base table switched to my_concepts view.

This is the core of the refactor - all concept queries now target the my_concepts view instead of the Concept table, which improves performance by avoiding RLS evaluation on the base table.

Based on learnings: Security views were introduced specifically because direct table access had dismal performance, and these views improve performance significantly.


179-179: LGTM: Filter path updated to match view alias.

The filter path Content.source_local_id correctly references the Content alias created at line 121 (Content:my_contents!represented_by_id). The capitalization is intentional and matches the alias naming convention.

packages/database/src/lib/contextFunctions.ts (1)

105-115: Verify result2.error.context.body type
Wrapping it in new Response(...).text() implies it may not be a string. If it’s already a string, append directly (error += result2.error.context.body;); otherwise, the wrapper is needed. Confirm its type and simplify accordingly.

packages/database/supabase/schemas/concept.sql (2)

118-135: my_concepts depends on my_space_ids — ensure create-order

This view requires public.my_space_ids() to exist at creation time. Please confirm migration order guarantees the function is defined before this schema file runs (or move the view into the same migration that defines my_space_ids()).


149-159: Co-locate composite-type views and dependent functions
Functions using the public.my_concepts, public.my_contents, and public.my_accounts composite types must be created after those views exist. Either move each CREATE FUNCTION … block immediately after its corresponding CREATE VIEW in the same file or enforce your migration ordering to guarantee the views are in place first.

packages/database/supabase/schemas/embedding.sql (1)

102-104: Subset function refactor LGTM

Switch to the scoped view and selecting the vector column directly looks correct.

packages/database/supabase/schemas/content.sql (3)

72-85: my_documents view LGTM

Explicit column list and my_space_ids scoping look good.


177-193: my_contents view LGTM

Column selection and scoping align with usage in embedding queries.


194-215: No ordering issue — views precede functions
Both public.my_documents (in content.sql line 73) and public.my_accounts (in account.sql) are defined before the functions that return their composite types.

packages/database/supabase/migrations/20251008131345_security_views.sql (1)

31-41: my_space_ids NULL handling fixed — good

Using COALESCE on array_agg prevents NULL arrays from breaking ANY(...) checks. Nice.

@maparent maparent marked this pull request as ready for review October 15, 2025 00:13
@maparent maparent requested a review from mdroidian October 15, 2025 00:14
Copy link
Contributor

@mdroidian mdroidian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@maparent maparent merged commit 5ef439f into main Oct 16, 2025
5 checks passed
@maparent maparent deleted the eng-950-optimize-data-access-following-the-simulation branch October 16, 2025 17:47
@github-project-automation github-project-automation bot moved this to Done in General Oct 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants