In addition to the C# infrastructure project, Azure hosting resources are defined with Bicep templates.
Location:
- infra/azure/main.bicep
- infra/azure/modules/app-service-plan.bicep
- infra/azure/modules/web-app.bicep
- infra/azure/modules/web-app-slot.bicep
Provisioned resources:
- Linux App Service plan
- API App Service (learningbank-api)
- Web App Service (learningbank-web)
- Optional staging slots for API and Web apps
Deployment behavior:
- .github/workflows/deploy-azure-prod.yaml deploys Bicep with createStagingSlots=true.
- .github/workflows/deploy-azure-dev.yaml deploys Bicep with createStagingSlots=false.
- Deployments are idempotent via az deployment group create.
Primary template parameters:
- appServicePlanName
- apiAppName
- webAppName
- createStagingSlots
- slotName
- appServicePlanSkuName
- appServicePlanSkuTier
- apiAuthAuthority
- apiAuthAudience
- nextAuthUrl
- nextPublicApiUrl
- googleClientId
- googleClientSecret (secure)
- azureAdClientId
- azureAdClientSecret (secure)
- azureAdTenantId
- authSecret (secure)
- enableSql (provisions Azure SQL server + serverless database; default true)
- sqlServerName
- sqlDatabaseName
- sqlAdminIdentityName (user-assigned identity used as the SQL Entra admin)
- deployPrincipalObjectId (deploy SP object id, granted db_ddladmin for migrations)
- enableFrontDoorDnsRecords (optional; reconciles apex/www Azure DNS records to Front Door)
- frontDoorDnsZoneName (optional; Azure DNS zone name when DNS reconciliation is enabled)
- frontDoorEnableGeoAllowList (optional; enables country allow-list block rule)
- frontDoorAllowedCountries (optional; array of allowed country codes)
- frontDoorEnableApiUserAgentBlock (optional; enables API-only user-agent blocking rule)
- frontDoorBlockedApiUserAgents (optional; array of blocked user-agent substrings)
The passwordless API connection string is computed from the provisioned SQL
server/database and exposed as the apiConnectionString deployment output
(alongside sqlServerFqdn and sqlDatabaseName). The contained database users
for the app/slot/deploy identities are created by an in-template deployment
script that runs as the SQL Entra admin identity.
Automated runtime configuration:
- API and Web app settings are declared in Bicep and applied during az deployment group create.
- Slot workflow applies the same settings to staging slots.
- No separate az webapp config appsettings set step is required.
The infrastructure project is in src/LearningBank.Infrastructure and implements persistence and data access for domain contracts using Entity Framework Core.
- Configure EF Core DbContext and entity mappings.
- Implement domain repository interfaces.
- Manage database provider selection by configuration.
- Expose a single DI extension for the API host.
- Hold EF migrations.
Infrastructure depends on:
- LearningBank.Domain (entities and repository interfaces)
- EF Core provider packages
Infrastructure is consumed by:
- LearningBank.Api via AddInfrastructure
File: src/LearningBank.Infrastructure/InfrastructureServiceExtensions.cs
AddInfrastructure reads Database:Provider and configures DbContext:
- SqlServer provider when Database:Provider is SqlServer
- Sqlite provider otherwise
Default Sqlite connection string:
- Data Source=App_Data/learningbank.dev.db
Repositories registered as scoped services:
- UnitOfWork
- UserRepository
- TransactionRepository
- CategoryRepository
- TransferRequestRepository
- LearningTaskRepository
- AuditLogRepository
File: src/LearningBank.Infrastructure/Data/LearningBankDbContext.cs
DbSets:
- Users
- ChildLinks
- Categories
- Transactions
- TransferRequests
- LearningTasks
- TaskCompletions
- AuditLogs
Configuration strategy:
- ApplyConfigurationsFromAssembly to auto-load IEntityTypeConfiguration classes.
Location: src/LearningBank.Infrastructure/Data/Configurations
- Amount column type decimal(18,4)
- Description max length 500
- Child foreign key with cascade delete
- Category foreign key with restrict delete
- Indexes on child plus account and posted timestamp
Other configuration files:
- UserConfiguration
- ChildLinkConfiguration
- CategoryConfiguration
- TransferRequestConfiguration
- AuditLogConfiguration
Location: src/LearningBank.Infrastructure/Data/Migrations
Current migration set includes:
- InitialCreate migration and designer
- AddLearningTasks migration and designer
- AddTaskCategory migration and designer
- LearningBankDbContextModelSnapshot
Migration assembly is explicitly set to LearningBank.Infrastructure in provider options.
Location: src/LearningBank.Infrastructure/Repositories
Implemented repository classes:
- UserRepository
- TransactionRepository
- CategoryRepository
- TransferRequestRepository
- LearningTaskRepository
- AuditLogRepository
- UnitOfWork
Repository purpose:
- Translate domain repository contract calls into EF queries and writes.
- Keep API and domain free from EF-specific logic.
Local development:
- Uses Sqlite file under src/LearningBank.Api/App_Data when configured.
Production direction:
- Supports SqlServer provider switching through configuration.
Startup behavior:
- API applies migrations at startup only in Development.
- Production migrations are expected to run through deployment workflows.
- Postgres provider branch is not yet implemented in AddInfrastructure.
- There are no infrastructure-level integration tests yet.
- Performance profiling and query-level metrics are not yet documented.
When adding new persistence features:
- Add domain contract changes first in LearningBank.Domain.
- Implement repository method in LearningBank.Infrastructure.
- Add or update EF configuration for new fields and indexes.
- Create migration and validate startup migration path.
- Add integration tests for non-trivial query behavior.