Create Your Own Store
Follow these steps to create a new store package using the recommended patterns.
1. Define Constants
Create a constants.go file for all statuses, types, and configuration values. Use UPPER_SNAKE_CASE for public, lowerCamelCase for private constants.
2. Define Private Structs & Public Interfaces
Make all entity structs private. Define a public interface for all operations (getters, setters, meta, etc.).
3. Embed DataObject
Embed a DataObject in your struct for generic data handling. Provide constructors for new and existing data.
4. Design SQL Schema
Use Goqu or a similar builder to define your schema. Implement AutoMigrate for setup and updates. Support multiple SQL drivers.
5. Implement Store Layer
Create a StoreInterface for CRUD and queries. Implement a concrete store struct. Organize methods by entity.
6. Wire Up the Store
Add a store config flag (Get<Name>StoreUsed() bool) to internal/config/config_interfaces.go and implement it in config_implementation.go. Add a store builder function in internal/config/store_builders.go. Wire the store initialization in internal/app/datastores.go.
7. Create Migration File
Create a migration file in database/migrations/ (e.g., 2026_01_01_0001_store_<name>_migrate.go) and register it in database/migrations/registry.go. The migration is applied automatically via migrations.MigrateAll(app) during testutils.Setup().
8. Write Tests
Test using real in-memory SQLite databases via testutils.Setup(). Avoid mocks. Use interfaces for flexibility. Add a With<Name>Store(true) testutils option for enabling the store in tests.
Checklist
- Constants defined
- Private entity struct
- Public interface
- DataObject embedded
- SQL schema ready
- Store layer implemented
- Config flag added to ConfigInterface
- Store builder added to store_builders.go
- Store wired in datastores.go
- Migration file created and registered
- Tests written with testutils.Setup()