Skip to main content

Onboarding a Customer Project

This guide is for a delivery team starting a customer project on NimBus: developers who know integration work and the systems being connected, but not NimBus. It uses the most common case — Dynamics 365 Sales (Dataverse) and Business Central exchanging customer and sales data — and takes you from an empty Azure subscription to adapters running in production.

It does not repeat the reference documentation. Each step says what to do, what to decide, and which page holds the detail. Read it once end to end, then work through it phase by phase.

PhaseYou end up with
1. Learn the modelA shared vocabulary: endpoint, event, catalog, session, Resolver, WebApp, adapter
2. PrerequisitesAccess, identities and tools, requested early because other teams own them
3. Day-one decisionsStorage, hosting, networking, naming and repository layout
4. The catalogThe endpoints and events, published as a versioned contracts package
5. The platformService Bus, message store, Resolver and WebApp in each environment
6. Local developmentA laptop stack for building and debugging adapters
7. The adaptersA Dynamics 365 adapter and a Business Central adapter
8. Adapter deploymentPipelines that build, test and deploy each adapter
9. Go-live and operationsInitial sync, monitoring, failure recovery and upgrades

1. The model in ten minutes​

NimBus is a set of .NET libraries and two hosted applications on top of Azure Service Bus. You write the adapters; NimBus provides the transport, ordering, the audit trail and the operator console.

TermMeaning
EndpointOne participant on the bus, usually one per external system: D365SalesEndpoint, BusinessCentralEndpoint. Each endpoint gets its own Service Bus topic and subscriptions.
EventA C# class deriving from Event (for example D365ProspectUpdated). Its class name is its EventTypeId, which is global to the Service Bus namespace: two classes with the same name collide, whatever their namespace.
Catalog (platform)A class deriving from Platform that lists the endpoints. Each endpoint declares the events it Produces<T>() and Consumes<T>(). The Service Bus topology and the WebApp's view are both generated from it.
Session keyThe property that orders messages, such as the CRM account id. Messages with the same key are processed one at a time, in order. When one fails, later messages for that key are parked until an operator resubmits or skips the failure. Other keys keep flowing.
AdapterYour process for one endpoint. It translates between the system's API and catalog events, publishes changes from its system, and handles events from others.
ResolverA NimBus Function App that records the outcome of every message in the message store. You deploy it; you don't change it.
WebAppThe NimBus management console: message history, failed and parked messages, resubmit and skip, metrics, access control. You deploy it with your catalog.
nbThe NimBus CLI. It provisions the Azure resources, applies the Service Bus topology and deploys the Resolver and WebApp.

Delivery is ordered and at-least-once, not exactly-once: every handler must be idempotent.

Read architecture.md for the full picture and message-flows.md for the flows (publish, failure, resubmit, skip, deferral, request/reply).

See it working first​

Before designing anything, run the Dynamics 365 Sales ↔ Business Central demo on a laptop. It is the closest thing to your project: simulated CRM and BC systems, two real adapters, the Resolver and the WebApp, with customer, prospect, opportunity, product-group and quote flows in both directions. Break a message and recover it in the WebApp. The demo's DynamicsBcDemo.Contracts project is a complete catalog to copy from.

2. Prerequisites​

Where everything comes from​

Nothing requires a copy of the NimBus repository (ADR-015).

WhatWhereNotes
Librariesnuget.org, Akaule.NimBus.*Akaule.NimBus.SDK (publish/subscribe), Akaule.NimBus.Abstractions (catalog types), Akaule.NimBus.Inbox.SqlServer, Akaule.NimBus.Outbox.SqlServer, Akaule.NimBus.Testing. The assemblies and namespaces are NimBus.*.
CLInuget.org, Akaule.NimBus.CommandLineA .NET tool: dotnet tool install --global Akaule.NimBus.CommandLine --version <x.y.z> (cli.md)
Resolver and WebAppAkaule.NimBus.DeployDownloaded by nb deploy apps for the CLI's own version. You don't build them.
Infrastructure templatesInside the CLI packageThe Bicep that nb infra apply deploys
Local stackAkaule.NimBus.AspireHosting and the tool packagesService Bus emulator, Resolver and WebApp from packages (section 6)
Adapter template, patterns and system packsNimBus Adapter Kitdotnet new nimbus-adapter, 29 patterns, and Dataverse, Business Central and F&O packs (section 7)
Releases and release notesGitHub ReleasesPick one version for the whole project (section 9)

