diff --git a/complete_schema.sql b/complete_schema.sql index 2b343a9..0827fba 100644 --- a/complete_schema.sql +++ b/complete_schema.sql @@ -605,4 +605,105 @@ UPDATE directus_collections SET display_template = '{{site_name}}' WHERE - collection = 'globals'; \ No newline at end of file + collection = 'globals'; + +-- =================================================================================== +-- 🔐 PERMISSIONS GRANT PROTOCOL v1.0 +-- Purpose: Grant full CRUDS access to Admin Policy for all 13 new tables +-- Author: Spark Overlord +-- Note: This runs automatically during fresh install to unlock new collections +-- =================================================================================== + +DO $$ +DECLARE + admin_policy_id UUID := ( + SELECT id FROM directus_policies + WHERE name = 'Administrator' + LIMIT 1 + ); +BEGIN + -- Skip if no Administrator policy found (will be created by Directus on first boot) + IF admin_policy_id IS NULL THEN + RAISE NOTICE '⚠️ Administrator policy not found. Permissions will need to be set manually in Directus.'; + RETURN; + END IF; + + -- ANALYTICS ENGINE (4 tables) + INSERT INTO directus_permissions (policy, collection, action, permissions, validation, fields) VALUES + (admin_policy_id, 'site_analytics', 'create', '{}', '{}', '*'), + (admin_policy_id, 'site_analytics', 'read', '{}', '{}', '*'), + (admin_policy_id, 'site_analytics', 'update', '{}', '{}', '*'), + (admin_policy_id, 'site_analytics', 'delete', '{}', '{}', '*'), + + (admin_policy_id, 'events', 'create', '{}', '{}', '*'), + (admin_policy_id, 'events', 'read', '{}', '{}', '*'), + (admin_policy_id, 'events', 'update', '{}', '{}', '*'), + (admin_policy_id, 'events', 'delete', '{}', '{}', '*'), + + (admin_policy_id, 'pageviews', 'create', '{}', '{}', '*'), + (admin_policy_id, 'pageviews', 'read', '{}', '{}', '*'), + (admin_policy_id, 'pageviews', 'update', '{}', '{}', '*'), + (admin_policy_id, 'pageviews', 'delete', '{}', '{}', '*'), + + (admin_policy_id, 'conversions', 'create', '{}', '{}', '*'), + (admin_policy_id, 'conversions', 'read', '{}', '{}', '*'), + (admin_policy_id, 'conversions', 'update', '{}', '{}', '*'), + (admin_policy_id, 'conversions', 'delete', '{}', '{}', '*') + ON CONFLICT DO NOTHING; + + -- GEO-INTELLIGENCE (3 tables) + INSERT INTO directus_permissions (policy, collection, action, permissions, validation, fields) VALUES + (admin_policy_id, 'locations_states', 'create', '{}', '{}', '*'), + (admin_policy_id, 'locations_states', 'read', '{}', '{}', '*'), + (admin_policy_id, 'locations_states', 'update', '{}', '{}', '*'), + (admin_policy_id, 'locations_states', 'delete', '{}', '{}', '*'), + + (admin_policy_id, 'locations_counties', 'create', '{}', '{}', '*'), + (admin_policy_id, 'locations_counties', 'read', '{}', '{}', '*'), + (admin_policy_id, 'locations_counties', 'update', '{}', '{}', '*'), + (admin_policy_id, 'locations_counties', 'delete', '{}', '{}', '*'), + + (admin_policy_id, 'locations_cities', 'create', '{}', '{}', '*'), + (admin_policy_id, 'locations_cities', 'read', '{}', '{}', '*'), + (admin_policy_id, 'locations_cities', 'update', '{}', '{}', '*'), + (admin_policy_id, 'locations_cities', 'delete', '{}', '{}', '*') + ON CONFLICT DO NOTHING; + + -- LEAD CAPTURE (2 tables) + INSERT INTO directus_permissions (policy, collection, action, permissions, validation, fields) VALUES + (admin_policy_id, 'forms', 'create', '{}', '{}', '*'), + (admin_policy_id, 'forms', 'read', '{}', '{}', '*'), + (admin_policy_id, 'forms', 'update', '{}', '{}', '*'), + (admin_policy_id, 'forms', 'delete', '{}', '{}', '*'), + + (admin_policy_id, 'form_submissions', 'create', '{}', '{}', '*'), + (admin_policy_id, 'form_submissions', 'read', '{}', '{}', '*'), + (admin_policy_id, 'form_submissions', 'update', '{}', '{}', '*'), + (admin_policy_id, 'form_submissions', 'delete', '{}', '{}', '*') + ON CONFLICT DO NOTHING; + + -- SITE BUILDER & SYSTEM (4 tables) + INSERT INTO directus_permissions (policy, collection, action, permissions, validation, fields) VALUES + (admin_policy_id, 'navigation', 'create', '{}', '{}', '*'), + (admin_policy_id, 'navigation', 'read', '{}', '{}', '*'), + (admin_policy_id, 'navigation', 'update', '{}', '{}', '*'), + (admin_policy_id, 'navigation', 'delete', '{}', '{}', '*'), + + (admin_policy_id, 'globals', 'create', '{}', '{}', '*'), + (admin_policy_id, 'globals', 'read', '{}', '{}', '*'), + (admin_policy_id, 'globals', 'update', '{}', '{}', '*'), + (admin_policy_id, 'globals', 'delete', '{}', '{}', '*'), + + (admin_policy_id, 'hub_pages', 'create', '{}', '{}', '*'), + (admin_policy_id, 'hub_pages', 'read', '{}', '{}', '*'), + (admin_policy_id, 'hub_pages', 'update', '{}', '{}', '*'), + (admin_policy_id, 'hub_pages', 'delete', '{}', '{}', '*'), + + (admin_policy_id, 'work_log', 'create', '{}', '{}', '*'), + (admin_policy_id, 'work_log', 'read', '{}', '{}', '*'), + (admin_policy_id, 'work_log', 'update', '{}', '{}', '*'), + (admin_policy_id, 'work_log', 'delete', '{}', '{}', '*') + ON CONFLICT DO NOTHING; + + RAISE NOTICE '✅ Permissions granted for all 13 new collections.'; +END $$; \ No newline at end of file diff --git a/docs/CTO_ONBOARDING.md b/docs/CTO_ONBOARDING.md index 94a4c7a..46e8c9c 100644 --- a/docs/CTO_ONBOARDING.md +++ b/docs/CTO_ONBOARDING.md @@ -265,6 +265,75 @@ Deploys, wipes DB, runs schema. **Data loss warning**. --- +## 9A. Stability Patch & Permissions Protocol + +### 9A.1 The Foundation Gap (RESOLVED) + +**Issue**: TypeScript referenced 28 collections but SQL schema only had 15 tables. + +**Solution**: Stability Patch v1.0 added 13 missing tables to `complete_schema.sql`: + +| Category | Tables Added | +|----------|-------------| +| Analytics | site_analytics, events, pageviews, conversions | +| Geo-Intelligence | locations_states, locations_counties, locations_cities | +| Lead Capture | forms, form_submissions | +| Site Builder | navigation, globals, hub_pages | +| System | work_log | + +### 9A.2 Permissions Grant Protocol + +**Issue**: Creating tables in PostgreSQL does NOT grant Directus permissions. Admin sees empty sidebar. + +**Solution**: `complete_schema.sql` now includes automatic permission grants. + +**What it does**: +```sql +DO $$ +DECLARE + admin_policy_id UUID := ( + SELECT id FROM directus_policies + WHERE name = 'Administrator' + LIMIT 1 + ); +BEGIN + -- Grants CRUD to all 13 new collections + INSERT INTO directus_permissions (policy, collection, action, ...) VALUES + (admin_policy_id, 'forms', 'create', ...), + (admin_policy_id, 'forms', 'read', ...), + ... +END $$; +``` + +### 9A.3 Fresh Install Includes Everything + +When deploying with `FORCE_FRESH_INSTALL=true`: + +1. ✅ 28 tables created (Foundation → Walls → Roof + Stability Patch) +2. ✅ Directus UI configured (dropdowns, display templates) +3. ✅ Admin permissions auto-granted for all collections + +### 9A.4 Manual Patch (For Existing Databases) + +If you need to add the new tables to an existing database WITHOUT wiping: + +```bash +# Connect to PostgreSQL +docker exec -it [postgres-container] psql -U postgres -d directus + +# Run just the Stability Patch section (lines 170-335 of complete_schema.sql) +# Then run the Permissions Protocol section (lines 610-709) +``` + +### 9A.5 Verification + +After patching, verify in Directus Admin: + +1. **Settings → Data Model** should show all 28 collections +2. **Content → Forms** should be accessible +3. **Content → Analytics → Events** should be accessible +4. **Content → Locations → States** should be accessible + ## 10. Critical Files | File | Purpose | Change Impact |