164 lines
5.5 KiB
Markdown
164 lines
5.5 KiB
Markdown
# 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) and `sid` (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 `id` columns
|
|
- Promote `sid` to `id`
|
|
- 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:
|
|
|
|
```go
|
|
// 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
|
|
|
|
1. **Complete Phase 2 repository updates** (7 more repositories)
|
|
2. **Update API layer** to accept both ID formats
|
|
3. **Apply migration 0010**
|
|
4. **Test dual-write** functionality
|
|
5. **Verify** both integer and string IDs work in API
|
|
|
|
## Migration Commands
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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"
|
|
```
|