{"id":31542088,"url":"https://github.com/a0s21en5/two-tier-user-management-api","last_synced_at":"2026-04-12T02:36:01.396Z","repository":{"id":313239148,"uuid":"1050634056","full_name":"a0s21en5/two-tier-user-management-api","owner":"a0s21en5","description":"A modern ASP.NET Core Web API demonstrating two-tier architecture with CQRS, MediatR, Dapper ORM, and SQL Server for comprehensive user management.","archived":false,"fork":false,"pushed_at":"2025-09-09T03:55:07.000Z","size":5439,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-04T11:41:51.406Z","etag":null,"topics":["aspnet-core","containerization-with-docker","cqrs","dapper","docker","dotnet9","fluentvalidation","mediatr","rest-api","sql-server","two-tier-architecture","web-api"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/a0s21en5.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-04T17:54:35.000Z","updated_at":"2025-09-09T03:55:10.000Z","dependencies_parsed_at":"2025-09-04T19:34:41.604Z","dependency_job_id":"977e5cd4-6d02-41a4-9abb-78488fe485e3","html_url":"https://github.com/a0s21en5/two-tier-user-management-api","commit_stats":null,"previous_names":["a0s21en5/two-tier-user-management-api"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/a0s21en5/two-tier-user-management-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a0s21en5%2Ftwo-tier-user-management-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a0s21en5%2Ftwo-tier-user-management-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a0s21en5%2Ftwo-tier-user-management-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a0s21en5%2Ftwo-tier-user-management-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/a0s21en5","download_url":"https://codeload.github.com/a0s21en5/two-tier-user-management-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/a0s21en5%2Ftwo-tier-user-management-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31702580,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-11T21:17:31.016Z","status":"online","status_checked_at":"2026-04-12T02:00:06.763Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aspnet-core","containerization-with-docker","cqrs","dapper","docker","dotnet9","fluentvalidation","mediatr","rest-api","sql-server","two-tier-architecture","web-api"],"created_at":"2025-10-04T11:30:14.063Z","updated_at":"2026-04-12T02:36:01.382Z","avatar_url":"https://github.com/a0s21en5.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Two-Tier Web Application\n\nA modern ASP.NET Core Web API application demonstrating a two-tier architecture with comprehensive user management functionality using CQRS pattern, MediatR, Dapper ORM, and SQL Server.\n\n## 🏗️ Architecture\n\nThis application follows a **two-tier architecture**:\n- **Presentation Tier**: ASP.NET Core Web API with RESTful endpoints\n- **Data Tier**: SQL Server database with optimized data access using Dapper\n\n### Design Patterns \u0026 Technologies\n\n- **CQRS (Command Query Responsibility Segregation)** with MediatR\n- **Repository Pattern** with Dapper ORM\n- **Validation** using FluentValidation\n- **Dependency Injection** with built-in ASP.NET Core DI container\n- **OpenAPI/Swagger** documentation\n- **Docker** containerization support\n\n## 🚀 Features\n\n### User Management\n- ✅ Create new users\n- ✅ Retrieve all active users\n- ✅ Get user by ID\n- ✅ Search users by email\n- ✅ Update existing users\n- ✅ Soft delete users\n- ✅ Input validation with detailed error messages\n\n### Technical Features\n- 🔄 Automatic database initialization\n- 📊 Comprehensive API documentation with Swagger UI\n- 🐳 Docker containerization\n- 🛡️ Input validation and error handling\n- 📈 Performance optimized with database indexing\n- 🔍 Search functionality\n- 📝 Structured logging\n\n## 🛠️ Technology Stack\n\n### **Core Framework**\n- **🎯 .NET 9.0** - Latest Microsoft development platform\n- **🌐 ASP.NET Core** - Cross-platform web framework\n\n### **Data \u0026 Persistence**\n- **🏗️ Dapper 2.1.35** - Lightweight, high-performance ORM\n- **🗄️ SQL Server 2022** - Enterprise-grade relational database\n- **📊 Microsoft.Data.SqlClient 5.2.2** - Modern SQL Server connectivity\n\n### **Architecture \u0026 Patterns**\n- **📡 MediatR 12.4.1** - CQRS and Mediator pattern implementation\n- **✅ FluentValidation 11.10.0** - Fluent interface for validation rules\n\n### **API \u0026 Documentation**\n- **📖 Swashbuckle.AspNetCore 7.2.0** - OpenAPI/Swagger documentation\n- **🔧 Microsoft.AspNetCore.OpenApi 9.0.8** - OpenAPI specification support\n\n### **Development \u0026 Deployment**\n- **🐳 Docker** - Containerization platform\n- **🔨 Visual Studio Code** - Recommended IDE with REST Client extension\n- **⚙️ PowerShell** - Windows development environment\n\n## 📋 Prerequisites\n\n- [.NET 9.0 SDK](https://dotnet.microsoft.com/download/dotnet/9.0)\n- [SQL Server](https://www.microsoft.com/en-us/sql-server/sql-server-downloads) (or Docker container)\n- [Docker](https://www.docker.com/get-started) (optional, for containerization)\n\n## 🚀 Getting Started\n\n### 1. Clone the Repository\n\n```bash\ngit clone https://github.com/a0s21en5/two-tier-user-management-api.git\ncd two-tier-web-app\n```\n\n### 2. Choose Your Setup Method\n\nYou can run this application using either .NET CLI or Docker. Choose the method that best fits your environment:\n\n#### Option A: Local Development (.NET CLI)\n\n1. **Database Setup**: Ensure SQL Server is running locally and update the connection string in `appsettings.json`:\n   ```json\n   {\n     \"ConnectionStrings\": {\n       \"DefaultConnection\": \"Server=localhost;Database=TwoTierWebAppDB;User Id=sa;Password=your-password;TrustServerCertificate=True;MultipleActiveResultSets=true;\"\n     }\n   }\n   ```\n\n2. **Run the Application**:\n   ```bash\n   dotnet restore\n   dotnet build\n   dotnet run\n   ```\n\n#### Option B: Full Docker Setup (Recommended)\n\n1. **Create Docker Network**:\n   ```bash\n   docker network create -d bridge two-tier\n   ```\n\n2. **Start SQL Server Container**:\n   ```bash\n   docker run -d --name sqlserver2022 --network two-tier \\\n     -e \"ACCEPT_EULA=Y\" \\\n     -e \"MSSQL_SA_PASSWORD=Obito#9775\" \\\n     mcr.microsoft.com/mssql/server:2022-latest\n   ```\n\n3. **Build and Run Application**:\n   ```bash\n   docker build -t two-tier-backend:v1 .\n   docker run -d -p 5000:5000 --network two-tier two-tier-backend:v1\n   ```\n\n### 3. Access the Application\n\nOnce running, you can access the application at:\n\n- **🌐 API Base URL**: `http://localhost:5000`\n- **📖 Swagger UI**: `http://localhost:5000/swagger`\n- **📋 OpenAPI Spec**: `http://localhost:5000/swagger/v1/swagger.json`\n\n\u003e **Note**: The application runs on HTTP port 5000 when using Docker. For local development with .NET CLI, both HTTP (5000) and HTTPS (5001) are available.\n\n## 📚 API Documentation\n\n### 🔗 API Endpoints\n\nThe application provides a RESTful API for user management operations:\n\n| Method | Endpoint | Description | Status Codes |\n|--------|----------|-------------|--------------|\n| 🟢 GET | `/api/users` | Retrieve all active users | 200 |\n| 🟢 GET | `/api/users/{id}` | Get user by ID | 200, 400, 404 |\n| 🔍 GET | `/api/users/search?email={email}` | Search users by email | 200, 400 |\n| ✅ POST | `/api/users` | Create a new user | 201, 400, 500 |\n| 🔄 PUT | `/api/users/{id}` | Update existing user | 204, 400, 404, 500 |\n| ❌ DELETE | `/api/users/{id}` | Soft delete user | 204, 400, 404, 500 |\n\n### 📝 Example API Calls\n\n#### Create User\n```http\nPOST /api/users\nContent-Type: application/json\n\n{\n  \"firstName\": \"John\",\n  \"lastName\": \"Doe\",\n  \"email\": \"john.doe@example.com\",\n  \"phone\": \"+1234567890\"\n}\n```\n\n**Response** (201 Created):\n```json\n3\n```\n\n#### Get All Users\n```http\nGET /api/users\n```\n\n**Response** (200 OK):\n```json\n[\n  {\n    \"id\": 1,\n    \"firstName\": \"John\",\n    \"lastName\": \"Doe\",\n    \"email\": \"john.doe@example.com\",\n    \"phone\": \"+1234567890\",\n    \"createdDate\": \"2025-09-04T10:30:00Z\",\n    \"updatedDate\": null,\n    \"isActive\": true\n  },\n  {\n    \"id\": 2,\n    \"firstName\": \"Jane\",\n    \"lastName\": \"Smith\",\n    \"email\": \"jane.smith@example.com\",\n    \"phone\": \"+1987654321\",\n    \"createdDate\": \"2025-09-04T11:15:00Z\",\n    \"updatedDate\": \"2025-09-04T12:00:00Z\",\n    \"isActive\": true\n  }\n]\n```\n\n#### Get User by ID\n```http\nGET /api/users/1\n```\n\n**Response** (200 OK):\n```json\n{\n  \"id\": 1,\n  \"firstName\": \"John\",\n  \"lastName\": \"Doe\",\n  \"email\": \"john.doe@example.com\",\n  \"phone\": \"+1234567890\",\n  \"createdDate\": \"2025-09-04T10:30:00Z\",\n  \"updatedDate\": null,\n  \"isActive\": true\n}\n```\n\n#### Search Users by Email\n```http\nGET /api/users/search?email=john\n```\n\n#### Update User\n```http\nPUT /api/users/1\nContent-Type: application/json\n\n{\n  \"id\": 1,\n  \"firstName\": \"John\",\n  \"lastName\": \"Smith\",\n  \"email\": \"john.smith@example.com\",\n  \"phone\": \"+1234567890\"\n}\n```\n\n**Response** (204 No Content)\n\n#### Delete User\n```http\nDELETE /api/users/1\n```\n\n**Response** (204 No Content)\n\n### 🔧 Testing the API\n\n1. **Swagger UI**: Navigate to `http://localhost:5000/swagger` for interactive testing\n2. **HTTP Files**: Use the provided `.http` files in VS Code with REST Client extension\n3. **Postman**: Import the API endpoints using the OpenAPI specification\n4. **cURL**: Use command-line tools for testing\n\n### 🛡️ Error Responses\n\nThe API returns consistent error responses:\n\n```json\n{\n  \"errors\": [\n    \"FirstName is required\",\n    \"Email must be a valid email address\"\n  ]\n}\n```\n\nCommon HTTP status codes:\n- **200**: Success\n- **201**: Created\n- **204**: No Content (successful update/delete)\n- **400**: Bad Request (validation errors)\n- **404**: Not Found\n- **500**: Internal Server Error\n\n## 🗂️ Project Structure\n\n```\ntwo-tier-web-app/\n├── 📁 Controllers/\n│   └── 📄 UsersController.cs          # REST API endpoints and HTTP request handling\n├── 📁 Features/                       # CQRS implementation\n│   └── 📁 Users/\n│       ├── 📁 Commands/               # Write operations (Create, Update, Delete)\n│       ├── 📁 Queries/                # Read operations (Get, Search)\n│       └── 📁 Validators/             # FluentValidation rules for requests\n├── 📁 Infrastructure/                 # Core infrastructure services\n│   ├── 📄 DatabaseInitializer.cs     # Automatic database setup and seeding\n│   └── 📄 DbConnectionFactory.cs     # Database connection management\n├── 📁 Models/                         # Data models and DTOs\n│   └── 📄 User.cs                     # User entity and request/response models\n├── 📁 Database/                       # Database scripts\n│   └── 📄 CreateDatabase.sql          # Database schema and sample data\n├── 📁 Properties/                     # Application configuration\n│   └── 📄 launchSettings.json         # Development server settings\n├── 📄 Program.cs                      # Application entry point and service configuration\n├── 📄 Dockerfile                      # Container configuration\n├── 📄 appsettings.json               # Application configuration\n├── 📄 appsettings.Development.json   # Development environment settings\n├── 📄 appsettings.Production.json    # Production environment settings\n└── 📄 *.http                         # HTTP test files for API testing\n```\n\n### 🏛️ Architecture Layers\n\n#### **Presentation Layer**\n- **Controllers**: Handle HTTP requests and responses\n- **Validation**: Input validation using FluentValidation\n\n#### **Application Layer** \n- **Commands**: Handle write operations (CQRS)\n- **Queries**: Handle read operations (CQRS)\n- **MediatR**: Decouples request handling\n\n#### **Infrastructure Layer**\n- **Database**: SQL Server with Dapper ORM\n- **Connection Management**: Factory pattern for database connections\n\n#### **Domain Layer**\n- **Models**: Core business entities and DTOs\n\n## 🔧 Configuration\n\n### Environment-Specific Settings\n\nThe application supports multiple environments with specific configuration files:\n\n- `appsettings.json` - Base configuration\n- `appsettings.Development.json` - Development environment\n- `appsettings.Production.json` - Production environment\n\n### Key Configuration Options\n\n```json\n{\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Your SQL Server connection string\"\n  },\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  }\n}\n```\n\n## 🧪 Testing\n\n### **Included Test Files**\n\nThe project includes HTTP test files for comprehensive API testing:\n\n- **📁 `two-tier-web-app.http`** - General API endpoint tests\n- **📁 `two-tier-web-app-api.http`** - Specific user management scenarios\n\n### **Testing Tools \u0026 Methods**\n\n#### **1. VS Code REST Client** (Recommended)\n- Install the \"REST Client\" extension in VS Code\n- Open any `.http` file and click \"Send Request\" above each HTTP call\n- View responses directly in VS Code\n\n#### **2. Swagger UI** (Interactive)\n- Navigate to `http://localhost:5000/swagger`\n- Test all endpoints with an interactive interface\n- View request/response schemas and examples\n\n#### **3. Postman/Insomnia**\n- Import the OpenAPI specification: `http://localhost:5000/swagger/v1/swagger.json`\n- Automatically generate a complete collection of API calls\n\n#### **4. cURL Command Line**\n```bash\n# Test API health\ncurl -X GET \"http://localhost:5000/api/users\"\n\n# Create a new user\ncurl -X POST \"http://localhost:5000/api/users\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"firstName\": \"Test\",\n    \"lastName\": \"User\",\n    \"email\": \"test@example.com\",\n    \"phone\": \"+1234567890\"\n  }'\n```\n\n### **Test Scenarios Covered**\n\n✅ **CRUD Operations**\n- Create new users with valid data\n- Retrieve all users\n- Get specific users by ID\n- Update existing user information  \n- Soft delete users\n\n✅ **Validation Testing**\n- Required field validation\n- Email format validation\n- Input length constraints\n- Invalid ID handling\n\n✅ **Error Handling**\n- Non-existent user lookup\n- Invalid request formats\n- Server error scenarios\n\n### **Sample Test Data**\n\nThe database initializes with sample users for immediate testing:\n- John Doe (john.doe@example.com)\n- Jane Smith (jane.smith@example.com)\n- Bob Johnson (bob.johnson@example.com)\n- Alice Brown (alice.brown@example.com)\n- Charlie Wilson (charlie.wilson@example.com)\n\n## 🐳 Docker Support\n\n### Network Architecture\n\nThe Docker setup uses a custom bridge network to enable communication between containers:\n\n```\n┌─────────────────────────────────────┐\n│           two-tier network          │\n│                                     │\n│  ┌─────────────────┐ ┌────────────┐ │\n│  │  sqlserver2022  │ │ web-app    │ │\n│  │  (SQL Server)   │ │ (Backend)  │ │\n│  │  Port: 1433     │ │ Port: 5000 │ │\n│  └─────────────────┘ └────────────┘ │\n│                                     │\n└─────────────────────────────────────┘\n```\n\n### Container Management\n\n#### View Running Containers\n```bash\ndocker ps\n```\n\n#### Check Application Logs\n```bash\n# Get container ID first\ndocker ps\n\n# View logs\ndocker logs \u003ccontainer-id\u003e\n\n# Follow logs in real-time\ndocker logs -f \u003ccontainer-id\u003e\n```\n\n#### Stop and Clean Up\n```bash\n# Stop containers\ndocker stop sqlserver2022 \u003cweb-app-container-id\u003e\n\n# Remove containers\ndocker rm sqlserver2022 \u003cweb-app-container-id\u003e\n\n# Remove network\ndocker network rm two-tier\n\n# Remove image (optional)\ndocker rmi two-tier-backend:v1\n```\n\n### Alternative: Docker Compose\n\nFor easier management, create a `docker-compose.yml` file:\n\n```yaml\nversion: '3.8'\n\nnetworks:\n  two-tier:\n    driver: bridge\n\nservices:\n  sqlserver:\n    image: mcr.microsoft.com/mssql/server:2022-latest\n    container_name: sqlserver2022\n    environment:\n      - ACCEPT_EULA=Y\n      - MSSQL_SA_PASSWORD=Obito#9775\n    networks:\n      - two-tier\n    volumes:\n      - sqlserver_data:/var/opt/mssql\n    healthcheck:\n      test: [\"CMD-SHELL\", \"/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Obito#9775 -Q 'SELECT 1'\"]\n      interval: 30s\n      timeout: 10s\n      retries: 3\n\n  web-app:\n    build: .\n    container_name: two-tier-backend\n    ports:\n      - \"5000:5000\"\n    depends_on:\n      sqlserver:\n        condition: service_healthy\n    networks:\n      - two-tier\n    environment:\n      - ASPNETCORE_ENVIRONMENT=Production\n      - ConnectionStrings__DefaultConnection=Server=sqlserver2022,1433;Database=TwoTierWebAppDB;User Id=sa;Password=Obito#9775;TrustServerCertificate=True;MultipleActiveResultSets=true;\n\nvolumes:\n  sqlserver_data:\n```\n\n#### Using Docker Compose\n```bash\n# Start all services\ndocker-compose up -d\n\n# View logs\ndocker-compose logs -f\n\n# Stop all services\ndocker-compose down\n\n# Stop and remove volumes\ndocker-compose down -v\n```\n\n## 📊 Database Schema\n\n### Users Table\n\n| Column | Type | Description |\n|--------|------|-------------|\n| Id | INT IDENTITY | Primary key |\n| FirstName | NVARCHAR(50) | User's first name |\n| LastName | NVARCHAR(50) | User's last name |\n| Email | NVARCHAR(100) | User's email address |\n| Phone | NVARCHAR(20) | User's phone number |\n| CreatedDate | DATETIME2 | Record creation timestamp |\n| UpdatedDate | DATETIME2 | Last update timestamp |\n| IsActive | BIT | Soft delete flag |\n\n### Indexes\n- `IX_Users_Email` - Email lookup optimization\n- `IX_Users_IsActive` - Active users filtering\n- `IX_Users_CreatedDate` - Date-based queries\n\n## 🔍 Validation Rules\n\n### Create User Request\n- **FirstName**: Required, max 50 characters\n- **LastName**: Required, max 50 characters\n- **Email**: Required, valid email format, max 100 characters\n- **Phone**: Required, max 20 characters\n\n### Update User Request\n- **Id**: Required, must be positive integer\n- All fields from Create User Request\n\n## 🚀 Development\n\n### Adding New Features\n\n1. **Commands/Queries**: Add to `Features/Users/Commands` or `Features/Users/Queries`\n2. **Validation**: Add validators to `Features/Users/Validators`\n3. **API Endpoints**: Extend `UsersController`\n4. **Database Changes**: Update `CreateDatabase.sql` and `DatabaseInitializer`\n\n### Best Practices\n\n- Follow CQRS pattern for separation of concerns\n- Use FluentValidation for input validation\n- Implement proper error handling and logging\n- Write comprehensive API documentation\n- Use async/await for database operations\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## 📝 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 📞 Support\n\nFor support and questions:\n- Create an issue in the repository\n- Contact the development team\n\n---\n\n**Happy Coding! 🎉**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa0s21en5%2Ftwo-tier-user-management-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fa0s21en5%2Ftwo-tier-user-management-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fa0s21en5%2Ftwo-tier-user-management-api/lists"}