Working with it
Fear is a bad compass. How I'm approaching AI as a developer without reacting to the noise.
All notes, decisions, and half-baked thoughts — sorted by date. Unpolished, mostly for my future self.
Fear is a bad compass. How I'm approaching AI as a developer without reacting to the noise.
Why ServiceDeskLite enforces Clean Architecture dependency rules through project references rather than naming conventions — and what that costs.
Why ServiceDeskLite injects handlers directly into endpoints instead of dispatching through a mediator — and when that decision should be revisited.
How ServiceDeskLite uses an explicit Result type to make handler outcomes visible — and where DomainExceptions still belong.
Why ServiceDeskLite uses ProblemDetails with custom extension fields as its single error format — and how the contract is shared without coupling the Web to the API.
Why ServiceDeskLite wraps Guid in a TicketId record struct — what the compiler catches, what the mapping overhead costs, and how UUIDv7 makes it better.
Why ServiceDeskLite ships two complete persistence implementations — and why EF Core's built-in InMemory provider wasn't one of them.
Thinking about what to build next — and why it's not another clean architecture project.
Why Ingestor processes large import files in 500-line chunks instead of all-at-once — bounded blast radius, partial success semantics, and the tradeoffs that came with it.
Designing deterministic idempotency keys for an import pipeline — why SHA256 over file content, what the unique index enforces, and how HTTP clients benefit.
Why Ingestor starts with a database-backed outbox instead of RabbitMQ — and what the switchable dispatcher pattern makes possible later.
Why Ingestor uses a Result<T> type instead of exceptions at application boundaries — what it makes explicit, what it costs, and where exceptions still belong.
How an explicit domain state machine with nine states and an enumerated transition table prevents silent state corruption in a long-running pipeline.