When to use this skill
When you need to add a new domain type to the ORE Studio project with complete support for JSON I/O, table I/O, test data generation, and database persistence with CRUD operations.
How to use this skill
- •Gather information about the domain type (name, fields, project location).
- •Follow the detailed instructions to create all required artefacts in order.
- •Build and test the new domain type.
- •Raise PRs at designated checkpoints and wait for review before proceeding.
Related skills
- •cmake-runner: For building and testing the component.
- •plantuml-class-modeler: Update class diagrams for the component.
- •feature-branch-manager: Manage branch transitions between phases.
- •pr-manager: Create a new Pull Request (PR).
PR strategy
Creating a complete domain type involves significant work across multiple files. To keep PRs reviewable, the implementation is split into phases with designated checkpoints.
| Phase | Steps | Focus | PR Title Template |
|---|---|---|---|
| 1 | 1-3 | Domain class and I/O support | [COMPONENT] Add <Entity> domain type |
| 2 | 4 | Test data generator | [COMPONENT] Add <Entity> generator |
| 3 | 5-6 | Repository and persistence | [COMPONENT] Add <Entity> repository |
| 4 | 7-10 | Tests and documentation | [COMPONENT] Add <Entity> tests and diagrams |
Phase checkpoints
After completing each phase:
- •Using cmake-runner skill, build and verify there are no errors.
- •Commit all changes with an appropriate message.
- •Push the branch and use pr-manager skill to raise a PR with the suggested title.
- •Wait for review feedback and address any comments.
- •Once approved, merge the PR back to main.
- •Use the feature-branch-manager skill to transition to the next phase.
Detailed instructions
The following sections describe the step-by-step process for creating a complete domain type.
Gather requirements
Before starting, gather the following information from the user:
- •Domain type name: the name of the new type (e.g.,
currency,account). - •Component location: which component the domain type belongs to (e.g.,
ores.refdata,ores.accounts). - •Fields: list of fields with their types and descriptions.
Phase 1: Domain class and I/O support
Step 1: Create the domain class definition
Follow the instructions in Domain Type Class Definition Facet.
Step 2: Create JSON I/O support
Follow the instructions in Domain Type JSON I/O Facet.
Step 3: Create table I/O support
Follow the instructions in Domain Type Table I/O Facet.
Phase 1 checkpoint
At this point you have a complete domain type with JSON and table I/O support.
- •Build the component library to verify there are no errors.
- •Commit with message:
[COMPONENT] Add <Entity> domain type - •Push and raise PR:
[COMPONENT] Add <Entity> domain type - •Wait for review and merge before continuing.
- •Use feature-branch-manager to transition to Phase 2.
Phase 2: Test data generator
Step 4: Create generator support
Follow the instructions in Domain Type Generator Support Facet.
Phase 2 checkpoint
At this point you have a test data generator for the domain type.
- •Build the component library to verify there are no errors.
- •Commit with message:
[COMPONENT] Add <Entity> generator - •Push and raise PR:
[COMPONENT] Add <Entity> generator - •Wait for review and merge before continuing.
- •Use feature-branch-manager to transition to Phase 3.
Phase 3: Repository and persistence
Step 5: Create repository entity and mapper
Follow the instructions in Domain Type Repository Entity and Mapper Facet.
Step 6: Create repository with CRUD operations
Follow the instructions in Domain Type Repository CRUD Operations Facet.
Phase 3 checkpoint
At this point you have full repository support for the domain type.
- •Build the component library to verify there are no errors.
- •Commit with message:
[COMPONENT] Add <Entity> repository - •Push and raise PR:
[COMPONENT] Add <Entity> repository - •Wait for review and merge before continuing.
- •Use feature-branch-manager to transition to Phase 4.
Phase 4: Tests and documentation
Step 7: Update CMakeLists.txt
Follow the instructions in Domain Type CMakeLists Update Facet.
Step 8: Create tests
Follow the instructions in Domain Type Test Creation Facet.
Step 9: Update UML diagrams
Update the component's UML diagrams to include the new domain type:
- •Use the plantuml-class-modeler skill to update class diagrams showing the new domain type and its relationships.
- •If repository support was added, use the plantuml-er-modeler skill to update the database ER diagram with the new table.
- •Build the diagrams using the appropriate CMake targets.
Step 9: Build and verify
Using the cmake-runner skill:
- •Configure the project (reconfigure to pick up new files).
- •Build the component library (
COMPONENT.libtarget). - •Build and run the component tests (
test_COMPONENT.teststarget).
Step 10: Update UML diagrams
Update the component's UML diagrams to include the new domain type:
- •Use the plantuml-class-modeler skill to update class diagrams showing the new domain type and its relationships.
- •Build the diagrams using the appropriate CMake targets.
Phase 4 checkpoint
This is the final phase. At this point you have complete domain type support with tests and documentation.
- •Build and run all tests to verify everything works.
- •Commit with message:
[COMPONENT] Add <Entity> tests and diagrams - •Push and raise PR:
[COMPONENT] Add <Entity> tests and diagrams - •Wait for review and merge.
The domain type implementation is now complete.
Common patterns and conventions
Naming conventions
- •Use snake_case for all C++ identifiers (classes, methods, variables)
- •File names should match the class name exactly
- •Headers use
.hppextension - •Implementation files use
.cppextension
Code organization
- •Group related functionality in logically named files
- •Standard library includes first, then third-party, then project headers
- •Use namespace aliases to reduce verbosity
Documentation
- •Add doxygen comments for all public APIs
- •Explain the "why" in comments, not the "what"
- •Include
@brieftags for all documented items
Service layer patterns
When creating a service class to expose repository operations, follow these patterns:
Use save_* for upsert semantics
The repository write() method has upsert semantics - it creates a new record or updates an existing one. The service layer should expose this same behavior through save_* methods:
// CORRECT: Single save_* method with upsert semantics
void currency_service::save_currency(const domain::currency& currency) {
currency_repo_.write(currency);
}
DO NOT create separate create_* and update_* methods at the service level:
// WRONG: Separate create/update methods duplicate repository semantics void currency_service::create_currency(const domain::currency& c); // Don't do this void currency_service::update_currency(const domain::currency& c); // Don't do this
Service method naming convention
| Operation | Method Name Pattern | Notes |
|---|---|---|
| Create or update | save_<entity> | Upsert via repository write() |
| Delete | remove_<entity> | Soft delete via repository |
| Find by key | find_<entity> | Returns std::optional |
| List all | list_<entities> | Returns vector |
| List with filter | list_<entities>_by_<key> | Filtered list |
| List since time | list_<entities>_since | Incremental loading support |
| Get history | get_<entity>_history | All versions of an entity |
Reference implementation
See projects/ores.refdata/src/service/currency_service.cpp for a correct implementation of the service layer pattern.