5.5 KiB
5.5 KiB
Unique ID Prefixes & Entity Renaming - Implementation Status
Phase 1: ID Generation Infrastructure ✅ COMPLETE
Completed Files
- ✅
/migrations/0009_id_sequences/up.sql- Creates id_sequences table - ✅
/migrations/0009_id_sequences/down.sql- Rollback script - ✅
/internal/idgen/generator.go- ID generation service - ✅
/internal/idgen/generator_test.go- Comprehensive tests
Verification
- ✅ Migration applied successfully
- ✅ All tests passing (including concurrency tests)
- ✅ Manual verification complete - IDs generating correctly:
- Customer: CR-0000003
- Project: PJ-0000003
- Asset: ME-0000004
- Component: PT-0000047
- Ticket: TT-0000002
- Failure Event: FE-0000001
Phase 2: Dual-Write Period ✅ COMPLETE
Completed Files
- ✅
/migrations/0010_add_string_ids/up.sql- Adds sid columns - ✅
/migrations/0010_add_string_ids/down.sql- Rollback script - ✅ Migration Applied - All existing data backfilled with formatted IDs
- ✅
/internal/domain/registry.go- Updated all models (Customer, Project, Location, Lot, Asset, Component) - ✅
/internal/domain/tickets.go- Updated Ticket and TicketLink models - ✅
/internal/domain/failure_events.go- Updated FailureEvent model
All Repositories Updated with Dual-Write
- ✅
/internal/repository/registry/customers.go- Dual-write implemented - ✅
/internal/repository/registry/projects.go- Dual-write implemented - ✅
/internal/repository/registry/locations.go- Dual-write implemented - ✅
/internal/repository/registry/lots.go- Dual-write implemented - ✅
/internal/repository/registry/assets.go- Dual-write implemented (handles nullable location_sid) - ✅
/internal/repository/registry/components.go- Dual-write implemented (handles nullable lot_sid) - ✅
/internal/repository/registry/installations.go- Query updated to SELECT sid columns - ✅
/internal/repository/tickets/tickets.go- Upsert and LinkToAsset updated - ✅
/internal/repository/failures/failures.go- Upsert updated (handles nullable asset_sid)
Verification Completed
- ✅ Migration 0010 applied successfully
- ✅ All existing data backfilled with formatted IDs (CR-0000001, PJ-0000001, etc.)
- ✅ All code compiles without errors
- ✅ Database schema verified with sid columns present
API Layer Status
- ⚠️ Not required - User confirmed backwards compatibility not needed
- New records will have both
id(int) andsid(string) in JSON responses - Future work: Can transition API to use string IDs as primary identifiers
Phase 3: Entity Renaming ⏳ NOT STARTED
Breaking changes - requires maintenance window
- Rename tables:
assets→machines,components→parts - Rename columns:
asset_id→machine_id,component_id→part_id,asset_tag→machine_tag - Update all foreign keys
- Rename Go types and files
- Update API routes with redirects
- Update UI templates
Phase 4: Switch to String IDs Primary ⏳ NOT STARTED
Breaking changes - requires maintenance window
- Drop integer
idcolumns - Promote
sidtoid - Update all foreign keys
- Remove dual-write logic
Phase 5: Cleanup ⏳ NOT STARTED
- Remove temporary columns/indexes
- Remove deprecated routes
- Optimize indexes
Pattern for Repository Updates
Each repository needs this pattern:
// 1. Add to imports
import "reanimator/internal/idgen"
// 2. Update struct
type XRepository struct {
db *sql.DB
idgen *idgen.Generator
}
// 3. Update constructor
func NewXRepository(db *sql.DB) *XRepository {
return &XRepository{
db: db,
idgen: idgen.NewGenerator(db),
}
}
// 4. Update Create() - example for projects
func (r *XRepository) Create(ctx context.Context, ...) (domain.X, error) {
// Generate SID
sid, err := r.idgen.Generate(ctx, idgen.EntityType)
if err != nil {
return domain.X{}, err
}
// Lookup foreign key SIDs (if needed)
var foreignSID string
err = r.db.QueryRowContext(ctx, `SELECT sid FROM foreign_table WHERE id = ?`, foreignID).Scan(&foreignSID)
if err != nil {
return domain.X{}, classifyError(err)
}
// INSERT with both id (auto-increment) and sid
result, err := r.db.ExecContext(ctx,
`INSERT INTO table (sid, foreign_id, foreign_sid, ...) VALUES (?, ?, ?, ...)`,
sid, foreignID, foreignSID, ...,
)
// ... rest of create logic
}
// 5. Update all SELECT statements to include sid and *_sid columns
// 6. Update all Scan() calls to include the new fields
Next Steps
- Complete Phase 2 repository updates (7 more repositories)
- Update API layer to accept both ID formats
- Apply migration 0010
- Test dual-write functionality
- Verify both integer and string IDs work in API
Migration Commands
# Apply Phase 2 migration
docker exec -i reanimator-mariadb mariadb -u reanimator -preanimator reanimator < migrations/0010_add_string_ids/up.sql
# Rollback if needed
docker exec -i reanimator-mariadb mariadb -u reanimator -preanimator reanimator < migrations/0010_add_string_ids/down.sql
Testing After Phase 2
# Run all tests
go test ./...
# Test ID generation
go test ./internal/idgen/... -v
# Create a customer via API
curl -X POST http://localhost:9999/customers -d '{"name": "Test Corp"}'
# Should return: {"id": 4, "sid": "CR-0000004", ...}
# Verify database
docker exec -i reanimator-mariadb mariadb -u reanimator -preanimator reanimator -e "SELECT id, sid, name FROM customers LIMIT 5"