Skip to content

docs: update coding standards#19

Open
aseguragonzalez wants to merge 1 commit into
mainfrom
docs/update-coding-standards
Open

docs: update coding standards#19
aseguragonzalez wants to merge 1 commit into
mainfrom
docs/update-coding-standards

Conversation

@aseguragonzalez
Copy link
Copy Markdown
Owner

No description provided.

@aseguragonzalez aseguragonzalez self-assigned this May 22, 2026
Copilot AI review requested due to automatic review settings May 22, 2026 19:17
@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the repository’s coding standards documentation to reflect the current seedwork patterns (DDD/hexagonal layering, command/query handling, domain event coordination, integration events, background tasks, and wiring conventions).

Changes:

  • Reworks the Python baseline and Do/Don’t guidance (ports via Protocol, handler naming, bus stack, deferred domain-event coordination).
  • Expands the document with end-to-end examples for aggregates, domain events, command/query handlers, integration events, background tasks, and repository wiring.
  • Adds/updates naming and folder structure conventions and testing InMemory/spy guidance.
Comments suppressed due to low confidence (2)

docs/coding-standards.md:204

  • In the command example, __post_init__ raises ValueError. RegistryCommandBus only converts DomainError into Result.failed; a ValueError will bubble out as an unhandled exception. Update the example (and guidance) to raise a DomainError subclass for domain/validation failures if you expect failures to be represented as Result.failed.
    def __post_init__(self) -> None:
        if self.initial_balance < 0:
            raise ValueError("initial_balance must be non-negative")

docs/coding-standards.md:200

  • Command (and Query) in this seedwork are defined as @dataclass(frozen=True, kw_only=True), and the examples in docs/examples also use kw_only=True. This example omits kw_only=True, which makes the snippet inconsistent with the established pattern in this repo's examples.
@dataclass(frozen=True)
class OpenAccountCommand(Command):
    account_id: str
    initial_balance: float
    currency: str


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/coding-standards.md Outdated
Comment thread docs/coding-standards.md Outdated
Comment thread docs/coding-standards.md Outdated
Comment thread docs/coding-standards.md Outdated
Comment thread docs/coding-standards.md
Comment thread docs/coding-standards.md
Comment thread docs/coding-standards.md Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (4)

docs/coding-standards.md:99

  • The aggregate example uses @dataclass(..., eq=True) implicitly. In seedwork, Entity/AggregateRoot provide identity-based equality; leaving eq as default will generate a dataclass __eq__ on the subclass and override identity semantics. Set eq=False on aggregate/entity dataclasses (as seedwork does).
```python
from __future__ import annotations
from dataclasses import dataclass, field
from uuid import UUID

docs/coding-standards.md:107

  • BankAccount.open() constructs AccountOpenedPayload(initial_balance=...), but the payload type shown later includes both initial_balance and currency. As written, this example wouldn’t type-check/run; align the factory signature and payload construction with the payload dataclass fields (and remove unused imports like field if not needed).
from seedwork.domain import AggregateRoot

@dataclass(frozen=True, kw_only=True)
class BankAccount(AggregateRoot[BankAccountId]):
    owner_id: BankAccountId
    balance: int

    @classmethod

docs/coding-standards.md:186

  • This section refers to DomainException, but the seedwork defines/catches DomainError (there is no DomainException type). RegistryCommandBus catches DomainError specifically and converts it to Result.failed, so the terminology and behavior described here should be updated accordingly.
- `Protocol` with `Repository[BankAccountId, BankAccount]` as base — structural typing. The method signatures (`find_by_id`, `save`, `delete_by_id`) are inherited from `Repository`; no need to redeclare them.
- `pass` body is intentional: inheriting `Repository[TId, TAgg]` already carries the full contract. Redeclaring methods is redundant and couples the port to the base class's naming.
- Returns domain types, never ORM models.

docs/coding-standards.md:219

  • The command example diverges from seedwork’s conventions and won’t work as shown: (1) seedwork commands are @dataclass(frozen=True, kw_only=True), (2) raising ValueError in __post_init__ won’t be converted into Result.failed (only DomainError is caught), and (3) the BankAccount.open(...) call here doesn’t match the aggregate factory signature shown above (missing required args / differing types).
- Extend `DomainError`, the domain base exception type defined in the seedwork.
- The `RegistryCommandBus` catches `DomainError` and returns it in `Result.failed`.
- Keep error classes thin — message goes in the constructor argument.

---

## Application layer

### Command and handler

```python
from __future__ import annotations
from dataclasses import dataclass
from uuid import UUID
from seedwork.application import Command, CommandHandler
from seedwork.domain import DomainError


class InvalidInitialBalanceError(DomainError):
    pass

Comment thread docs/coding-standards.md
Comment thread docs/coding-standards.md
Comment thread docs/coding-standards.md Outdated
Comment thread docs/coding-standards.md
Comment thread docs/coding-standards.md
Comment thread docs/coding-standards.md
- Add scope note clarifying these standards apply to consumer projects
- Entity: use Entity[TId] base (frozen, eq=False, kw_only) + validate()
- ValueObject: use ValueObject base + validate() raising DomainError subclasses
- Aggregate: add eq=False, validate(), fix AccountOpenedPayload to include currency
- Domain Events: clarify aggregate_id is a required argument (not automatic)
- Errors: fix DomainException→DomainError; show __init__ with message+code
- Command: add kw_only=True; raise DomainError subclass instead of ValueError
- Query: add Query[AccountView] type param and kw_only=True
- Integration event TYPE: align with example ("bank_account.account_opened")
- Repository impl: rename to SqlAlchemyBankAccountRepository per convention

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@aseguragonzalez aseguragonzalez force-pushed the docs/update-coding-standards branch from 8efde84 to 652da57 Compare May 22, 2026 19:41
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.

2 participants