Use one NimBus version everywhere: the libraries in every adapter and the contracts package, the nb CLI in every pipeline, and therefore the deployed Resolver and WebApp. Pin it explicitly. Never install "latest" in a pipeline.

Request these in week one​

Several of these belong to other teams and take time. Start them first.

Azure

  • A subscription and one resource group per environment (for example rg-contoso-int-dev, -test, -prod).
  • Resource providers registered on the subscription by someone with subscription-level rights: Microsoft.ServiceBus, Microsoft.Web, Microsoft.Storage, Microsoft.Insights, Microsoft.DocumentDB (Cosmos DB only), Microsoft.Sql (provisioned SQL Server only), Microsoft.EventGrid. Add Microsoft.App, Microsoft.ContainerRegistry, Microsoft.KeyVault and Microsoft.ManagedIdentity for the adapters' resources. The full list is in azure-requirements.md.
  • A deployment identity per environment (an Azure DevOps service connection with workload identity federation) with Owner, or Contributor + Role Based Access Control Administrator, on its resource group. Plain Contributor fails, because the templates create role assignments (deployment.md).
  • For private networking only: subnets, a DNS decision and self-hosted agents inside the network (private-networking.md).

Microsoft Entra ID

  • An app registration for WebApp sign-in, with redirect URI https://<webapp-host>/.auth/login/aad/callback (authentication.md).
  • The object ids of the first WebApp administrators, or of a security group (authentication.md).
  • Business Central: an app registration with Dynamics 365 Business Central → API.ReadWrite.All (application permission, admin consent), registered in BC under Microsoft Entra applications with permission sets. See the Business Central pack for the managed-identity caveats.

Dynamics 365 / Dataverse

  • A sandbox environment per non-production environment.
  • An application user for each adapter's identity, with a security role scoped to the tables the flows touch. The Dataverse pack covers the options.
  • Rights to register a plug-in step or Service Endpoint for change detection (section 7).

Business Central

  • A sandbox environment and company per non-production environment.
  • Rights to deploy an AL extension if a flow needs a custom API page (most cross-reference and upsert flows do).

Azure DevOps

  • A project, with repositories for the contracts, the platform deployment and each adapter (section 3).
  • An Azure Artifacts feed for the contracts package.
  • Pipeline environments (dev, test, prod) with approvals on test and prod.

Workstation​

ToolVersionUsed for
.NET SDK10Everything
Docker Desktop or another container runtimeCurrentSQL Server and the local stack
Azure CLI≥ 2.60 (≥ 2.70 recommended)Deployments; nb refuses older versions for Flex Consumption
Bicep CLI≥ 0.35.1az bicep upgrade
nbThe project's NimBus versionTopology and deployments
Node.js22Only to build NimBus from source; not needed for packages
uv and AGR (optional)CurrentInstalling the adapter kit's agent skill into an adapter repo

3. Day-one decisions​

Record these in a short decision log before the first deployment. Most are hard to change later.

