# AGENTS.md: Azure Functions

## Commands
- Local run: `func start` (Azure Functions Core Tools); storage emulation with Azurite (`npx azurite` or the repo's compose file).
- Build/test with the language's normal commands (`dotnet test`, `npm test`, `pytest`).
- Never run `func azure functionapp publish` or `az` commands that change cloud resources unless asked; deployments go through CI/IaC.

## Programming model
- Use the current model for the language and don't mix models in one app: .NET isolated worker (`Program.cs` with `FunctionsApplication`/host builder), Node.js v4 (`app.http(...)`, `app.storageQueue(...)` in code, no `function.json`), Python v2 (`func.FunctionApp()` with decorators).
- One function per file/class, named for the trigger and purpose (`ProcessOrderQueue`). Function code is thin: parse input, call a service, return output.

## Triggers and reliability
- Queue, Service Bus, Event Hubs and Event Grid triggers retry and can deliver twice: handlers must be idempotent (dedupe on message/event ID). Let poison messages go to the poison/dead-letter queue instead of catching and dropping them.
- HTTP functions validate input and return proper status codes; set `authLevel` deliberately (`function`/`admin`, or anonymous behind API Management/Easy Auth).
- Timer triggers must tolerate overlap and missed runs; keep the CRON in app settings if environments differ.
- Keep executions short; long work goes to queues or Durable Functions.

## Durable Functions
Orchestrators must be deterministic: no `DateTime.Now`/`Date.now()`, random, network or IO calls inside them; use the context's current time and call activities for side effects. Change orchestrator code with versioning in mind (in-flight instances replay old history).

## Config and security
- Settings come from app settings/environment; `local.settings.json` is gitignored and holds only local values.
- Use managed identity with identity-based connections (`<CONN>__fullyQualifiedNamespace`, `__serviceUri`) instead of connection strings where supported; secrets via Key Vault references.
- Reuse clients (HTTP, SDK clients) as singletons via DI; never create one per invocation.
- Log with structured properties through the host logger (Application Insights); no secrets or full payloads with personal data.
