The intelligent command center of the TenderTool ecosystem! π§ This .NET 8 Web API serves as the central orchestration hub, seamlessly connecting users to South Africa's most comprehensive tender intelligence platform. Deployed as a serverless AWS Lambda function, it's the secure, scalable brain that powers every user interaction and business decision.
- β¨ Key Features
- π§ Architecture: The "Central Hub"
- π§ Core Responsibilities
- π§© Project Structure
- π¦ Tech Stack
- βοΈ Configuration (Critical)
- π Security: API Gateway & IAM
- ποΈ Database: EF Core & Migrations
- π Getting Started (Local Development)
- π¦ Deployment (CI/CD)
- π§° Troubleshooting & Team Gotchas
- π― Centralized Business Logic: The single source of truth for all user operations, watchlist management, and tender intelligence delivery
- π¨ Service Orchestration Maestro: Conducts a symphony of microservices (Mailer, Analytics, Logging) with precision and security
- π Fort Knox Security: VPC-native deployment with enterprise-grade security through API Gateway and IAM authorization
- β‘ Lightning-Fast Serverless: .NET 8 Lambda function that scales instantly from zero to thousands of users
- π‘οΈ Secure by Design: Every endpoint protected by Amazon API Gateway with military-grade IAM security
- π DevOps Excellence: Automated CI/CD pipeline ensures flawless deployments with zero downtime
Our API is the mission control center that connects users to the entire tender intelligence ecosystem! π
React Frontend (AWS Amplify + Cognito)
β [IAM Signed Requests]
Amazon API Gateway (IAM Auth)
β [Proxies Securely]
π§ Lambda: Core Logic API (This Project)
ββ π Reads/Writes β Amazon RDS (MS SQL Server)
ββ π§ Invokes β Lambda: Mailer Function
ββ π Invokes β Lambda: Logging Function
ββ π Invokes β Lambda: Analytics Function
π― The Intelligence Flow:
- Users authenticate through Cognito-powered frontend
- All requests flow through our secure API Gateway fortress
- Our .NET 8 Lambda processes business logic with lightning speed
- Data flows seamlessly between our RDS database and supporting microservices
This powerhouse is organized as a modern ASP.NET Core Web API with specialized controllers for maximum efficiency:
GET /api/tendersπ Delivers paginated lists of live opportunitiesGET /api/tenders/{id}π Provides comprehensive tender details and specificationsGET /api/tenders/searchπ― Powers intelligent search with keywords, tags, sources, and advanced filters
GET /api/watchlistπ Retrieves user's curated opportunity portfolioPOST /api/watchlist/{tenderId}β Adds high-value opportunities to personal trackerDELETE /api/watchlist/{tenderId}ποΈ Removes opportunities from surveillance
GET /api/user/profileπ Fetches comprehensive user profile and preferencesPUT /api/user/profileβοΈ Updates user information and notification settings
GET /api/admin/logsπ Triggers advanced logging intelligence via Logging FunctionGET /api/admin/analyticsπ Activates comprehensive system analytics via Analytics Function
Internal orchestration service that triggers the Mailer Function for:
- New opportunities matching user watchlists
- Deadline proximity alerts
- System notifications and updates
Tender_Tool_Core_Logic/
βββ Controllers/
β βββ TendersController.cs # π― Opportunity discovery & search engine
β βββ WatchlistController.cs # β Personal portfolio management
β βββ UserController.cs # π€ Profile & preferences hub
β βββ AdminController.cs # π¦Έ Super user command center
βββ Data/
β βββ ApplicationDbContext.cs # ποΈ Master EF Core database context
βββ Models/
β βββ DTOs/ # π¦ API response objects
β β βββ TenderDetailsDto.cs # π Comprehensive tender information
β β βββ UserProfileDto.cs # π€ User profile data structures
β β βββ SearchResultDto.cs # π Search response formatting
β βββ Output/ # ποΈ EF Core database entities
β βββ BaseTender.cs # π Core tender structure
β βββ Tag.cs # π·οΈ AI-generated categorization
β βββ UserWatchlist.cs # β Personal opportunity tracking
βββ Services/
β βββ TenderSearchService.cs # π Advanced search & filtering logic
β βββ WatchlistService.cs # β Personal portfolio operations
β βββ NotificationService.cs # π§ Communication orchestration
βββ Program.cs # π Application bootstrap & DI setup
βββ aws-lambda-tools-defaults.json # βοΈ Deployment configuration
βββ README.md # π This comprehensive guide
- ποΈ Runtime: .NET 8 (LTS) - Latest long-term support for maximum stability
- π Framework: ASP.NET Core Web API - Enterprise-grade web framework
- βοΈ Compute: AWS Lambda - Serverless scalability and cost efficiency
- π API: Amazon API Gateway (REST API) - Secure, managed API layer
- π Security: AWS IAM Authorization - Military-grade request signing
- ποΈ Database: Amazon RDS (MS SQL Server) - Managed, scalable data storage
- π Data Access: Entity Framework Core 8 - Modern ORM with LINQ support
- π Deployment: GitHub Actions - Automated CI/CD pipeline excellence
| Variable Name | Required | Description | Example Value |
|---|---|---|---|
DB_CONNECTION_STRING |
β Yes | SQL Server connection to RDS database | Server=tender-db.cluster-xxx.rds.amazonaws.com;Database=TenderTool;... |
MAILER_FUNCTION_ARN |
β Yes | ARN for email notification service | arn:aws:lambda:us-east-1:123456789:function:TenderMailer |
LOGGING_FUNCTION_ARN |
β Yes | ARN for advanced logging service | arn:aws:lambda:us-east-1:123456789:function:TenderLogger |
ANALYTICS_FUNCTION_ARN |
β Yes | ARN for business intelligence service | arn:aws:lambda:us-east-1:123456789:function:TenderAnalytics |
π‘ Pro Tip: Store sensitive configurations in AWS Secrets Manager for maximum security!
Our security architecture is built like a digital fortress! π°
- π Authentication: Users authenticate via AWS Cognito in the React/Amplify frontend
- βοΈ Request Signing: Amplify automatically signs all API requests with AWS IAM signatures
- π Gateway Validation: API Gateway validates IAM signatures before processing
- β Trusted Execution: Lambda receives only verified, authenticated requests
- π€ User Context: User details flow securely through request context
π― Security Benefits:
- Zero exposed API keys or passwords
- Automatic request authentication
- Industry-standard AWS IAM security
- Complete audit trail of all requests
We are the database schema owners and migration masters! ποΈ
# Create new migration
dotnet ef migrations add FeatureName --context ApplicationDbContext
# Apply migrations to database
dotnet ef database update --context ApplicationDbContext
# Generate SQL scripts for production
dotnet ef migrations script --context ApplicationDbContext- Lambda IAM role has read/write only permissions (no DDL)
- Database connection uses dedicated service account
- Migrations applied through secure bastion or local development
- Production deployments use pre-generated SQL scripts
Ready to dive into the central command? Let's power up your development environment! π₯
- .NET 8 SDK π οΈ
- AWS CLI configured with appropriate credentials π
- Access to development database connection string ποΈ
- Your favorite IDE (Visual Studio 2022 recommended) π»
-
π Clone & Navigate
git clone <repository-url> cd Tender_Tool_Core_Logic
-
π¦ Restore Dependencies
dotnet restore
-
π Configure Secrets
dotnet user-secrets init dotnet user-secrets set "ConnectionStrings:DefaultConnection" "your-dev-db-connection" dotnet user-secrets set "MailerFunctionArn" "your-dev-mailer-arn" dotnet user-secrets set "LoggingFunctionArn" "your-dev-logging-arn" dotnet user-secrets set "AnalyticsFunctionArn" "your-dev-analytics-arn"
-
π Launch Development Server
dotnet watch run
-
π§ͺ Test Your Setup Navigate to
https://localhost:7001/swaggerfor interactive API documentation!
- Temporarily disable
[Authorize]attributes for local testing - Use Postman with AWS Signature v4 for realistic request signing
- Monitor logs in console for debugging information
This ASP.NET Core Lambda function can be deployed using three different methods. Choose the one that best fits your workflow and requirements.
Before deploying, ensure you have:
- .NET 8 SDK installed
- AWS CLI configured with appropriate credentials
- SQL Server RDS instance running and accessible
- Required environment variables configured (see Configuration section)
- IAM permissions for Lambda execution and API Gateway
Deploy directly from your IDE using the AWS Toolkit extension.
-
Install AWS Toolkit:
- Install the AWS Toolkit for Visual Studio from the Visual Studio Marketplace
-
Configure AWS Credentials:
- Ensure your AWS credentials are configured in Visual Studio
- Go to View β AWS Explorer and configure your profile
-
Deploy the Function:
- Right-click on the
Tender-Core-Logic.csprojproject - Select "Publish to AWS Lambda..."
- Choose "ASP.NET Core Web API" as the function blueprint
- Configure the deployment settings:
- Function Name:
TenderCoreLogicAPI - Runtime:
.NET 8 - Memory:
512 MB - Timeout:
30 seconds - Handler:
Tender-Core-Logic::Tender_Core_Logic.LambdaEntryPoint::FunctionHandlerAsync
- Function Name:
- Right-click on the
-
Configure API Gateway:
- The function will automatically create an API Gateway with
/{proxy+}and/routes - Both
ANYandOPTIONSmethods will be configured for CORS support - Note the generated API Gateway URL for testing
- The function will automatically create an API Gateway with
-
Set Environment Variables:
DB_CONNECTION_STRING: Server=your-rds-endpoint,1433;Database=TenderTool;User Id=admin;Password=YOUR_PASSWORD;Encrypt=True;TrustServerCertificate=True MAILER_FUNCTION_ARN: arn:aws:lambda:us-east-1:123456789:function:TenderMailer LOGGING_FUNCTION_ARN: arn:aws:lambda:us-east-1:123456789:function:TenderLogger ANALYTICS_FUNCTION_ARN: arn:aws:lambda:us-east-1:123456789:function:TenderAnalytics
-
Install AWS Toolkit:
- Install the AWS Toolkit extension for VS Code
-
Open Command Palette:
- Press
Ctrl+Shift+P(Windows/Linux) orCmd+Shift+P(Mac) - Type "AWS: Deploy SAM Application"
- Press
-
Follow the deployment wizard to configure and deploy your function
Deploy using AWS SAM CLI with the provided serverless template.
# For Windows (using Chocolatey)
choco install aws-sam-cli
# For macOS (using Homebrew)
brew install aws-sam-cli
# For Linux (using pip)
pip install aws-sam-clidotnet tool install -g Amazon.Lambda.Toolscd Tender-Core-Logic/src/Tender-Core-LogicCreate a parameters.json file for environment variables:
{
"DBConnectionString": "Server=your-rds-endpoint,1433;Database=TenderTool;User Id=admin;Password=YOUR_PASSWORD;Encrypt=True;TrustServerCertificate=True",
"MailerFunctionArn": "arn:aws:lambda:us-east-1:123456789:function:TenderMailer",
"LoggingFunctionArn": "arn:aws:lambda:us-east-1:123456789:function:TenderLogger",
"AnalyticsFunctionArn": "arn:aws:lambda:us-east-1:123456789:function:TenderAnalytics"
}# Build the project
dotnet restore
dotnet build -c Release
# Package the Lambda function (ASP.NET Core style)
dotnet lambda package -c Release -o ./lambda-package.zip Tender-Core-Logic.csproj
# Deploy using SAM with guided setup
sam deploy --template-file serverless.template \
--stack-name tender-core-logic-api-stack \
--capabilities CAPABILITY_IAM \
--guidedFor subsequent deployments after initial setup:
sam deploy --template-file serverless.template \
--stack-name tender-core-logic-api-stack \
--capabilities CAPABILITY_IAM \
--parameter-overrides \
DBConnectionString="Server=your-rds-endpoint,1433;Database=TenderTool;User Id=admin;Password=YOUR_PASSWORD;Encrypt=True;TrustServerCertificate=True" \
MailerFunctionArn="arn:aws:lambda:us-east-1:123456789:function:TenderMailer" \
LoggingFunctionArn="arn:aws:lambda:us-east-1:123456789:function:TenderLogger" \
AnalyticsFunctionArn="arn:aws:lambda:us-east-1:123456789:function:TenderAnalytics"The serverless template includes AWSLambda_FullAccess policy. For production, consider using more restrictive permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"arn:aws:lambda:us-east-1:123456789:function:TenderMailer",
"arn:aws:lambda:us-east-1:123456789:function:TenderLogger",
"arn:aws:lambda:us-east-1:123456789:function:TenderAnalytics"
]
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}Deploy automatically using GitHub Actions when pushing to the release branch.
In your GitHub repository, go to Settings β Secrets and variables β Actions, and add:
AWS_ACCESS_KEY_ID: your-aws-access-key-id
AWS_SECRET_ACCESS_KEY: your-aws-secret-access-key
AWS_REGION: us-east-1
LAMBDA_FUNCTION_NAME: your-lambda-function-name
# Create and switch to release branch
git checkout -b release
# Make your changes and commit
git add .
git commit -m "Deploy Tender Core Logic API updates"
# Push to trigger deployment
git push origin release- Go to your repository's Actions tab
- Monitor the "Deploy Lambda on Release Merge" workflow
- Check the deployment logs for any issues
You can also trigger the deployment manually:
- Go to the Actions tab in your repository
- Select "Deploy Lambda on Release Merge"
- Click "Run workflow"
- Select the branch and click "Run workflow"
After deploying using any method, verify the deployment:
# Verify function exists and configuration
aws lambda get-function --function-name TenderCoreLogicAPI
# Check environment variables
aws lambda get-function-configuration --function-name TenderCoreLogicAPI# Get the API Gateway URL from CloudFormation outputs
aws cloudformation describe-stacks --stack-name tender-core-logic-api-stack --query 'Stacks[0].Outputs'
# Test the health check endpoint
curl -X GET https://your-api-gateway-url.execute-api.us-east-1.amazonaws.com/Prod/
# Test API endpoints (requires proper IAM signing)
curl -X GET https://your-api-gateway-url.execute-api.us-east-1.amazonaws.com/Prod/api/tenders \
--aws-sigv4 "aws:amz:us-east-1:execute-api" \
--user "your-access-key:your-secret-key"# Check CloudWatch logs for any connection issues
aws logs describe-log-groups --log-group-name-prefix "/aws/lambda/TenderCoreLogicAPI"
# View recent logs
aws logs tail "/aws/lambda/TenderCoreLogicAPI" --followConfigure these environment variables in your Lambda function:
| Variable | Value | Description |
|---|---|---|
DB_CONNECTION_STRING |
Server=your-rds-endpoint,1433;Database=TenderTool;User Id=admin;Password=YOUR_PASSWORD;Encrypt=True;TrustServerCertificate=True |
SQL Server connection string |
MAILER_FUNCTION_ARN |
arn:aws:lambda:us-east-1:123456789:function:TenderMailer |
ARN for email notification service |
LOGGING_FUNCTION_ARN |
arn:aws:lambda:us-east-1:123456789:function:TenderLogger |
ARN for advanced logging service |
ANALYTICS_FUNCTION_ARN |
arn:aws:lambda:us-east-1:123456789:function:TenderAnalytics |
ARN for business intelligence service |
Security Note: For production deployments, store sensitive configuration values in AWS Secrets Manager or Parameter Store instead of environment variables.
The deployment automatically creates an API Gateway with the following configuration:
- Base URL:
https://{api-id}.execute-api.us-east-1.amazonaws.com/Prod/ - API Endpoints:
GET/POST/PUT/DELETE /api/tenders- Tender managementGET/POST/DELETE /api/watchlist- Watchlist operationsGET/PUT /api/user/profile- User profile managementGET /api/admin/logs- Admin logging (super users only)GET /api/admin/analytics- Admin analytics (super users only)
The template includes OPTIONS methods for CORS support. Ensure your frontend is configured to handle CORS properly:
// Example frontend configuration
const API_CONFIG = {
endpoints: {
apiGateway: 'https://your-api-gateway-url.execute-api.us-east-1.amazonaws.com/Prod'
},
aws_api_gateway_method: 'ANY',
aws_api_gateway_path: '/{proxy+}'
};Since this is the central hub, you may need to run database migrations:
# Navigate to project directory
cd Tender-Core-Logic/src/Tender-Core-Logic
# Add new migration
dotnet ef migrations add YourMigrationName --context ApplicationDbContext
# Update database (development only)
dotnet ef database update --context ApplicationDbContext# Generate SQL script for production
dotnet ef migrations script --context ApplicationDbContext -o migration.sql
# Apply manually to production database via secure connectionFor production deployment, ensure proper IAM policies:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"arn:aws:lambda:*:*:function:TenderMailer",
"arn:aws:lambda:*:*:function:TenderLogger",
"arn:aws:lambda:*:*:function:TenderAnalytics"
]
}
]
}{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:123456789:*/*/api/*",
"Condition": {
"StringEquals": {
"aws:SourceIp": "your-allowed-ip-ranges"
}
}
}
]
}Build Failures:
- Ensure .NET 8 SDK is installed and available in PATH
- Verify all NuGet packages are restored successfully
- Check for any compilation errors in the project
Deployment Permission Errors:
- Verify AWS credentials have necessary permissions for Lambda, API Gateway, and IAM
- Check CloudFormation stack creation permissions
- Ensure S3 bucket access for deployment artifacts
Runtime Errors:
- Check CloudWatch logs for detailed error messages
- Verify environment variables are correctly set
- Test database connectivity from Lambda VPC
- Validate IAM permissions for invoking other Lambda functions
API Gateway Integration Issues:
- Verify proxy integration is correctly configured
- Check CORS settings if accessing from web frontend
- Ensure proper IAM authentication is configured
- Test API endpoints with proper AWS Signature v4 signing
Function Update Failures:
- Verify the function name matches between secrets and actual function
- Check that the ZIP file is properly formatted
- Ensure the function handler path is correct
- Validate Lambda runtime and architecture settings
π« ERROR: 403 Forbidden on All Requests
Issue: Every API call returns 403 Forbidden status.
Root Cause: IAM request signing is failing or missing required permissions.
π§ Fix Checklist:
- β
Verify Amplify app's authenticated role has
execute-api:Invokepermissions - β Check API Gateway ARN in IAM policy matches deployed API
- β Ensure requests are properly signed with AWS Signature v4
- β Validate user authentication status in Cognito
β° ERROR: 504 Gateway Timeout / Task Timed Out
Issue: API calls timing out after 30 seconds.
Root Cause: VPC networking issues preventing database connectivity.
π§ Network Diagnosis:
- Lambda Security Group: Outbound rule for port 1433 to RDS
- RDS Security Group: Inbound rule from Lambda security group
- VPC Configuration: Lambda and RDS in same VPC/subnets
- Route Tables: Proper routing between Lambda and RDS subnets
ποΈ ERROR: Database Connection Failures
Issue: EF Core cannot connect to SQL Server database.
Root Cause: Connection string or VPC configuration issues.
π§ Database Troubleshooting:
- β Verify connection string format and credentials
- β Test database connectivity from VPC bastion host
- β Check RDS instance status and security groups
- β Validate SQL Server authentication mode
π ERROR: Microservice Invocation Failures
Issue: Cannot invoke Mailer, Analytics, or Logging functions.
Root Cause: IAM permissions or function ARN configuration issues.
π§ Service Integration Fix:
- β
Verify Lambda execution role has
lambda:InvokeFunctionpermissions - β Check function ARNs in environment variables
- β Test function invocation from AWS Console
- β Review CloudWatch logs for detailed error messages
Built with love, bread, and code by Bread Corporation π¦β€οΈπ»