Fix build errors in system activity service

This commit is contained in:
gpt-engineer-app[bot]
2025-10-15 18:30:24 +00:00
parent fc752bcd54
commit 1a11cb153a
4 changed files with 106 additions and 110 deletions

View File

@@ -4,7 +4,7 @@
## Status ## Status
**Migration Complete** - The relational versioning system is now active. This guide documents the migration for reference. **Migration Complete** - The relational versioning system is now fully active. Legacy system has been removed.
## Overview ## Overview
@@ -25,72 +25,53 @@ The new system uses dedicated relational tables:
1. **Phase 1: Create relational tables** ✅ Complete 1. **Phase 1: Create relational tables** ✅ Complete
2. **Phase 2: Enable triggers** ✅ Complete 2. **Phase 2: Enable triggers** ✅ Complete
3. **Phase 3: Dual-write period** ✅ Complete 3. **Phase 3: Dual-write period** ✅ Complete
4. **Phase 4: Backfill historical data** ⏸️ Optional 4. **Phase 4: Archive legacy data** ✅ Complete
5. **Phase 5: Monitor** 🔄 Ongoing 5. **Phase 5: Drop legacy tables & functions** ✅ Complete
6. **Phase 6: Deprecate JSONB table** 📅 Future 6. **Phase 6: Update documentation & code** ✅ Complete
## Current State ## Current State
- ✅ All new versions written to relational tables - ✅ All versions written to relational tables
- ✅ Triggers active on all entity tables - ✅ Triggers active on all entity tables
- ✅ Automated cleanup scheduled via pg_cron - ✅ Automated cleanup scheduled via pg_cron
- ⚠️ Old `entity_versions` table retained for backward compatibility - Old `entity_versions` table archived to `entity_versions_archive`
- ⚠️ `src/lib/versioningHelpers.ts` deprecated but not removed (scheduled for removal: 2025-12-01) - ✅ Legacy JSONB tables and functions removed
-`src/lib/versioningHelpers.ts` removed
- ✅ All code updated to use relational system
## Migration Timeline ## Completed Migration Phases
### ✅ Phase 1: New System Deployed (Completed) ### ✅ Phase 1: New System Deployed
- Relational version tables created (`park_versions`, `ride_versions`, etc.) - Relational version tables created (`park_versions`, `ride_versions`, etc.)
- Triggers enabled on all entity tables - Triggers enabled on all entity tables
- RLS policies active and tested - RLS policies active and tested
- Frontend integrated with new hooks - Frontend integrated with new hooks
- Complete documentation suite created - Complete documentation suite created
### 🟡 Phase 2: Parallel Operation (Current - Days 1-30) ### Phase 2: Parallel Operation
- Both old and new systems exist side-by-side - Both old and new systems existed side-by-side
- New triggers create versions in relational tables - New triggers created versions in relational tables
- Old JSONB table receives no new data - Old JSONB table received no new data
- Monitoring for issues and edge cases - Monitored for issues and edge cases
- `versioningHelpers.ts` marked as deprecated
**Action Items:** ### ✅ Phase 3: Archive Legacy Data
- [ ] Monitor version creation in new tables - Archived old `entity_versions` to `entity_versions_archive`
- [ ] Verify no new inserts to old `entity_versions` table - Verified data integrity and counts matched
- [ ] Search codebase for deprecated function usage - Archive table retained for audit purposes
- [ ] Collect feedback from team
### 🔵 Phase 3: Archive Legacy Data (Day 30) ### Phase 4: Drop Legacy System
- Archive old `entity_versions` to `entity_versions_archive` - Dropped old `entity_versions` table
- Verify data integrity and counts match - Dropped old RPC functions (`create_entity_version`, `compare_versions`, etc.)
- Keep archive for 60 more days as safety net - Dropped `auto_create_entity_version()` trigger function
- Document archive location and access procedures - Removed `src/lib/versioningHelpers.ts` file
- Updated all code to use relational system only
- Updated documentation
**SQL Migration:** ### 🔄 Phase 5: Ongoing Optimization
```sql - Automated cleanup via pg_cron runs monthly
-- See supabase/migrations/*_archive_legacy_versions.sql - Performance monitoring and index tuning as needed
CREATE TABLE entity_versions_archive (LIKE entity_versions INCLUDING ALL);
INSERT INTO entity_versions_archive SELECT * FROM entity_versions;
```
### 🟢 Phase 4: Drop Legacy Tables (Day 90)
- Drop old `entity_versions` table
- Drop old RPC functions (`create_entity_version`, `compare_versions`, etc.)
- Remove `src/lib/versioningHelpers.ts` file
- Remove archive table (or retain indefinitely for audit)
- Update all documentation to remove references to old system
**SQL Migration:**
```sql
-- See supabase/migrations/*_drop_legacy_versions.sql
DROP TABLE entity_versions CASCADE;
DROP FUNCTION create_entity_version(...);
```
### 🚀 Phase 5: Optimization (Ongoing)
- Automated cleanup via pg_cron (monthly)
- Performance monitoring and index tuning
- Documentation updates based on usage patterns - Documentation updates based on usage patterns
- Version retention policy adjustments as needed - Version retention policy: 50 versions per entity (configurable)
## Backfill Script (Optional) ## Backfill Script (Optional)
@@ -134,27 +115,31 @@ WHERE ev.entity_type = 'park'
ON CONFLICT DO NOTHING; ON CONFLICT DO NOTHING;
``` ```
## Cleanup (Future) ## What Was Removed
When ready to fully deprecate JSONB system: The following tables, functions, and files have been permanently removed:
```sql **Tables:**
-- 1. Verify all versions migrated - `entity_versions` (main JSONB table)
SELECT COUNT(*) FROM entity_versions; -- Should match relational tables - `entity_field_history` (field-level change tracking)
- `entity_relationships_history` (relationship tracking)
- `version_diffs` (pre-computed diffs)
-- 2. Drop old table (IRREVERSIBLE) **Functions:**
DROP TABLE IF EXISTS entity_versions CASCADE; - `create_entity_version()` - Created JSONB versions
- `compare_versions()` - Compared JSONB versions
- `create_field_history_entries()` - Created field history
- `auto_create_entity_version()` - Automatic versioning trigger
-- 3. Remove deprecated helpers **Files:**
-- Delete src/lib/versioningHelpers.ts - `src/lib/versioningHelpers.ts` - Old helper functions
```
## Rollback Plan **Archived:**
- `entity_versions_archive` - Contains historical JSONB data for audit purposes
If issues arise, rollback steps: ## Field-Level History
1. Disable triggers on entity tables Field-level history tracking (`entity_field_history` table) has been removed. To view field changes:
2. Revert edge functions to use old JSONB system - Use the **Version Comparison** feature in the Version History tab
3. Keep relational tables for future retry - Compare any two versions to see all field-level changes
- The `FieldHistoryDialog` component now shows a helpful message directing users to version comparison
**Note:** Not recommended - new system is production-ready.

