Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,15 @@ Docs: [@grida/refig](https://grida.co/docs/packages/@grida/refig)

## Quickstart (monorepo)

**Requirements:** Node.js **22+**, pnpm **10+**
**Requirements:** mise, Node.js **22+**, pnpm **10+**

```bash
pnpm install
mise install
pnpm dev:init
pnpm dev:services
pnpm dev
Comment on lines +183 to 189
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

List Docker as a quickstart prerequisite.

pnpm dev:services hard-exits when Docker is missing or not running (scripts/dev/services.sh:31-39), so the current quickstart still fails on a clean machine that only followed the documented requirements.

Suggested change
-**Requirements:** mise, Node.js **22+**, pnpm **10+**
+**Requirements:** mise, Docker / Docker Desktop, Node.js **22+**, pnpm **10+**
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**Requirements:** mise, Node.js **22+**, pnpm **10+**
```bash
pnpm install
mise install
pnpm dev:init
pnpm dev:services
pnpm dev
**Requirements:** mise, Docker / Docker Desktop, Node.js **22+**, pnpm **10+**
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 183 - 189, Update the quickstart requirements to list
Docker (and Docker Desktop/docker engine) as a prerequisite and add a note that
the Docker daemon must be running before running the "pnpm dev:services"
command; specifically mention the dev services script that fails when Docker is
absent and suggest either adding a one-line check/instruction to start Docker or
a link to Docker installation docs in the README.

```
now editor is running on `http://localhost:3000`.

Common tasks:

Expand Down
7 changes: 4 additions & 3 deletions editor/app/(insiders)/insiders/auth/basic/sign-in/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ export async function POST(req: NextRequest) {
console.log("[INSIDER] Sign in successful");

if (redirect_uri) {
return NextResponse.redirect(redirect_uri, {
status: 302,
});
return NextResponse.redirect(
new URL(redirect_uri, requestUrl.origin),
{ status: 302 }
);
}

if (next) {
Expand Down
7 changes: 7 additions & 0 deletions mise.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[tools]
node = "22"
pnpm = "10"
rust = "1.92.0"
supabase = "2"
deno = "2"
python = "3.12"
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"build": "turbo run build",
"build:packages": "turbo run build --filter=./packages/*",
"dev": "turbo run dev",
"dev:init": " ./scripts/dev/init.sh",
"dev:services": "./scripts/dev/services.sh",
"dev:editor": "turbo run dev --filter=./editor",
"dev:packages": "turbo run dev --filter=./packages/*",
"generate": "turbo run generate",
Expand Down
88 changes: 88 additions & 0 deletions scripts/dev/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env bash
set -euo pipefail

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m'

REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"

echo ""
echo -e "${CYAN}${BOLD}"
echo " ____ _ _ "
echo " / ___|_ __(_) __| | __ _ "
echo " | | _| '__| |/ _\` |/ _\` |"
echo " | |_| | | | | (_| | (_| |"
echo " \____|_| |_|\__,_|\__,_|"
echo -e "${NC}"
echo -e "${DIM} Development Environment Init${NC}"
echo ""

# 1. Check prerequisites
echo -e "${BLUE}${BOLD}[1/3]${NC} Checking prerequisites..."

if command -v node &>/dev/null; then
NODE_V=$(node --version)
echo -e " ${GREEN}+${NC} node ${DIM}${NODE_V}${NC}"
else
echo -e " ${RED}x${NC} node not found - install Node.js 22+"
exit 1
fi

if command -v pnpm &>/dev/null; then
PNPM_V=$(pnpm --version)
echo -e " ${GREEN}+${NC} pnpm ${DIM}v${PNPM_V}${NC}"
else
echo -e " ${RED}x${NC} pnpm not found - install pnpm 10+"
exit 1
fi
Comment on lines +30 to +44
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n '"node": ">=22\.0\.0"|"pnpm": ">=10\.0\.0"|command -v node|command -v pnpm|NODE_V=|PNPM_V=' package.json scripts/dev/init.sh

Repository: gridaco/grida

Length of output: 355


Enforce the declared Node.js and pnpm minimums in this script.

Lines 30–44 only check whether node and pnpm are installed, not whether they meet the minimum versions declared in package.json (node >=22.0.0 and pnpm >=10.0.0). A user with Node 20 or pnpm 9 gets a passing check and fails later during build steps.

Suggested change
 if command -v node &>/dev/null; then
   NODE_V=$(node --version)
+  NODE_MAJOR="${NODE_V#v}"
+  NODE_MAJOR="${NODE_MAJOR%%.*}"
+  if [ "$NODE_MAJOR" -lt 22 ]; then
+    echo -e "  ${RED}x${NC} node ${DIM}${NODE_V}${NC} detected - install Node.js 22+"
+    exit 1
+  fi
   echo -e "  ${GREEN}+${NC} node ${DIM}${NODE_V}${NC}"
 else
   echo -e "  ${RED}x${NC} node not found - install Node.js 22+"
   exit 1
 fi
 
 if command -v pnpm &>/dev/null; then
   PNPM_V=$(pnpm --version)
+  PNPM_MAJOR="${PNPM_V%%.*}"
+  if [ "$PNPM_MAJOR" -lt 10 ]; then
+    echo -e "  ${RED}x${NC} pnpm ${DIM}v${PNPM_V}${NC} detected - install pnpm 10+"
+    exit 1
+  fi
   echo -e "  ${GREEN}+${NC} pnpm ${DIM}v${PNPM_V}${NC}"
 else
   echo -e "  ${RED}x${NC} pnpm not found - install pnpm 10+"
   exit 1
 fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if command -v node &>/dev/null; then
NODE_V=$(node --version)
echo -e " ${GREEN}+${NC} node ${DIM}${NODE_V}${NC}"
else
echo -e " ${RED}x${NC} node not found - install Node.js 22+"
exit 1
fi
if command -v pnpm &>/dev/null; then
PNPM_V=$(pnpm --version)
echo -e " ${GREEN}+${NC} pnpm ${DIM}v${PNPM_V}${NC}"
else
echo -e " ${RED}x${NC} pnpm not found - install pnpm 10+"
exit 1
fi
if command -v node &>/dev/null; then
NODE_V=$(node --version)
NODE_MAJOR="${NODE_V#v}"
NODE_MAJOR="${NODE_MAJOR%%.*}"
if [ "$NODE_MAJOR" -lt 22 ]; then
echo -e " ${RED}x${NC} node ${DIM}${NODE_V}${NC} detected - install Node.js 22+"
exit 1
fi
echo -e " ${GREEN}+${NC} node ${DIM}${NODE_V}${NC}"
else
echo -e " ${RED}x${NC} node not found - install Node.js 22+"
exit 1
fi
if command -v pnpm &>/dev/null; then
PNPM_V=$(pnpm --version)
PNPM_MAJOR="${PNPM_V%%.*}"
if [ "$PNPM_MAJOR" -lt 10 ]; then
echo -e " ${RED}x${NC} pnpm ${DIM}v${PNPM_V}${NC} detected - install pnpm 10+"
exit 1
fi
echo -e " ${GREEN}+${NC} pnpm ${DIM}v${PNPM_V}${NC}"
else
echo -e " ${RED}x${NC} pnpm not found - install pnpm 10+"
exit 1
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/dev/init.sh` around lines 30 - 44, Update the node and pnpm checks in
init.sh to enforce the minimum versions: capture NODE_V from `node --version`
(strip leading "v") and PNPM_V from `pnpm --version`, parse their major (and
optionally minor/patch) components and compare them against the declared minima
(node >= 22.0.0, pnpm >= 10.0.0); if the version check fails for either `NODE_V`
or `PNPM_V` emit the existing red error message (augmenting it to show the
detected version) and exit 1, otherwise print the green success line; use the
existing variables NODE_V and PNPM_V and the same echo messages to keep output
consistent.


if command -v docker &>/dev/null; then
echo -e " ${GREEN}+${NC} docker"
else
echo -e " ${YELLOW}~${NC} docker not found ${DIM}(needed for pnpm dev:services)${NC}"
fi

if command -v supabase &>/dev/null; then
SB_V=$(supabase --version 2>/dev/null || echo "unknown")
echo -e " ${GREEN}+${NC} supabase ${DIM}${SB_V}${NC}"
else
echo -e " ${YELLOW}~${NC} supabase CLI not found ${DIM}(needed for pnpm dev:services)${NC}"
fi

echo ""

# 2. Create .env.local
echo -e "${BLUE}${BOLD}[2/3]${NC} Setting up environment..."

ENV_FILE="$REPO_ROOT/editor/.env.local"
ENV_EXAMPLE="$REPO_ROOT/editor/.env.example"

if [ -f "$ENV_FILE" ]; then
echo -e " ${YELLOW}~${NC} editor/.env.local already exists, skipping"
else
cp "$ENV_EXAMPLE" "$ENV_FILE"
echo -e " ${GREEN}+${NC} Created editor/.env.local from .env.example"
fi

echo ""

# 3. Install dependencies
echo -e "${BLUE}${BOLD}[3/3]${NC} Installing dependencies..."
echo ""
pnpm install
echo ""

# Done
echo -e "${GREEN}${BOLD}Init complete!${NC}"
echo ""
echo -e " Next steps:"
echo -e " ${DIM}1.${NC} pnpm dev:services ${DIM}# start Supabase${NC}"
echo -e " ${DIM}2.${NC} pnpm dev ${DIM}# start the editor${NC}"
echo ""
128 changes: 128 additions & 0 deletions scripts/dev/services.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/usr/bin/env bash
set -euo pipefail

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
DIM='\033[2m'
NC='\033[0m'

REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
ENV_FILE="$REPO_ROOT/editor/.env.local"

echo ""
echo -e "${CYAN}${BOLD}"
echo " ____ _ _ "
echo " / ___|_ __(_) __| | __ _ "
echo " | | _| '__| |/ _\` |/ _\` |"
echo " | |_| | | | | (_| | (_| |"
echo " \____|_| |_|\__,_|\__,_|"
echo -e "${NC}"
echo -e "${DIM} Development Services${NC}"
echo ""

# 1. Check prerequisites
echo -e "${BLUE}${BOLD}[1/4]${NC} Checking prerequisites..."

if ! command -v docker &>/dev/null; then
echo -e " ${RED}x${NC} Docker is not installed"
exit 1
fi

if ! docker info &>/dev/null 2>&1; then
echo -e " ${RED}x${NC} Docker is not running - please start Docker Desktop"
exit 1
fi
echo -e " ${GREEN}+${NC} Docker is running"

if ! command -v supabase &>/dev/null; then
echo -e " ${RED}x${NC} Supabase CLI not found"
echo -e " ${DIM} Install: brew install supabase/tap/supabase${NC}"
echo -e " ${DIM} Or: mise install${NC}"
exit 1
fi
echo -e " ${GREEN}+${NC} Supabase CLI"

if [ ! -f "$ENV_FILE" ]; then
echo -e " ${RED}x${NC} editor/.env.local not found - run ${BOLD}pnpm dev:init${NC} first"
exit 1
fi
echo -e " ${GREEN}+${NC} editor/.env.local"

echo ""

# 2. Generate signing keys if missing
SIGNING_KEYS="$REPO_ROOT/supabase/signing_keys.json"
if [ ! -f "$SIGNING_KEYS" ] || [ "$(cat "$SIGNING_KEYS")" = "[]" ]; then
echo -e "${BLUE}${BOLD}[2/4]${NC} Generating Supabase signing keys..."
node -e "
const crypto = require('crypto');
const { privateKey } = crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' });
const jwk = privateKey.export({ format: 'jwk' });
jwk.kid = crypto.randomUUID();
jwk.use = 'sig';
jwk.key_ops = ['sign', 'verify'];
jwk.alg = 'ES256';
jwk.ext = true;
console.log(JSON.stringify([jwk], null, 2));
" > "$SIGNING_KEYS"
Comment on lines +59 to +72
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Treat zero-byte signing_keys.json as missing.

Line 60 only regenerates when the file is absent or exactly []. If the redirected node -e write is interrupted, the next run leaves an empty file in place and never self-heals.

Suggested change
-if [ ! -f "$SIGNING_KEYS" ] || [ "$(cat "$SIGNING_KEYS")" = "[]" ]; then
+if [ ! -s "$SIGNING_KEYS" ] || [ "$(tr -d '[:space:]' < "$SIGNING_KEYS")" = "[]" ]; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
SIGNING_KEYS="$REPO_ROOT/supabase/signing_keys.json"
if [ ! -f "$SIGNING_KEYS" ] || [ "$(cat "$SIGNING_KEYS")" = "[]" ]; then
echo -e "${BLUE}${BOLD}[2/4]${NC} Generating Supabase signing keys..."
node -e "
const crypto = require('crypto');
const { privateKey } = crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' });
const jwk = privateKey.export({ format: 'jwk' });
jwk.kid = crypto.randomUUID();
jwk.use = 'sig';
jwk.key_ops = ['sign', 'verify'];
jwk.alg = 'ES256';
jwk.ext = true;
console.log(JSON.stringify([jwk], null, 2));
" > "$SIGNING_KEYS"
SIGNING_KEYS="$REPO_ROOT/supabase/signing_keys.json"
if [ ! -s "$SIGNING_KEYS" ] || [ "$(tr -d '[:space:]' < "$SIGNING_KEYS")" = "[]" ]; then
echo -e "${BLUE}${BOLD}[2/4]${NC} Generating Supabase signing keys..."
node -e "
const crypto = require('crypto');
const { privateKey } = crypto.generateKeyPairSync('ec', { namedCurve: 'P-256' });
const jwk = privateKey.export({ format: 'jwk' });
jwk.kid = crypto.randomUUID();
jwk.use = 'sig';
jwk.key_ops = ['sign', 'verify'];
jwk.alg = 'ES256';
jwk.ext = true;
console.log(JSON.stringify([jwk], null, 2));
" > "$SIGNING_KEYS"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/dev/services.sh` around lines 59 - 72, The script currently only
regenerates signing_keys.json when the file is missing or equals "[]", so
zero-byte files left by interrupted writes are ignored; update the existence
check around SIGNING_KEYS in the if condition (the test that currently uses [ !
-f "$SIGNING_KEYS" ] || [ "$(cat "$SIGNING_KEYS")" = "[]" ]) to detect empty
files as missing by using the -s test (e.g., replace [ ! -f "$SIGNING_KEYS" ]
with [ ! -s "$SIGNING_KEYS" ]) while keeping the existing check for the "[]"
content so the node key-generation block will run when the file is missing,
empty, or contains only [].

echo -e " ${GREEN}+${NC} Created supabase/signing_keys.json"
else
echo -e "${BLUE}${BOLD}[2/4]${NC} Signing keys exist, skipping"
fi

echo ""

# 3. Start Supabase
echo -e "${BLUE}${BOLD}[3/4]${NC} Starting Supabase..."
echo ""
cd "$REPO_ROOT"
supabase start || true
echo ""

# 4. Inject local Supabase keys into .env.local
echo -e "${BLUE}${BOLD}[4/4]${NC} Configuring environment..."

SUPABASE_OUTPUT=$(supabase status -o env 2>/dev/null || true)

API_URL=$(echo "$SUPABASE_OUTPUT" | grep '^API_URL=' | cut -d= -f2- | tr -d '"' || true)
PUBLISHABLE_KEY=$(echo "$SUPABASE_OUTPUT" | grep '^PUBLISHABLE_KEY=' | cut -d= -f2- | tr -d '"' || true)
SECRET_KEY=$(echo "$SUPABASE_OUTPUT" | grep '^SECRET_KEY=' | cut -d= -f2- | tr -d '"' || true)

UPDATED=0

if [ -n "$API_URL" ]; then
sed -i.bak "s|^SUPABASE_URL=.*|SUPABASE_URL=\"$API_URL\"|" "$ENV_FILE"
sed -i.bak "s|^NEXT_PUBLIC_SUPABASE_URL=.*|NEXT_PUBLIC_SUPABASE_URL=\"$API_URL\"|" "$ENV_FILE"
echo -e " ${GREEN}+${NC} SUPABASE_URL ${DIM}${API_URL}${NC}"
UPDATED=1
fi

if [ -n "$PUBLISHABLE_KEY" ]; then
sed -i.bak "s|^NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=.*|NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=\"$PUBLISHABLE_KEY\"|" "$ENV_FILE"
echo -e " ${GREEN}+${NC} NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY ${DIM}${PUBLISHABLE_KEY:0:20}...${NC}"
UPDATED=1
fi

if [ -n "$SECRET_KEY" ]; then
sed -i.bak "s|^SUPABASE_SECRET_KEY=.*|SUPABASE_SECRET_KEY=\"$SECRET_KEY\"|" "$ENV_FILE"
echo -e " ${GREEN}+${NC} SUPABASE_SECRET_KEY ${DIM}${SECRET_KEY:0:20}...${NC}"
UPDATED=1
fi

rm -f "$ENV_FILE.bak"

if [ "$UPDATED" -eq 0 ]; then
echo -e " ${YELLOW}~${NC} Could not read Supabase keys - update .env.local manually"
fi

echo ""
echo -e "${GREEN}${BOLD}Services running!${NC}"
echo ""
Comment on lines +81 to +125
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Do not print a success path after a failed Supabase start.

Lines 84 and 119-125 let the script continue all the way to Services running! even when supabase start failed or supabase status -o env returned nothing. That makes first-run failures much harder to diagnose.

Suggested change
-supabase start || true
+if ! supabase start && ! supabase status -o env >/dev/null 2>&1; then
+  echo -e "  ${RED}x${NC} Supabase failed to start"
+  exit 1
+fi
@@
 if [ "$UPDATED" -eq 0 ]; then
   echo -e "  ${YELLOW}~${NC} Could not read Supabase keys - update .env.local manually"
+  exit 1
 fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/dev/services.sh` around lines 81 - 125, The script continues to the
final "Services running!" message even when "supabase start" fails or
SUPABASE_OUTPUT is empty; update the flow so failures stop the script: capture
the exit code of the supabase start command and if it fails print a clear error
and exit non-zero, and after obtaining SUPABASE_OUTPUT validate it is non-empty
before injecting keys — if SUPABASE_OUTPUT is empty print an error/helpful
message and exit non-zero instead of proceeding; only print the final success
message when supabase start succeeded and at least one environment value was
updated (i.e., SUPABASE_OUTPUT non-empty or UPDATED==1). Reference symbols:
supabase start, SUPABASE_OUTPUT, UPDATED, ENV_FILE.

echo -e " Next step:"
echo -e " ${DIM}$${NC} pnpm dev ${DIM}# start the editor${NC}"
echo ""
4 changes: 4 additions & 0 deletions supabase/migrations/20250503123355_pgmq.sql
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
-- generated from supabase ui - enable supabase queue via ui.

create schema if not exists "pgmq";
create schema if not exists "pgmq_public";

create extension if not exists "pgmq" with schema "pgmq" version '1.4.4';

grant usage on schema "pgmq" to "service_role";
grant usage on schema "pgmq_public" to "service_role";
Comment on lines +4 to +9
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching pgmq privilege statements..."
rg -n -C2 --type=sql 'pgmq_public|grant\s+execute|revoke\s+all|grant\s+usage' supabase/migrations supabase/tests || true

echo
echo "Searching for application call sites that use pgmq_public..."
rg -n -C2 --type=ts 'schema:\s*"pgmq_public"|rpc\("read"|rpc\("archive"' jobs supabase || true

Repository: gridaco/grida

Length of output: 2727


🏁 Script executed:

cat -n supabase/migrations/20250503123355_pgmq.sql

Repository: gridaco/grida

Length of output: 949


🏁 Script executed:

# Search for all pgmq-related migrations to see if a later one hardens the functions
rg -l 'pgmq' supabase/migrations/*.sql | sort

Repository: gridaco/grida

Length of output: 286


🏁 Script executed:

# Check if there are any other pgmq_public-specific modifications after the initial migration
rg -n 'pgmq_public' supabase/migrations/ --type=sql

Repository: gridaco/grida

Length of output: 246


🏁 Script executed:

# Search for pgmq function calls or documentation references
rg -n 'pgmq.*\(read|archive\)' jobs supabase --type=ts --type=sql -A2 -B2

Repository: gridaco/grida

Length of output: 39


🏁 Script executed:

# Check if there's any pgmq documentation or README that explains the schema setup
find . -name "*.md" -o -name "*.txt" | xargs grep -l pgmq 2>/dev/null || echo "No markdown/text references found"

Repository: gridaco/grida

Length of output: 73


🏁 Script executed:

# Look for comments or documentation in migrations that mention pgmq defaults
rg -n 'pgmq' supabase/migrations/20250503123355_pgmq.sql --type=sql -B5

Repository: gridaco/grida

Length of output: 868


🏁 Script executed:

cat -n jobs/README.md | head -50

Repository: gridaco/grida

Length of output: 1353


🏁 Script executed:

# Check if pgmq functions are RPC functions (stored procedures) in PostgreSQL
# Search for pgmq function definitions or any CREATE FUNCTION statements in migrations
rg -n 'create.*function.*pgmq|pgmq.*function' supabase/migrations --type=sql

Repository: gridaco/grida

Length of output: 39


🏁 Script executed:

# Search for any function definitions or wrappers in pgmq_public in migrations
rg -n 'pgmq_public\.' supabase/migrations --type=sql

Repository: gridaco/grida

Length of output: 39


🏁 Script executed:

# Check if pgmq extension documentation is available or if functions are created elsewhere
rg -n 'read.*function|archive.*function' supabase/migrations --type=sql -i

Repository: gridaco/grida

Length of output: 39


🏁 Script executed:

# Check test files for pgmq or queue-related RLS/permission tests
rg -n 'pgmq|queue' supabase/tests --type=sql

Repository: gridaco/grida

Length of output: 39


🏁 Script executed:

# Look for any test files that might cover permissions for pgmq
fd '\.sql$' supabase/tests -x grep -l 'pgmq\|queue' {} \;

Repository: gridaco/grida

Length of output: 39


🏁 Script executed:

# Check if there's any pgmq documentation in code comments or if RPC is documented
rg -n 'pgmq' jobs/src --type=ts -B3 -A3

Repository: gridaco/grida

Length of output: 1123


🏁 Script executed:

# See if supabase tests directory exists and what structure it has
ls -la supabase/tests/ 2>/dev/null || echo "Tests directory structure check"

Repository: gridaco/grida

Length of output: 688


🏁 Script executed:

# Look for all migration files after pgmq to see if any other queue-related changes were made
ls -1 supabase/migrations/ | grep -E '202505|202506' | head -20

Repository: gridaco/grida

Length of output: 337


Lock down pgmq_public function access with explicit ACLs.

The migration grants schema USAGE to service_role but does not explicitly control EXECUTE permissions on the read and archive functions that the application calls via RPC. This relies on the extension's default privileges instead of an explicit least-privilege contract. The codebase pattern (e.g., 20260201133814_rpc_delete_project_with_timeout.sql) establishes the standard: REVOKE ALL ... FROM public followed by GRANT EXECUTE ... TO service_role. Add the same hardening here, and include pgTAP tests to verify that only service_role can execute these functions.

Proposed hardening
 grant usage on schema "pgmq" to "service_role";
 grant usage on schema "pgmq_public" to "service_role";
+revoke all on all functions in schema "pgmq_public" from public;
+grant execute on all functions in schema "pgmq_public" to "service_role";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
create schema if not exists "pgmq_public";
create extension if not exists "pgmq" with schema "pgmq" version '1.4.4';
grant usage on schema "pgmq" to "service_role";
grant usage on schema "pgmq_public" to "service_role";
create schema if not exists "pgmq_public";
create extension if not exists "pgmq" with schema "pgmq" version '1.4.4';
grant usage on schema "pgmq" to "service_role";
grant usage on schema "pgmq_public" to "service_role";
revoke all on all functions in schema "pgmq_public" from public;
grant execute on all functions in schema "pgmq_public" to "service_role";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@supabase/migrations/20250503123355_pgmq.sql` around lines 4 - 9, Add explicit
ACL hardening for pgmq_public functions by revoking public execute privileges
and granting only service_role EXECUTE on the pgmq_public.read and
pgmq_public.archive functions (follow the pattern used in other migrations like
rpc_delete_project_with_timeout: REVOKE ALL ON FUNCTION ... FROM public; GRANT
EXECUTE ON FUNCTION ... TO service_role). Update the migration that creates
schema "pgmq_public" / extension "pgmq" to include these REVOKE/GRANT statements
for the read and archive functions, and add pgTAP tests that assert public
cannot execute them while service_role can (tests should call pgmq_public.read
and pgmq_public.archive and expect permission denied for public and success for
service_role).


grant select on table "pgmq"."meta" to "pg_monitor";
grant delete on table "pgmq"."meta" to "service_role";
grant insert on table "pgmq"."meta" to "service_role";
Expand Down