# Package Modernization Instructions ## Goal Transform legacy packages to use generic MasterList pattern with simplified database operations. ## Steps ### 1. Implement Generic MasterList Base Create `internal/common/master_list.go` with generic collection management: ```go type MasterList[K comparable, V Identifiable[K]] struct { items map[K]V mutex sync.RWMutex } ``` ### 2. Consolidate Package Structure **Remove:** - Legacy wrapper functions (LoadAll, SaveAll, etc.) - Duplicate database files (database.go, database_legacy.go) - README.md (use doc.go instead) - Separate "active_record.go" files **Consolidate into:** - `{type}.go` - Main type with embedded database operations - `types.go` - Supporting types only (no main type) - `master.go` - MasterList using generic base - `player.go` - Player-specific logic (if applicable) - `doc.go` - Primary documentation - `{type}_test.go` - Focused tests ### 3. Refactor Main Type Transform the main type to include database operations: ```go // Before: Separate type and database operations type Achievement struct { ID uint32 Title string } func LoadAchievement(db *database.Database, id uint32) (*Achievement, error) func SaveAchievement(db *database.Database, a *Achievement) error // After: Embedded database operations type Achievement struct { ID uint32 Title string db *database.Database isNew bool } func New(db *database.Database) *Achievement func Load(db *database.Database, id uint32) (*Achievement, error) func (a *Achievement) Save() error func (a *Achievement) Delete() error func (a *Achievement) Reload() error ``` ### 4. Update MasterList Replace manual implementation with generic base: ```go // Before: Manual thread-safety type MasterList struct { items map[uint32]*Achievement mutex sync.RWMutex } func (m *MasterList) AddAchievement(a *Achievement) bool { m.mutex.Lock() defer m.mutex.Unlock() // manual implementation } // After: Generic base type MasterList struct { *common.MasterList[uint32, *Achievement] } func NewMasterList() *MasterList { return &MasterList{ MasterList: common.NewMasterList[uint32, *Achievement](), } } func (m *MasterList) AddAchievement(a *Achievement) bool { return m.MasterList.Add(a) } ``` ### 5. Implement Identifiable Interface Ensure main type implements `GetID()`: ```go func (a *Achievement) GetID() uint32 { return a.AchievementID // or appropriate ID field } ``` ### 6. Simplify API **Remove:** - Legacy type variants (Achievement vs AchievementRecord) - Conversion methods (ToLegacy, FromLegacy) - Duplicate CRUD operations - Complex wrapper functions **Keep:** - Single type definition - Direct database methods on type - Domain-specific extensions only ### 7. Update Documentation Create concise `doc.go`: ```go // Package achievements provides [brief description]. // // Basic Usage: // // achievement := achievements.New(db) // achievement.Title = "Dragon Slayer" // achievement.Save() // // loaded, _ := achievements.Load(db, 1001) // loaded.Delete() // // Master List: // // masterList := achievements.NewMasterList() // masterList.Add(achievement) package achievements ``` ### 8. Testing Create focused tests: - Test core type operations (New, Save, Load, Delete) - Test MasterList basic operations - Remove legacy compatibility tests - Keep tests simple and direct ## Key Principles 1. **Single Source of Truth**: One type definition, not multiple variants 2. **Embedded Operations**: Database methods on the type itself 3. **Generic Base**: Use common.MasterList for thread-safety 4. **No Legacy Baggage**: Remove all "Legacy" types and converters 5. **Documentation in Code**: Use doc.go, not README.md ## Migration Checklist - [ ] Create/verify generic MasterList in common package - [ ] Identify main type and supporting types - [ ] Consolidate database operations into main type - [ ] Add db field and methods to main type - [ ] Replace manual MasterList with generic base - [ ] Implement GetID() for Identifiable interface - [ ] Remove all legacy types and converters - [ ] Update doc.go with concise examples - [ ] Simplify tests to cover core functionality - [ ] Run `go fmt` and `go test` ## Expected Results - **80% less code** in most packages - **Single type** instead of multiple variants - **Thread-safe** operations via generic base - **Consistent API** across all packages - **Better maintainability** with less duplication ## Example Commands ```bash # Remove legacy files rm README.md database_legacy.go active_record.go # Rename if needed mv active_record.go achievement.go # Test the changes go fmt ./... go test ./... go build ./... ```