Skip to content

chore: refactor database layer#13

Merged
hackmajoris merged 14 commits into
mainfrom
chore/refactor-database-layer
Dec 14, 2025
Merged

chore: refactor database layer#13
hackmajoris merged 14 commits into
mainfrom
chore/refactor-database-layer

Conversation

@hackmajoris
Copy link
Copy Markdown
Owner

Database Layer Refactoring: Scalable File Organization Pattern

Summary

Refactored the database package to use a scalable file organization pattern that groups related files by entity and implementation, making the codebase easier to navigate and ready to scale to 10+ repositories.

📊 Change Statistics

19 files changed, 1428 insertions(+), 1187 deletions(-)
  • 9 new files - Separated implementation files
  • 6 modified - Converted to interface-only files
  • 3 deleted - Replaced by new structure
  • 1 renamed - Test file to match new client.go

🎯 What Changed

Database Layer Restructuring

New Pattern: {entity}_repository.go, {entity}_repository_{implementation}.go

Created Files:

✨ client.go                              # Repository struct definitions
✨ user_repository_dynamodb.go            # User DynamoDB implementation
✨ user_repository_mock.go                # User Mock implementation
✨ user_skill_repository_dynamodb.go      # Skill DynamoDB implementation
✨ user_skill_repository_mock.go          # Skill Mock implementation
✨ master_skill_repository_dynamodb.go    # Master skill DynamoDB implementation
✨ master_skill_repository_mock.go        # Master skill Mock implementation

Modified Files (now interface-only):

📝 user_repository.go                     # UserRepository interface
📝 user_skill_repository.go               # SkillRepository interface
📝 master_skill_repository.go             # MasterSkillRepository interface
📝 factory.go                             # Updated Repository interface docs

Removed Files:

❌ dynamodb.go                            # → replaced by client.go
❌ mock.go (407 lines)                    # → split into 3 mock files
❌ skill_repository.go                    # → deprecated file

Documentation: Complete README Regeneration

415 lines changed - Updated to accurately reflect current project state:

  • ✅ New "Database Layer Organization" section with file structure
  • ✅ All 18 API endpoints documented (was missing 13)
  • ✅ Skills management features fully documented
  • ✅ Data model with all 5 GSIs explained
  • ✅ Complete configuration table
  • ✅ Practical curl examples for all endpoints
  • ✅ Repository auto-selection logic documented
  • ✅ Accurate AWS infrastructure details

💡 Why This Change?

Before (Problems):

Monolithic Files:

❌ dynamodb.go     (31 lines, would grow to 500+)
❌ mock.go         (407 lines, unmanageable)
❌ skill_repository.go (deprecated but not removed)

Issues:

  • Hard to find specific implementations
  • Files would become massive with more entities
  • No clear pattern for adding new repositories
  • Documentation 50% outdated

After (Solutions):

Organized Files:

✅ client.go                    (58 lines - struct definitions)
✅ user_repository.go           (12 lines - interface)
✅ user_repository_dynamodb.go  (182 lines - implementation)
✅ user_repository_mock.go      (103 lines - implementation)

Benefits:

  • Files group alphabetically by entity
  • Easy to locate any repository code
  • Clear pattern: 3 files per entity
  • Scales elegantly to 10+ entities

📁 New File Structure

cmd/app/internal/database/
├── client.go                              # DynamoDBRepository + MockRepository
├── constants.go                           # Table/GSI names
├── entity_keys.go                         # Entity ID builders
├── factory.go                             # Factory + Repository interface
│
├── user_repository.go                     # Interface
├── user_repository_dynamodb.go            # DynamoDB impl
├── user_repository_mock.go                # Mock impl
│
├── user_skill_repository.go               # Interface
├── user_skill_repository_dynamodb.go      # DynamoDB impl
├── user_skill_repository_mock.go          # Mock impl
│
├── master_skill_repository.go             # Interface
├── master_skill_repository_dynamodb.go    # DynamoDB impl
└── master_skill_repository_mock.go        # Mock impl

File Listing (Alphabetically Sorted):

client.go
client_test.go
constants.go
entity_keys.go
factory.go
factory_test.go
master_skill_repository.go               ⎤
master_skill_repository_dynamodb.go      ⎥ Grouped!
master_skill_repository_mock.go          ⎦
user_repository.go                       ⎤
user_repository_dynamodb.go              ⎥ Grouped!
user_repository_mock.go                  ⎦
user_skill_repository.go                 ⎤
user_skill_repository_dynamodb.go        ⎥ Grouped!
user_skill_repository_mock.go            ⎦

🔧 Technical Details

Repository Pattern (Unchanged - Pure Refactor)

// Unified interface composes all repositories
type Repository interface {
    UserRepository
    SkillRepository
    MasterSkillRepository
}

// Both implementations satisfy this interface
type DynamoDBRepository struct { /* ... */ }
type MockRepository struct { /* ... */ }

Auto-Selection Logic (factory.go)

AWS_LAMBDA_FUNCTION_NAME exists → DynamoDB
ENVIRONMENT=production          → DynamoDB
ENVIRONMENT=development         → Mock
DB_MOCK=true                    → Mock
Default                         → DynamoDB

