aios-core 2.2.2 → 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.js +2 -1
- package/package.json +1 -3
- package/packages/installer/package.json +39 -39
- 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,140 +1,140 @@
|
|
|
1
|
-
-- Seed Data Template
|
|
2
|
-
-- Purpose: Idempotent seed data for development and testing
|
|
3
|
-
-- Created: :created_date
|
|
4
|
-
-- Author: :author
|
|
5
|
-
--
|
|
6
|
-
-- IMPORTANT: All seed operations should be idempotent (safe to run multiple times)
|
|
7
|
-
|
|
8
|
-
-- =============================================================================
|
|
9
|
-
-- SEED CONFIGURATION
|
|
10
|
-
-- =============================================================================
|
|
11
|
-
|
|
12
|
-
-- Disable triggers during seeding (optional, speeds up bulk insert)
|
|
13
|
-
-- SET session_replication_role = replica;
|
|
14
|
-
|
|
15
|
-
BEGIN;
|
|
16
|
-
|
|
17
|
-
-- =============================================================================
|
|
18
|
-
-- SEED: REFERENCE DATA (Lookup tables, static data)
|
|
19
|
-
-- =============================================================================
|
|
20
|
-
|
|
21
|
-
-- Example: Status types
|
|
22
|
-
INSERT INTO status_types (id, name, description, sort_order)
|
|
23
|
-
VALUES
|
|
24
|
-
('11111111-1111-1111-1111-111111111001', 'draft', 'Initial draft state', 1),
|
|
25
|
-
('11111111-1111-1111-1111-111111111002', 'pending', 'Awaiting action', 2),
|
|
26
|
-
('11111111-1111-1111-1111-111111111003', 'active', 'Currently active', 3),
|
|
27
|
-
('11111111-1111-1111-1111-111111111004', 'completed', 'Work completed', 4),
|
|
28
|
-
('11111111-1111-1111-1111-111111111005', 'archived', 'No longer active', 5)
|
|
29
|
-
ON CONFLICT (id) DO UPDATE SET
|
|
30
|
-
name = EXCLUDED.name,
|
|
31
|
-
description = EXCLUDED.description,
|
|
32
|
-
sort_order = EXCLUDED.sort_order;
|
|
33
|
-
|
|
34
|
-
-- Example: Categories
|
|
35
|
-
INSERT INTO categories (id, name, slug, parent_id)
|
|
36
|
-
VALUES
|
|
37
|
-
('22222222-2222-2222-2222-222222222001', 'General', 'general', NULL),
|
|
38
|
-
('22222222-2222-2222-2222-222222222002', 'Development', 'development', NULL),
|
|
39
|
-
('22222222-2222-2222-2222-222222222003', 'Frontend', 'frontend', '22222222-2222-2222-2222-222222222002'),
|
|
40
|
-
('22222222-2222-2222-2222-222222222004', 'Backend', 'backend', '22222222-2222-2222-2222-222222222002')
|
|
41
|
-
ON CONFLICT (id) DO UPDATE SET
|
|
42
|
-
name = EXCLUDED.name,
|
|
43
|
-
slug = EXCLUDED.slug,
|
|
44
|
-
parent_id = EXCLUDED.parent_id;
|
|
45
|
-
|
|
46
|
-
-- =============================================================================
|
|
47
|
-
-- SEED: ROLES AND PERMISSIONS
|
|
48
|
-
-- =============================================================================
|
|
49
|
-
|
|
50
|
-
INSERT INTO roles (id, name, description, permissions)
|
|
51
|
-
VALUES
|
|
52
|
-
('33333333-3333-3333-3333-333333333001', 'admin', 'Full system access', '["*"]'::JSONB),
|
|
53
|
-
('33333333-3333-3333-3333-333333333002', 'editor', 'Can edit content', '["read", "write", "update"]'::JSONB),
|
|
54
|
-
('33333333-3333-3333-3333-333333333003', 'viewer', 'Read-only access', '["read"]'::JSONB)
|
|
55
|
-
ON CONFLICT (id) DO UPDATE SET
|
|
56
|
-
description = EXCLUDED.description,
|
|
57
|
-
permissions = EXCLUDED.permissions;
|
|
58
|
-
|
|
59
|
-
-- =============================================================================
|
|
60
|
-
-- SEED: TEST USERS (Development only!)
|
|
61
|
-
-- =============================================================================
|
|
62
|
-
|
|
63
|
-
-- NOTE: Only run in development environment
|
|
64
|
-
-- These are fake users for testing - DO NOT use in production
|
|
65
|
-
|
|
66
|
-
-- Check environment before inserting test data
|
|
67
|
-
DO $$
|
|
68
|
-
BEGIN
|
|
69
|
-
-- Only seed test users if this appears to be a dev environment
|
|
70
|
-
IF current_database() LIKE '%dev%' OR current_database() LIKE '%test%' THEN
|
|
71
|
-
-- Test Admin User
|
|
72
|
-
INSERT INTO auth.users (
|
|
73
|
-
id,
|
|
74
|
-
email,
|
|
75
|
-
encrypted_password,
|
|
76
|
-
email_confirmed_at,
|
|
77
|
-
raw_user_meta_data
|
|
78
|
-
) VALUES (
|
|
79
|
-
'00000000-0000-0000-0000-000000000001',
|
|
80
|
-
'admin@test.local',
|
|
81
|
-
crypt('testpassword123', gen_salt('bf')),
|
|
82
|
-
NOW(),
|
|
83
|
-
'{"full_name": "Test Admin"}'::JSONB
|
|
84
|
-
) ON CONFLICT (id) DO NOTHING;
|
|
85
|
-
|
|
86
|
-
-- Test Regular User
|
|
87
|
-
INSERT INTO auth.users (
|
|
88
|
-
id,
|
|
89
|
-
email,
|
|
90
|
-
encrypted_password,
|
|
91
|
-
email_confirmed_at,
|
|
92
|
-
raw_user_meta_data
|
|
93
|
-
) VALUES (
|
|
94
|
-
'00000000-0000-0000-0000-000000000002',
|
|
95
|
-
'user@test.local',
|
|
96
|
-
crypt('testpassword123', gen_salt('bf')),
|
|
97
|
-
NOW(),
|
|
98
|
-
'{"full_name": "Test User"}'::JSONB
|
|
99
|
-
) ON CONFLICT (id) DO NOTHING;
|
|
100
|
-
|
|
101
|
-
RAISE NOTICE 'Test users seeded successfully';
|
|
102
|
-
ELSE
|
|
103
|
-
RAISE NOTICE 'Skipping test user seeding - not a dev/test environment';
|
|
104
|
-
END IF;
|
|
105
|
-
END $$;
|
|
106
|
-
|
|
107
|
-
-- =============================================================================
|
|
108
|
-
-- SEED: SAMPLE DATA (Development only!)
|
|
109
|
-
-- =============================================================================
|
|
110
|
-
|
|
111
|
-
-- Example: Sample projects for testing
|
|
112
|
-
INSERT INTO :table_name (id, name, description, user_id, status, created_at)
|
|
113
|
-
VALUES
|
|
114
|
-
('44444444-4444-4444-4444-444444444001', 'Sample Project 1', 'First sample project for testing', '00000000-0000-0000-0000-000000000001', 'active', NOW()),
|
|
115
|
-
('44444444-4444-4444-4444-444444444002', 'Sample Project 2', 'Second sample project for testing', '00000000-0000-0000-0000-000000000002', 'draft', NOW())
|
|
116
|
-
ON CONFLICT (id) DO UPDATE SET
|
|
117
|
-
name = EXCLUDED.name,
|
|
118
|
-
description = EXCLUDED.description,
|
|
119
|
-
updated_at = NOW();
|
|
120
|
-
|
|
121
|
-
COMMIT;
|
|
122
|
-
|
|
123
|
-
-- =============================================================================
|
|
124
|
-
-- RE-ENABLE TRIGGERS
|
|
125
|
-
-- =============================================================================
|
|
126
|
-
|
|
127
|
-
-- SET session_replication_role = DEFAULT;
|
|
128
|
-
|
|
129
|
-
-- =============================================================================
|
|
130
|
-
-- VERIFICATION
|
|
131
|
-
-- =============================================================================
|
|
132
|
-
|
|
133
|
-
SELECT
|
|
134
|
-
'status_types' as table_name,
|
|
135
|
-
COUNT(*) as row_count
|
|
136
|
-
FROM status_types
|
|
137
|
-
UNION ALL
|
|
138
|
-
SELECT 'categories', COUNT(*) FROM categories
|
|
139
|
-
UNION ALL
|
|
140
|
-
SELECT 'roles', COUNT(*) FROM roles;
|
|
1
|
+
-- Seed Data Template
|
|
2
|
+
-- Purpose: Idempotent seed data for development and testing
|
|
3
|
+
-- Created: :created_date
|
|
4
|
+
-- Author: :author
|
|
5
|
+
--
|
|
6
|
+
-- IMPORTANT: All seed operations should be idempotent (safe to run multiple times)
|
|
7
|
+
|
|
8
|
+
-- =============================================================================
|
|
9
|
+
-- SEED CONFIGURATION
|
|
10
|
+
-- =============================================================================
|
|
11
|
+
|
|
12
|
+
-- Disable triggers during seeding (optional, speeds up bulk insert)
|
|
13
|
+
-- SET session_replication_role = replica;
|
|
14
|
+
|
|
15
|
+
BEGIN;
|
|
16
|
+
|
|
17
|
+
-- =============================================================================
|
|
18
|
+
-- SEED: REFERENCE DATA (Lookup tables, static data)
|
|
19
|
+
-- =============================================================================
|
|
20
|
+
|
|
21
|
+
-- Example: Status types
|
|
22
|
+
INSERT INTO status_types (id, name, description, sort_order)
|
|
23
|
+
VALUES
|
|
24
|
+
('11111111-1111-1111-1111-111111111001', 'draft', 'Initial draft state', 1),
|
|
25
|
+
('11111111-1111-1111-1111-111111111002', 'pending', 'Awaiting action', 2),
|
|
26
|
+
('11111111-1111-1111-1111-111111111003', 'active', 'Currently active', 3),
|
|
27
|
+
('11111111-1111-1111-1111-111111111004', 'completed', 'Work completed', 4),
|
|
28
|
+
('11111111-1111-1111-1111-111111111005', 'archived', 'No longer active', 5)
|
|
29
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
30
|
+
name = EXCLUDED.name,
|
|
31
|
+
description = EXCLUDED.description,
|
|
32
|
+
sort_order = EXCLUDED.sort_order;
|
|
33
|
+
|
|
34
|
+
-- Example: Categories
|
|
35
|
+
INSERT INTO categories (id, name, slug, parent_id)
|
|
36
|
+
VALUES
|
|
37
|
+
('22222222-2222-2222-2222-222222222001', 'General', 'general', NULL),
|
|
38
|
+
('22222222-2222-2222-2222-222222222002', 'Development', 'development', NULL),
|
|
39
|
+
('22222222-2222-2222-2222-222222222003', 'Frontend', 'frontend', '22222222-2222-2222-2222-222222222002'),
|
|
40
|
+
('22222222-2222-2222-2222-222222222004', 'Backend', 'backend', '22222222-2222-2222-2222-222222222002')
|
|
41
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
42
|
+
name = EXCLUDED.name,
|
|
43
|
+
slug = EXCLUDED.slug,
|
|
44
|
+
parent_id = EXCLUDED.parent_id;
|
|
45
|
+
|
|
46
|
+
-- =============================================================================
|
|
47
|
+
-- SEED: ROLES AND PERMISSIONS
|
|
48
|
+
-- =============================================================================
|
|
49
|
+
|
|
50
|
+
INSERT INTO roles (id, name, description, permissions)
|
|
51
|
+
VALUES
|
|
52
|
+
('33333333-3333-3333-3333-333333333001', 'admin', 'Full system access', '["*"]'::JSONB),
|
|
53
|
+
('33333333-3333-3333-3333-333333333002', 'editor', 'Can edit content', '["read", "write", "update"]'::JSONB),
|
|
54
|
+
('33333333-3333-3333-3333-333333333003', 'viewer', 'Read-only access', '["read"]'::JSONB)
|
|
55
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
56
|
+
description = EXCLUDED.description,
|
|
57
|
+
permissions = EXCLUDED.permissions;
|
|
58
|
+
|
|
59
|
+
-- =============================================================================
|
|
60
|
+
-- SEED: TEST USERS (Development only!)
|
|
61
|
+
-- =============================================================================
|
|
62
|
+
|
|
63
|
+
-- NOTE: Only run in development environment
|
|
64
|
+
-- These are fake users for testing - DO NOT use in production
|
|
65
|
+
|
|
66
|
+
-- Check environment before inserting test data
|
|
67
|
+
DO $$
|
|
68
|
+
BEGIN
|
|
69
|
+
-- Only seed test users if this appears to be a dev environment
|
|
70
|
+
IF current_database() LIKE '%dev%' OR current_database() LIKE '%test%' THEN
|
|
71
|
+
-- Test Admin User
|
|
72
|
+
INSERT INTO auth.users (
|
|
73
|
+
id,
|
|
74
|
+
email,
|
|
75
|
+
encrypted_password,
|
|
76
|
+
email_confirmed_at,
|
|
77
|
+
raw_user_meta_data
|
|
78
|
+
) VALUES (
|
|
79
|
+
'00000000-0000-0000-0000-000000000001',
|
|
80
|
+
'admin@test.local',
|
|
81
|
+
crypt('testpassword123', gen_salt('bf')),
|
|
82
|
+
NOW(),
|
|
83
|
+
'{"full_name": "Test Admin"}'::JSONB
|
|
84
|
+
) ON CONFLICT (id) DO NOTHING;
|
|
85
|
+
|
|
86
|
+
-- Test Regular User
|
|
87
|
+
INSERT INTO auth.users (
|
|
88
|
+
id,
|
|
89
|
+
email,
|
|
90
|
+
encrypted_password,
|
|
91
|
+
email_confirmed_at,
|
|
92
|
+
raw_user_meta_data
|
|
93
|
+
) VALUES (
|
|
94
|
+
'00000000-0000-0000-0000-000000000002',
|
|
95
|
+
'user@test.local',
|
|
96
|
+
crypt('testpassword123', gen_salt('bf')),
|
|
97
|
+
NOW(),
|
|
98
|
+
'{"full_name": "Test User"}'::JSONB
|
|
99
|
+
) ON CONFLICT (id) DO NOTHING;
|
|
100
|
+
|
|
101
|
+
RAISE NOTICE 'Test users seeded successfully';
|
|
102
|
+
ELSE
|
|
103
|
+
RAISE NOTICE 'Skipping test user seeding - not a dev/test environment';
|
|
104
|
+
END IF;
|
|
105
|
+
END $$;
|
|
106
|
+
|
|
107
|
+
-- =============================================================================
|
|
108
|
+
-- SEED: SAMPLE DATA (Development only!)
|
|
109
|
+
-- =============================================================================
|
|
110
|
+
|
|
111
|
+
-- Example: Sample projects for testing
|
|
112
|
+
INSERT INTO :table_name (id, name, description, user_id, status, created_at)
|
|
113
|
+
VALUES
|
|
114
|
+
('44444444-4444-4444-4444-444444444001', 'Sample Project 1', 'First sample project for testing', '00000000-0000-0000-0000-000000000001', 'active', NOW()),
|
|
115
|
+
('44444444-4444-4444-4444-444444444002', 'Sample Project 2', 'Second sample project for testing', '00000000-0000-0000-0000-000000000002', 'draft', NOW())
|
|
116
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
117
|
+
name = EXCLUDED.name,
|
|
118
|
+
description = EXCLUDED.description,
|
|
119
|
+
updated_at = NOW();
|
|
120
|
+
|
|
121
|
+
COMMIT;
|
|
122
|
+
|
|
123
|
+
-- =============================================================================
|
|
124
|
+
-- RE-ENABLE TRIGGERS
|
|
125
|
+
-- =============================================================================
|
|
126
|
+
|
|
127
|
+
-- SET session_replication_role = DEFAULT;
|
|
128
|
+
|
|
129
|
+
-- =============================================================================
|
|
130
|
+
-- VERIFICATION
|
|
131
|
+
-- =============================================================================
|
|
132
|
+
|
|
133
|
+
SELECT
|
|
134
|
+
'status_types' as table_name,
|
|
135
|
+
COUNT(*) as row_count
|
|
136
|
+
FROM status_types
|
|
137
|
+
UNION ALL
|
|
138
|
+
SELECT 'categories', COUNT(*) FROM categories
|
|
139
|
+
UNION ALL
|
|
140
|
+
SELECT 'roles', COUNT(*) FROM roles;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
-- Basic post-migration checks (fill placeholders)
|
|
2
|
-
SET client_min_messages = warning;
|
|
3
|
-
|
|
4
|
-
-- Count tables/policies/functions expected
|
|
5
|
-
SELECT COUNT(*) AS tables FROM information_schema.tables WHERE table_schema='public';
|
|
6
|
-
SELECT COUNT(*) AS policies FROM pg_policies WHERE schemaname='public';
|
|
7
|
-
SELECT proname FROM pg_proc WHERE pronamespace = 'public'::regnamespace
|
|
8
|
-
AND proname IN ('current_mind_id','provision_user_profile','set_fragment_mind_id');
|
|
9
|
-
|
|
10
|
-
-- Sanity queries (examples)
|
|
11
|
-
-- SELECT * FROM categories LIMIT 5;
|
|
12
|
-
-- SELECT * FROM minds LIMIT 5;
|
|
13
|
-
|
|
14
|
-
-- RLS sanity (should not error even if it returns 0)
|
|
15
|
-
-- SET LOCAL request.jwt.claims = '{"sub":"<user-uuid>","role":"authenticated"}';
|
|
16
|
-
-- SELECT 1 FROM fragments WHERE false;
|
|
1
|
+
-- Basic post-migration checks (fill placeholders)
|
|
2
|
+
SET client_min_messages = warning;
|
|
3
|
+
|
|
4
|
+
-- Count tables/policies/functions expected
|
|
5
|
+
SELECT COUNT(*) AS tables FROM information_schema.tables WHERE table_schema='public';
|
|
6
|
+
SELECT COUNT(*) AS policies FROM pg_policies WHERE schemaname='public';
|
|
7
|
+
SELECT proname FROM pg_proc WHERE pronamespace = 'public'::regnamespace
|
|
8
|
+
AND proname IN ('current_mind_id','provision_user_profile','set_fragment_mind_id');
|
|
9
|
+
|
|
10
|
+
-- Sanity queries (examples)
|
|
11
|
+
-- SELECT * FROM categories LIMIT 5;
|
|
12
|
+
-- SELECT * FROM minds LIMIT 5;
|
|
13
|
+
|
|
14
|
+
-- RLS sanity (should not error even if it returns 0)
|
|
15
|
+
-- SET LOCAL request.jwt.claims = '{"sub":"<user-uuid>","role":"authenticated"}';
|
|
16
|
+
-- SELECT 1 FROM fragments WHERE false;
|
|
@@ -1,139 +1,139 @@
|
|
|
1
|
-
-- Staging Copy Merge Template
|
|
2
|
-
-- Purpose: Safely load external data through staging table and merge to target
|
|
3
|
-
-- Created: :created_date
|
|
4
|
-
-- Author: :author
|
|
5
|
-
--
|
|
6
|
-
-- This pattern prevents data corruption by validating in staging before merge
|
|
7
|
-
|
|
8
|
-
-- =============================================================================
|
|
9
|
-
-- STEP 1: CREATE STAGING TABLE (temporary)
|
|
10
|
-
-- =============================================================================
|
|
11
|
-
|
|
12
|
-
-- Create staging table mirroring target structure
|
|
13
|
-
CREATE TEMP TABLE IF NOT EXISTS :staging_table (
|
|
14
|
-
-- Match target table columns
|
|
15
|
-
id UUID,
|
|
16
|
-
:column1 :type1,
|
|
17
|
-
:column2 :type2,
|
|
18
|
-
-- Metadata for import tracking
|
|
19
|
-
_row_number INTEGER,
|
|
20
|
-
_import_status TEXT DEFAULT 'pending',
|
|
21
|
-
_import_error TEXT
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
-- =============================================================================
|
|
25
|
-
-- STEP 2: COPY DATA TO STAGING
|
|
26
|
-
-- =============================================================================
|
|
27
|
-
|
|
28
|
-
-- Option A: From CSV file
|
|
29
|
-
-- COPY :staging_table (id, :column1, :column2)
|
|
30
|
-
-- FROM '/path/to/file.csv'
|
|
31
|
-
-- WITH (FORMAT csv, HEADER true);
|
|
32
|
-
|
|
33
|
-
-- Option B: From STDIN (programmatic)
|
|
34
|
-
-- COPY :staging_table (id, :column1, :column2) FROM STDIN;
|
|
35
|
-
|
|
36
|
-
-- Option C: Insert from another query
|
|
37
|
-
-- INSERT INTO :staging_table (id, :column1, :column2)
|
|
38
|
-
-- SELECT id, col1, col2 FROM external_source;
|
|
39
|
-
|
|
40
|
-
-- =============================================================================
|
|
41
|
-
-- STEP 3: VALIDATE STAGING DATA
|
|
42
|
-
-- =============================================================================
|
|
43
|
-
|
|
44
|
-
-- Mark rows with validation errors
|
|
45
|
-
UPDATE :staging_table
|
|
46
|
-
SET
|
|
47
|
-
_import_status = 'error',
|
|
48
|
-
_import_error = 'Missing required field'
|
|
49
|
-
WHERE :column1 IS NULL;
|
|
50
|
-
|
|
51
|
-
-- Check for duplicates
|
|
52
|
-
UPDATE :staging_table s
|
|
53
|
-
SET
|
|
54
|
-
_import_status = 'duplicate',
|
|
55
|
-
_import_error = 'Duplicate ID found'
|
|
56
|
-
WHERE EXISTS (
|
|
57
|
-
SELECT 1 FROM :staging_table s2
|
|
58
|
-
WHERE s2.id = s.id
|
|
59
|
-
AND s2._row_number < s._row_number
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
-- Check for existing records (will update instead of insert)
|
|
63
|
-
UPDATE :staging_table s
|
|
64
|
-
SET _import_status = 'update'
|
|
65
|
-
WHERE EXISTS (
|
|
66
|
-
SELECT 1 FROM :target_table t
|
|
67
|
-
WHERE t.id = s.id
|
|
68
|
-
)
|
|
69
|
-
AND s._import_status = 'pending';
|
|
70
|
-
|
|
71
|
-
-- Mark remaining as new inserts
|
|
72
|
-
UPDATE :staging_table
|
|
73
|
-
SET _import_status = 'insert'
|
|
74
|
-
WHERE _import_status = 'pending';
|
|
75
|
-
|
|
76
|
-
-- =============================================================================
|
|
77
|
-
-- STEP 4: REPORT VALIDATION RESULTS
|
|
78
|
-
-- =============================================================================
|
|
79
|
-
|
|
80
|
-
-- Get summary of staging data
|
|
81
|
-
SELECT
|
|
82
|
-
_import_status,
|
|
83
|
-
COUNT(*) as count,
|
|
84
|
-
STRING_AGG(DISTINCT _import_error, ', ') as errors
|
|
85
|
-
FROM :staging_table
|
|
86
|
-
GROUP BY _import_status
|
|
87
|
-
ORDER BY _import_status;
|
|
88
|
-
|
|
89
|
-
-- =============================================================================
|
|
90
|
-
-- STEP 5: MERGE TO TARGET (UPSERT)
|
|
91
|
-
-- =============================================================================
|
|
92
|
-
|
|
93
|
-
BEGIN;
|
|
94
|
-
|
|
95
|
-
-- Insert new records
|
|
96
|
-
INSERT INTO :target_table (id, :column1, :column2, created_at)
|
|
97
|
-
SELECT id, :column1, :column2, NOW()
|
|
98
|
-
FROM :staging_table
|
|
99
|
-
WHERE _import_status = 'insert';
|
|
100
|
-
|
|
101
|
-
-- Update existing records
|
|
102
|
-
UPDATE :target_table t
|
|
103
|
-
SET
|
|
104
|
-
:column1 = s.:column1,
|
|
105
|
-
:column2 = s.:column2,
|
|
106
|
-
updated_at = NOW()
|
|
107
|
-
FROM :staging_table s
|
|
108
|
-
WHERE t.id = s.id
|
|
109
|
-
AND s._import_status = 'update';
|
|
110
|
-
|
|
111
|
-
COMMIT;
|
|
112
|
-
|
|
113
|
-
-- =============================================================================
|
|
114
|
-
-- STEP 6: VERIFY AND CLEANUP
|
|
115
|
-
-- =============================================================================
|
|
116
|
-
|
|
117
|
-
-- Verify merge results
|
|
118
|
-
SELECT
|
|
119
|
-
'inserted' as operation,
|
|
120
|
-
COUNT(*) as count
|
|
121
|
-
FROM :staging_table WHERE _import_status = 'insert'
|
|
122
|
-
UNION ALL
|
|
123
|
-
SELECT
|
|
124
|
-
'updated' as operation,
|
|
125
|
-
COUNT(*) as count
|
|
126
|
-
FROM :staging_table WHERE _import_status = 'update'
|
|
127
|
-
UNION ALL
|
|
128
|
-
SELECT
|
|
129
|
-
'errors' as operation,
|
|
130
|
-
COUNT(*) as count
|
|
131
|
-
FROM :staging_table WHERE _import_status = 'error';
|
|
132
|
-
|
|
133
|
-
-- Get error details for review
|
|
134
|
-
SELECT id, :column1, _import_error
|
|
135
|
-
FROM :staging_table
|
|
136
|
-
WHERE _import_status = 'error';
|
|
137
|
-
|
|
138
|
-
-- Drop staging table (automatic for TEMP, but explicit is clearer)
|
|
139
|
-
DROP TABLE IF EXISTS :staging_table;
|
|
1
|
+
-- Staging Copy Merge Template
|
|
2
|
+
-- Purpose: Safely load external data through staging table and merge to target
|
|
3
|
+
-- Created: :created_date
|
|
4
|
+
-- Author: :author
|
|
5
|
+
--
|
|
6
|
+
-- This pattern prevents data corruption by validating in staging before merge
|
|
7
|
+
|
|
8
|
+
-- =============================================================================
|
|
9
|
+
-- STEP 1: CREATE STAGING TABLE (temporary)
|
|
10
|
+
-- =============================================================================
|
|
11
|
+
|
|
12
|
+
-- Create staging table mirroring target structure
|
|
13
|
+
CREATE TEMP TABLE IF NOT EXISTS :staging_table (
|
|
14
|
+
-- Match target table columns
|
|
15
|
+
id UUID,
|
|
16
|
+
:column1 :type1,
|
|
17
|
+
:column2 :type2,
|
|
18
|
+
-- Metadata for import tracking
|
|
19
|
+
_row_number INTEGER,
|
|
20
|
+
_import_status TEXT DEFAULT 'pending',
|
|
21
|
+
_import_error TEXT
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
-- =============================================================================
|
|
25
|
+
-- STEP 2: COPY DATA TO STAGING
|
|
26
|
+
-- =============================================================================
|
|
27
|
+
|
|
28
|
+
-- Option A: From CSV file
|
|
29
|
+
-- COPY :staging_table (id, :column1, :column2)
|
|
30
|
+
-- FROM '/path/to/file.csv'
|
|
31
|
+
-- WITH (FORMAT csv, HEADER true);
|
|
32
|
+
|
|
33
|
+
-- Option B: From STDIN (programmatic)
|
|
34
|
+
-- COPY :staging_table (id, :column1, :column2) FROM STDIN;
|
|
35
|
+
|
|
36
|
+
-- Option C: Insert from another query
|
|
37
|
+
-- INSERT INTO :staging_table (id, :column1, :column2)
|
|
38
|
+
-- SELECT id, col1, col2 FROM external_source;
|
|
39
|
+
|
|
40
|
+
-- =============================================================================
|
|
41
|
+
-- STEP 3: VALIDATE STAGING DATA
|
|
42
|
+
-- =============================================================================
|
|
43
|
+
|
|
44
|
+
-- Mark rows with validation errors
|
|
45
|
+
UPDATE :staging_table
|
|
46
|
+
SET
|
|
47
|
+
_import_status = 'error',
|
|
48
|
+
_import_error = 'Missing required field'
|
|
49
|
+
WHERE :column1 IS NULL;
|
|
50
|
+
|
|
51
|
+
-- Check for duplicates
|
|
52
|
+
UPDATE :staging_table s
|
|
53
|
+
SET
|
|
54
|
+
_import_status = 'duplicate',
|
|
55
|
+
_import_error = 'Duplicate ID found'
|
|
56
|
+
WHERE EXISTS (
|
|
57
|
+
SELECT 1 FROM :staging_table s2
|
|
58
|
+
WHERE s2.id = s.id
|
|
59
|
+
AND s2._row_number < s._row_number
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
-- Check for existing records (will update instead of insert)
|
|
63
|
+
UPDATE :staging_table s
|
|
64
|
+
SET _import_status = 'update'
|
|
65
|
+
WHERE EXISTS (
|
|
66
|
+
SELECT 1 FROM :target_table t
|
|
67
|
+
WHERE t.id = s.id
|
|
68
|
+
)
|
|
69
|
+
AND s._import_status = 'pending';
|
|
70
|
+
|
|
71
|
+
-- Mark remaining as new inserts
|
|
72
|
+
UPDATE :staging_table
|
|
73
|
+
SET _import_status = 'insert'
|
|
74
|
+
WHERE _import_status = 'pending';
|
|
75
|
+
|
|
76
|
+
-- =============================================================================
|
|
77
|
+
-- STEP 4: REPORT VALIDATION RESULTS
|
|
78
|
+
-- =============================================================================
|
|
79
|
+
|
|
80
|
+
-- Get summary of staging data
|
|
81
|
+
SELECT
|
|
82
|
+
_import_status,
|
|
83
|
+
COUNT(*) as count,
|
|
84
|
+
STRING_AGG(DISTINCT _import_error, ', ') as errors
|
|
85
|
+
FROM :staging_table
|
|
86
|
+
GROUP BY _import_status
|
|
87
|
+
ORDER BY _import_status;
|
|
88
|
+
|
|
89
|
+
-- =============================================================================
|
|
90
|
+
-- STEP 5: MERGE TO TARGET (UPSERT)
|
|
91
|
+
-- =============================================================================
|
|
92
|
+
|
|
93
|
+
BEGIN;
|
|
94
|
+
|
|
95
|
+
-- Insert new records
|
|
96
|
+
INSERT INTO :target_table (id, :column1, :column2, created_at)
|
|
97
|
+
SELECT id, :column1, :column2, NOW()
|
|
98
|
+
FROM :staging_table
|
|
99
|
+
WHERE _import_status = 'insert';
|
|
100
|
+
|
|
101
|
+
-- Update existing records
|
|
102
|
+
UPDATE :target_table t
|
|
103
|
+
SET
|
|
104
|
+
:column1 = s.:column1,
|
|
105
|
+
:column2 = s.:column2,
|
|
106
|
+
updated_at = NOW()
|
|
107
|
+
FROM :staging_table s
|
|
108
|
+
WHERE t.id = s.id
|
|
109
|
+
AND s._import_status = 'update';
|
|
110
|
+
|
|
111
|
+
COMMIT;
|
|
112
|
+
|
|
113
|
+
-- =============================================================================
|
|
114
|
+
-- STEP 6: VERIFY AND CLEANUP
|
|
115
|
+
-- =============================================================================
|
|
116
|
+
|
|
117
|
+
-- Verify merge results
|
|
118
|
+
SELECT
|
|
119
|
+
'inserted' as operation,
|
|
120
|
+
COUNT(*) as count
|
|
121
|
+
FROM :staging_table WHERE _import_status = 'insert'
|
|
122
|
+
UNION ALL
|
|
123
|
+
SELECT
|
|
124
|
+
'updated' as operation,
|
|
125
|
+
COUNT(*) as count
|
|
126
|
+
FROM :staging_table WHERE _import_status = 'update'
|
|
127
|
+
UNION ALL
|
|
128
|
+
SELECT
|
|
129
|
+
'errors' as operation,
|
|
130
|
+
COUNT(*) as count
|
|
131
|
+
FROM :staging_table WHERE _import_status = 'error';
|
|
132
|
+
|
|
133
|
+
-- Get error details for review
|
|
134
|
+
SELECT id, :column1, _import_error
|
|
135
|
+
FROM :staging_table
|
|
136
|
+
WHERE _import_status = 'error';
|
|
137
|
+
|
|
138
|
+
-- Drop staging table (automatic for TEMP, but explicit is clearer)
|
|
139
|
+
DROP TABLE IF EXISTS :staging_table;
|