DecisionOptionsDefault for this scenario
Message storeCosmos DB or SQL Server (storage-providers.md)SQL Server if the customer's approved stack has no Cosmos DB, or if adapters need SQL anyway (the inbox). nb defaults to Cosmos DB, so pass --storage-provider sqlserver explicitly.
Solution id and environment namesAny short lower-case idResource names derive from them (sb-<solution>-<env>). Choose once.
NetworkPublic, or private endpoints with Service Bus PremiumPublic unless the customer's policy requires private (private-networking.md)
Resolver hostingFlex Consumption or Elastic PremiumFlex Consumption (nb's default)
WebApp sign-inEntra ID, or username/password (SQL Server only)Entra ID (authentication.md)
Adapter hostingWorker in an Azure Container App, or Azure FunctionsWorker in a Container App: what the adapter kit generates, and the only host that supports the circuit breaker (building-adapters.md)
EndpointsOne per system, or moreOne per system: D365SalesEndpoint and BusinessCentralEndpoint. Add a second endpoint for a system only for a separate lane, such as bulk loads.
OwnershipPer entity and per fieldWrite down which system owns each entity and field (for example: CRM owns prospects and opportunities, BC owns customers and quotes). The demo's ownership model is a worked example.

Repository layout​

The layout that keeps versions and responsibilities clear:

RepositoryContainsIts pipeline
Contoso.Integration.ContractsThe catalog: the Platform, the endpoints and the events. References only Akaule.NimBus.Abstractions.Builds, tests and publishes the NuGet package to the Azure Artifacts feed
Contoso.Integration.PlatformPipeline YAML and parameters, no application codenb setup per environment, with the pinned CLI and contracts versions (section 5)
Contoso.D365Sales.AdapterThe D365 Sales adapter, generated from the kitBuild, test, image, deploy dev → test → prod (section 8)
Contoso.BusinessCentral.AdapterThe Business Central adapter, generated from the kitThe same

The adapters consume the contracts package, so both always agree on the catalog version. A team that prefers a single repository can keep the same four parts as folders, with one pipeline each.

4. Define the catalog: endpoints and events​

The catalog is the integration's contract. Design it with both adapter teams in the room.

Events​

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using NimBus.Core.Events;

namespace Contoso.Integration.Contracts.D365Sales;

[Description("Published by Dynamics 365 Sales when a prospect is created or a seller changes it.")]
[SessionKey(nameof(AccountId))]
public class D365ProspectUpdated : Event
{
public static readonly D365ProspectUpdated Example = new()
{
AccountId = Guid.Parse("acc00000-0000-4000-8000-000000000105"),
Name = "Tailspin Marine Research",
UpdatedAt = new DateTimeOffset(2026, 9, 28, 9, 30, 0, TimeSpan.Zero),
};

[Required]
[Description("The CRM account (accountid). Session key.")]
public Guid AccountId { get; set; }

[Required]
[Description("The account name.")]
public string Name { get; set; } = "";

[Description("When the account was created or changed in CRM.")]
public DateTimeOffset UpdatedAt { get; set; }
}

Conventions:

  • Prefix event names with the publishing system (D365…, Bc…). The class name is the global EventTypeId, so prefixes prevent collisions and show who owns the event.
  • Name events as facts in the past tense (…Created, …Updated), not as commands to the receiver.
  • Choose the session key for each event from the entity whose changes must stay in order, usually the publishing system's record id. Use the same key for every event about that entity. See pattern 02.
  • Document every event and property with [Description], mark mandatory fields [Required], and provide an Example. The WebApp, nb catalog export and AsyncAPI export all use them.
  • Carry business data, not the source system's schema. Map Dataverse columns and BC API fields to neutral names in the adapter.

The full conventions, including personal-data marking, are in pattern 01.

Endpoints and the platform​

using Contoso.Integration.Contracts.BusinessCentral;
using Contoso.Integration.Contracts.D365Sales;
using NimBus.Core;
using NimBus.Core.Endpoints;

namespace Contoso.Integration.Contracts;

public class D365SalesEndpoint : Endpoint
{
public D365SalesEndpoint()
{
Produces<D365ProspectUpdated>();
Consumes<BcCustomerUpdated>();
}

public override ISystem System => new D365SalesSystem();

public override string Description => "Dynamics 365 Sales adapter endpoint.";
}

internal sealed class D365SalesSystem : ISystem
{
public string SystemId => "D365Sales";
}

public class ContosoPlatform : Platform
{
public ContosoPlatform()
{
AddEndpoint(new D365SalesEndpoint());
AddEndpoint(new BusinessCentralEndpoint());
}
}

Give every event a producer and at least one consumer. The Consumes<T>() declarations become the Service Bus routing rules: an event that no endpoint declares it consumes is not delivered, even if an adapter has a handler for it. Synchronous questions, such as a credit check from CRM to BC, use request/reply; see D365CreditCheckRequested in the demo and pattern 19.

Publish it as a package​

The contracts project is a plain class library:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<PackageId>Contoso.Integration.Contracts</PackageId>
<Version>1.0.0</Version>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Akaule.NimBus.Abstractions" Version="<nimbus-version>" />
</ItemGroup>
</Project>

Its pipeline runs dotnet pack and pushes to the Azure Artifacts feed (with a NuGetAuthenticate@1 step before the push). Keep the package's dependencies to Akaule.NimBus.Abstractions and the BCL: nb loads the package to provision the topology and adds its assemblies to the WebApp, without resolving further dependencies.

Version the package deliberately. The catalog decides the Service Bus routing, so a new event or a new Consumes<T>() is a new version, rolled out by the platform pipeline before any adapter uses it.

5. Stand up the platform​

The platform is the same in every environment and is deployed by nb setup. It runs three layers in order (deployment.md):

  1. Azure resources (nb infra apply): the Service Bus namespace, the message store, Application Insights, the Resolver Function App and the WebApp.
  2. Service Bus topology (nb topology apply): topics, session-enabled subscriptions and routing rules for every endpoint in your catalog.
  3. Applications (nb deploy apps): the released Resolver, and the WebApp with your catalog added.

The platform pipeline​

The repository's own pipelines/azure-pipelines-deploy.yml builds nb from a NimBus clone, which suits NimBus developers. A customer platform repository installs the pinned CLI instead. A minimal stage:

parameters:
- name: environment
type: string
values: [dev, test, prod]

variables:
nimbusVersion: '<x.y.z>' # the project's NimBus version
contractsVersion: '<a.b.c>' # Contoso.Integration.Contracts version to deploy

jobs:
- deployment: Platform
environment: contoso-integration-${{ parameters.environment }}
pool:
vmImage: ubuntu-latest
strategy:
runOnce:
deploy:
steps:
- checkout: self
- task: UseDotNet@2
inputs:
packageType: sdk
version: 10.0.x
- script: dotnet tool install --global Akaule.NimBus.CommandLine --version $(nimbusVersion)
displayName: Install nb
- task: AzureCLI@2
displayName: nb setup
inputs:
azureSubscription: sc-contoso-integration-${{ parameters.environment }}
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
az bicep upgrade
nb setup \
--solution-id contosoint \
--environment ${{ parameters.environment }} \
--resource-group rg-contoso-int-${{ parameters.environment }} \
--storage-provider sqlserver \
--sql-admin-login nimbusadmin \
--platform-package Contoso.Integration.Contracts@$(contractsVersion)
env:
NIMBUS_SQL_ADMIN_PASSWORD: $(sqlAdminPassword) # secret variable
NIMBUS_PLATFORM_FEED: https://pkgs.dev.azure.com/<org>/<project>/_packaging/<feed>/nuget
NIMBUS_PLATFORM_FEED_TOKEN: $(contractsFeedToken) # secret: PAT with Packaging (Read)

nb reads the feed's /v3/index.json. Secrets go in environment variables, never on the command line. Every option, including the SQL variants and private networking, is in cli.md. Running nb setup again is safe: existing resources keep their region, plan and SKU.

Run it whenever the NimBus version or the contracts version changes. Topology always goes before adapter code that depends on it.

After the first deployment​

  • WebApp sign-in. Set AzureAd__TenantId, AzureAd__ClientId, AzureAd__Domain (and AzureAd__ClientSecret for a confidential client) on the WebApp, plus Authorization__AdminUserObjectIds or Authorization__AdminGroupObjectIds for the first administrators. Later nb setup runs keep these settings (authentication.md).
  • Access. Administrators grant Reader, Contributor or Owner per endpoint on the WebApp's Access Control page. Payload viewing needs the separate PII Reader grant.
  • Check it. Open the WebApp: both endpoints should be listed with their events.

Resources the adapters need​

nb creates only the NimBus platform. The adapter kit's Bicep expects these to exist in the same resource group, so create them with the customer's own infrastructure code:

  • a Container Apps environment;
  • an Azure Container Registry;
  • a Key Vault with the Azure RBAC permission model;
  • an integration SQL database for the adapters' inboxes (it can share the server with the message store).

6. Develop locally​

There are two local setups. Use both.

The adapter's own stack, generated with the adapter: the adapter, a simulator of the external system with fault injection, and an Aspire AppHost. It connects to a Service Bus namespace of the developer's own (Standard tier). Never point a local adapter at a namespace a deployed adapter uses: they compete for the same messages. The template's README explains how to drive the simulator.

A full NimBus stack from packages, to see the audit trail, failures and resubmits in the WebApp: an AppHost that references Akaule.NimBus.AspireHosting and starts the Service Bus emulator, the topology, the Resolver, the WebApp and your adapters. The complete AppHost is in building-adapters.md.

Develop against the simulator first, then against a CRM and BC sandbox. Most production issues come from behaviour a simulator doesn't have, such as throttling, update windows and plug-ins firing on the adapter's own writes. Test against the sandboxes before test.

7. Build the adapters​

Generate the adapter​

git clone https://github.com/akakaule/nimbus-adapter-kit
dotnet new install ./nimbus-adapter-kit/skills/nimbus-adapter/template

dotnet new nimbus-adapter -n Contoso.D365Sales.Adapter --SystemName D365Sales `
--Contracts package --ContractsPackageId Contoso.Integration.Contracts `
--ContractsPackageVersion <a.b.c> --PlatformType Contoso.Integration.Contracts.ContosoPlatform `
--ContractsFeed https://pkgs.dev.azure.com/<org>/<project>/_packaging/<feed>/nuget/v3/index.json `
--NimBusVersion <x.y.z>

--ContractsFeed is the feed's full index.json URL, as in a nuget.config. The platform pipeline's NIMBUS_PLATFORM_FEED is the same URL without /v3/index.json.

Do the same for --SystemName BusinessCentral. The endpoint name defaults to <SystemName>Endpoint and must equal the endpoint class in the catalog. --PlatformType is the platform class's full name, including its namespace.

The generated solution already has the NimBus wiring, typed client failures, retry rules, a circuit breaker, an inbox, the simulator, tests, Bicep and an Azure DevOps pipeline. Start from it rather than from an empty project: it encodes the failures earlier adapters hit in production.

What package mode leaves out. With --Contracts package the template doesn't generate:

  • The ingress path (system → bus). --Ingress true takes effect only with local contracts, so you build the change-notification queue, the re-read and the publish yourself (below). To use the template's ingress code as a reference, generate a throwaway copy with --Contracts local --Ingress true.
  • Handlers and their tests. The adapter starts with no handlers. You add one per consumed event, with handler and pipeline tests (Tests).

The kit's agent skill can do the same interactively. In Claude Code, Codex or GitHub Copilot, ask it to "create a NimBus adapter for Business Central", then "add a flow: …" for each flow, and "review this adapter" before a pull request. Install it as described in the kit's README.

Design each flow before coding it​

For every flow, write down these answers in docs/flows/<flow>.md in the adapter repo. The kit's flow checklist walks through them.

  • the session key and the deterministic MessageId;
  • the idempotency key on the receiving side (an alternate key in Dataverse, an upstream id field in BC);
  • what happens when a referenced record doesn't exist yet;
  • which fields the receiver may overwrite;
  • how the adapter recognises its own writes when they come back as changes (echo loops).

Change detection (system → bus)​

The pattern for both systems is the same: the system sends a thin notification to a queue, and the adapter re-reads the record and publishes it (pattern 04). Don't build event payloads inside the source system. In package mode the template doesn't generate this path, so each adapter adds it, following the pattern.

SystemRecommendedAlternativesDetail
Dynamics 365 / DataverseAn asynchronous post-operation plug-in step or Service Endpoint that sends a notification to a Service Bus queue, filtered on the changed attributes and on the adapter's own userWebhook, Event Grid, Power Automate, modifiedon polling, change trackingDataverse pack: change detection
Business CentralWebhook subscriptions, received by an HTTP endpoint that answers the validation handshake and enqueues the notification. Subscriptions expire after three days and must be renewed.Polling on lastModifiedDateTime with a stored watermark, or an outbox table in an AL extensionBusiness Central pack: change detection

Plan the initial sync (existing customers and contacts at go-live) as a flow of its own (pattern 09).

Writing (bus → system)​

  • Upsert on a key that survives retries: an alternate key in Dataverse, a custom API page keyed on the upstream id in BC (pattern 12).
  • Read before writing, and write only the fields the receiver owns and that actually changed. This also stops most echo loops (pattern 16, pattern 08).
  • Store the other system's id on the record you write, so later events can find it (pattern 13).

Failures and retries​

Classify every failure where the external system is called. Throttling (429), timeouts and update windows (503) are transient and retried with backoff. Validation errors and missing data are permanent: they fail at once and appear in the WebApp for an operator. Keep HTTP-level retries off the client so every attempt fits inside the message lock. The generated adapter does all of this; building-adapters.md § Resilience and the kit's patterns 20–23 explain why.

Tests​

The template's tests cover client classification, retry rules, the circuit breaker, the catalog and the wiring. In package mode it has no handler or pipeline tests: write them for each flow you add.

The architecture test compares the handlers with the endpoint's Consumes<T>() declarations. In package mode it reports inconclusive while the adapter has no handlers at all, and lists the events still to build. From the first handler on, it fails on any mismatch. Don't deploy an adapter while that test is inconclusive. See building-adapters.md § Adapter testing.

Before an adapter goes to test, work through the kit's review checklist and the production checklist.

8. Deploy the adapters​

Each generated adapter has an azure-pipelines.yml. Pull requests build and test only. main also builds a container image and deploys deploy/main.bicep to dev, test and prod, waiting for the approvals on each pipeline environment.

Topology has one owner. In package mode the adapter pipeline doesn't apply the topology: the platform pipeline does, from the same contracts package (section 5). So the release order is always: contracts package → platform pipeline → adapters. (In local-contracts mode the adapter pipeline applies its own catalog before deploying.)

The template's README lists the one-time setup. In short:

  1. Fill in the placeholders in azure-pipelines.yml and deploy/main.<env>.bicepparam.
  2. Authenticate to the contracts feed. The generated NuGet.config restores the contracts package from your Azure Artifacts feed, but the generated pipeline has no credential step. Add a NuGetAuthenticate@1 task before the build, and in the job that publishes the container image. Give the pipeline's build service read access to the feed.
  3. Create a service connection per environment with Contributor + Role Based Access Control Administrator on the resource group, because the Bicep creates the adapter's managed identity and its role assignments.
  4. After the first deployment, give the adapter's managed identity (the identityPrincipalId output) access to its system: an application user in Dataverse, or the BC setup described in the Business Central pack.
  5. Prepare the inbox database.
    • Store its connection string in the Key Vault under the secret name the Bicep expects (integration-db-connection-string by default).
    • The inbox creates its table on first use, so the database user needs permission to create it once. Otherwise create the table up front and set AutoCreateTable to false.
    • Managed-identity SQL authentication with SqlClient 7 also needs the Microsoft.Data.SqlClient.Extensions.Azure package.

Details: the kit's pattern 28. Adapters on Azure Functions instead: azure-functions-hosting.md.

9. Go-live and operations​

Before go-live​

  • The initial sync has run in test against production-sized data, and its duration is known.
  • MaxConcurrentSessions and the replica counts are sized to what Dataverse and BC tolerate (throughput-tuning.md).
  • Alerts exist on the circuit-breaker log line (Circuit for <Endpoint> opened), on failed messages and on heartbeat gaps (heartbeat.md, notifications.md).
  • Operators have their WebApp roles and have practised resubmit and skip in test.
  • BC webhook renewal is running, and copied BC environments have their webhooks re-created.
  • Every adapter, the contracts package and the platform run the same NimBus version.

Operating​

A failed message shows in the WebApp with its error. The failed message blocks its session, and later messages for the same key are parked behind it. The operator fixes the cause, usually data in CRM or BC, then:

  • Resubmit to process it again; the parked messages follow in order.
  • Skip when it no longer matters; the parked messages are then processed.

See webapp-failed-messages.md, deferred-messages.md and error-handling.md. On Cosmos DB, the nb container commands handle bulk resubmit, skip and clean-up (cli.md). They work on Cosmos DB only. On SQL Server, recover failures from the WebApp.

Upgrading NimBus​

Read the release notes of every version between yours and the target. Then, in this order:

  1. Update the NimBus version in the contracts package, build it and publish a new package version.
  2. Update nimbusVersion and contractsVersion in the platform pipeline and run it in dev.
  3. Update the NimBus version in each adapter (Directory.Packages.props and azure-pipelines.yml), build in Release, run the tests and deploy.
  4. Promote to test and prod in the same order.

Patch releases contain fixes only. Minor and major releases are described in versioning.md.

Reading list​

WhenRead
First dayThis guide, README, architecture.md, the Dynamics 365 ↔ BC demo
Designing the cataloggetting-started.md, message-flows.md, sdk-api-reference.md, kit patterns 01–03
Setting up environmentsdeployment.md, azure-requirements.md, cli.md, authentication.md, storage-providers.md
Building adaptersbuilding-adapters.md, the kit's patterns and the Dataverse and Business Central packs
Before go-livethroughput-tuning.md, error-handling.md, deferred-messages.md, private-networking.md