@autoship/react 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -7
- package/dist/AutoshipProvider.d.ts +7 -1
- package/dist/AutoshipProvider.d.ts.map +1 -1
- package/dist/AutoshipProvider.js +11 -2
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +18 -13
- package/dist/hooks/useTasks.js +3 -3
- package/dist/migrations/20250118000000_initial_schema.sql +70 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ Create a new Supabase project (or use an existing one). Get the SUPABASE_URL and
|
|
|
26
26
|
Run the migrations using the CLI:
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
npx @autoship init
|
|
29
|
+
npx @autoship/react init
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
The CLI will prompt you for credentials. You can provide them in two ways:
|
|
@@ -35,26 +35,38 @@ The CLI will prompt you for credentials. You can provide them in two ways:
|
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
37
|
# Find this in Supabase Dashboard > Project Settings > Database > Connection string > URI
|
|
38
|
-
npx @autoship init --database-url "postgresql://postgres.xxx:password@aws-0-region.pooler.supabase.com:6543/postgres"
|
|
38
|
+
npx @autoship/react init --database-url "postgresql://postgres.xxx:password@aws-0-region.pooler.supabase.com:6543/postgres"
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
**Option B: Supabase URL + Database Password**
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
npx @autoship init --supabase-url https://xxx.supabase.co --db-password yourpassword
|
|
44
|
+
npx @autoship/react init --supabase-url https://xxx.supabase.co --db-password yourpassword
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
**Using environment variables:**
|
|
48
48
|
|
|
49
49
|
```bash
|
|
50
50
|
# Option A
|
|
51
|
-
DATABASE_URL="postgresql://..." npx @autoship init
|
|
51
|
+
DATABASE_URL="postgresql://..." npx @autoship/react init
|
|
52
52
|
|
|
53
53
|
# Option B
|
|
54
54
|
SUPABASE_URL="https://xxx.supabase.co" DB_PASSWORD="yourpassword" npx @autoship/react init
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
### 3.
|
|
57
|
+
### 3. Expose the Autoship Schema in Supabase
|
|
58
|
+
|
|
59
|
+
Autoship uses a dedicated `autoship` database schema to avoid conflicts with your existing tables. You need to expose this schema via the Supabase API:
|
|
60
|
+
|
|
61
|
+
1. Go to your Supabase project dashboard
|
|
62
|
+
2. Navigate to **Project Settings** (gear icon) → **API**
|
|
63
|
+
3. Scroll down to **Data API Settings**
|
|
64
|
+
4. Find **Extra search path** and add `autoship` to the list
|
|
65
|
+
5. Save the changes
|
|
66
|
+
|
|
67
|
+
This allows the Supabase client to access the `autoship` schema via the REST API.
|
|
68
|
+
|
|
69
|
+
### 4. Add React Components (Optional)
|
|
58
70
|
|
|
59
71
|
Install the package:
|
|
60
72
|
|
|
@@ -90,7 +102,7 @@ Available components:
|
|
|
90
102
|
- `TaskDetailDialog` - View task details and answer questions
|
|
91
103
|
- `QuestionDialog` - Answer clarifying questions from Claude
|
|
92
104
|
|
|
93
|
-
###
|
|
105
|
+
### 5. Set Up GitHub Action
|
|
94
106
|
|
|
95
107
|
Copy these files into your project:
|
|
96
108
|
|
|
@@ -108,7 +120,7 @@ Add GitHub Secrets (Settings > Secrets and variables > Actions):
|
|
|
108
120
|
| `SUPABASE_URL` | Your Supabase project URL (e.g., `https://xxx.supabase.co`) |
|
|
109
121
|
| `SUPABASE_SERVICE_KEY` | Supabase service role key (not the anon key) |
|
|
110
122
|
|
|
111
|
-
###
|
|
123
|
+
### 6. Test Locally (Optional)
|
|
112
124
|
|
|
113
125
|
Build the MCP server:
|
|
114
126
|
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { SupabaseClient } from "@supabase/supabase-js";
|
|
2
2
|
import React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* The database schema used by Autoship.
|
|
5
|
+
* All tables are created in this schema to avoid conflicts with other schemas.
|
|
6
|
+
*/
|
|
7
|
+
export declare const AUTOSHIP_SCHEMA = "autoship";
|
|
3
8
|
export interface AutoshipContextValue {
|
|
4
|
-
supabase: SupabaseClient
|
|
9
|
+
supabase: SupabaseClient<any, typeof AUTOSHIP_SCHEMA>;
|
|
5
10
|
userId?: string;
|
|
11
|
+
schema: string;
|
|
6
12
|
}
|
|
7
13
|
export declare function useAutoshipContext(): AutoshipContextValue;
|
|
8
14
|
export interface AutoshipProviderProps {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutoshipProvider.d.ts","sourceRoot":"","sources":["../src/AutoshipProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAA6C,MAAM,OAAO,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"AutoshipProvider.d.ts","sourceRoot":"","sources":["../src/AutoshipProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgB,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAA6C,MAAM,OAAO,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,eAAe,aAAa,CAAC;AAE1C,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,cAAc,CAAC,GAAG,EAAE,OAAO,eAAe,CAAC,CAAC;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,wBAAgB,kBAAkB,IAAI,oBAAoB,CAMzD;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,WAAW,EACX,eAAe,EACf,MAAM,EACN,QAAQ,GACT,EAAE,qBAAqB,GAAG,KAAK,CAAC,YAAY,CAe5C"}
|
package/dist/AutoshipProvider.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createClient } from "@supabase/supabase-js";
|
|
3
3
|
import { createContext, useContext, useMemo } from "react";
|
|
4
|
+
/**
|
|
5
|
+
* The database schema used by Autoship.
|
|
6
|
+
* All tables are created in this schema to avoid conflicts with other schemas.
|
|
7
|
+
*/
|
|
8
|
+
export const AUTOSHIP_SCHEMA = "autoship";
|
|
4
9
|
const AutoshipContext = createContext(null);
|
|
5
10
|
export function useAutoshipContext() {
|
|
6
11
|
const ctx = useContext(AutoshipContext);
|
|
@@ -10,6 +15,10 @@ export function useAutoshipContext() {
|
|
|
10
15
|
return ctx;
|
|
11
16
|
}
|
|
12
17
|
export function AutoshipProvider({ supabaseUrl, supabaseAnonKey, userId, children, }) {
|
|
13
|
-
const supabase = useMemo(() => createClient(supabaseUrl, supabaseAnonKey
|
|
14
|
-
|
|
18
|
+
const supabase = useMemo(() => createClient(supabaseUrl, supabaseAnonKey, {
|
|
19
|
+
db: {
|
|
20
|
+
schema: AUTOSHIP_SCHEMA,
|
|
21
|
+
},
|
|
22
|
+
}), [supabaseUrl, supabaseAnonKey]);
|
|
23
|
+
return (_jsx(AutoshipContext.Provider, { value: { supabase, userId, schema: AUTOSHIP_SCHEMA }, children: children }));
|
|
15
24
|
}
|
package/dist/cli/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAkXA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAcvD"}
|
package/dist/cli/init.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import postgres from "postgres";
|
|
2
1
|
import * as fs from "fs";
|
|
3
2
|
import * as path from "path";
|
|
3
|
+
import postgres from "postgres";
|
|
4
4
|
import * as readline from "readline";
|
|
5
5
|
import { fileURLToPath } from "url";
|
|
6
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -56,7 +56,7 @@ function printHelp() {
|
|
|
56
56
|
autoship init - Initialize Autoship database schema
|
|
57
57
|
|
|
58
58
|
Usage:
|
|
59
|
-
npx autoship init [options]
|
|
59
|
+
npx @autoship/react init [options]
|
|
60
60
|
|
|
61
61
|
Options:
|
|
62
62
|
--database-url <url> Full PostgreSQL connection URL (includes password)
|
|
@@ -79,16 +79,16 @@ Connection Methods:
|
|
|
79
79
|
|
|
80
80
|
Examples:
|
|
81
81
|
# Interactive mode (prompts for credentials)
|
|
82
|
-
npx autoship init
|
|
82
|
+
npx @autoship/react init
|
|
83
83
|
|
|
84
84
|
# With full database URL
|
|
85
|
-
npx autoship init --database-url "postgresql://postgres.xxx:password@aws-0-region.pooler.supabase.com:6543/postgres"
|
|
85
|
+
npx @autoship/react init --database-url "postgresql://postgres.xxx:password@aws-0-region.pooler.supabase.com:6543/postgres"
|
|
86
86
|
|
|
87
87
|
# With Supabase URL + password
|
|
88
|
-
npx autoship init --supabase-url https://xxx.supabase.co --db-password mypassword
|
|
88
|
+
npx @autoship/react init --supabase-url https://xxx.supabase.co --db-password mypassword
|
|
89
89
|
|
|
90
90
|
# Using environment variables
|
|
91
|
-
DATABASE_URL="postgresql://..." npx autoship init
|
|
91
|
+
DATABASE_URL="postgresql://..." npx @autoship/react init
|
|
92
92
|
`);
|
|
93
93
|
}
|
|
94
94
|
function createReadlineInterface() {
|
|
@@ -250,16 +250,21 @@ async function runMigration(databaseUrl, migrationSql) {
|
|
|
250
250
|
let allTablesExist = true;
|
|
251
251
|
for (const table of tables) {
|
|
252
252
|
try {
|
|
253
|
-
await sql.unsafe(`SELECT 1 FROM
|
|
254
|
-
console.log(` [x]
|
|
253
|
+
await sql.unsafe(`SELECT 1 FROM autoship.${table} LIMIT 0`);
|
|
254
|
+
console.log(` [x] autoship.${table}`);
|
|
255
255
|
}
|
|
256
256
|
catch (error) {
|
|
257
|
-
console.log(` [ ]
|
|
257
|
+
console.log(` [ ] autoship.${table} - NOT FOUND`);
|
|
258
258
|
allTablesExist = false;
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
if (allTablesExist) {
|
|
262
|
-
console.log("\n All tables created
|
|
262
|
+
console.log("\n All tables created in the 'autoship' schema.\n");
|
|
263
|
+
console.log(" IMPORTANT: Expose the schema in Supabase Dashboard:");
|
|
264
|
+
console.log(" 1. Go to Project Settings > API");
|
|
265
|
+
console.log(" 2. Scroll to 'Data API Settings'");
|
|
266
|
+
console.log(" 3. Add 'autoship' to the 'Extra search path'");
|
|
267
|
+
console.log(" 4. Save changes\n");
|
|
263
268
|
console.log(" Next steps:");
|
|
264
269
|
console.log(" 1. Add SUPABASE_URL and SUPABASE_ANON_KEY to your app's environment");
|
|
265
270
|
console.log(" 2. Wrap your app with <AutoshipProvider>");
|
|
@@ -300,11 +305,11 @@ async function runMigration(databaseUrl, migrationSql) {
|
|
|
300
305
|
let allTablesExist = true;
|
|
301
306
|
for (const table of tables) {
|
|
302
307
|
try {
|
|
303
|
-
await sql.unsafe(`SELECT 1 FROM
|
|
304
|
-
console.log(` [x]
|
|
308
|
+
await sql.unsafe(`SELECT 1 FROM autoship.${table} LIMIT 0`);
|
|
309
|
+
console.log(` [x] autoship.${table}`);
|
|
305
310
|
}
|
|
306
311
|
catch {
|
|
307
|
-
console.log(` [ ]
|
|
312
|
+
console.log(` [ ] autoship.${table} - NOT FOUND`);
|
|
308
313
|
allTablesExist = false;
|
|
309
314
|
}
|
|
310
315
|
}
|
package/dist/hooks/useTasks.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useCallback, useEffect, useState } from "react";
|
|
2
2
|
import { useAutoshipContext } from "../AutoshipProvider";
|
|
3
3
|
export function useTasks() {
|
|
4
|
-
const { supabase, userId } = useAutoshipContext();
|
|
4
|
+
const { supabase, userId, schema } = useAutoshipContext();
|
|
5
5
|
const [tasks, setTasks] = useState([]);
|
|
6
6
|
const [loading, setLoading] = useState(true);
|
|
7
7
|
const loadTasks = useCallback(async () => {
|
|
@@ -42,7 +42,7 @@ export function useTasks() {
|
|
|
42
42
|
.channel("agent_tasks_changes")
|
|
43
43
|
.on("postgres_changes", {
|
|
44
44
|
event: "*",
|
|
45
|
-
schema:
|
|
45
|
+
schema: schema,
|
|
46
46
|
table: "agent_tasks",
|
|
47
47
|
filter: userId ? `submitted_by=eq.${userId}` : undefined,
|
|
48
48
|
}, () => {
|
|
@@ -52,6 +52,6 @@ export function useTasks() {
|
|
|
52
52
|
return () => {
|
|
53
53
|
channel.unsubscribe();
|
|
54
54
|
};
|
|
55
|
-
}, [supabase, userId, loadTasks]);
|
|
55
|
+
}, [supabase, userId, schema, loadTasks]);
|
|
56
56
|
return { tasks, loading, refresh: loadTasks };
|
|
57
57
|
}
|
|
@@ -1,10 +1,32 @@
|
|
|
1
1
|
-- Autoship MCP Initial Schema
|
|
2
2
|
-- Tables: agent_tasks, task_categories, task_category_assignments, task_questions
|
|
3
3
|
|
|
4
|
+
-- =============================================================================
|
|
5
|
+
-- Create autoship schema to isolate from other schemas
|
|
6
|
+
-- =============================================================================
|
|
7
|
+
CREATE SCHEMA IF NOT EXISTS autoship;
|
|
8
|
+
|
|
9
|
+
-- Set search_path for this session to use autoship schema
|
|
10
|
+
SET search_path TO autoship, public;
|
|
11
|
+
|
|
12
|
+
-- =============================================================================
|
|
13
|
+
-- Expose the autoship schema via PostgREST API
|
|
14
|
+
-- Grant usage on the schema to the API roles
|
|
15
|
+
-- =============================================================================
|
|
16
|
+
GRANT USAGE ON SCHEMA autoship TO anon, authenticated, service_role;
|
|
17
|
+
|
|
18
|
+
-- Grant table permissions to service_role (full access)
|
|
19
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA autoship GRANT ALL ON TABLES TO service_role;
|
|
20
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA autoship GRANT ALL ON SEQUENCES TO service_role;
|
|
21
|
+
|
|
22
|
+
-- Grant table permissions to anon and authenticated (controlled by RLS)
|
|
23
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA autoship GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO anon, authenticated;
|
|
24
|
+
ALTER DEFAULT PRIVILEGES IN SCHEMA autoship GRANT USAGE ON SEQUENCES TO anon, authenticated;
|
|
25
|
+
|
|
4
26
|
-- =============================================================================
|
|
5
27
|
-- Categories table (for tagging tasks)
|
|
6
28
|
-- =============================================================================
|
|
7
|
-
CREATE TABLE IF NOT EXISTS task_categories (
|
|
29
|
+
CREATE TABLE IF NOT EXISTS autoship.task_categories (
|
|
8
30
|
id TEXT PRIMARY KEY,
|
|
9
31
|
name TEXT NOT NULL UNIQUE,
|
|
10
32
|
description TEXT,
|
|
@@ -15,7 +37,7 @@ CREATE TABLE IF NOT EXISTS task_categories (
|
|
|
15
37
|
-- =============================================================================
|
|
16
38
|
-- Agent tasks table (main tasks table)
|
|
17
39
|
-- =============================================================================
|
|
18
|
-
CREATE TABLE IF NOT EXISTS agent_tasks (
|
|
40
|
+
CREATE TABLE IF NOT EXISTS autoship.agent_tasks (
|
|
19
41
|
id TEXT PRIMARY KEY,
|
|
20
42
|
title TEXT NOT NULL,
|
|
21
43
|
description TEXT NOT NULL,
|
|
@@ -33,29 +55,29 @@ CREATE TABLE IF NOT EXISTS agent_tasks (
|
|
|
33
55
|
);
|
|
34
56
|
|
|
35
57
|
-- Index for finding pending tasks quickly
|
|
36
|
-
CREATE INDEX idx_agent_tasks_status_priority ON agent_tasks(status, priority DESC);
|
|
58
|
+
CREATE INDEX idx_agent_tasks_status_priority ON autoship.agent_tasks(status, priority DESC);
|
|
37
59
|
|
|
38
60
|
-- Index for user's tasks (React components)
|
|
39
|
-
CREATE INDEX idx_agent_tasks_submitted_by ON agent_tasks(submitted_by);
|
|
61
|
+
CREATE INDEX idx_agent_tasks_submitted_by ON autoship.agent_tasks(submitted_by);
|
|
40
62
|
|
|
41
63
|
-- =============================================================================
|
|
42
64
|
-- Category assignments (many-to-many relationship)
|
|
43
65
|
-- =============================================================================
|
|
44
|
-
CREATE TABLE IF NOT EXISTS task_category_assignments (
|
|
45
|
-
task_id TEXT NOT NULL REFERENCES agent_tasks(id) ON DELETE CASCADE,
|
|
46
|
-
category_id TEXT NOT NULL REFERENCES task_categories(id) ON DELETE CASCADE,
|
|
66
|
+
CREATE TABLE IF NOT EXISTS autoship.task_category_assignments (
|
|
67
|
+
task_id TEXT NOT NULL REFERENCES autoship.agent_tasks(id) ON DELETE CASCADE,
|
|
68
|
+
category_id TEXT NOT NULL REFERENCES autoship.task_categories(id) ON DELETE CASCADE,
|
|
47
69
|
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
48
70
|
PRIMARY KEY (task_id, category_id)
|
|
49
71
|
);
|
|
50
72
|
|
|
51
|
-
CREATE INDEX idx_task_category_assignments_category ON task_category_assignments(category_id);
|
|
73
|
+
CREATE INDEX idx_task_category_assignments_category ON autoship.task_category_assignments(category_id);
|
|
52
74
|
|
|
53
75
|
-- =============================================================================
|
|
54
76
|
-- Questions and answers for tasks
|
|
55
77
|
-- =============================================================================
|
|
56
|
-
CREATE TABLE IF NOT EXISTS task_questions (
|
|
78
|
+
CREATE TABLE IF NOT EXISTS autoship.task_questions (
|
|
57
79
|
id TEXT PRIMARY KEY,
|
|
58
|
-
task_id TEXT NOT NULL REFERENCES agent_tasks(id) ON DELETE CASCADE,
|
|
80
|
+
task_id TEXT NOT NULL REFERENCES autoship.agent_tasks(id) ON DELETE CASCADE,
|
|
59
81
|
question TEXT NOT NULL,
|
|
60
82
|
answer TEXT, -- NULL until answered
|
|
61
83
|
asked_by TEXT DEFAULT 'agent', -- 'agent' or 'user'
|
|
@@ -63,13 +85,13 @@ CREATE TABLE IF NOT EXISTS task_questions (
|
|
|
63
85
|
answered_at TIMESTAMPTZ
|
|
64
86
|
);
|
|
65
87
|
|
|
66
|
-
CREATE INDEX idx_task_questions_task ON task_questions(task_id);
|
|
67
|
-
CREATE INDEX idx_task_questions_unanswered ON task_questions(task_id) WHERE answer IS NULL;
|
|
88
|
+
CREATE INDEX idx_task_questions_task ON autoship.task_questions(task_id);
|
|
89
|
+
CREATE INDEX idx_task_questions_unanswered ON autoship.task_questions(task_id) WHERE answer IS NULL;
|
|
68
90
|
|
|
69
91
|
-- =============================================================================
|
|
70
92
|
-- Trigger to update updated_at on agent_tasks
|
|
71
93
|
-- =============================================================================
|
|
72
|
-
CREATE OR REPLACE FUNCTION update_agent_tasks_updated_at()
|
|
94
|
+
CREATE OR REPLACE FUNCTION autoship.update_agent_tasks_updated_at()
|
|
73
95
|
RETURNS TRIGGER AS $$
|
|
74
96
|
BEGIN
|
|
75
97
|
NEW.updated_at = NOW();
|
|
@@ -78,32 +100,32 @@ END;
|
|
|
78
100
|
$$ LANGUAGE plpgsql;
|
|
79
101
|
|
|
80
102
|
CREATE TRIGGER agent_tasks_updated_at
|
|
81
|
-
BEFORE UPDATE ON agent_tasks
|
|
103
|
+
BEFORE UPDATE ON autoship.agent_tasks
|
|
82
104
|
FOR EACH ROW
|
|
83
|
-
EXECUTE FUNCTION update_agent_tasks_updated_at();
|
|
105
|
+
EXECUTE FUNCTION autoship.update_agent_tasks_updated_at();
|
|
84
106
|
|
|
85
107
|
-- =============================================================================
|
|
86
108
|
-- Row Level Security
|
|
87
109
|
-- =============================================================================
|
|
88
110
|
|
|
89
111
|
-- Enable RLS on all tables
|
|
90
|
-
ALTER TABLE agent_tasks ENABLE ROW LEVEL SECURITY;
|
|
91
|
-
ALTER TABLE task_categories ENABLE ROW LEVEL SECURITY;
|
|
92
|
-
ALTER TABLE task_category_assignments ENABLE ROW LEVEL SECURITY;
|
|
93
|
-
ALTER TABLE task_questions ENABLE ROW LEVEL SECURITY;
|
|
112
|
+
ALTER TABLE autoship.agent_tasks ENABLE ROW LEVEL SECURITY;
|
|
113
|
+
ALTER TABLE autoship.task_categories ENABLE ROW LEVEL SECURITY;
|
|
114
|
+
ALTER TABLE autoship.task_category_assignments ENABLE ROW LEVEL SECURITY;
|
|
115
|
+
ALTER TABLE autoship.task_questions ENABLE ROW LEVEL SECURITY;
|
|
94
116
|
|
|
95
117
|
-- Service role has full access (used by the MCP server)
|
|
96
118
|
CREATE POLICY "Service role has full access to agent_tasks"
|
|
97
|
-
ON agent_tasks FOR ALL USING (true) WITH CHECK (true);
|
|
119
|
+
ON autoship.agent_tasks FOR ALL USING (true) WITH CHECK (true);
|
|
98
120
|
|
|
99
121
|
CREATE POLICY "Service role has full access to task_categories"
|
|
100
|
-
ON task_categories FOR ALL USING (true) WITH CHECK (true);
|
|
122
|
+
ON autoship.task_categories FOR ALL USING (true) WITH CHECK (true);
|
|
101
123
|
|
|
102
124
|
CREATE POLICY "Service role has full access to task_category_assignments"
|
|
103
|
-
ON task_category_assignments FOR ALL USING (true) WITH CHECK (true);
|
|
125
|
+
ON autoship.task_category_assignments FOR ALL USING (true) WITH CHECK (true);
|
|
104
126
|
|
|
105
127
|
CREATE POLICY "Service role has full access to task_questions"
|
|
106
|
-
ON task_questions FOR ALL USING (true) WITH CHECK (true);
|
|
128
|
+
ON autoship.task_questions FOR ALL USING (true) WITH CHECK (true);
|
|
107
129
|
|
|
108
130
|
-- =============================================================================
|
|
109
131
|
-- Policies for React components (using anon key)
|
|
@@ -111,33 +133,47 @@ CREATE POLICY "Service role has full access to task_questions"
|
|
|
111
133
|
|
|
112
134
|
-- Users can view their own tasks or tasks without a submitter
|
|
113
135
|
CREATE POLICY "Users can view their own tasks"
|
|
114
|
-
ON agent_tasks FOR SELECT
|
|
136
|
+
ON autoship.agent_tasks FOR SELECT
|
|
115
137
|
USING (submitted_by IS NULL OR submitted_by = coalesce(auth.uid()::text, submitted_by));
|
|
116
138
|
|
|
117
139
|
-- Anyone can insert tasks
|
|
118
140
|
CREATE POLICY "Anyone can insert tasks"
|
|
119
|
-
ON agent_tasks FOR INSERT
|
|
141
|
+
ON autoship.agent_tasks FOR INSERT
|
|
120
142
|
WITH CHECK (true);
|
|
121
143
|
|
|
122
144
|
-- Users can update their own tasks (for answering questions)
|
|
123
145
|
CREATE POLICY "Users can update their own tasks"
|
|
124
|
-
ON agent_tasks FOR UPDATE
|
|
146
|
+
ON autoship.agent_tasks FOR UPDATE
|
|
125
147
|
USING (submitted_by IS NULL OR submitted_by = coalesce(auth.uid()::text, submitted_by));
|
|
126
148
|
|
|
127
149
|
-- Users can view questions for their tasks
|
|
128
150
|
CREATE POLICY "Users can view questions for their tasks"
|
|
129
|
-
ON task_questions FOR SELECT
|
|
151
|
+
ON autoship.task_questions FOR SELECT
|
|
130
152
|
USING (EXISTS (
|
|
131
|
-
SELECT 1 FROM agent_tasks
|
|
132
|
-
WHERE agent_tasks.id = task_questions.task_id
|
|
133
|
-
AND (agent_tasks.submitted_by IS NULL OR agent_tasks.submitted_by = coalesce(auth.uid()::text, agent_tasks.submitted_by))
|
|
153
|
+
SELECT 1 FROM autoship.agent_tasks
|
|
154
|
+
WHERE autoship.agent_tasks.id = autoship.task_questions.task_id
|
|
155
|
+
AND (autoship.agent_tasks.submitted_by IS NULL OR autoship.agent_tasks.submitted_by = coalesce(auth.uid()::text, autoship.agent_tasks.submitted_by))
|
|
134
156
|
));
|
|
135
157
|
|
|
136
158
|
-- Users can update questions (to provide answers)
|
|
137
159
|
CREATE POLICY "Users can update questions for their tasks"
|
|
138
|
-
ON task_questions FOR UPDATE
|
|
160
|
+
ON autoship.task_questions FOR UPDATE
|
|
139
161
|
USING (EXISTS (
|
|
140
|
-
SELECT 1 FROM agent_tasks
|
|
141
|
-
WHERE agent_tasks.id = task_questions.task_id
|
|
142
|
-
AND (agent_tasks.submitted_by IS NULL OR agent_tasks.submitted_by = coalesce(auth.uid()::text, agent_tasks.submitted_by))
|
|
162
|
+
SELECT 1 FROM autoship.agent_tasks
|
|
163
|
+
WHERE autoship.agent_tasks.id = autoship.task_questions.task_id
|
|
164
|
+
AND (autoship.agent_tasks.submitted_by IS NULL OR autoship.agent_tasks.submitted_by = coalesce(auth.uid()::text, autoship.agent_tasks.submitted_by))
|
|
143
165
|
));
|
|
166
|
+
|
|
167
|
+
-- =============================================================================
|
|
168
|
+
-- Grant explicit permissions on tables (since ALTER DEFAULT PRIVILEGES only
|
|
169
|
+
-- affects future tables, not tables created in the same transaction)
|
|
170
|
+
-- =============================================================================
|
|
171
|
+
GRANT ALL ON autoship.agent_tasks TO service_role;
|
|
172
|
+
GRANT ALL ON autoship.task_categories TO service_role;
|
|
173
|
+
GRANT ALL ON autoship.task_category_assignments TO service_role;
|
|
174
|
+
GRANT ALL ON autoship.task_questions TO service_role;
|
|
175
|
+
|
|
176
|
+
GRANT SELECT, INSERT, UPDATE, DELETE ON autoship.agent_tasks TO anon, authenticated;
|
|
177
|
+
GRANT SELECT, INSERT, UPDATE, DELETE ON autoship.task_categories TO anon, authenticated;
|
|
178
|
+
GRANT SELECT, INSERT, UPDATE, DELETE ON autoship.task_category_assignments TO anon, authenticated;
|
|
179
|
+
GRANT SELECT, INSERT, UPDATE, DELETE ON autoship.task_questions TO anon, authenticated;
|