aios-core 2.2.1 → 2.3.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/.aios-core/.session/current-session.json +14 -14
- package/.aios-core/cli/commands/migrate/validate.js +1 -1
- package/.aios-core/core/docs/session-update-pattern.md +17 -10
- package/.aios-core/core/elicitation/elicitation-engine.js +11 -6
- package/.aios-core/core/elicitation/session-manager.js +2 -1
- package/.aios-core/core/registry/registry-schema.json +166 -166
- package/.aios-core/core/registry/service-registry.json +6585 -6585
- package/.aios-core/core-config.yaml +12 -1
- package/.aios-core/data/agent-config-requirements.yaml +5 -5
- package/.aios-core/development/agents/devops.md +12 -0
- package/.aios-core/development/scripts/squad/README.md +112 -0
- package/.aios-core/development/scripts/squad/index.js +41 -0
- package/.aios-core/development/scripts/squad/squad-loader.js +359 -0
- package/.aios-core/development/scripts/squad/squad-validator.js +685 -0
- package/.aios-core/development/tasks/add-mcp.md +11 -5
- package/.aios-core/development/tasks/search-mcp.md +309 -0
- package/.aios-core/development/tasks/setup-mcp-docker.md +11 -8
- package/.aios-core/development/tasks/squad-creator-validate.md +151 -0
- package/.aios-core/docs/standards/AGENT-PERSONALIZATION-STANDARD-V1.md +3 -3
- package/.aios-core/index.d.ts +7 -7
- package/.aios-core/index.js +1 -1
- package/.aios-core/infrastructure/scripts/batch-creator.js +1 -1
- package/.aios-core/infrastructure/scripts/component-generator.js +1 -1
- package/.aios-core/infrastructure/templates/coderabbit.yaml.template +279 -279
- package/.aios-core/infrastructure/templates/github-workflows/ci.yml.template +169 -169
- package/.aios-core/infrastructure/templates/github-workflows/pr-automation.yml.template +330 -330
- package/.aios-core/infrastructure/templates/github-workflows/release.yml.template +196 -196
- package/.aios-core/infrastructure/templates/gitignore/gitignore-aios-base.tmpl +63 -63
- package/.aios-core/infrastructure/templates/gitignore/gitignore-brownfield-merge.tmpl +18 -18
- package/.aios-core/infrastructure/templates/gitignore/gitignore-node.tmpl +85 -85
- package/.aios-core/infrastructure/templates/gitignore/gitignore-python.tmpl +145 -145
- package/.aios-core/infrastructure/tests/utilities-audit-results.json +500 -500
- package/.aios-core/infrastructure/tools/README.md +1 -1
- package/.aios-core/install-manifest.yaml +4 -1
- package/.aios-core/manifests/schema/manifest-schema.json +190 -190
- package/.aios-core/manifests/workers.csv +203 -203
- package/.aios-core/package.json +102 -102
- package/.aios-core/product/templates/activation-instructions-template.md +7 -7
- package/.aios-core/product/templates/adr.hbs +125 -125
- package/.aios-core/product/templates/component-react-tmpl.tsx +98 -98
- package/.aios-core/product/templates/dbdr.hbs +241 -241
- package/.aios-core/product/templates/engine/schemas/adr.schema.json +102 -102
- package/.aios-core/product/templates/engine/schemas/dbdr.schema.json +205 -205
- package/.aios-core/product/templates/engine/schemas/epic.schema.json +175 -175
- package/.aios-core/product/templates/engine/schemas/pmdr.schema.json +175 -175
- package/.aios-core/product/templates/engine/schemas/prd-v2.schema.json +300 -300
- package/.aios-core/product/templates/engine/schemas/prd.schema.json +152 -152
- package/.aios-core/product/templates/engine/schemas/story.schema.json +222 -222
- package/.aios-core/product/templates/engine/schemas/task.schema.json +154 -154
- package/.aios-core/product/templates/epic.hbs +212 -212
- package/.aios-core/product/templates/eslintrc-security.json +32 -32
- package/.aios-core/product/templates/github-actions-cd.yml +212 -212
- package/.aios-core/product/templates/github-actions-ci.yml +172 -172
- package/.aios-core/product/templates/pmdr.hbs +186 -186
- package/.aios-core/product/templates/prd-v2.0.hbs +216 -216
- package/.aios-core/product/templates/prd.hbs +201 -201
- package/.aios-core/product/templates/shock-report-tmpl.html +502 -502
- package/.aios-core/product/templates/story.hbs +263 -263
- package/.aios-core/product/templates/task.hbs +170 -170
- package/.aios-core/product/templates/tmpl-comment-on-examples.sql +158 -158
- package/.aios-core/product/templates/tmpl-migration-script.sql +91 -91
- package/.aios-core/product/templates/tmpl-rls-granular-policies.sql +104 -104
- package/.aios-core/product/templates/tmpl-rls-kiss-policy.sql +10 -10
- package/.aios-core/product/templates/tmpl-rls-roles.sql +135 -135
- package/.aios-core/product/templates/tmpl-rls-simple.sql +77 -77
- package/.aios-core/product/templates/tmpl-rls-tenant.sql +152 -152
- package/.aios-core/product/templates/tmpl-rollback-script.sql +77 -77
- package/.aios-core/product/templates/tmpl-seed-data.sql +140 -140
- package/.aios-core/product/templates/tmpl-smoke-test.sql +16 -16
- package/.aios-core/product/templates/tmpl-staging-copy-merge.sql +139 -139
- package/.aios-core/product/templates/tmpl-stored-proc.sql +140 -140
- package/.aios-core/product/templates/tmpl-trigger.sql +152 -152
- package/.aios-core/product/templates/tmpl-view-materialized.sql +133 -133
- package/.aios-core/product/templates/tmpl-view.sql +177 -177
- package/.aios-core/product/templates/token-exports-css-tmpl.css +240 -240
- package/.aios-core/quality/schemas/quality-metrics.schema.json +233 -233
- package/.aios-core/schemas/squad-schema.json +185 -0
- package/.aios-core/scripts/README.md +90 -322
- package/.aios-core/scripts/migrate-framework-docs.sh +300 -300
- package/.claude/rules/mcp-usage.md +116 -100
- package/LICENSE +48 -48
- package/README.md +3 -4
- package/bin/aios-init.js +11 -6
- package/bin/aios.js +2 -1
- package/package.json +2 -3
- package/packages/installer/package.json +39 -39
- package/packages/installer/tests/integration/environment-configuration.test.js +2 -2
- package/packages/installer/tests/unit/env-template.test.js +4 -3
- package/templates/squad/LICENSE +21 -21
- package/templates/squad/README.md +37 -37
- package/templates/squad/agents/example-agent.yaml +36 -36
- package/templates/squad/package.json +19 -19
- package/templates/squad/squad.yaml +25 -25
- package/templates/squad/tasks/example-task.yaml +46 -46
- package/templates/squad/templates/example-template.md +24 -24
- package/templates/squad/tests/example-agent.test.js +53 -53
- package/templates/squad/workflows/example-workflow.yaml +54 -54
- package/tools/diagnose-npx-issue.ps1 +96 -96
- package/tools/quick-diagnose.cmd +85 -85
- package/tools/quick-diagnose.ps1 +117 -117
- package/.aios-core/core/data/agent-config-requirements.yaml +0 -368
- package/.aios-core/core/data/aios-kb.md +0 -924
- package/.aios-core/core/data/workflow-patterns.yaml +0 -267
- package/.aios-core/product/templates/1mcp-config.yaml +0 -225
- package/.aios-core/scripts/context-detector.js +0 -226
- package/.aios-core/scripts/elicitation-engine.js +0 -385
- package/.aios-core/scripts/elicitation-session-manager.js +0 -300
- package/.claude/CLAUDE.md +0 -221
|
@@ -1,91 +1,91 @@
|
|
|
1
|
-
-- Migration Script Template
|
|
2
|
-
-- Migration: :migration_name
|
|
3
|
-
-- Created: :created_date
|
|
4
|
-
-- Author: :author
|
|
5
|
-
-- Description: :description
|
|
6
|
-
--
|
|
7
|
-
-- IMPORTANT: Run in transaction, test with dry-run first
|
|
8
|
-
-- ROLLBACK: See tmpl-rollback-script.sql for corresponding rollback
|
|
9
|
-
|
|
10
|
-
BEGIN;
|
|
11
|
-
|
|
12
|
-
-- =============================================================================
|
|
13
|
-
-- PRE-MIGRATION CHECKS
|
|
14
|
-
-- =============================================================================
|
|
15
|
-
|
|
16
|
-
-- Verify prerequisites are met
|
|
17
|
-
DO $$
|
|
18
|
-
BEGIN
|
|
19
|
-
-- Add any precondition checks here
|
|
20
|
-
-- Example: ASSERT (SELECT EXISTS (SELECT 1 FROM :prerequisite_table));
|
|
21
|
-
RAISE NOTICE 'Pre-migration checks passed';
|
|
22
|
-
END $$;
|
|
23
|
-
|
|
24
|
-
-- =============================================================================
|
|
25
|
-
-- SCHEMA CHANGES
|
|
26
|
-
-- =============================================================================
|
|
27
|
-
|
|
28
|
-
-- Create new table (if needed)
|
|
29
|
-
CREATE TABLE IF NOT EXISTS :table_name (
|
|
30
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
31
|
-
-- Add columns here
|
|
32
|
-
:column_name :column_type :constraints,
|
|
33
|
-
|
|
34
|
-
-- Standard audit columns
|
|
35
|
-
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
36
|
-
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
-- Add column to existing table (if needed)
|
|
40
|
-
-- ALTER TABLE :existing_table ADD COLUMN IF NOT EXISTS :new_column :column_type;
|
|
41
|
-
|
|
42
|
-
-- Create index (if needed)
|
|
43
|
-
-- CREATE INDEX IF NOT EXISTS idx_:table_:column ON :table_name (:column_name);
|
|
44
|
-
|
|
45
|
-
-- =============================================================================
|
|
46
|
-
-- DATA MIGRATION (if needed)
|
|
47
|
-
-- =============================================================================
|
|
48
|
-
|
|
49
|
-
-- Migrate data from old structure to new
|
|
50
|
-
-- INSERT INTO :new_table (col1, col2)
|
|
51
|
-
-- SELECT old_col1, old_col2 FROM :old_table;
|
|
52
|
-
|
|
53
|
-
-- =============================================================================
|
|
54
|
-
-- POST-MIGRATION SETUP
|
|
55
|
-
-- =============================================================================
|
|
56
|
-
|
|
57
|
-
-- Add updated_at trigger
|
|
58
|
-
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
|
59
|
-
RETURNS TRIGGER AS $$
|
|
60
|
-
BEGIN
|
|
61
|
-
NEW.updated_at = NOW();
|
|
62
|
-
RETURN NEW;
|
|
63
|
-
END;
|
|
64
|
-
$$ LANGUAGE plpgsql;
|
|
65
|
-
|
|
66
|
-
DROP TRIGGER IF EXISTS trigger_update_:table_name_updated_at ON :table_name;
|
|
67
|
-
CREATE TRIGGER trigger_update_:table_name_updated_at
|
|
68
|
-
BEFORE UPDATE ON :table_name
|
|
69
|
-
FOR EACH ROW
|
|
70
|
-
EXECUTE FUNCTION update_updated_at_column();
|
|
71
|
-
|
|
72
|
-
-- Add table comments
|
|
73
|
-
COMMENT ON TABLE :table_name IS ':table_description';
|
|
74
|
-
COMMENT ON COLUMN :table_name.:column_name IS ':column_description';
|
|
75
|
-
|
|
76
|
-
-- =============================================================================
|
|
77
|
-
-- VERIFICATION
|
|
78
|
-
-- =============================================================================
|
|
79
|
-
|
|
80
|
-
DO $$
|
|
81
|
-
BEGIN
|
|
82
|
-
-- Verify migration was successful
|
|
83
|
-
ASSERT (SELECT EXISTS (
|
|
84
|
-
SELECT 1 FROM information_schema.tables
|
|
85
|
-
WHERE table_name = ':table_name'
|
|
86
|
-
)), 'Table :table_name was not created';
|
|
87
|
-
|
|
88
|
-
RAISE NOTICE 'Migration completed successfully';
|
|
89
|
-
END $$;
|
|
90
|
-
|
|
91
|
-
COMMIT;
|
|
1
|
+
-- Migration Script Template
|
|
2
|
+
-- Migration: :migration_name
|
|
3
|
+
-- Created: :created_date
|
|
4
|
+
-- Author: :author
|
|
5
|
+
-- Description: :description
|
|
6
|
+
--
|
|
7
|
+
-- IMPORTANT: Run in transaction, test with dry-run first
|
|
8
|
+
-- ROLLBACK: See tmpl-rollback-script.sql for corresponding rollback
|
|
9
|
+
|
|
10
|
+
BEGIN;
|
|
11
|
+
|
|
12
|
+
-- =============================================================================
|
|
13
|
+
-- PRE-MIGRATION CHECKS
|
|
14
|
+
-- =============================================================================
|
|
15
|
+
|
|
16
|
+
-- Verify prerequisites are met
|
|
17
|
+
DO $$
|
|
18
|
+
BEGIN
|
|
19
|
+
-- Add any precondition checks here
|
|
20
|
+
-- Example: ASSERT (SELECT EXISTS (SELECT 1 FROM :prerequisite_table));
|
|
21
|
+
RAISE NOTICE 'Pre-migration checks passed';
|
|
22
|
+
END $$;
|
|
23
|
+
|
|
24
|
+
-- =============================================================================
|
|
25
|
+
-- SCHEMA CHANGES
|
|
26
|
+
-- =============================================================================
|
|
27
|
+
|
|
28
|
+
-- Create new table (if needed)
|
|
29
|
+
CREATE TABLE IF NOT EXISTS :table_name (
|
|
30
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
31
|
+
-- Add columns here
|
|
32
|
+
:column_name :column_type :constraints,
|
|
33
|
+
|
|
34
|
+
-- Standard audit columns
|
|
35
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
36
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
-- Add column to existing table (if needed)
|
|
40
|
+
-- ALTER TABLE :existing_table ADD COLUMN IF NOT EXISTS :new_column :column_type;
|
|
41
|
+
|
|
42
|
+
-- Create index (if needed)
|
|
43
|
+
-- CREATE INDEX IF NOT EXISTS idx_:table_:column ON :table_name (:column_name);
|
|
44
|
+
|
|
45
|
+
-- =============================================================================
|
|
46
|
+
-- DATA MIGRATION (if needed)
|
|
47
|
+
-- =============================================================================
|
|
48
|
+
|
|
49
|
+
-- Migrate data from old structure to new
|
|
50
|
+
-- INSERT INTO :new_table (col1, col2)
|
|
51
|
+
-- SELECT old_col1, old_col2 FROM :old_table;
|
|
52
|
+
|
|
53
|
+
-- =============================================================================
|
|
54
|
+
-- POST-MIGRATION SETUP
|
|
55
|
+
-- =============================================================================
|
|
56
|
+
|
|
57
|
+
-- Add updated_at trigger
|
|
58
|
+
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
|
59
|
+
RETURNS TRIGGER AS $$
|
|
60
|
+
BEGIN
|
|
61
|
+
NEW.updated_at = NOW();
|
|
62
|
+
RETURN NEW;
|
|
63
|
+
END;
|
|
64
|
+
$$ LANGUAGE plpgsql;
|
|
65
|
+
|
|
66
|
+
DROP TRIGGER IF EXISTS trigger_update_:table_name_updated_at ON :table_name;
|
|
67
|
+
CREATE TRIGGER trigger_update_:table_name_updated_at
|
|
68
|
+
BEFORE UPDATE ON :table_name
|
|
69
|
+
FOR EACH ROW
|
|
70
|
+
EXECUTE FUNCTION update_updated_at_column();
|
|
71
|
+
|
|
72
|
+
-- Add table comments
|
|
73
|
+
COMMENT ON TABLE :table_name IS ':table_description';
|
|
74
|
+
COMMENT ON COLUMN :table_name.:column_name IS ':column_description';
|
|
75
|
+
|
|
76
|
+
-- =============================================================================
|
|
77
|
+
-- VERIFICATION
|
|
78
|
+
-- =============================================================================
|
|
79
|
+
|
|
80
|
+
DO $$
|
|
81
|
+
BEGIN
|
|
82
|
+
-- Verify migration was successful
|
|
83
|
+
ASSERT (SELECT EXISTS (
|
|
84
|
+
SELECT 1 FROM information_schema.tables
|
|
85
|
+
WHERE table_name = ':table_name'
|
|
86
|
+
)), 'Table :table_name was not created';
|
|
87
|
+
|
|
88
|
+
RAISE NOTICE 'Migration completed successfully';
|
|
89
|
+
END $$;
|
|
90
|
+
|
|
91
|
+
COMMIT;
|
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
-- Granular RLS Policies Template
|
|
2
|
-
-- Table: :table_name
|
|
3
|
-
-- Security Model: Granular (separate policies per operation)
|
|
4
|
-
-- Created: :created_date
|
|
5
|
-
--
|
|
6
|
-
-- This template creates separate policies for SELECT, INSERT, UPDATE, DELETE
|
|
7
|
-
-- Useful when different users have different permissions per operation
|
|
8
|
-
|
|
9
|
-
-- Enable RLS on table
|
|
10
|
-
ALTER TABLE :table_name ENABLE ROW LEVEL SECURITY;
|
|
11
|
-
|
|
12
|
-
-- Force RLS for table owner too (recommended for security)
|
|
13
|
-
ALTER TABLE :table_name FORCE ROW LEVEL SECURITY;
|
|
14
|
-
|
|
15
|
-
-- =============================================================================
|
|
16
|
-
-- SELECT POLICY - Who can read rows
|
|
17
|
-
-- =============================================================================
|
|
18
|
-
DROP POLICY IF EXISTS ":table_name_select" ON :table_name;
|
|
19
|
-
CREATE POLICY ":table_name_select"
|
|
20
|
-
ON :table_name
|
|
21
|
-
FOR SELECT
|
|
22
|
-
TO authenticated
|
|
23
|
-
USING (
|
|
24
|
-
-- Owner can read their own rows
|
|
25
|
-
auth.uid() = user_id
|
|
26
|
-
-- OR user has read permission via role
|
|
27
|
-
OR EXISTS (
|
|
28
|
-
SELECT 1 FROM user_roles
|
|
29
|
-
WHERE user_id = auth.uid()
|
|
30
|
-
AND role IN ('admin', 'reader')
|
|
31
|
-
)
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
-- =============================================================================
|
|
35
|
-
-- INSERT POLICY - Who can create rows
|
|
36
|
-
-- =============================================================================
|
|
37
|
-
DROP POLICY IF EXISTS ":table_name_insert" ON :table_name;
|
|
38
|
-
CREATE POLICY ":table_name_insert"
|
|
39
|
-
ON :table_name
|
|
40
|
-
FOR INSERT
|
|
41
|
-
TO authenticated
|
|
42
|
-
WITH CHECK (
|
|
43
|
-
-- User can only insert rows they will own
|
|
44
|
-
auth.uid() = user_id
|
|
45
|
-
-- OR user has creator permission
|
|
46
|
-
OR EXISTS (
|
|
47
|
-
SELECT 1 FROM user_roles
|
|
48
|
-
WHERE user_id = auth.uid()
|
|
49
|
-
AND role IN ('admin', 'creator')
|
|
50
|
-
)
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
-- =============================================================================
|
|
54
|
-
-- UPDATE POLICY - Who can modify rows
|
|
55
|
-
-- =============================================================================
|
|
56
|
-
DROP POLICY IF EXISTS ":table_name_update" ON :table_name;
|
|
57
|
-
CREATE POLICY ":table_name_update"
|
|
58
|
-
ON :table_name
|
|
59
|
-
FOR UPDATE
|
|
60
|
-
TO authenticated
|
|
61
|
-
USING (
|
|
62
|
-
-- Can only see rows to update if owner
|
|
63
|
-
auth.uid() = user_id
|
|
64
|
-
OR EXISTS (
|
|
65
|
-
SELECT 1 FROM user_roles
|
|
66
|
-
WHERE user_id = auth.uid()
|
|
67
|
-
AND role IN ('admin', 'editor')
|
|
68
|
-
)
|
|
69
|
-
)
|
|
70
|
-
WITH CHECK (
|
|
71
|
-
-- Can only update to valid state
|
|
72
|
-
auth.uid() = user_id
|
|
73
|
-
OR EXISTS (
|
|
74
|
-
SELECT 1 FROM user_roles
|
|
75
|
-
WHERE user_id = auth.uid()
|
|
76
|
-
AND role IN ('admin', 'editor')
|
|
77
|
-
)
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
-- =============================================================================
|
|
81
|
-
-- DELETE POLICY - Who can delete rows
|
|
82
|
-
-- =============================================================================
|
|
83
|
-
DROP POLICY IF EXISTS ":table_name_delete" ON :table_name;
|
|
84
|
-
CREATE POLICY ":table_name_delete"
|
|
85
|
-
ON :table_name
|
|
86
|
-
FOR DELETE
|
|
87
|
-
TO authenticated
|
|
88
|
-
USING (
|
|
89
|
-
-- Only owner or admin can delete
|
|
90
|
-
auth.uid() = user_id
|
|
91
|
-
OR EXISTS (
|
|
92
|
-
SELECT 1 FROM user_roles
|
|
93
|
-
WHERE user_id = auth.uid()
|
|
94
|
-
AND role = 'admin'
|
|
95
|
-
)
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
-- =============================================================================
|
|
99
|
-
-- VERIFICATION
|
|
100
|
-
-- =============================================================================
|
|
101
|
-
-- Test these policies with:
|
|
102
|
-
-- SET LOCAL ROLE authenticated;
|
|
103
|
-
-- SET LOCAL request.jwt.claims = '{"sub": "user-uuid-here"}';
|
|
104
|
-
-- SELECT * FROM :table_name; -- Should only return authorized rows
|
|
1
|
+
-- Granular RLS Policies Template
|
|
2
|
+
-- Table: :table_name
|
|
3
|
+
-- Security Model: Granular (separate policies per operation)
|
|
4
|
+
-- Created: :created_date
|
|
5
|
+
--
|
|
6
|
+
-- This template creates separate policies for SELECT, INSERT, UPDATE, DELETE
|
|
7
|
+
-- Useful when different users have different permissions per operation
|
|
8
|
+
|
|
9
|
+
-- Enable RLS on table
|
|
10
|
+
ALTER TABLE :table_name ENABLE ROW LEVEL SECURITY;
|
|
11
|
+
|
|
12
|
+
-- Force RLS for table owner too (recommended for security)
|
|
13
|
+
ALTER TABLE :table_name FORCE ROW LEVEL SECURITY;
|
|
14
|
+
|
|
15
|
+
-- =============================================================================
|
|
16
|
+
-- SELECT POLICY - Who can read rows
|
|
17
|
+
-- =============================================================================
|
|
18
|
+
DROP POLICY IF EXISTS ":table_name_select" ON :table_name;
|
|
19
|
+
CREATE POLICY ":table_name_select"
|
|
20
|
+
ON :table_name
|
|
21
|
+
FOR SELECT
|
|
22
|
+
TO authenticated
|
|
23
|
+
USING (
|
|
24
|
+
-- Owner can read their own rows
|
|
25
|
+
auth.uid() = user_id
|
|
26
|
+
-- OR user has read permission via role
|
|
27
|
+
OR EXISTS (
|
|
28
|
+
SELECT 1 FROM user_roles
|
|
29
|
+
WHERE user_id = auth.uid()
|
|
30
|
+
AND role IN ('admin', 'reader')
|
|
31
|
+
)
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
-- =============================================================================
|
|
35
|
+
-- INSERT POLICY - Who can create rows
|
|
36
|
+
-- =============================================================================
|
|
37
|
+
DROP POLICY IF EXISTS ":table_name_insert" ON :table_name;
|
|
38
|
+
CREATE POLICY ":table_name_insert"
|
|
39
|
+
ON :table_name
|
|
40
|
+
FOR INSERT
|
|
41
|
+
TO authenticated
|
|
42
|
+
WITH CHECK (
|
|
43
|
+
-- User can only insert rows they will own
|
|
44
|
+
auth.uid() = user_id
|
|
45
|
+
-- OR user has creator permission
|
|
46
|
+
OR EXISTS (
|
|
47
|
+
SELECT 1 FROM user_roles
|
|
48
|
+
WHERE user_id = auth.uid()
|
|
49
|
+
AND role IN ('admin', 'creator')
|
|
50
|
+
)
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
-- =============================================================================
|
|
54
|
+
-- UPDATE POLICY - Who can modify rows
|
|
55
|
+
-- =============================================================================
|
|
56
|
+
DROP POLICY IF EXISTS ":table_name_update" ON :table_name;
|
|
57
|
+
CREATE POLICY ":table_name_update"
|
|
58
|
+
ON :table_name
|
|
59
|
+
FOR UPDATE
|
|
60
|
+
TO authenticated
|
|
61
|
+
USING (
|
|
62
|
+
-- Can only see rows to update if owner
|
|
63
|
+
auth.uid() = user_id
|
|
64
|
+
OR EXISTS (
|
|
65
|
+
SELECT 1 FROM user_roles
|
|
66
|
+
WHERE user_id = auth.uid()
|
|
67
|
+
AND role IN ('admin', 'editor')
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
WITH CHECK (
|
|
71
|
+
-- Can only update to valid state
|
|
72
|
+
auth.uid() = user_id
|
|
73
|
+
OR EXISTS (
|
|
74
|
+
SELECT 1 FROM user_roles
|
|
75
|
+
WHERE user_id = auth.uid()
|
|
76
|
+
AND role IN ('admin', 'editor')
|
|
77
|
+
)
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
-- =============================================================================
|
|
81
|
+
-- DELETE POLICY - Who can delete rows
|
|
82
|
+
-- =============================================================================
|
|
83
|
+
DROP POLICY IF EXISTS ":table_name_delete" ON :table_name;
|
|
84
|
+
CREATE POLICY ":table_name_delete"
|
|
85
|
+
ON :table_name
|
|
86
|
+
FOR DELETE
|
|
87
|
+
TO authenticated
|
|
88
|
+
USING (
|
|
89
|
+
-- Only owner or admin can delete
|
|
90
|
+
auth.uid() = user_id
|
|
91
|
+
OR EXISTS (
|
|
92
|
+
SELECT 1 FROM user_roles
|
|
93
|
+
WHERE user_id = auth.uid()
|
|
94
|
+
AND role = 'admin'
|
|
95
|
+
)
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
-- =============================================================================
|
|
99
|
+
-- VERIFICATION
|
|
100
|
+
-- =============================================================================
|
|
101
|
+
-- Test these policies with:
|
|
102
|
+
-- SET LOCAL ROLE authenticated;
|
|
103
|
+
-- SET LOCAL request.jwt.claims = '{"sub": "user-uuid-here"}';
|
|
104
|
+
-- SELECT * FROM :table_name; -- Should only return authorized rows
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
-- KISS single FOR ALL policy template (owner-only by column user_id)
|
|
2
|
-
ALTER TABLE :table ENABLE ROW LEVEL SECURITY;
|
|
3
|
-
|
|
4
|
-
DROP POLICY IF EXISTS ":table_kiss_all" ON :table;
|
|
5
|
-
CREATE POLICY ":table_kiss_all"
|
|
6
|
-
ON :table
|
|
7
|
-
FOR ALL
|
|
8
|
-
TO authenticated
|
|
9
|
-
USING (auth.uid() = user_id)
|
|
10
|
-
WITH CHECK (auth.uid() = user_id);
|
|
1
|
+
-- KISS single FOR ALL policy template (owner-only by column user_id)
|
|
2
|
+
ALTER TABLE :table ENABLE ROW LEVEL SECURITY;
|
|
3
|
+
|
|
4
|
+
DROP POLICY IF EXISTS ":table_kiss_all" ON :table;
|
|
5
|
+
CREATE POLICY ":table_kiss_all"
|
|
6
|
+
ON :table
|
|
7
|
+
FOR ALL
|
|
8
|
+
TO authenticated
|
|
9
|
+
USING (auth.uid() = user_id)
|
|
10
|
+
WITH CHECK (auth.uid() = user_id);
|