Use this template to specify the complete implementation requirements for a new Kotlin service module in the operations repository. This document bridges the feature requirements and the actual code structure.
See Implementation Best Practices for guidance on filling in each section.
Brief description of the service being specified. What domain capability does it provide? What entities does it manage?
- Package:
cards.arda.operations.<domain>.<module>
- Repository:
operations
- Feature Requirements: Feature Name Requirements List
- Domain Specification: Domain Specification
- API Documentation: API Documentation
Define the business entities managed by this service using the sealed interface + Entity data class pattern.
- Description: What this entity represents in the domain.
- Sealed Interface:
EntityName extends EntityPayload
- Implementation:
EntityName.Entity data class
- Metadata Class:
EntityNameMetadata extends ScopedMetadata or ChildMetadata
| Property | Type | Required | Default | Description |
|---|
eId | EntityId (UUID) | Yes | Generated | Unique entity identifier |
name | String | Yes | - | Description |
| Rule ID | Condition | Error | Message |
|---|
| VR-001 | name.isBlank() | AppError.ArgumentValidation | ”Name is required” |
- Type:
enum class | sealed interface | data class
- Package:
cards.arda.operations.<domain>.<module>.domain
| Value/Property | Description |
|---|
| VALUE | Description |
- Extends:
EditableDataAuthorityService<Entity, Metadata> (if CRUD service)
ObserverManager<DataAuthorityNotification<Entity, Metadata>> (if observable)
| Method | Signature | Description |
|---|
create | suspend fun create(payload: E, metadata: M, time: Long, author: String, qualifier: MutationQualifier): Result<EntityRecord<E, M>> | Creates a new entity |
update | suspend fun update(payload: E, metadata: M, time: Long, author: String, qualifier: MutationQualifier): Result<EntityRecord<E, M>> | Updates an existing entity |
delete | suspend fun delete(eId: UUID, time: Long, author: String): Result<EntityRecord<E, M>> | Soft-deletes an entity |
getAsOf | suspend fun getAsOf(eId: UUID, asOf: TimeCoordinates): Result<EntityRecord<E, M>?> | Retrieves entity at point in time |
- Signature:
suspend fun methodName(parameters): Result<ReturnType>
- Purpose: What this method accomplishes.
| Parameter | Type | Required | Description |
|---|
qualifier | MutationQualifier | Yes | Mutation mode (LAX, STRICT, PROPAGATE) |
time | Long | Yes | Effective timestamp for bitemporal storage |
author | String | Yes | Identity of the actor performing the operation |
| Qualifier | Behavior |
|---|
| LAX | Flexibility, minimal validation, upsert behavior |
| STRICT | Verify consistency, fail on mismatch |
| PROPAGATE | Cascade changes to related entities |
| Effect | Entities Affected | Condition |
|---|
| Description | EntityName | When does this occur? |
| Condition | Error Type | Error Message |
|---|
| Entity not found | AppError.NotFound | ”Entity [id] not found” |
| Validation failure | AppError.ArgumentValidation | ”field: message” |
| State conflict | AppError.IncompatibleState | Description |
- Table Object:
TABLE_NAME extends ScopedTable
- Record Class:
EntityNameRecord extends ScopedRecord
| Column Name | Kotlin Property | Type | Nullable | Description |
|---|
e_id | (inherited) | uuid | No | Entity identifier |
tenant_id | (inherited) | uuid | No | Tenant scope |
| Constraint | Columns | Scope |
|---|
| Natural identifier | name, tenant_id | Per-tenant unique name |
- Class:
EntityNameUniverse extends ScopedUniverse
- Purpose: Encapsulates all persistence operations for the entity
| Method | Description |
|---|
create(entity, metadata, asOf, author) | Insert new entity |
update(entity, asOf, author, idempotency) | Update existing entity |
delete(eId, asOf, author) | Soft-delete entity |
readAsOf(eId, asOf) | Read entity at point in time |
- Extension Function:
Application.moduleName(cfgProvider, authentication, ...dependencies): ServiceName
| Config Path | Type | Description |
|---|
system.<domain>.<module>.dataSource | DataSourceConfig | Database connection |
| Dependency | Type | Purpose |
|---|
cfgProvider | ConfigurationProvider | Application configuration |
authentication | Authentication | Auth context |
| Test Category | Coverage Target | Patterns |
|---|
| Entity validation | All validation rules | Test each VR-* with valid and invalid inputs |
| Service methods | All MS-* specifications | Mock universe, test each qualifier behavior |
| Error conditions | All error scenarios | Verify correct AppError types and messages |
| Test Category | Setup | Verification |
|---|
| Persistence round-trip | ContainerizedPostgres | Create → Read → Update → Delete cycle |
| Transaction behavior | Database with test data | Rollback on failure, commit on success |
| ID | Category | Description | Status |
|---|
| ED-XXX-001 | Entity Definition | EntityName entity | Proposed |
| VT-XXX-001 | Value Type | ValueTypeName | Proposed |
| SI-XXX-001 | Service Interface | ServiceName interface | Proposed |
| MS-XXX-001 | Method Spec | methodName method | Proposed |
| PS-XXX-001 | Persistence | TableName table | Proposed |
| PS-XXX-002 | Persistence | EntityNameUniverse | Proposed |
| MC-XXX-001 | Module Config | Module entry point | Proposed |
| ID | Question | Owner | Status | Resolution |
|---|
| Q-001 | Question text | Person | Open/Resolved | Answer when resolved |
| Version | Date | Author | Changes |
|---|
| 1.0.0 | YYYY-MM-DD | Author | Initial draft |