{"id":31542209,"url":"https://github.com/zienk/dev-blog","last_synced_at":"2026-04-09T02:01:55.234Z","repository":{"id":311564631,"uuid":"1044081289","full_name":"zienk/dev-blog","owner":"zienk","description":"A knowledge-sharing DevBlog for Vietnamese developers, focusing on hacking, new tech, and real-world coding experiences.","archived":false,"fork":false,"pushed_at":"2025-09-17T14:07:43.000Z","size":2074,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-07T20:47:26.299Z","etag":null,"topics":["angular","asp-net-core","clean-architecture","coreui-dashboard-template","csharp","dependency-injection","developer-blog","domain-driven-design","dotnet","entity-framework-core","jwt-auth","repository-pattern","restful-api","sqlserver","uow-pattern"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/zienk.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-08-25T06:48:18.000Z","updated_at":"2025-09-17T14:07:47.000Z","dependencies_parsed_at":"2025-09-17T16:10:04.105Z","dependency_job_id":"5276fc8f-d583-4620-a485-4f4f36d385d2","html_url":"https://github.com/zienk/dev-blog","commit_stats":null,"previous_names":["zienk/dev-blog"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zienk/dev-blog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zienk%2Fdev-blog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zienk%2Fdev-blog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zienk%2Fdev-blog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zienk%2Fdev-blog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zienk","download_url":"https://codeload.github.com/zienk/dev-blog/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zienk%2Fdev-blog/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31581864,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"online","status_checked_at":"2026-04-09T02:00:06.848Z","response_time":112,"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":["angular","asp-net-core","clean-architecture","coreui-dashboard-template","csharp","dependency-injection","developer-blog","domain-driven-design","dotnet","entity-framework-core","jwt-auth","repository-pattern","restful-api","sqlserver","uow-pattern"],"created_at":"2025-10-04T11:32:31.489Z","updated_at":"2026-04-09T02:01:55.227Z","avatar_url":"https://github.com/zienk.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DevBlog - Nền tảng chia sẻ kiến thức cho Developer Việt Nam 🚀\n\n[![.NET](https://img.shields.io/badge/.NET-8.0-512BD4?logo=dotnet)](https://dotnet.microsoft.com/)\n[![Angular](https://img.shields.io/badge/Angular-20.2-DD0031?logo=angular)](https://angular.io/)\n[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n\nMột nền tảng blog chuyên nghiệp được xây dựng để chia sẻ kiến thức về lập trình, công nghệ mới, và kinh nghiệm thực tế cho cộng đồng developer Việt Nam.\n\n## 📋 Mục lục\n\n- [Giới thiệu](#-giới-thiệu)\n- [Kiến trúc hệ thống](#-kiến-trúc-hệ-thống)\n- [Công nghệ sử dụng](#-công-nghệ-sử-dụng)\n- [Cấu trúc dự án](#-cấu-trúc-dự-án)\n- [Hướng dẫn cài đặt](#-hướng-dẫn-cài-đặt)\n- [Tính năng chính](#-tính-năng-chính)\n- [API Documentation](#-api-documentation)\n- [Database Schema](#-database-schema)\n- [Authentication \u0026 Authorization](#-authentication--authorization)\n- [Deployment](#-deployment)\n- [Contributing](#-contributing)\n- [Troubleshooting](#-troubleshooting)\n- [Tài liệu học tập](#-tài-liệu-học-tập)\n\n## 🎯 Giới thiệu\n\n**DevBlog** là một hệ thống blog được thiết kế theo kiến trúc **Clean Architecture** và **Domain-Driven Design (DDD)**, giúp developers Việt Nam:\n\n- 📝 **Chia sẻ kiến thức**: Viết và chia sẻ bài viết về công nghệ, kinh nghiệm lập trình\n- 🔍 **Học hỏi kinh nghiệm**: Tìm kiếm và học từ các bài viết chất lượng cao\n- 💬 **Tương tác cộng đồng**: Comment, thảo luận và networking với các developers khác\n- 🏆 **Xây dựng profile**: Tạo portfolio cá nhân thông qua các bài viết chất lượng\n\n### Tại sao chọn DevBlog?\n\n- ✅ **Kiến trúc sạch**: Clean Architecture giúp code dễ maintain và scale\n- ✅ **Performance cao**: Tối ưu hóa với caching, lazy loading\n- ✅ **Bảo mật**: JWT authentication, role-based authorization\n- ✅ **UI/UX hiện đại**: Angular + CoreUI cho trải nghiệm mượt mà\n- ✅ **API First**: RESTful API có thể tích hợp với mobile app\n\n## 🏗 Kiến trúc hệ thống\n\n### Clean Architecture Layers\n\n```\n┌─────────────────────────────────────────────────┐\n│                  Presentation                   │\n│          (Angular UI + WebApp MVC)              │\n├─────────────────────────────────────────────────┤\n│                   API Layer                     │\n│            (RESTful Web API)                    │\n├─────────────────────────────────────────────────┤\n│              Application Core                   │\n│        (Business Logic \u0026 Interfaces)            │\n├─────────────────────────────────────────────────┤\n│              Infrastructure                     │\n│    (Data Access, External Services)             │\n└─────────────────────────────────────────────────┘\n```\n\n### Giải thích các Layer:\n\n#### 1. **Presentation Layer** (Tầng giao diện)\n- **Angular Admin UI**: Giao diện quản trị sử dụng Angular 20 + CoreUI\n- **WebApp MVC**: Giao diện người dùng sử dụng ASP.NET Core MVC với Razor Pages\n\n#### 2. **API Layer** (Tầng API)\n- **RESTful API**: Cung cấp endpoints cho cả Admin và Public\n- **Authentication**: JWT Bearer token\n- **Authorization**: Policy-based với custom permissions\n\n#### 3. **Core Layer** (Tầng nghiệp vụ)\n- **Entities**: Domain models (Post, User, Category, etc.)\n- **Interfaces**: Repository patterns, Unit of Work\n- **Business Logic**: Services, Specifications\n- **DTOs**: Data Transfer Objects cho API\n\n#### 4. **Infrastructure Layer** (Tầng hạ tầng)\n- **Entity Framework Core**: ORM cho data access\n- **Identity**: ASP.NET Core Identity cho authentication\n- **External Services**: Email, File storage, etc.\n\n## 🛠 Công nghệ sử dụng\n\n### Backend (.NET 8)\n- **ASP.NET Core Web API**: RESTful API framework\n- **Entity Framework Core**: ORM với Code-First approach\n- **ASP.NET Core Identity**: Authentication \u0026 User management\n- **AutoMapper**: Object mapping\n- **FluentValidation**: Input validation\n- **Swagger/OpenAPI**: API documentation\n- **JWT Bearer**: Token-based authentication\n- **Serilog**: Structured logging\n\n### Frontend (Angular 20)\n- **Angular 20**: SPA framework\n- **CoreUI 5.5**: Admin template\n- **PrimeNG**: UI components library\n- **RxJS**: Reactive programming\n- **NgRx** (optional): State management\n- **Chart.js**: Data visualization\n- **NSwag**: TypeScript client generation từ OpenAPI\n\n### Database \u0026 Tools\n- **SQL Server**: Primary database\n- **Redis** (optional): Caching layer\n- **Docker**: Containerization\n- **GitHub Actions**: CI/CD pipeline\n\n## 📁 Cấu trúc dự án\n\n```\nDevBlog/\n├── src/                              # Source code chính\n│   ├── DevBlog.Api/                 # Web API project\n│   │   ├── Controllers/             # API Controllers\n│   │   │   ├── AdminApi/           # Admin endpoints\n│   │   │   └── PublicApi/          # Public endpoints\n│   │   ├── Services/                # API services (JWT, etc.)\n│   │   ├── Filters/                 # Action filters\n│   │   ├── Middleware/              # Custom middleware\n│   │   └── Program.cs               # Entry point\n│   │\n│   ├── DevBlog.Core/                # Core business logic\n│   │   ├── Entities/                # Domain entities\n│   │   │   ├── Blog/               # Blog-related entities\n│   │   │   └── Identity/           # User, Role entities\n│   │   ├── Models/                  # DTOs và ViewModels\n│   │   ├── Repositories/            # Repository interfaces\n│   │   ├── SeedWorks/              # Base classes, constants\n│   │   └── Specifications/          # Query specifications\n│   │\n│   ├── DevBlog.Infrastructure/     # Infrastructure implementation\n│   │   ├── Data/                   # DbContext, Migrations\n│   │   ├── Repositories/           # Repository implementations\n│   │   ├── Services/               # External service integrations\n│   │   └── Identity/               # Identity configuration\n│   │\n│   └── DevBlog.WebApp/             # MVC Web application\n│       ├── Controllers/            # MVC Controllers\n│       ├── Views/                  # Razor views\n│       ├── wwwroot/               # Static files\n│       └── Areas/                 # Area-based organization\n│\n├── dev-blog-admin-ui/              # Angular Admin UI\n│   ├── src/\n│   │   ├── app/                   # Angular application\n│   │   │   ├── api/              # Generated API clients\n│   │   │   ├── views/            # Page components\n│   │   │   ├── shared/           # Shared components\n│   │   │   └── core/             # Core services\n│   │   ├── assets/               # Images, fonts\n│   │   └── environments/         # Environment configs\n│   ├── angular.json              # Angular configuration\n│   └── package.json              # NPM dependencies\n│\n├── tests/                         # Unit \u0026 Integration tests\n│   ├── DevBlog.Api.Tests/\n│   ├── DevBlog.Core.Tests/\n│   └── DevBlog.Infrastructure.Tests/\n│\n├── docs/                          # Documentation\n├── scripts/                       # Build \u0026 deployment scripts\n├── DevBlog.sln                   # Solution file\n└── README.md                     # This file\n```\n\n## 🚀 Hướng dẫn cài đặt\n\n### Yêu cầu hệ thống\n\n- ✅ [.NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0)\n- ✅ [Node.js 20.x hoặc 22.x](https://nodejs.org/)\n- ✅ [SQL Server 2019+](https://www.microsoft.com/sql-server/) hoặc [SQL Server Express](https://www.microsoft.com/sql-server/sql-server-express)\n- ✅ [Visual Studio 2022](https://visualstudio.microsoft.com/) hoặc [VS Code](https://code.visualstudio.com/)\n- ✅ [Git](https://git-scm.com/)\n\n### Bước 1: Clone repository\n\n```bash\ngit clone https://github.com/yourusername/DevBlog.git\ncd DevBlog\n```\n\n### Bước 2: Cài đặt Backend\n\n#### 2.1. Cấu hình Database Connection\n\nMở file `appsettings.json` trong `src/DevBlog.Api/` và cập nhật connection string:\n\n```json\n{\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Server=localhost;Database=DevBlogDb;Trusted_Connection=true;TrustServerCertificate=true;\"\n  }\n}\n```\n\n#### 2.2. Chạy Database Migrations\n\n```bash\ncd src/DevBlog.Api\ndotnet ef database update\n```\n\n#### 2.3. Seed dữ liệu mẫu (optional)\n\n```bash\ndotnet run --seed\n```\n\n#### 2.4. Chạy API\n\n```bash\ndotnet run\n```\n\nAPI sẽ chạy tại: `https://localhost:7001` (hoặc port được configure)\n\n### Bước 3: Cài đặt Frontend (Angular Admin)\n\n#### 3.1. Cài đặt dependencies\n\n```bash\ncd dev-blog-admin-ui\nnpm install\n```\n\n#### 3.2. Generate API Client từ Swagger\n\n```bash\nnpm run nswag-admin\n```\n\n#### 3.3. Cấu hình API endpoint\n\nMở file `src/environments/environment.ts` và cập nhật:\n\n```typescript\nexport const environment = {\n  production: false,\n  apiUrl: 'https://localhost:7001'\n};\n```\n\n#### 3.4. Chạy Angular development server\n\n```bash\nnpm start\n```\n\nAdmin UI sẽ mở tại: `http://localhost:4200`\n\n### Bước 4: Chạy Web Application (optional)\n\n```bash\ncd src/DevBlog.WebApp\ndotnet run\n```\n\nWebApp sẽ chạy tại: `https://localhost:7002`\n\n## ⚡ Tính năng chính\n\n### 👤 User Management\n- Đăng ký/Đăng nhập với email confirmation\n- Quản lý profile và avatar\n- Password reset qua email\n- Two-factor authentication (2FA)\n\n### 📝 Blog Management\n- **CRUD Posts**: Tạo, sửa, xóa bài viết với rich text editor\n- **Categories**: Phân loại bài viết theo chủ đề\n- **Tags**: Gắn tag cho bài viết để dễ tìm kiếm\n- **Draft/Publish**: Lưu nháp và xuất bản bài viết\n- **SEO Optimization**: Meta tags, URL slug tự động\n\n### 💬 Interaction Features\n- Comment system với nested replies\n- Like/Bookmark bài viết\n- Share lên social media\n- Follow authors\n\n### 🔍 Search \u0026 Filter\n- Full-text search\n- Filter theo category, tag, author\n- Sort theo date, views, likes\n\n### 📊 Analytics (Admin)\n- Dashboard với charts\n- Post views tracking\n- User engagement metrics\n- Popular posts/categories\n\n### 🔐 Security Features\n- JWT token với refresh token\n- Role-based access control (RBAC)\n- Permission-based authorization\n- API rate limiting\n- XSS/CSRF protection\n\n## 📖 API Documentation\n\n### Authentication Flow\n\n#### 1. Login\n```http\nPOST /api/admin/auth\nContent-Type: application/json\n\n{\n  \"username\": \"admin@devblog.com\",\n  \"password\": \"Admin@123\"\n}\n```\n\nResponse:\n```json\n{\n  \"token\": \"eyJhbGciOiJIUzI1NiIs...\",\n  \"refreshToken\": \"fdb8fdbecf1d03ce5e6125c067733c0d51de209c...\",\n  \"expiresIn\": 3600\n}\n```\n\n#### 2. Use Token\n```http\nGET /api/admin/posts\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIs...\n```\n\n### Main API Endpoints\n\n| Method | Endpoint | Description | Auth Required |\n|--------|----------|-------------|---------------|\n| **Auth** |\n| POST | `/api/admin/auth` | Login | No |\n| POST | `/api/admin/token/refresh` | Refresh token | Yes |\n| POST | `/api/admin/token/revoke` | Logout | Yes |\n| **Posts** |\n| GET | `/api/posts` | Get public posts | No |\n| GET | `/api/posts/{id}` | Get post detail | No |\n| POST | `/api/admin/post` | Create post | Yes (Author) |\n| PUT | `/api/admin/post/{id}` | Update post | Yes (Author) |\n| DELETE | `/api/admin/post` | Delete posts | Yes (Admin) |\n| **Categories** |\n| GET | `/api/categories` | Get all categories | No |\n| POST | `/api/admin/post-category` | Create category | Yes (Admin) |\n| PUT | `/api/admin/post-category/{id}` | Update category | Yes (Admin) |\n| **Users** |\n| GET | `/api/admin/user/paging` | Get users list | Yes (Admin) |\n| POST | `/api/admin/user` | Create user | Yes (Admin) |\n| PUT | `/api/admin/user/{id}` | Update user | Yes (Admin) |\n| **Roles \u0026 Permissions** |\n| GET | `/api/admin/role/paging` | Get roles | Yes (Admin) |\n| POST | `/api/admin/role` | Create role | Yes (Admin) |\n| PUT | `/api/admin/role/permissions` | Update permissions | Yes (Admin) |\n\n### Swagger/OpenAPI\n\nKhi chạy API ở development mode, bạn có thể truy cập Swagger UI tại:\n```\nhttps://localhost:7001/swagger\n```\n\n## 🗄 Database Schema\n\n### Core Tables\n\n#### Users Table\n```sql\nCREATE TABLE Users (\n    Id UNIQUEIDENTIFIER PRIMARY KEY,\n    UserName NVARCHAR(256) NOT NULL,\n    Email NVARCHAR(256) NOT NULL,\n    FirstName NVARCHAR(100),\n    LastName NVARCHAR(100),\n    Avatar NVARCHAR(500),\n    IsActive BIT,\n    DateCreated DATETIME2,\n    -- ASP.NET Identity fields...\n)\n```\n\n#### Posts Table\n```sql\nCREATE TABLE Posts (\n    Id UNIQUEIDENTIFIER PRIMARY KEY,\n    Title NVARCHAR(500) NOT NULL,\n    Slug VARCHAR(500) NOT NULL UNIQUE,\n    Content NVARCHAR(MAX),\n    Description NVARCHAR(1000),\n    Thumbnail NVARCHAR(500),\n    CategoryId UNIQUEIDENTIFIER,\n    AuthorUserId UNIQUEIDENTIFIER,\n    ViewCount INT DEFAULT 0,\n    Status INT, -- Draft, Published, Archived\n    DateCreated DATETIME2,\n    DateModified DATETIME2,\n    FOREIGN KEY (CategoryId) REFERENCES PostCategories(Id),\n    FOREIGN KEY (AuthorUserId) REFERENCES Users(Id)\n)\n```\n\n#### PostCategories Table\n```sql\nCREATE TABLE PostCategories (\n    Id UNIQUEIDENTIFIER PRIMARY KEY,\n    Name NVARCHAR(250) NOT NULL,\n    Slug VARCHAR(250) NOT NULL UNIQUE,\n    ParentId UNIQUEIDENTIFIER NULL,\n    SeoDescription NVARCHAR(160),\n    SortOrder INT,\n    IsActive BIT,\n    DateCreated DATETIME2,\n    FOREIGN KEY (ParentId) REFERENCES PostCategories(Id)\n)\n```\n\n### Relationships\n\n```mermaid\nerDiagram\n    Users ||--o{ Posts : \"writes\"\n    Posts }o--|| PostCategories : \"belongs to\"\n    Posts ||--o{ PostTags : \"has\"\n    Tags ||--o{ PostTags : \"tagged in\"\n    Posts ||--o{ Comments : \"has\"\n    Users ||--o{ Comments : \"writes\"\n    Users ||--o{ UserRoles : \"has\"\n    Roles ||--o{ UserRoles : \"assigned to\"\n    Roles ||--o{ RoleClaims : \"has permissions\"\n```\n\n## 🔐 Authentication \u0026 Authorization\n\n### JWT Configuration\n\nTrong `appsettings.json`:\n\n```json\n{\n  \"JwtSettings\": {\n    \"SecretKey\": \"your-secret-key-min-32-characters-long\",\n    \"Issuer\": \"DevBlog\",\n    \"Audience\": \"DevBlogUsers\",\n    \"ExpiryMinutes\": 60\n  }\n}\n```\n\n### Permission System\n\nHệ thống sử dụng permission-based authorization với các permissions được định nghĩa trong `Permissions.cs`:\n\n```csharp\npublic static class Permissions\n{\n    public static class Posts\n    {\n        public const string View = \"Permissions.Posts.View\";\n        public const string Create = \"Permissions.Posts.Create\";\n        public const string Edit = \"Permissions.Posts.Edit\";\n        public const string Delete = \"Permissions.Posts.Delete\";\n    }\n    // More permissions...\n}\n```\n\n### Roles mặc định\n\n1. **Admin**: Full access\n2. **Editor**: Manage posts và categories\n3. **Author**: Create và edit own posts\n4. **User**: Read và comment\n\n## 🚢 Deployment\n\n### Docker Deployment\n\n#### 1. Build Docker images\n\n```bash\n# Build API image\ndocker build -f src/DevBlog.Api/Dockerfile -t devblog-api .\n\n# Build Angular image\ndocker build -f dev-blog-admin-ui/Dockerfile -t devblog-admin .\n```\n\n#### 2. Docker Compose\n\n```yaml\n# docker-compose.yml\nversion: '3.8'\n\nservices:\n  db:\n    image: mcr.microsoft.com/mssql/server:2019-latest\n    environment:\n      - ACCEPT_EULA=Y\n      - SA_PASSWORD=Your@Password123\n    ports:\n      - \"1433:1433\"\n    volumes:\n      - sql_data:/var/opt/mssql\n\n  api:\n    image: devblog-api\n    depends_on:\n      - db\n    environment:\n      - ConnectionStrings__DefaultConnection=Server=db;Database=DevBlogDb;User=sa;Password=Your@Password123;\n    ports:\n      - \"5000:80\"\n\n  admin:\n    image: devblog-admin\n    depends_on:\n      - api\n    ports:\n      - \"4200:80\"\n\nvolumes:\n  sql_data:\n```\n\n#### 3. Run với Docker Compose\n\n```bash\ndocker-compose up -d\n```\n\n### Azure Deployment\n\n1. **Azure SQL Database**: Tạo database trên Azure\n2. **Azure App Service**: Deploy API và WebApp\n3. **Azure Static Web Apps**: Deploy Angular SPA\n4. **Azure Blob Storage**: Lưu trữ images/files\n5. **Azure CDN**: Tối ưu static content delivery\n\n### CI/CD với GitHub Actions\n\n```yaml\n# .github/workflows/deploy.yml\nname: Deploy to Azure\n\non:\n  push:\n    branches: [main]\n\njobs:\n  build-and-deploy:\n    runs-on: ubuntu-latest\n    \n    steps:\n    - uses: actions/checkout@v2\n    \n    - name: Setup .NET\n      uses: actions/setup-dotnet@v1\n      with:\n        dotnet-version: '8.0.x'\n    \n    - name: Build and publish API\n      run: |\n        dotnet build\n        dotnet publish -c Release -o ./publish\n    \n    - name: Deploy to Azure App Service\n      uses: azure/webapps-deploy@v2\n      with:\n        app-name: 'devblog-api'\n        publish-profile: ${{ secrets.AZURE_PUBLISH_PROFILE }}\n        package: './publish'\n```\n\n## 🤝 Contributing\n\nChúng tôi luôn chào đón contributions từ cộng đồng!\n\n### Development Process\n\n1. Fork repository\n2. Tạo feature branch (`git checkout -b feature/AmazingFeature`)\n3. Commit changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to branch (`git push origin feature/AmazingFeature`)\n5. Tạo Pull Request\n\n### Coding Standards\n\n- **C# Code**: Follow [Microsoft C# Coding Conventions](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/inside-a-program/coding-conventions)\n- **TypeScript/Angular**: Follow [Angular Style Guide](https://angular.io/guide/styleguide)\n- **Git Commits**: Use [Conventional Commits](https://www.conventionalcommits.org/)\n\n### Testing\n\n```bash\n# Run backend tests\ndotnet test\n\n# Run frontend tests\ncd dev-blog-admin-ui\nnpm test\n\n# Run e2e tests\nnpm run e2e\n```\n\n## 🐛 Troubleshooting\n\n### Common Issues\n\n#### 1. Database connection failed\n- Kiểm tra SQL Server service đang chạy\n- Verify connection string trong appsettings.json\n- Ensure SQL Server authentication mode\n\n#### 2. CORS errors in Angular\n- Check CORS configuration trong Program.cs\n- Verify API URL trong environment.ts\n\n#### 3. JWT token invalid\n- Check token expiry time\n- Verify secret key configuration\n- Ensure clock sync between client/server\n\n#### 4. npm install fails\n- Clear npm cache: `npm cache clean --force`\n- Delete node_modules và package-lock.json\n- Run `npm install` again\n\n## 🗺️ Roadmap \u0026 Implementation Guide\n\n### Các tính năng sắp tới (Upcoming Features)\n\n#### Phase 1: Core Enhancements (Q1 2025)\n\n##### 1. 🔍 **Advanced Search với Elasticsearch**\n**Mục tiêu**: Tìm kiếm full-text nhanh và chính xác hơn\n\n**Implementation Steps**:\n```csharp\n// 1. Install packages\n// dotnet add package NEST\n// dotnet add package Elasticsearch.Net\n\n// 2. Create Elasticsearch service\npublic interface IElasticsearchService\n{\n    Task\u003cISearchResponse\u003cPostDocument\u003e\u003e SearchPostsAsync(string query);\n    Task IndexPostAsync(Post post);\n    Task DeletePostAsync(Guid postId);\n}\n\n// 3. Implementation trong Infrastructure layer\npublic class ElasticsearchService : IElasticsearchService\n{\n    private readonly IElasticClient _elasticClient;\n    \n    public ElasticsearchService(IConfiguration configuration)\n    {\n        var settings = new ConnectionSettings(new Uri(configuration[\"Elasticsearch:Uri\"]))\n            .DefaultIndex(\"devblog-posts\");\n        _elasticClient = new ElasticClient(settings);\n    }\n    \n    // Implement methods...\n}\n\n// 4. Register trong Program.cs\nbuilder.Services.AddSingleton\u003cIElasticsearchService, ElasticsearchService\u003e();\n```\n\n**Tasks**:\n- [ ] Setup Elasticsearch Docker container\n- [ ] Create PostDocument DTO for indexing\n- [ ] Implement indexing on post create/update\n- [ ] Create search API endpoint\n- [ ] Update Angular UI với search suggestions\n\n##### 2. 💬 **Real-time Chat với SignalR**\n**Mục tiêu**: Chat real-time giữa users\n\n**Implementation Guide**:\n```csharp\n// 1. Create Chat Hub\npublic class ChatHub : Hub\n{\n    private readonly IUserConnectionManager _userConnectionManager;\n    \n    public async Task SendMessage(string receiverId, string message)\n    {\n        var senderId = Context.UserIdentifier;\n        await Clients.User(receiverId).SendAsync(\"ReceiveMessage\", senderId, message);\n        \n        // Save to database\n        await _chatService.SaveMessageAsync(senderId, receiverId, message);\n    }\n    \n    public override async Task OnConnectedAsync()\n    {\n        await _userConnectionManager.AddConnection(Context.UserIdentifier, Context.ConnectionId);\n        await base.OnConnectedAsync();\n    }\n}\n\n// 2. Configure trong Program.cs\nbuilder.Services.AddSignalR();\napp.MapHub\u003cChatHub\u003e(\"/chathub\");\n\n// 3. Angular client\n// npm install @microsoft/signalr\nimport * as signalR from '@microsoft/signalr';\n\nconst connection = new signalR.HubConnectionBuilder()\n    .withUrl('/chathub', { accessTokenFactory: () =\u003e this.token })\n    .build();\n```\n\n**Database Schema**:\n```sql\nCREATE TABLE ChatMessages (\n    Id UNIQUEIDENTIFIER PRIMARY KEY,\n    SenderId UNIQUEIDENTIFIER NOT NULL,\n    ReceiverId UNIQUEIDENTIFIER NOT NULL,\n    Message NVARCHAR(1000) NOT NULL,\n    IsRead BIT DEFAULT 0,\n    CreatedAt DATETIME2 DEFAULT GETDATE(),\n    FOREIGN KEY (SenderId) REFERENCES Users(Id),\n    FOREIGN KEY (ReceiverId) REFERENCES Users(Id)\n);\n```\n\n##### 3. 📧 **Email Newsletter System**\n**Mục tiêu**: Gửi newsletter cho subscribers\n\n**Implementation**:\n```csharp\n// 1. Create Newsletter entities\npublic class Subscriber\n{\n    public Guid Id { get; set; }\n    public string Email { get; set; }\n    public bool IsActive { get; set; }\n    public DateTime SubscribedAt { get; set; }\n    public string UnsubscribeToken { get; set; }\n}\n\npublic class Newsletter\n{\n    public Guid Id { get; set; }\n    public string Subject { get; set; }\n    public string Content { get; set; }\n    public DateTime ScheduledAt { get; set; }\n    public NewsletterStatus Status { get; set; }\n}\n\n// 2. Email service với SendGrid\npublic class EmailService : IEmailService\n{\n    private readonly ISendGridClient _sendGridClient;\n    \n    public async Task SendNewsletterAsync(Newsletter newsletter, List\u003cSubscriber\u003e subscribers)\n    {\n        var msg = new SendGridMessage();\n        msg.SetFrom(\"newsletter@devblog.vn\", \"DevBlog\");\n        msg.AddTos(subscribers.Select(s =\u003e new EmailAddress(s.Email)).ToList());\n        msg.SetSubject(newsletter.Subject);\n        msg.AddContent(MimeType.Html, newsletter.Content);\n        \n        await _sendGridClient.SendEmailAsync(msg);\n    }\n}\n\n// 3. Background job với Hangfire\npublic class NewsletterJob\n{\n    public async Task ProcessScheduledNewsletters()\n    {\n        var newsletters = await _newsletterService.GetScheduledNewslettersAsync();\n        // Process and send...\n    }\n}\n```\n\n#### Phase 2: Social Features (Q2 2025)\n\n##### 4. 👥 **Social Login (OAuth 2.0)**\n**Providers**: Google, GitHub, Facebook\n\n**Implementation Steps**:\n```csharp\n// 1. Configure OAuth trong Program.cs\nbuilder.Services.AddAuthentication()\n    .AddGoogle(options =\u003e\n    {\n        options.ClientId = configuration[\"Authentication:Google:ClientId\"];\n        options.ClientSecret = configuration[\"Authentication:Google:ClientSecret\"];\n    })\n    .AddGitHub(options =\u003e\n    {\n        options.ClientId = configuration[\"Authentication:GitHub:ClientId\"];\n        options.ClientSecret = configuration[\"Authentication:GitHub:ClientSecret\"];\n    });\n\n// 2. External login controller\n[HttpGet(\"external-login/{provider}\")]\npublic IActionResult ExternalLogin(string provider, string returnUrl = null)\n{\n    var redirectUrl = Url.Action(nameof(ExternalLoginCallback), new { returnUrl });\n    var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);\n    return Challenge(properties, provider);\n}\n```\n\n##### 5. 🏆 **Gamification System**\n**Features**: Points, Badges, Leaderboard\n\n**Database Design**:\n```sql\n-- User Points\nCREATE TABLE UserPoints (\n    Id UNIQUEIDENTIFIER PRIMARY KEY,\n    UserId UNIQUEIDENTIFIER NOT NULL,\n    Points INT DEFAULT 0,\n    Level INT DEFAULT 1,\n    FOREIGN KEY (UserId) REFERENCES Users(Id)\n);\n\n-- Badges\nCREATE TABLE Badges (\n    Id UNIQUEIDENTIFIER PRIMARY KEY,\n    Name NVARCHAR(100),\n    Description NVARCHAR(500),\n    Icon NVARCHAR(200),\n    RequiredPoints INT\n);\n\n-- User Badges\nCREATE TABLE UserBadges (\n    UserId UNIQUEIDENTIFIER,\n    BadgeId UNIQUEIDENTIFIER,\n    EarnedAt DATETIME2,\n    PRIMARY KEY (UserId, BadgeId)\n);\n```\n\n**Point System Logic**:\n```csharp\npublic class PointService : IPointService\n{\n    private readonly Dictionary\u003cUserAction, int\u003e _pointRules = new()\n    {\n        { UserAction.CreatePost, 10 },\n        { UserAction.ReceiveLike, 2 },\n        { UserAction.CommentOnPost, 3 },\n        { UserAction.SharePost, 5 }\n    };\n    \n    public async Task AwardPointsAsync(Guid userId, UserAction action)\n    {\n        var points = _pointRules[action];\n        await _userPointRepository.AddPointsAsync(userId, points);\n        \n        // Check for new badges\n        await CheckAndAwardBadgesAsync(userId);\n    }\n}\n```\n\n##### 6. 📊 **Analytics Dashboard với Chart.js**\n**Metrics**: Views, Engagement, User Growth\n\n**Implementation**:\n```typescript\n// Angular component\nexport class AnalyticsDashboardComponent implements OnInit {\n    public chartData: ChartConfiguration['data'];\n    \n    ngOnInit() {\n        this.loadAnalytics();\n    }\n    \n    private loadAnalytics() {\n        this.analyticsService.getPostAnalytics().subscribe(data =\u003e {\n            this.chartData = {\n                labels: data.labels,\n                datasets: [{\n                    data: data.views,\n                    label: 'Views',\n                    backgroundColor: 'rgba(75, 192, 192, 0.2)'\n                }]\n            };\n        });\n    }\n}\n```\n\n#### Phase 3: Advanced Features (Q3 2025)\n\n##### 7. 🤖 **AI-Powered Features**\n\n**7.1 Content Recommendations**\n```csharp\npublic class RecommendationService\n{\n    private readonly IOpenAIService _openAIService;\n    \n    public async Task\u003cList\u003cPost\u003e\u003e GetRecommendationsAsync(Guid userId)\n    {\n        // Get user reading history\n        var history = await _userHistoryRepository.GetReadingHistoryAsync(userId);\n        \n        // Use OpenAI embeddings for similarity\n        var embeddings = await _openAIService.GetEmbeddingsAsync(history);\n        \n        // Find similar posts\n        return await _postRepository.FindSimilarPostsAsync(embeddings);\n    }\n}\n```\n\n**7.2 Auto-tagging với AI**\n```csharp\npublic async Task\u003cList\u003cstring\u003e\u003e GenerateTagsAsync(string content)\n{\n    var prompt = $\"Generate 5 relevant tags for this blog post: {content.Substring(0, 500)}\";\n    var response = await _openAIService.CompletionAsync(prompt);\n    return ParseTags(response);\n}\n```\n\n##### 8. 💰 **Monetization Features**\n\n**8.1 Premium Subscriptions**\n```csharp\npublic class SubscriptionService\n{\n    public async Task\u003cSubscription\u003e CreateSubscriptionAsync(Guid userId, SubscriptionPlan plan)\n    {\n        // Integrate with Stripe\n        var customer = await _stripeService.CreateCustomerAsync(userId);\n        var subscription = await _stripeService.CreateSubscriptionAsync(customer.Id, plan);\n        \n        // Save to database\n        return await _subscriptionRepository.CreateAsync(new Subscription\n        {\n            UserId = userId,\n            StripeSubscriptionId = subscription.Id,\n            Plan = plan,\n            Status = SubscriptionStatus.Active\n        });\n    }\n}\n```\n\n**8.2 Donation System**\n```csharp\n// Buy Me a Coffee integration\npublic class DonationController : ControllerBase\n{\n    [HttpPost(\"donate\")]\n    public async Task\u003cIActionResult\u003e ProcessDonation([FromBody] DonationRequest request)\n    {\n        var payment = await _paymentService.ProcessPaymentAsync(request);\n        if (payment.Success)\n        {\n            await _notificationService.NotifyAuthorAsync(request.AuthorId, \n                $\"You received a {request.Amount} donation!\");\n        }\n        return Ok(payment);\n    }\n}\n```\n\n##### 9. 📱 **Mobile App với .NET MAUI**\n\n**Project Structure**:\n```\nDevBlog.Mobile/\n├── Platforms/\n│   ├── Android/\n│   ├── iOS/\n│   └── Windows/\n├── Views/\n│   ├── HomePage.xaml\n│   ├── PostDetailPage.xaml\n│   └── ProfilePage.xaml\n├── ViewModels/\n├── Services/\n└── MauiProgram.cs\n```\n\n**API Integration**:\n```csharp\npublic class BlogApiService\n{\n    private readonly HttpClient _httpClient;\n    \n    public async Task\u003cList\u003cPost\u003e\u003e GetPostsAsync()\n    {\n        var response = await _httpClient.GetAsync(\"api/posts\");\n        var content = await response.Content.ReadAsStringAsync();\n        return JsonSerializer.Deserialize\u003cList\u003cPost\u003e\u003e(content);\n    }\n}\n```\n\n##### 10. 🌍 **Multi-language Support (i18n)**\n\n**Backend Implementation**:\n```csharp\n// Resource files structure\nResources/\n├── SharedResource.resx (default - English)\n├── SharedResource.vi.resx (Vietnamese)\n└── SharedResource.ja.resx (Japanese)\n\n// Configure trong Program.cs\nbuilder.Services.AddLocalization(options =\u003e options.ResourcesPath = \"Resources\");\nbuilder.Services.Configure\u003cRequestLocalizationOptions\u003e(options =\u003e\n{\n    var supportedCultures = new[] { \"en\", \"vi\", \"ja\" };\n    options.SetDefaultCulture(supportedCultures[0])\n        .AddSupportedCultures(supportedCultures)\n        .AddSupportedUICultures(supportedCultures);\n});\n```\n\n**Angular Implementation**:\n```bash\n# Generate locale files\nng add @angular/localize\nng generate @angular/localize:extract\n```\n\n```typescript\n// app.module.ts\nimport { registerLocaleData } from '@angular/common';\nimport localeVi from '@angular/common/locales/vi';\nregisterLocaleData(localeVi);\n\n// Use in template\n\u003cp\u003e{{ 'WELCOME_MESSAGE' | translate }}\u003c/p\u003e\n```\n\n### 📋 Implementation Checklist Template\n\nKhi implement mỗi feature, follow checklist này:\n\n#### Backend Tasks:\n- [ ] Create domain entities\n- [ ] Define DTOs and ViewModels\n- [ ] Implement repository interfaces\n- [ ] Create repository implementations\n- [ ] Add business logic services\n- [ ] Create API controllers\n- [ ] Add validation rules\n- [ ] Write unit tests\n- [ ] Add integration tests\n- [ ] Update Swagger documentation\n\n#### Frontend Tasks:\n- [ ] Create Angular services\n- [ ] Generate API clients (NSwag)\n- [ ] Create components\n- [ ] Implement routing\n- [ ] Add state management (if needed)\n- [ ] Create UI/UX designs\n- [ ] Add form validations\n- [ ] Write component tests\n- [ ] Add e2e tests\n\n#### Database Tasks:\n- [ ] Design table schema\n- [ ] Create Entity Framework migrations\n- [ ] Add indexes for performance\n- [ ] Create stored procedures (if needed)\n- [ ] Add seed data\n\n#### DevOps Tasks:\n- [ ] Update Docker configuration\n- [ ] Modify CI/CD pipelines\n- [ ] Update environment variables\n- [ ] Configure monitoring\n- [ ] Update documentation\n\n### 🔧 Technical Debt \u0026 Refactoring\n\n#### Planned Refactoring:\n1. **Repository Pattern Enhancement**\n   - Implement Generic Repository\n   - Add Specification Pattern\n   - Improve query performance\n\n2. **Caching Strategy**\n   - Implement Redis caching\n   - Add cache invalidation logic\n   - Memory cache for static data\n\n3. **Code Quality**\n   - Add SonarQube analysis\n   - Implement code coverage \u003e 80%\n   - Refactor long methods\n\n4. **Performance Optimization**\n   - Implement lazy loading for images\n   - Add pagination for all lists\n   - Optimize database queries with indexes\n\n### 🎯 Success Metrics\n\nMỗi feature cần đạt các metrics sau:\n- **Performance**: Response time \u003c 200ms\n- **Test Coverage**: \u003e 80%\n- **Code Quality**: SonarQube rating A\n- **Security**: OWASP compliance\n- **User Experience**: Loading time \u003c 3s\n\n## 📚 Tài liệu học tập\n\n### Clean Architecture \u0026 DDD\n- [Clean Architecture by Uncle Bob](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)\n- [Domain-Driven Design của Eric Evans](https://www.domainlanguage.com/ddd/)\n- [Implementing Domain-Driven Design](https://www.amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577)\n\n### .NET Core Resources\n- [Microsoft Docs - ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/)\n- [Entity Framework Core Documentation](https://docs.microsoft.com/en-us/ef/core/)\n- [ASP.NET Core Identity](https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity)\n\n### Angular Resources\n- [Angular Documentation](https://angular.io/docs)\n- [RxJS Documentation](https://rxjs.dev/)\n- [CoreUI Angular Documentation](https://coreui.io/angular/docs/)\n\n### Best Practices\n- [SOLID Principles](https://www.digitalocean.com/community/conceptual_articles/s-o-l-i-d-the-first-five-principles-of-object-oriented-design)\n- [REST API Design Best Practices](https://stackoverflow.blog/2020/03/02/best-practices-for-rest-api-design/)\n- [Security Best Practices for ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/security/)\n\n### Video Tutorials (Tiếng Việt)\n- [TEDU YouTube Channel](https://www.youtube.com/c/TEDU)\n- [200Lab Education](https://200lab.io/)\n- [CodeGym Vietnam](https://codegym.vn/)\n\n## 📞 Support \u0026 Contact\n\n- 📧 Email: support@devblog.vn\n- 💬 Discord: [Join our community](https://discord.gg/devblog)\n- 🐛 Issues: [GitHub Issues](https://github.com/yourusername/DevBlog/issues)\n- 📖 Wiki: [Project Wiki](https://github.com/yourusername/DevBlog/wiki)\n\n## 📄 License\n\nDự án này được phân phối dưới giấy phép MIT. Xem file [LICENSE](LICENSE) để biết thêm chi tiết.\n\n## 🙏 Acknowledgments\n\n- [ASP.NET Core team](https://github.com/dotnet/aspnetcore)\n- [Angular team](https://github.com/angular/angular)\n- [CoreUI team](https://github.com/coreui/coreui-angular)\n- Cộng đồng developer Việt Nam\n\n---\n\n**Happy Coding! 🎉**\n\n*Được phát triển với ❤️ bởi cộng đồng DevBlog Việt Nam*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzienk%2Fdev-blog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzienk%2Fdev-blog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzienk%2Fdev-blog/lists"}