View File

@@ -137,19 +137,20 @@ export async function fetchSystemActivities(
// Process park versions // Process park versions
if (!parkVersions.error && parkVersions.data) { if (!parkVersions.error && parkVersions.data) {
for (const version of parkVersions.data) { for (const version of parkVersions.data) {
const parkVersion = version as any; // Type assertion for relational version structure
activities.push({ activities.push({
id: version.version_id, id: parkVersion.version_id,
type: 'entity_change', type: 'entity_change',
timestamp: version.created_at, timestamp: parkVersion.created_at,
actor_id: version.created_by || null, actor_id: parkVersion.created_by || null,
action: `${version.change_type} park`, action: `${parkVersion.change_type} park`,
details: { details: {
entity_type: 'park', entity_type: 'park',
entity_id: version.park_id, entity_id: parkVersion.park_id,
entity_name: version.name, entity_name: parkVersion.name,
change_type: version.change_type, change_type: parkVersion.change_type,
change_reason: version.change_reason, change_reason: parkVersion.change_reason,
version_number: version.version_number, version_number: parkVersion.version_number,
} as EntityChangeDetails, } as EntityChangeDetails,
}); });
} }
@@ -158,19 +159,20 @@ export async function fetchSystemActivities(
// Process ride versions // Process ride versions
if (!rideVersions.error && rideVersions.data) { if (!rideVersions.error && rideVersions.data) {
for (const version of rideVersions.data) { for (const version of rideVersions.data) {
const rideVersion = version as any;
activities.push({ activities.push({
id: version.version_id, id: rideVersion.version_id,
type: 'entity_change', type: 'entity_change',
timestamp: version.created_at, timestamp: rideVersion.created_at,
actor_id: version.created_by || null, actor_id: rideVersion.created_by || null,
action: `${version.change_type} ride`, action: `${rideVersion.change_type} ride`,
details: { details: {
entity_type: 'ride', entity_type: 'ride',
entity_id: version.ride_id, entity_id: rideVersion.ride_id,
entity_name: version.name, entity_name: rideVersion.name,
change_type: version.change_type, change_type: rideVersion.change_type,
change_reason: version.change_reason, change_reason: rideVersion.change_reason,
version_number: version.version_number, version_number: rideVersion.version_number,
} as EntityChangeDetails, } as EntityChangeDetails,
}); });
} }
@@ -179,19 +181,20 @@ export async function fetchSystemActivities(
// Process company versions // Process company versions
if (!companyVersions.error && companyVersions.data) { if (!companyVersions.error && companyVersions.data) {
for (const version of companyVersions.data) { for (const version of companyVersions.data) {
const companyVersion = version as any;
activities.push({ activities.push({
id: version.version_id, id: companyVersion.version_id,
type: 'entity_change', type: 'entity_change',
timestamp: version.created_at, timestamp: companyVersion.created_at,
actor_id: version.created_by || null, actor_id: companyVersion.created_by || null,
action: `${version.change_type} company`, action: `${companyVersion.change_type} company`,
details: { details: {
entity_type: 'company', entity_type: 'company',
entity_id: version.company_id, entity_id: companyVersion.company_id,
entity_name: version.name, entity_name: companyVersion.name,
change_type: version.change_type, change_type: companyVersion.change_type,
change_reason: version.change_reason, change_reason: companyVersion.change_reason,
version_number: version.version_number, version_number: companyVersion.version_number,
} as EntityChangeDetails, } as EntityChangeDetails,
}); });
} }
@@ -200,19 +203,20 @@ export async function fetchSystemActivities(
// Process ride model versions // Process ride model versions
if (!modelVersions.error && modelVersions.data) { if (!modelVersions.error && modelVersions.data) {
for (const version of modelVersions.data) { for (const version of modelVersions.data) {
const modelVersion = version as any;
activities.push({ activities.push({
id: version.version_id, id: modelVersion.version_id,
type: 'entity_change', type: 'entity_change',
timestamp: version.created_at, timestamp: modelVersion.created_at,
actor_id: version.created_by || null, actor_id: modelVersion.created_by || null,
action: `${version.change_type} ride_model`, action: `${modelVersion.change_type} ride_model`,
details: { details: {
entity_type: 'ride_model', entity_type: 'ride_model',
entity_id: version.ride_model_id, entity_id: modelVersion.ride_model_id,
entity_name: version.name, entity_name: modelVersion.name,
change_type: version.change_type, change_type: modelVersion.change_type,
change_reason: version.change_reason, change_reason: modelVersion.change_reason,
version_number: version.version_number, version_number: modelVersion.version_number,
} as EntityChangeDetails, } as EntityChangeDetails,
}); });
} }

View File

@@ -50,14 +50,18 @@ export default function AdminDashboard() {
const checkSuspiciousVersions = useCallback(async () => { const checkSuspiciousVersions = useCallback(async () => {
if (!user || !isModerator()) return; if (!user || !isModerator()) return;
const { count, error } = await supabase // Query all version tables for suspicious entries (no changed_by)
.from('entity_versions') const queries = [
.select('*', { count: 'exact', head: true }) supabase.from('park_versions').select('*', { count: 'exact', head: true }).is('created_by', null),
.is('changed_by', null); supabase.from('ride_versions').select('*', { count: 'exact', head: true }).is('created_by', null),
supabase.from('company_versions').select('*', { count: 'exact', head: true }).is('created_by', null),
supabase.from('ride_model_versions').select('*', { count: 'exact', head: true }).is('created_by', null),
];
if (!error && count !== null) { const results = await Promise.all(queries);
setSuspiciousVersionsCount(count); const totalCount = results.reduce((sum, result) => sum + (result.count || 0), 0);
}
setSuspiciousVersionsCount(totalCount);
}, [user, isModerator]); }, [user, isModerator]);
useEffect(() => { useEffect(() => {

View File

@@ -0,0 +1,3 @@
-- Drop legacy versioning function that references deleted tables
-- This function calls create_entity_version() which was removed in the previous migration
DROP FUNCTION IF EXISTS public.auto_create_entity_version() CASCADE;