✅ Testing & Verification

All tests passing - no behavior changes:

$ go test ./cmd/app/internal/database/... -v
=== RUN   TestNewRepository_EnvironmentDetection
=== RUN   TestMockRepository_CreateUser
=== RUN   TestMockRepository_GetUser
=== RUN   TestMockRepository_UpdateUser
=== RUN   TestMockRepository_UserExists
=== RUN   TestMockRepository_ListUsers
=== RUN   TestMockRepository_ConcurrentAccess
=== RUN   TestMockRepository_CreateSkill
=== RUN   TestMockRepository_GetSkill
=== RUN   TestMockRepository_ListSkillsForUser
=== RUN   TestMockRepository_ListUsersBySkill
=== RUN   TestMockRepository_UnifiedInterface
--- PASS: All tests (0.99s)
PASS
ok  	github.com/hackmajoris/glad/cmd/app/internal/database	0.993s

Coverage maintained:

  • ✅ Repository initialization
  • ✅ Factory pattern tests
  • ✅ Mock CRUD operations
  • ✅ Concurrent access
  • ✅ Unified interface

🚀 Future Scalability

Adding a new entity (e.g., Project):

  1. Create project_repository.go (interface)
  2. Create project_repository_dynamodb.go (DynamoDB impl)
  3. Create project_repository_mock.go (Mock impl)
  4. Add ProjectRepository to unified Repository interface

Result: Files automatically group together alphabetically!

🔄 Migration Impact

⚠️ Zero Breaking Changes

  • ✅ All public interfaces unchanged
  • ✅ All method signatures identical
  • ✅ Factory function unchanged
  • ✅ Tests verify preserved behavior
  • ✅ No consumer code updates needed

📈 Benefits

Immediate:

  • 🎯 Easier navigation (entity-based grouping)
  • 📦 Smaller, focused files (150-300 lines vs 400+)
  • 🔍 Clear interface/implementation separation
  • 📚 Accurate, comprehensive documentation

Long-term:

  • 📊 Ready to scale to 10+ repositories
  • 🎨 Consistent pattern for all entities
  • 🚀 Faster onboarding for new developers
  • 🛠️ Easy to locate and modify code

📝 Checklist

  • All tests passing
  • No breaking changes
  • Documentation updated (comprehensive README regeneration)
  • Code follows project style
  • Clear commit messages
  • File naming consistent

@hackmajoris
Copy link
Copy Markdown
Owner Author

/q review

Copy link
Copy Markdown
Contributor

@amazon-q-developer amazon-q-developer Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

This PR successfully refactors the database layer with a clean, scalable file organization pattern. The separation of interfaces from implementations and the entity-based grouping will make the codebase much easier to navigate as it grows.

✅ Strengths

  • Excellent file organization: The {entity}_repository.go, {entity}_repository_{implementation}.go pattern is clean and scalable
  • Clear separation of concerns: Interfaces are properly separated from implementations
  • Consistent code structure: All repository implementations follow the same patterns
  • Good logging and performance tracking: Comprehensive logging with duration tracking throughout

🔧 Issues Found

I've identified 7 critical issues that need to be addressed before merge:

  1. Comment/code mismatch in user_repository_dynamodb.go - Comment says "Scan" but code uses "Query"
  2. Error message mismatch in user_repository_dynamodb.go - Log says "scan" but operation is "query"
  3. Inconsistent error handling in multiple files - Functions always return domain-specific errors (like ErrSkillAlreadyExists) for any DynamoDB error, but should only return these for specific condition failures

The error handling issues are particularly important as they could mask real infrastructure problems (network issues, permissions, etc.) by always returning domain-specific errors.

📋 Next Steps

Please address the code suggestions provided in the individual comments. All issues have one-click commit suggestions to make fixes easy to apply.

Overall, this is a well-structured refactoring that significantly improves code organization. Once the error handling issues are resolved, this will be ready to merge.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Comment thread cmd/app/internal/database/user_repository_dynamodb.go Outdated
Comment thread cmd/app/internal/database/user_repository_dynamodb.go Outdated
Comment thread cmd/app/internal/database/user_skill_repository_dynamodb.go
Comment thread cmd/app/internal/database/user_skill_repository_dynamodb.go
Comment thread cmd/app/internal/database/user_skill_repository_dynamodb.go
Comment thread cmd/app/internal/database/master_skill_repository_dynamodb.go
Comment thread cmd/app/internal/database/master_skill_repository_dynamodb.go
Comment thread cmd/app/internal/database/master_skill_repository_dynamodb.go
hackmajoris and others added 8 commits December 14, 2025 14:19
Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com>
Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com>
Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com>
Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com>
Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com>
Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com>
Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com>
Co-authored-by: amazon-q-developer[bot] <208079219+amazon-q-developer[bot]@users.noreply.github.com>
@hackmajoris hackmajoris merged commit 306d599 into main Dec 14, 2025
1 check passed
@hackmajoris hackmajoris deleted the chore/refactor-database-layer branch December 14, 2025 12:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant