nnews-guide — for Claude Code Peleja, community, for Claude Code, ide skills, $ARGUMENTS, dotnet add package NNews, ### ArticleInfo, ### ArticleInsertedInfo, ### ArticleUpdatedInfo, ### CategoryInfo

v1.0.0

Sobre este Skill

Cenario recomendado: Ideal for AI agents that need nnews nuget package integration guide. Resumo localizado:.NET Discurtion Widget # NNews NuGet Package Integration Guide You are an expert assistant that helps developers integrate the NNews NuGet package for consuming the NNews CMS API in.NET 8 projects. This AI agent skill supports Claude Code, Cursor, and Windsurf workflows.

Recursos

NNews NuGet Package Integration Guide
The user may provide a specific question or context as argument: $ARGUMENTS
If no argument is provided, present a complete overview of the NNews integration.
When the user asks about NNews, use this knowledge base to provide accurate, contextual guidance.
NNews — Data Transfer Objects

# Tópicos principais

emaginebr emaginebr
[0]
[0]
Atualizado: 4/6/2026

Skill Overview

Start with fit, limitations, and setup before diving into the repository.

Cenario recomendado: Ideal for AI agents that need nnews nuget package integration guide. Resumo localizado:.NET Discurtion Widget # NNews NuGet Package Integration Guide You are an expert assistant that helps developers integrate the NNews NuGet package for consuming the NNews CMS API in.NET 8 projects. This AI agent skill supports Claude Code, Cursor, and Windsurf workflows.

Por que usar essa habilidade

Recomendacao: nnews-guide helps agents nnews nuget package integration guide..NET Discurtion Widget # NNews NuGet Package Integration Guide You are an expert assistant that helps developers integrate the NNews NuGet

Melhor para

Cenario recomendado: Ideal for AI agents that need nnews nuget package integration guide.

Casos de Uso Práticos for nnews-guide

Caso de uso: NNews NuGet Package Integration Guide
Caso de uso: The user may provide a specific question or context as argument: $ARGUMENTS
Caso de uso: If no argument is provided, present a complete overview of the NNews integration

! Segurança e Limitações

  • Limitacao: Requires repository-specific context from the skill documentation
  • Limitacao: Works best when the underlying tools and dependencies are already configured

About The Source

The section below is adapted from the upstream repository. Use it as supporting material alongside the fit, use-case, and installation summary on this page.

Demo Labs

Browser Sandbox Environment

⚡️ Ready to unleash?

Experience this Agent in a zero-setup browser environment powered by WebContainers. No installation required.

Boot Container Sandbox

FAQ e etapas de instalação

These questions and steps mirror the structured data on this page for better search understanding.

? Perguntas frequentes

O que é nnews-guide?

Cenario recomendado: Ideal for AI agents that need nnews nuget package integration guide. Resumo localizado:.NET Discurtion Widget # NNews NuGet Package Integration Guide You are an expert assistant that helps developers integrate the NNews NuGet package for consuming the NNews CMS API in.NET 8 projects. This AI agent skill supports Claude Code, Cursor, and Windsurf workflows.

Como instalar nnews-guide?

Execute o comando: npx killer-skills add emaginebr/Peleja. Ele funciona com Cursor, Windsurf, VS Code, Claude Code e mais de 19 outros IDEs.

Quais são os casos de uso de nnews-guide?

Os principais casos de uso incluem: Caso de uso: NNews NuGet Package Integration Guide, Caso de uso: The user may provide a specific question or context as argument: $ARGUMENTS, Caso de uso: If no argument is provided, present a complete overview of the NNews integration.

Quais IDEs são compatíveis com nnews-guide?

Esta skill é compatível com Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer. Use a CLI do Killer-Skills para uma instalação unificada.

nnews-guide tem limitações?

Limitacao: Requires repository-specific context from the skill documentation. Limitacao: Works best when the underlying tools and dependencies are already configured.

Como instalar este skill

  1. 1. Abra o terminal

    Abra o terminal ou linha de comando no diretório do projeto.

  2. 2. Execute o comando de instalação

    Execute: npx killer-skills add emaginebr/Peleja. A CLI detectará sua IDE ou agente automaticamente e configurará a skill.

  3. 3. Comece a usar o skill

    O skill já está ativo. Seu agente de IA pode usar nnews-guide imediatamente no projeto atual.

