Skip to content

refactor(arch): extract persistence codec and domain types to proper layers#47

Merged
pocky merged 1 commit into
mainfrom
chore/rewriting-code
May 13, 2026
Merged

refactor(arch): extract persistence codec and domain types to proper layers#47
pocky merged 1 commit into
mainfrom
chore/rewriting-code

Conversation

@pocky
Copy link
Copy Markdown
Contributor

@pocky pocky commented May 13, 2026

Summary

  • Refactor persistence codec from infrastructure/persistence/encoder.zig into application/persistence_codec.zig, enforcing strict hexagonal layer separation by keeping encode/decode logic out of I/O adapters
  • Introduce PersistencePort vtable interface and make Scheduler generic via SchedulerWith(comptime Backend: type) to decouple the application layer from concrete persistence backends
  • Promote domain-level types (timestamp.zig, shell_config.zig, telemetry_config.zig) and OTel instruments (instruments.zig) to their correct layers; extract shared subprocess spawn logic into runner/subprocess.zig
  • Fix ExecutionClient memory ownership: dupe job identifier strings at trigger time, propagate resolve() errors instead of silently discarding them, and switch all unit tests to std.testing.allocator for leak detection

Changes

Application Layer

  • src/application.zig: Export new persistence_codec and instruments modules
  • src/application/persistence_codec.zig: New — full encode/decode for all entry types (job, rule, removals, all 6 runner variants) with errdefer-safe allocation and comprehensive unit tests
  • src/application/persistence_port.zig: New — vtable-based PersistencePort interface decoupling Scheduler from concrete backend
  • src/application/instruments.zig: New — OTel Instruments struct promoted from infrastructure into application layer
  • src/application/execution_client.zig: Dupe job_identifier at trigger(), make resolve() return !void, fix pull_results to free owned identifiers, switch tests to std.testing.allocator
  • src/application/job_storage.zig: Replace linear scan + sort in get_to_execute with priority-queue peek/remove; add count() and count_by_status() accessors; switch tests to std.testing.allocator
  • src/application/query_handler.zig: Update to use new persistence port and codec interfaces
  • src/application/rule_storage.zig: Minor updates for layer alignment
  • src/application/scheduler.zig: Make generic via SchedulerWith(comptime Backend: type); wire through new persistence port
  • src/application/token_store.zig: Layer alignment cleanup

Domain Layer

  • src/domain.zig: Export new domain modules
  • src/domain/shell_config.zig: NewShellConfig type promoted from infrastructure
  • src/domain/telemetry_config.zig: NewTelemetryConfig type promoted from infrastructure
  • src/domain/timestamp.zig: NewTimestamp parsing/formatting promoted from infrastructure
  • src/domain/auth.zig: Layer alignment
  • src/domain/job.zig: Minor fix
  • src/domain/query.zig: Update query types for new layer structure
  • src/domain/runner.zig: Minor alignment
  • src/domain/server_stats.zig: Reduced — fields delegated to proper domain types

Infrastructure Layer

  • src/infrastructure/persistence/encoder.zig: Gutted — logic moved to application/persistence_codec.zig; now thin adapter delegating to codec
  • src/infrastructure/persistence/backend.zig: Updated to use PersistencePort and application-layer codec
  • src/infrastructure/persistence/background.zig: Updated for new codec/port interfaces
  • src/infrastructure/persistence/logfile.zig: Minor update
  • src/infrastructure/runner/subprocess.zig: New — extracted shared subprocess spawn logic used by shell, direct, awf runners
  • src/infrastructure/shell_runner.zig: New — shell runner adapter using new subprocess module
  • src/infrastructure/runner/shell.zig: Delegate to subprocess.zig
  • src/infrastructure/runner/direct.zig: Delegate to subprocess.zig
  • src/infrastructure/runner/awf.zig: Minor update
  • src/infrastructure/runner.zig: Barrel update
  • src/infrastructure/clock.zig: Minor alignment
  • src/infrastructure/http.zig: Layer alignment
  • src/infrastructure/http/json.zig: Layer alignment
  • src/infrastructure/protocol/parser.zig: Minor update
  • src/infrastructure/tcp_server.zig: Update for new scheduler generic type
  • src/infrastructure/telemetry.zig: Use application/instruments.zig types
  • src/infrastructure/tls_context.zig: Minor update

Interfaces & Entry Point

  • src/interfaces/cli.zig: Update for new scheduler type
  • src/interfaces/config.zig: Use promoted domain config types
  • src/interfaces/dump.zig: Update for new codec location
  • src/main.zig: Wire SchedulerWith generic, thread updates for new layer structure

