Skip to content

feat(domain): add pure Dart domain model: Agent, Hire, Payment, Feedback, validated StellarAddress/UsdcAmount, ports and typed errors - #60

Merged
XxHugheadxX merged 1 commit into
mainfrom
feat/9-domain-model
Sep 26, 2026
Merged

XxHugheadxX merged 1 commit into
mainfrom
feat/9-domain-model

Conversation

@XxHugheadxX

Copy link
Copy Markdown
Contributor

Closes #9

Summary

Adds puls3_domain/, the pure Dart domain package every other layer builds on, and docs/domain/model.md.

  • Location: puls3_domain/ at the repo root, next to the other puls3_* packages, as ADR-0001 decided (the issue's default was packages/puls3_domain/). Added to the root pub workspace; no new dependencies, so pubspec.lock is unchanged.
  • Entities: Agent (id, owner, wallet, name, description, 1–5 skills, price), Skill (A2A shape from ADR-0004), Hire (price and manifest version at hire time), Payment (with settles(hire, agentWallet:), the ADR-0003 rule: same hire, paid to the agent wallet, exact amount), Feedback (score 1–5, comment ≤ 500).
  • Value objects: StellarAddress (56 chars, base32, G/C prefix, version byte, CRC16-XModem checksum), UsdcAmount (integer stroops, 0..2^53−1 so it is exact on the web too), AgentId (u32, like the contract), HireId (1..2^53−1, the payment's muxed id), TransactionHash.
  • Ports (interfaces only): AgentRepository, LedgerPort, AgentRuntimePort.
  • Typed errors: a sealed DomainError with one subclass per rule (InvalidStellarAddress, InvalidAgent, …), each carrying an enum that names the broken rule.
  • docs/domain/model.md: glossary, Mermaid class diagram, and invariants I1–I17, each naming the error it raises.

Acceptance criteria

  • pubspec.yaml of the domain package has no dependency on serverpod, flutter, or stellar_flutter_sdk
  • dart analyze reports 0 issues (--fatal-infos)
  • dart test passes (40 tests)
  • Every invariant in model.md has at least one test that fails when the invariant is broken (see mutation run below)
  • StellarAddress rejects wrong prefix, wrong length, and bad checksum, with a test for each (plus invalid characters and a tampered payload)
  • Money is never a double anywhere in the package
  • Glossary names match the class names exactly (Owner and Reputation are glossary terms, not classes, and say so)

Verification evidence

Written test-first: the tests were run before lib/ existed and failed to compile (Type 'Skill' not found).

$ cd puls3_domain
$ dart format --set-exit-if-changed .     # Formatted 8 files (0 changed)
$ dart analyze --fatal-infos              # No issues found!
$ dart test                               # 00:00 +40: All tests passed!
$ grep -nE "serverpod|flutter|stellar" pubspec.yaml   # (empty)
$ grep -rn "double" lib/                               # (empty)
$ grep -rnE "package:(serverpod|flutter|stellar_flutter_sdk|stellar_dart|http)" lib/   # (empty)

Mutation run: each of the 24 invariant checks was broken one at a time, the suite was run, and the code restored:

OK  I1 length · I1 base32 · I1 checksum · I2 negative · I2 max · I3 AgentId · I4 HireId · I5 TxHash
OK  I6 kebab · I6 name · I7 agent name · I8 description · I9 skills · I10 duplicates · I11 agent price
OK  I12 hire price · I13 manifest version · I14 payment > 0 · I15 hire · I15 payee · I15 amount
OK  I16 score · I17 comment
--  I1 prefix letter alone: not detected, because the version-byte check still rejects it with the same error.
    Breaking both prefix guards together makes "I1 StellarAddress rejects a prefix other than G or C" fail.

StellarAddress tests use real testnet addresses: an account and the Identity Registry contract deployed in #58.

The current CI steps still pass with the new workspace member: flutter pub get at the root, then dart analyze --fatal-infos and dart format --set-exit-if-changed . in puls3_server.

Notes for reviewers

…, ports and typed errors

New puls3_domain package at the repo root (ADR-0001), added to the pub workspace. Entities Agent, Skill, Hire, Payment and Feedback; value objects StellarAddress (length, base32, version byte and CRC16 checksum), UsdcAmount (integer stroops, 0..2^53-1), AgentId (u32), HireId and TransactionHash; ports AgentRepository, LedgerPort and AgentRuntimePort; typed DomainError subclasses. docs/domain/model.md has the glossary, class diagram and invariants I1-I17. Written test-first: 40 tests, one group per invariant, and mutating each invariant check makes a test fail. No dependency on serverpod, flutter or any Stellar SDK.
@XxHugheadxX XxHugheadxX added this to the Stellar Elite (Oct 10) milestone Sep 26, 2026
@XxHugheadxX XxHugheadxX added area: domain Business logic: agents, identity, reputation, payments type: feat New functionality P0 Blocks a deadline deliverable labels Sep 26, 2026
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying puls3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 839da02
Status: ✅  Deploy successful!
Preview URL: https://ada875ca.puls3-4lw.pages.dev
Branch Preview URL: https://feat-9-domain-model.puls3-4lw.pages.dev

View logs

@XxHugheadxX
XxHugheadxX merged commit d35258c into main Sep 26, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: domain Business logic: agents, identity, reputation, payments P0 Blocks a deadline deliverable type: feat New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: core domain model (Agent, Skill, Hire, Payment, Reputation)

1 participant