! Source Notes

This page is still useful for installation and source reference. Before using it, compare the fit, limitations, and upstream repository notes above.

Upstream Repository Material

The section below is adapted from the upstream repository. Use it as supporting material alongside the fit, use-case, and installation summary on this page.

Upstream Source

nnews-guide

Install nnews-guide, an AI agent skill for AI agent workflows and automation. Explore features, use cases, limitations, and setup guidance.

SKILL.md
Readonly
Upstream Repository Material
The section below is adapted from the upstream repository. Use it as supporting material alongside the fit, use-case, and installation summary on this page.
Upstream Source

NNews NuGet Package Integration Guide

You are an expert assistant that helps developers integrate the NNews NuGet package for consuming the NNews CMS API in .NET 8 projects.

Input

The user may provide a specific question or context as argument: $ARGUMENTS

If no argument is provided, present a complete overview of the NNews integration.

When the user asks about NNews, use this knowledge base to provide accurate, contextual guidance.


NNews — Data Transfer Objects

Install: dotnet add package NNews

NNewsSetting

csharp
1public class NNewsSetting 2{ 3 public string ApiUrl { get; set; } = string.Empty; // NNews API base URL 4}

ArticleInfo

csharp
1public class ArticleInfo 2{ 3 public long ArticleId { get; set; } 4 public long CategoryId { get; set; } 5 public long? AuthorId { get; set; } 6 public string? ImageName { get; set; } // Max 560 chars 7 public string Title { get; set; } // Required, max 255 chars 8 public string Content { get; set; } // Required 9 public int Status { get; set; } // 0=Draft, 1=Published, 2=Archived, 3=Scheduled 10 public int ContentType { get; set; } = 2; // 1=PlainText, 2=Html, 3=MarkDown 11 public DateTime DateAt { get; set; } 12 public DateTime CreatedAt { get; set; } 13 public DateTime UpdatedAt { get; set; } 14 public CategoryInfo? Category { get; set; } 15 public List<TagInfo> Tags { get; set; } = new(); 16 public List<RoleInfo> Roles { get; set; } = new(); 17}

ArticleInsertedInfo

csharp
1public class ArticleInsertedInfo 2{ 3 public long CategoryId { get; set; } // Required 4 public long? AuthorId { get; set; } 5 public string? ImageName { get; set; } // Max 560 chars 6 public string Title { get; set; } // Required, max 255 chars 7 public string Content { get; set; } // Required 8 public int Status { get; set; } // 0=Draft, 1=Published, 2=Archived, 3=Scheduled 9 public int ContentType { get; set; } = 2; // Default: Html 10 public DateTime DateAt { get; set; } // Required 11 public string TagList { get; set; } = string.Empty; // Comma-separated tags 12 public List<string> Roles { get; set; } = new(); // Role slugs 13}

ArticleUpdatedInfo

csharp
1public class ArticleUpdatedInfo 2{ 3 public long ArticleId { get; set; } 4 public long CategoryId { get; set; } 5 public long? AuthorId { get; set; } 6 public string? ImageName { get; set; } 7 public string Title { get; set; } 8 public string Content { get; set; } 9 public int Status { get; set; } 10 public int ContentType { get; set; } = 2; 11 public DateTime DateAt { get; set; } 12 public string TagList { get; set; } = string.Empty; 13 public List<string> Roles { get; set; } = new(); 14}

CategoryInfo

csharp
1public class CategoryInfo 2{ 3 public long CategoryId { get; set; } 4 public long? ParentId { get; set; } // For hierarchical categories 5 public string Title { get; set; } // Required, max 240 chars 6 public DateTime CreatedAt { get; set; } 7 public DateTime UpdatedAt { get; set; } 8 public int ArticleCount { get; set; } // Read-only counter 9}

TagInfo

csharp
1public class TagInfo 2{ 3 public long TagId { get; set; } 4 public string Title { get; set; } // Required, max 120 chars 5 public string? Slug { get; set; } // Max 120 chars 6 public int ArticleCount { get; set; } // Read-only counter 7}

RoleInfo

csharp
1public class RoleInfo 2{ 3 public string Slug { get; set; } = string.Empty; 4 public string Name { get; set; } = string.Empty; 5}

PagedResult<T>

csharp
1public class PagedResult<T> 2{ 3 public IList<T> Items { get; set; } = new List<T>(); 4 public int Page { get; set; } 5 public int PageSize { get; set; } 6 public int TotalCount { get; set; } 7 public int TotalPages { get; set; } 8 public bool HasPrevious => Page > 1; 9 public bool HasNext => Page < TotalPages; 10}

AI DTOs

csharp
1// Request for AI content generation 2public class AIArticleRequest 3{ 4 public long? ArticleId { get; set; } 5 public string Prompt { get; set; } // Required, 10-2000 chars 6 public bool GenerateImage { get; set; } = false; 7} 8 9// Response from AI generation 10public class AIArticleResponse 11{ 12 public string Title { get; set; } = string.Empty; 13 public string Content { get; set; } = string.Empty; 14 public long CategoryId { get; set; } 15 public string TagList { get; set; } = string.Empty; 16 public string? ImagePrompt { get; set; } 17} 18 19// Response from AI article update 20public class AIArticleUpdateResponse 21{ 22 public long ArticleId { get; set; } 23 public string Title { get; set; } = string.Empty; 24 public string Content { get; set; } = string.Empty; 25 public long CategoryId { get; set; } 26 public string TagList { get; set; } = string.Empty; 27 public string? ImagePrompt { get; set; } 28} 29 30// Category summary for AI context 31public class AICategorySummary 32{ 33 public long CategoryId { get; set; } 34 public string Title { get; set; } = string.Empty; 35 public long? ParentId { get; set; } 36}

NNews — Anti-Corruption Layer (ACL)

IArticleClient

csharp
1public interface IArticleClient 2{ 3 Task<PagedResult<ArticleInfo>> GetAllAsync(long? categoryId = null, int? status = null, int page = 1, int pageSize = 10, CancellationToken cancellationToken = default); 4 Task<PagedResult<ArticleInfo>> ListByCategoryAsync(long categoryId, int page = 1, int pageSize = 10, CancellationToken cancellationToken = default); 5 Task<PagedResult<ArticleInfo>> ListByRolesAsync(int page = 1, int pageSize = 10, CancellationToken cancellationToken = default); 6 Task<PagedResult<ArticleInfo>> ListByTagAsync(string tagSlug, int page = 1, int pageSize = 10, CancellationToken cancellationToken = default); 7 Task<PagedResult<ArticleInfo>> SearchAsync(string keyword, int page = 1, int pageSize = 10, CancellationToken cancellationToken = default); 8 Task<ArticleInfo> GetByIdAsync(int id, CancellationToken cancellationToken = default); 9 Task<ArticleInfo> CreateAsync(ArticleInsertedInfo article, CancellationToken cancellationToken = default); 10 Task<ArticleInfo> UpdateAsync(ArticleUpdatedInfo article, CancellationToken cancellationToken = default); 11 Task DeleteAsync(int id, CancellationToken cancellationToken = default); 12}

IArticleAIClient

csharp
1public interface IArticleAIClient 2{ 3 Task<ArticleInfo> CreateWithAIAsync(string prompt, bool generateImage = false, CancellationToken cancellationToken = default); 4 Task<ArticleInfo> UpdateWithAIAsync(int articleId, string prompt, bool generateImage = false, CancellationToken cancellationToken = default); 5}

ICategoryClient

csharp
1public interface ICategoryClient 2{ 3 Task<IList<CategoryInfo>> GetAllAsync(CancellationToken cancellationToken = default); 4 Task<IList<CategoryInfo>> ListByParentAsync(long? parentId = null, CancellationToken cancellationToken = default); 5 Task<CategoryInfo> GetByIdAsync(int id, CancellationToken cancellationToken = default); 6 Task<CategoryInfo> CreateAsync(CategoryInfo category, CancellationToken cancellationToken = default); 7 Task<CategoryInfo> UpdateAsync(CategoryInfo category, CancellationToken cancellationToken = default); 8 Task DeleteAsync(int id, CancellationToken cancellationToken = default); 9}

ITagClient

csharp
1public interface ITagClient 2{ 3 Task<IList<TagInfo>> GetAllAsync(CancellationToken cancellationToken = default); 4 Task<IList<TagInfo>> ListByRolesAsync(CancellationToken cancellationToken = default); 5 Task<TagInfo> GetByIdAsync(int id, CancellationToken cancellationToken = default); 6 Task<TagInfo> CreateAsync(TagInfo tag, CancellationToken cancellationToken = default); 7 Task<TagInfo> UpdateAsync(TagInfo tag, CancellationToken cancellationToken = default); 8 Task DeleteAsync(int id, CancellationToken cancellationToken = default); 9 Task MergeTagsAsync(long sourceTagId, long targetTagId, CancellationToken cancellationToken = default); 10}

IImageClient

csharp
1public interface IImageClient 2{ 3 Task<string> UploadImageAsync(IFormFile file, CancellationToken cancellationToken = default); 4}

ITenantResolver

csharp
1public interface ITenantResolver 2{ 3 string TenantId { get; } 4 string ConnectionString { get; } 5 string JwtSecret { get; } 6}

NNews REST API Endpoints

All endpoints are prefixed by the controller name (e.g., /Article, /Category). Authenticated endpoints require a Bearer JWT token. Tenant is resolved via X-Tenant-Id header or JWT tenant_id claim.

Article (/Article)

MethodRouteQuery ParamsBodyAuthResponse
GET/ArticlecategoryId?, status?, page, pageSizeYesPagedResult<ArticleInfo>
GET/Article/ListByCategorycategoryId, page, pageSizeNoPagedResult<ArticleInfo>
GET/Article/ListByRolespage, pageSizeNoPagedResult<ArticleInfo>
GET/Article/ListByTagtagSlug, page, pageSizeNoPagedResult<ArticleInfo>
GET/Article/Searchkeyword, page, pageSizeNoPagedResult<ArticleInfo>
GET/Article/{id}NoArticleInfo
POST/ArticleArticleInsertedInfoYesArticleInfo (201)
POST/Article/insertWithAIAIArticleRequestYesArticleInfo (201)
PUT/ArticleArticleUpdatedInfoYesArticleInfo
PUT/Article/updateWithAIAIArticleRequestYesArticleInfo
DELETE/Article/{id}Yes204 No Content

Status filter values: 0 = Draft, 1 = Published, 2 = Archived, 3 = Scheduled

Category (/Category)

MethodRouteQuery ParamsBodyAuthResponse
GET/CategoryYesIList<CategoryInfo>
GET/Category/listByParentroles?, parentId?NoIList<CategoryInfo>
GET/Category/{id}NoCategoryInfo
POST/CategoryCategoryInfoYesCategoryInfo (201)
PUT/CategoryCategoryInfoYesCategoryInfo
DELETE/Category/{id}Yes204 No Content

Tag (/Tag)

MethodRouteQuery ParamsBodyAuthResponse
GET/TagYesIList<TagInfo>
GET/Tag/ListByRolesNoIList<TagInfo>
GET/Tag/{id}NoTagInfo
POST/TagTagInfoYesTagInfo (201)
PUT/TagTagInfoYesTagInfo
DELETE/Tag/{id}Yes204 No Content
POST/Tag/merge/{sourceTagId}/{targetTagId}Yes200 OK

Image (/Image)

MethodRouteQuery ParamsBodyAuthResponse
POST/Image/uploadImageIFormFile (multipart, max 100MB)Yesstring (image URL)

Multi-Tenancy

NNews supports multi-tenancy via the X-Tenant-Id HTTP header.

TenantHeaderHandler

A DelegatingHandler that automatically adds the X-Tenant-Id header to all outgoing HTTP requests. It reads the tenant ID from the configuration key Tenant:DefaultTenantId.

TenantResolver

Implements ITenantResolver. Reads tenant configuration from:

  • Tenant:DefaultTenantId — the default tenant ID
  • Tenants:{TenantId}:ConnectionString — database connection string
  • Tenants:{TenantId}:JwtSecret — JWT secret for the tenant

Step-by-Step Integration

1. Install Package

bash
1dotnet add package NNews

2. Configure appsettings.json

json
1{ 2 "NNews": { 3 "ApiUrl": "http://localhost:5007" 4 }, 5 "Tenant": { 6 "DefaultTenantId": "my-tenant" 7 } 8}

Docker: use "ApiUrl": "http://nnews-api:80".

3. Register Services (DI)

csharp
1using NNews.ACL; 2using NNews.ACL.Interfaces; 3using NNews.ACL.Handlers; 4using NNews.ACL.Services; 5using NNews.DTO.Settings; 6 7// Settings 8services.Configure<NNewsSetting>(configuration.GetSection("NNews")); 9 10// Tenant resolver 11services.AddScoped<ITenantResolver, TenantResolver>(); 12 13// Register TenantHeaderHandler for automatic X-Tenant-Id header 14services.AddTransient<TenantHeaderHandler>(); 15 16// Register HttpClients with TenantHeaderHandler 17services.AddHttpClient<IArticleClient, ArticleClient>() 18 .AddHttpMessageHandler<TenantHeaderHandler>(); 19 20services.AddHttpClient<IArticleAIClient, ArticleAIClient>() 21 .AddHttpMessageHandler<TenantHeaderHandler>(); 22 23services.AddHttpClient<ICategoryClient, CategoryClient>() 24 .AddHttpMessageHandler<TenantHeaderHandler>(); 25 26services.AddHttpClient<ITagClient, TagClient>() 27 .AddHttpMessageHandler<TenantHeaderHandler>(); 28 29services.AddHttpClient<IImageClient, ImageClient>() 30 .AddHttpMessageHandler<TenantHeaderHandler>();

4. Register Only What You Need

If you only need to read articles (e.g., a public blog frontend), register only the necessary clients:

csharp
1services.Configure<NNewsSetting>(configuration.GetSection("NNews")); 2services.AddTransient<TenantHeaderHandler>(); 3 4services.AddHttpClient<IArticleClient, ArticleClient>() 5 .AddHttpMessageHandler<TenantHeaderHandler>(); 6 7services.AddHttpClient<ICategoryClient, CategoryClient>() 8 .AddHttpMessageHandler<TenantHeaderHandler>(); 9 10services.AddHttpClient<ITagClient, TagClient>() 11 .AddHttpMessageHandler<TenantHeaderHandler>();

Usage Examples

List Articles (Paginated)

csharp
1public class BlogService 2{ 3 private readonly IArticleClient _articleClient; 4 5 public BlogService(IArticleClient articleClient) 6 { 7 _articleClient = articleClient; 8 } 9 10 public async Task<PagedResult<ArticleInfo>> GetLatestArticles(int page = 1, int pageSize = 12) 11 { 12 return await _articleClient.GetAllAsync(page: page, pageSize: pageSize); 13 } 14 15 public async Task<PagedResult<ArticleInfo>> GetPublishedArticles(int page = 1, int pageSize = 12) 16 { 17 // Filter by status: 0=Draft, 1=Published, 2=Archived, 3=Scheduled 18 return await _articleClient.GetAllAsync(status: 1, page: page, pageSize: pageSize); 19 } 20}

List Articles by Category

csharp
1public async Task<PagedResult<ArticleInfo>> GetByCategory(long categoryId, int page = 1) 2{ 3 return await _articleClient.ListByCategoryAsync(categoryId, page: page, pageSize: 10); 4}

List Articles by Tag

csharp
1public async Task<PagedResult<ArticleInfo>> GetByTag(string tagSlug, int page = 1) 2{ 3 return await _articleClient.ListByTagAsync(tagSlug, page: page, pageSize: 10); 4}

Search Articles

csharp
1public async Task<PagedResult<ArticleInfo>> Search(string keyword, int page = 1) 2{ 3 return await _articleClient.SearchAsync(keyword, page: page, pageSize: 10); 4}

Get Single Article

csharp
1public async Task<ArticleInfo> GetArticle(int id) 2{ 3 return await _articleClient.GetByIdAsync(id); 4}

Create Article

csharp
1public async Task<ArticleInfo> CreateArticle() 2{ 3 var article = new ArticleInsertedInfo 4 { 5 Title = "My First Article", 6 Content = "<p>Hello World!</p>", 7 CategoryId = 1, 8 Status = 1, // Published 9 ContentType = 2, // Html 10 DateAt = DateTime.UtcNow, 11 TagList = "dotnet,csharp,webapi", 12 Roles = new List<string> { "admin", "editor" } 13 }; 14 15 return await _articleClient.CreateAsync(article); 16}

Update Article

csharp
1public async Task<ArticleInfo> UpdateArticle(long articleId) 2{ 3 var article = new ArticleUpdatedInfo 4 { 5 ArticleId = articleId, 6 Title = "Updated Title", 7 Content = "<p>Updated content</p>", 8 CategoryId = 1, 9 Status = 1, 10 ContentType = 2, 11 DateAt = DateTime.UtcNow, 12 TagList = "dotnet,updated" 13 }; 14 15 return await _articleClient.UpdateAsync(article); 16}

Delete Article

csharp
1public async Task DeleteArticle(int articleId) 2{ 3 await _articleClient.DeleteAsync(articleId); 4}

Create Article with AI

csharp
1public async Task<ArticleInfo> CreateWithAI(string prompt, bool withImage = false) 2{ 3 return await _articleAIClient.CreateWithAIAsync(prompt, generateImage: withImage); 4} 5 6// Example usage: 7// var article = await CreateWithAI("Write an article about clean architecture in .NET 8", withImage: true);

Update Article with AI

csharp
1public async Task<ArticleInfo> UpdateWithAI(int articleId, string prompt) 2{ 3 return await _articleAIClient.UpdateWithAIAsync(articleId, prompt, generateImage: false); 4}

Category Management

csharp
1public async Task CategoryExamples() 2{ 3 // List all categories 4 var categories = await _categoryClient.GetAllAsync(); 5 6 // List root categories (no parent) 7 var rootCategories = await _categoryClient.ListByParentAsync(parentId: null); 8 9 // List subcategories 10 var subCategories = await _categoryClient.ListByParentAsync(parentId: 1); 11 12 // Create category 13 var newCategory = await _categoryClient.CreateAsync(new CategoryInfo 14 { 15 Title = "Technology", 16 ParentId = null // Root category 17 }); 18 19 // Create subcategory 20 var subCategory = await _categoryClient.CreateAsync(new CategoryInfo 21 { 22 Title = "Web Development", 23 ParentId = newCategory.CategoryId 24 }); 25 26 // Delete category 27 await _categoryClient.DeleteAsync((int)newCategory.CategoryId); 28}

Tag Management

csharp
1public async Task TagExamples() 2{ 3 // List all tags 4 var tags = await _tagClient.GetAllAsync(); 5 6 // List tags filtered by user roles 7 var roleTags = await _tagClient.ListByRolesAsync(); 8 9 // Create tag 10 var newTag = await _tagClient.CreateAsync(new TagInfo { Title = "C#" }); 11 12 // Merge tags (move all articles from source to target, then delete source) 13 await _tagClient.MergeTagsAsync(sourceTagId: 5, targetTagId: 2); 14 15 // Delete tag 16 await _tagClient.DeleteAsync((int)newTag.TagId); 17}

Image Upload

csharp
1[HttpPost("upload")] 2[Authorize] 3public async Task<ActionResult<string>> UploadImage(IFormFile file) 4{ 5 if (file == null || file.Length == 0) 6 return BadRequest("No file uploaded"); 7 8 var imageUrl = await _imageClient.UploadImageAsync(file); 9 return Ok(imageUrl); 10}

Controller Example — Blog API

csharp
1using Microsoft.AspNetCore.Mvc; 2using NNews.ACL.Interfaces; 3using NNews.DTO; 4 5[Route("api/[controller]")] 6[ApiController] 7public class BlogController : ControllerBase 8{ 9 private readonly IArticleClient _articleClient; 10 private readonly ICategoryClient _categoryClient; 11 private readonly ITagClient _tagClient; 12 13 public BlogController( 14 IArticleClient articleClient, 15 ICategoryClient categoryClient, 16 ITagClient tagClient) 17 { 18 _articleClient = articleClient; 19 _categoryClient = categoryClient; 20 _tagClient = tagClient; 21 } 22 23 [HttpGet("articles")] 24 public async Task<ActionResult<PagedResult<ArticleInfo>>> GetArticles( 25 [FromQuery] int page = 1, 26 [FromQuery] int pageSize = 12, 27 [FromQuery] long? categoryId = null, 28 [FromQuery] int? status = null) 29 { 30 var result = await _articleClient.GetAllAsync(categoryId, status, page, pageSize); 31 return Ok(result); 32 } 33 34 [HttpGet("articles/{id}")] 35 public async Task<ActionResult<ArticleInfo>> GetArticle(int id) 36 { 37 var article = await _articleClient.GetByIdAsync(id); 38 return Ok(article); 39 } 40 41 [HttpGet("articles/search")] 42 public async Task<ActionResult<PagedResult<ArticleInfo>>> Search( 43 [FromQuery] string keyword, 44 [FromQuery] int page = 1) 45 { 46 var result = await _articleClient.SearchAsync(keyword, page); 47 return Ok(result); 48 } 49 50 [HttpDelete("articles/{id}")] 51 public async Task<IActionResult> DeleteArticle(int id) 52 { 53 await _articleClient.DeleteAsync(id); 54 return NoContent(); 55 } 56 57 [HttpGet("categories")] 58 public async Task<ActionResult<IList<CategoryInfo>>> GetCategories() 59 { 60 var categories = await _categoryClient.GetAllAsync(); 61 return Ok(categories); 62 } 63 64 [HttpGet("tags")] 65 public async Task<ActionResult<IList<TagInfo>>> GetTags() 66 { 67 var tags = await _tagClient.GetAllAsync(); 68 return Ok(tags); 69 } 70}

Troubleshooting

IssueCauseSolution
HTTP 500 on all requestsNNews API unreachableVerify NNews:ApiUrl in appsettings
HTTP 401 UnauthorizedMissing or invalid auth tokenEnsure Bearer token is forwarded or endpoint is public
Empty PagedResultWrong tenant or no dataCheck Tenant:DefaultTenantId configuration
DI error for IArticleClientMissing registrationAdd services.AddHttpClient<IArticleClient, ArticleClient>()
Missing X-Tenant-Id headerTenantHeaderHandler not registeredAdd .AddHttpMessageHandler<TenantHeaderHandler>()
NNewsSetting.ApiUrl emptyMissing configuration sectionAdd "NNews": { "ApiUrl": "..." } to appsettings
CreateAsync returns errorMissing required fieldsEnsure Title, Content, CategoryId, and DateAt are set
Tags not appliedWrong formatUse comma-separated string in TagList (e.g., "tag1,tag2,tag3")

Response Guidelines

  1. Be specific: Reference exact class names, interfaces, and method signatures
  2. Show code: Always include working code examples based on the patterns above
  3. Context-aware: If the user is working in a project that consumes NNews, reference their existing DI setup and configuration
  4. Minimal changes: Only suggest what's needed for the user's specific question
  5. Multi-tenancy: Always remind about configuring Tenant:DefaultTenantId and registering TenantHeaderHandler
  6. Prerequisites: Mention required NuGet package and configuration if starting fresh

Habilidades Relacionadas

Looking for an alternative to nnews-guide or another community skill for your workflow? Explore these related open-source skills.

Ver tudo

openclaw-release-maintainer

Logo of openclaw
openclaw

Resumo localizado: 🦞 # OpenClaw Release Maintainer Use this skill for release and publish-time workflow. It covers ai, assistant, crustacean workflows. This AI agent skill supports Claude Code, Cursor, and Windsurf workflows.

widget-generator

Logo of f
f

Resumo localizado: Generate customizable widget plugins for the prompts.chat feed system # Widget Generator Skill This skill guides creation of widget plugins for prompts.chat. It covers ai, artificial-intelligence, awesome-list workflows. This AI agent skill supports Claude Code, Cursor, and

flags

Logo of vercel
vercel

Resumo localizado: The React Framework # Feature Flags Use this skill when adding or changing framework feature flags in Next.js internals. It covers blog, browser, compiler workflows. This AI agent skill supports Claude Code, Cursor, and Windsurf workflows.

138.4k
0
Navegador

pr-review

Logo of pytorch
pytorch

Resumo localizado: Usage Modes No Argument If the user invokes /pr-review with no arguments, do not perform a review. It covers autograd, deep-learning, gpu workflows. This AI agent skill supports Claude Code, Cursor, and Windsurf workflows.

98.6k
0
Desenvolvedor