An Attendance Platform in ASP.NET Core
Badge gates, WFH timers and shift allowances - the shape of a seven-project intranet attendance platform, the onion it almost is, and the roadmap for fourteen more parts.
348 articles filed under this topic.
Badge gates, WFH timers and shift allowances - the shape of a seven-project intranet attendance platform, the onion it almost is, and the roadmap for fourteen more parts.
A 6.23 MB JavaScript bundle loaded on every page, a manifest that minifies CSS but concatenates JS, and two copies of jQuery - the first of four frontend chapters the attendance series skipped.
Hard deletes destroy the audit trail; soft deletes clutter live tables forever. Introducing ArchiveKit, a .NET library that intercepts deletions and stores immutable archive snapshots with TTL policies and cascade archiving.
Unit tests mock what you assume, end-to-end tests tell you too late - consumer-driven contract testing closes the gap, and a small open-source .NET library called Pactify is the clearest way I know to learn how it works. Part 1 of a series.
The 22-part Convey series read the packages; it never once walked the sample system that ships with them. Opening the missing chapters with the trip an order takes through Orders, Pricing and Deliveries — and what the samples quietly teach that no package README does.
Rename a property, change a type, ship the release - and every payload you stored last year stops deserialising. Introducing VersionKit, a .NET library that declares schema history as attributes and migrates old data on read.
Controllers grow sideways and Minimal APIs grow into soup. FastEndpoints bets on a third shape - one class per endpoint - and this series reads its source to see how the bet is implemented. Part 1 of FastEndpoints in Depth.
Seventeen parts of reading FastEndpoints and the series never once mentioned mappers - the entity-translation layer half the endpoint base classes exist to serve. The Missing Chapters opens with the biggest gap: where mappers live, how they are found, and why they are secretly singletons. Part 1 of FastEndpoints — The Missing Chapters.
Inflow is a modular monolith whose modules agree on their boundaries and disagree about everything inside them - a four-project onion next to a single feature-sliced assembly. Part 1 of a series reading the money-moving half of the estate.
A teaching repo that implements one airline-charter domain three ways on purpose - CRUD, CRUD-plus-rich, and Clean Architecture - and persists it three ways to match. Part 1 of a source-reading series.
Every team's fifth microservice ships with the same four hundred lines of bootstrap code as the first four. Opening a deep-dive series on Convey, the open-source .NET toolkit that turned that boilerplate into thirty composable packages.
Database-per-tenant, schema-per-tenant, or packed into a shared database? Kicking off a series on building a multi-tenant platform where one EF Core codebase supports all three isolation strategies behind a single control plane.
DShop is one e-commerce shop stamped out as nine microservices over RabbitMQ - this series reads the real source to see how the topology holds together and where it drifts. Part 1 of Nine Services and a Message Bus.
A 2018 API gateway promises that routing, auth, validation and messaging need no code at all - this series reads the source that makes the promise true, and the places where it is not.
DevMentors' ModularMonolith sample packs three conference-system modules, a mini-framework and one deliberately broken contract into eighty-four C# files - opening a series that reads all of it, defects included.
A guided tour of FeedR, DevMentors' open-source .NET microservices sample for real-time data feeds - six services, Redis pub/sub, Apache Pulsar and a gRPC stream, and the two-tier eventing model that makes it worth reading. Part 1 of a source-level deep dive.
Split one database into five services and the transaction you deleted does not disappear - it goes feral. On sagas, compensation, process managers, and Chronicle, the small open-source .NET library this series reads line by line.
Dozens of Azure Functions and Logic Apps need each other's URLs and keys, and there is no Kubernetes, no sidecar, no mesh to hand them out. How a small .NET library turned one Key Vault and a naming convention into a working discovery layer - the consumer side of a registry made of secrets. Part 1 of a new series.
Reading a repository one project at a time hides everything that lives in the edges between them - and in this estate the edges are where the interesting failures are.
Convey sells a microservice in thirty lines, and Pacco builds ten of them - this series reads the whole estate to price what the framework compresses and what every consumer pays for by hand. Part 1 of The Convey Consumer Tax.
Five executables, zero queues - how an attendance platform coordinated a web app, three Azure Functions and a console job through one SQL database, and what that choice bought and cost. Part 1 of the series.
DShop.Common is the shared library nine microservices were built on - and the rough draft of a framework its authors later shipped as Convey.
Every modular monolith claims its modules are decoupled. Inflow proves it the only way that counts - by having no project reference between any two of them - and then has to build a whole mini-framework to make that survivable. Part 1 of a source-read through the shared layer.
Nobody in Pacco approves an order - a vehicle reservation does. A tour of DevMentors' parcel-delivery estate, the domain it models, and the fifteen-part series it earns.
Inflow ships an executable request collection - five .rest files, thirty-seven requests. On a fresh clone nine of them return a 2xx, and eight of those nine are in one file. This series reads the repository itself as the artefact.
Trill's Stories service is four projects with a dependency-free domain at the bottom. Its Users service is two projects with everything in one assembly - same author, same week, same estate, opposite answers to what a layer is.
The DevMentors Trill estate is a nine-service microservices sample spread over eleven sibling repositories with no README, no clone script and no bootstrap tooling - and the only artefact that names the whole system is a Visual Studio solution file.
What .NET Aspire actually does for a real multi-service system - the AppHost model, service defaults, the dashboard, and the road from F5 to deployment.
Wire four services into a .NET Aspire AppHost and run it once - traces, logs, health and environment variables for the whole system, before you have written a single line of observability code. Part 1 of a series on Aspire in production.
SaveChanges is already a transaction, until it isn't enough. A tour of explicit transactions, TransactionScope, execution strategies and the failure modes that only show up in production.
Twenty-two parts of source reading and not one about tests. How Convey's design choices land on your test suite: handlers that fake beautifully, an exposed host builder for integration tests, config flags as test infrastructure, and conventions that deserve a pin.
Three toy services, ten infrastructure containers. Reading Convey's docker-compose stack as the honest bill of the chassis: what each container is for, which volumes actually persist, the per-OS variants, and what I would cut in 2026.
The parent series covered the outbox pattern; it never compared the implementations. Entity Framework gets a real transaction, Mongo gets sessions you can switch off, expiry is three different mechanisms — and the processor that drains them all is a fire-and-forget timer.
Convey's real manifest is not Program.cs — it is the config file. Reading the Orders sample's appsettings.json as a single artifact: the section-per-package convention, the fleet of enabled:false switches, and what the defaults quietly tell you about production.
Convey.Persistence.OpenStack.OCS is the package the whole first series skipped — a hand-rolled Swift object-storage client with Keystone auth, an operation-result pattern, a server-side COPY verb, and a re-authentication habit worth learning from.
The 22-part Convey series read the packages; it never once walked the sample system that ships with them. Opening the missing chapters with the trip an order takes through Orders, Pricing and Deliveries — and what the samples quietly teach that no package README does.
Pactify.AspNetCore in one sitting: an attribute, an assembly scan, and a /pacts/{provider} endpoint that serves your contract classes as live JSON - plus what a runtime contracts endpoint is really for.
The series retrospective - what a thirty-file library taught me that a full-featured one couldn't, Pactify's honest limit list versus PactNet, the broker maturity ladder, and the org-shaped question hiding under the tooling.
A line-by-line read of Pactify's matching engine - top-level-only body comparison, header names that ignore your casing option, nested objects that can never match, and two format-string bugs that crash the error path.
How a pact travels from the consumer's pipeline to the provider's - Pactify's file and HTTP publishers, Pact Broker URL anatomy, and the unchecked response status that makes a failed publish silently pass your build.
The provider side of Pactify - how CreateFor<Startup> hosts your whole API in memory with TestServer, why interactions verify concurrently, the SmartFormat trick behind endpoint templating, and the discovery that Given(...) never runs.
An annotated tour of the JSON document Pactify produces - the serializer settings that shape it, the snake_case field inherited from Pact v1, and the unusual decision to ship the consumer's matching options inside the contract itself.
A walk through Pactify's PactMaker fluent API - the two-interface builder trick that hides Build() from you, why the consumer test always passes, and the uninitialized-object surprise inside WithBody<T>().
The retrospective: after ten parts inside DevMentors' real-time feeds sample, the honest scorecard - five decisions worth stealing for real systems, the sharp edges catalogued in one place, and the concrete backlog that separates this teaching codebase from a production deployment. Part 11 closes the FeedR deep dive.
Unit tests mock what you assume, end-to-end tests tell you too late - consumer-driven contract testing closes the gap, and a small open-source .NET library called Pactify is the clearest way I know to learn how it works. Part 1 of a series.
FeedR ships three ways to run its six services - pm2, Project Tye, and a deliberately split pair of docker compose files - plus per-service Dockerfiles and an environment-keyed configuration layer that lets the same build run on localhost and inside a compose network. Part 10 of the FeedR deep dive.
FeedR threads a correlation ID from a YARP transform through HTTP middleware and into Pulsar message metadata - and quietly loses it at the Redis hop in the middle. Tracing exactly where the chain holds and where it breaks is the best observability lesson in the sample. Part 8 of the FeedR deep dive.
How do you assert that an endpoint published an event when publishing is a side effect with no return channel? FeedR's end-to-end test answers with WebApplicationFactory, a real Redis round-trip, and a TaskCompletionSource - plus the timeout and determinism traps the sample leaves open. Part 9 of the FeedR deep dive.
Where FeedR's data graduates from tick to fact: the aggregator's pricing handler, a second messaging seam with envelopes and metadata, Apache Pulsar as the durable tier, and the notifier's acknowledge-as-you-go consume loop. Part 7 of the FeedR deep dive.
FeedR pushes live prices to clients through a gRPC server stream: a four-message proto contract, fixed-point decimals, dual Kestrel endpoints, and an event-to-stream bridge that busy-spins - plus the channel-based rewrite it's asking for. Part 5 of the FeedR deep dive.
FeedR's weather feed is the pattern for every external integration: poll a REST API inside an IAsyncEnumerable, guard it with a typed HttpClient and Polly retries, translate its JSON at the boundary, and republish it as a push. Plus the retry clause I can't defend and a hard-coded API key with a lesson in it. Part 6 of the FeedR deep dive.
FeedR moves every tick between services through a two-method streaming abstraction with a no-op default and a Redis implementation - which, despite the namespace, is pub/sub rather than streams. What that seam buys, how DI last-wins overrides it, and what you lose when nobody is listening. Part 4 of the FeedR deep dive.
How FeedR's quotes feed decouples a microsecond HTTP endpoint from an hours-long price generator: System.Threading.Channels as a command queue, marker records as the protocol, and an Interlocked flag for idempotent start/stop. Part 3 of the FeedR deep dive.
FeedR's API gateway is a YARP reverse proxy whose entire routing table lives in appsettings.json - prefix-stripping routes, per-environment cluster overrides, and a one-line transform that starts every distributed trace. Part 2 of the FeedR deep dive.
A guided tour of FeedR, DevMentors' open-source .NET microservices sample for real-time data feeds - six services, Redis pub/sub, Apache Pulsar and a gRPC stream, and the two-tier eventing model that makes it worth reading. Part 1 of a source-level deep dive.