Tests & Docs

  • src/functional_tests.zig: Extended test coverage for refactored paths
  • functional_tests: Compiled functional test binary (should be in .gitignore)
  • CHANGELOG.md: Document hexagonal architecture refactoring under [Unreleased]
  • CLAUDE.md: Expanded with Performance Principles, Memory & Allocators, Zig 0.15.2 Idioms, Hot Paths, Observability, and additional review/pitfall rules

Test plan

  • make build compiles without errors or warnings
  • zig build test-all passes all layer-specific unit tests including new persistence_codec tests
  • zig build test-functional passes end-to-end scheduler round-trip (SET job → tick → execute → persist → reload)
  • Run sanitizer targets: zig build test-asan and zig build test-tsan report no heap or data-race errors

Generated with awf commit workflow

@pocky pocky force-pushed the chore/rewriting-code branch from 2f5a99d to c75e67f Compare May 13, 2026 15:49
…layers

- `CHANGELOG.md`: Document hexagonal architecture refactoring in unreleased section
- `CLAUDE.md`: Expand architecture, performance, memory, concurrency, and Zig 0.15.2 idiom sections
- `functional_tests`: Add compiled functional test binary
- `src/application.zig`: Export persistence_codec and instruments modules
- `src/application/execution_client.zig`: Dupe job_identifier at boundary, propagate resolve errors, use testing.allocator in tests
- `src/application/instruments.zig`: Extract OTel instruments from infrastructure into application layer
- `src/application/job_storage.zig`: Align with PersistencePort interface
- `src/application/persistence_codec.zig`: Extract binary encode/decode from infrastructure/persistence/encoder.zig
- `src/application/persistence_port.zig`: Introduce vtable-based PersistencePort to decouple scheduler from backends
- `src/application/query_handler.zig`: Adapt to generic SchedulerWith backend type
- `src/application/rule_storage.zig`: Align with PersistencePort interface
- `src/application/scheduler.zig`: Make Scheduler generic via SchedulerWith(comptime Backend: type)
- `src/application/token_store.zig`: Minor cleanup and layer alignment
- `src/domain.zig`: Export shell_config, telemetry_config, timestamp modules
- `src/domain/auth.zig`: Minor cleanup
- `src/domain/job.zig`: Minor cleanup
- `src/domain/query.zig`: Update query types for generic scheduler
- `src/domain/runner.zig`: Minor cleanup
- `src/domain/server_stats.zig`: Simplify stats domain type
- `src/domain/shell_config.zig`: Promote shell config from infrastructure to domain
- `src/domain/telemetry_config.zig`: Promote telemetry config from infrastructure to domain
- `src/domain/timestamp.zig`: Extract timestamp parsing into standalone domain module
- `src/functional_tests.zig`: Expand functional test coverage
- `src/infrastructure/clock.zig`: Adapt to domain config types
- `src/infrastructure/http.zig`: Adapt to domain config types and generic scheduler
- `src/infrastructure/http/json.zig`: Adapt JSON codec to updated domain types
- `src/infrastructure/persistence/backend.zig`: Delegate encode/decode to persistence_codec
- `src/infrastructure/persistence/background.zig`: Delegate encode/decode to persistence_codec
- `src/infrastructure/persistence/encoder.zig`: Reduce to thin adapter delegating to application/persistence_codec
- `src/infrastructure/persistence/logfile.zig`: Minor cleanup
- `src/infrastructure/protocol/parser.zig`: Minor cleanup
- `src/infrastructure/runner.zig`: Update runner barrel export
- `src/infrastructure/runner/awf.zig`: Minor cleanup
- `src/infrastructure/runner/direct.zig`: Adapt to subprocess abstraction
- `src/infrastructure/runner/shell.zig`: Adapt to subprocess abstraction
- `src/infrastructure/runner/subprocess.zig`: Extract shared subprocess execution logic
- `src/infrastructure/shell_runner.zig`: Add shell runner adapter using domain shell_config
- `src/infrastructure/tcp_server.zig`: Adapt to generic scheduler and domain types
- `src/infrastructure/telemetry.zig`: Use application/instruments instead of inline OTel setup
- `src/infrastructure/tls_context.zig`: Adapt to domain telemetry_config type
- `src/interfaces/cli.zig`: Adapt CLI to domain config types
- `src/interfaces/config.zig`: Adapt config parser to emit domain config types
- `src/interfaces/dump.zig`: Adapt dump to use application/persistence_codec
- `src/main.zig`: Wire SchedulerWith generic and updated thread architecture
@pocky pocky force-pushed the chore/rewriting-code branch from c75e67f to 378b727 Compare May 13, 2026 16:19
@pocky pocky marked this pull request as ready for review May 13, 2026 16:38
@pocky pocky merged commit fbb9550 into main May 13, 2026
6 checks passed
@pocky pocky deleted the chore/rewriting-code branch May 13, 2026 16:39
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.

1 participant