一键导入
add-api
Add a new API endpoint with controller, service, and DTOs following OMS patterns
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Add a new API endpoint with controller, service, and DTOs following OMS patterns
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Add a new database entity with migrations for all three databases (MySQL, MSSQL, PostgreSQL)
Add a new mobile page to frontend.h5 using Vant 4 components
Add a new frontend page with proper layout, table, and API integration following OMS UI standards
Audit backend code to ensure all queries properly filter by OrgId for multi-tenant security
Debug and troubleshoot issues in the OMS system with systematic approach
Create database migration files for all three databases (MySQL, MSSQL, PostgreSQL) when schema changes are needed
| name | add-api |
| description | Add a new API endpoint with controller, service, and DTOs following OMS patterns |
| disable-model-invocation | false |
| allowed-tools | Read, Write, Edit, Glob, Grep |
Add a new API endpoint to the OMS backend following established patterns.
When the user requests to add a new API endpoint, follow these steps:
Location: backend/omsapi/Models/Dtos/{EntityName}/
Create necessary DTOs:
{EntityName}Dto.cs - Response DTOCreate{EntityName}Dto.cs - Create request DTOUpdate{EntityName}Dto.cs - Update request DTO{EntityName}QueryDto.cs - Query/filter DTO (if needed)Example:
namespace omsapi.Models.Dtos.{EntityName}
{
/// <summary>
/// {EntityName} response DTO
/// </summary>
public class {EntityName}Dto
{
public long Id { get; set; }
public long OrgId { get; set; }
public string PropertyName { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
}
Location: backend/omsapi/Services/I{EntityName}Service.cs
namespace omsapi.Services
{
public interface I{EntityName}Service
{
Task<List<{EntityName}Dto>> GetListAsync();
Task<{EntityName}Dto?> GetByIdAsync(long id);
Task<{EntityName}Dto> CreateAsync(Create{EntityName}Dto dto);
Task<{EntityName}Dto> UpdateAsync(long id, Update{EntityName}Dto dto);
Task DeleteAsync(long id);
}
}
Location: backend/omsapi/Services/{EntityName}Service.cs
CRITICAL Requirements:
[AutoInject(ServiceLifetime.Scoped)] attributeOmsContext and IHttpContextAccessor.Where(x => x.OrgId == currentOrgId)Example:
using omsapi.Infrastructure.Attributes;
using omsapi.Infrastructure.Extensions;
namespace omsapi.Services
{
[AutoInject(ServiceLifetime.Scoped)]
public class {EntityName}Service : I{EntityName}Service
{
private readonly OmsContext _context;
private readonly IHttpContextAccessor _httpContextAccessor;
public {EntityName}Service(OmsContext context, IHttpContextAccessor httpContextAccessor)
{
_context = context;
_httpContextAccessor = httpContextAccessor;
}
public async Task<List<{EntityName}Dto>> GetListAsync()
{
var currentOrgId = _httpContextAccessor.HttpContext!.GetCurrentOrgId();
var entities = await _context.{EntityName}s
.Where(x => x.OrgId == currentOrgId) // CRITICAL: OrgId filter
.OrderByDescending(x => x.CreatedAt)
.ToListAsync();
return entities.Select(MapToDto).ToList();
}
public async Task<{EntityName}Dto?> GetByIdAsync(long id)
{
var currentOrgId = _httpContextAccessor.HttpContext!.GetCurrentOrgId();
var entity = await _context.{EntityName}s
.Where(x => x.Id == id && x.OrgId == currentOrgId) // CRITICAL: OrgId filter
.FirstOrDefaultAsync();
return entity == null ? null : MapToDto(entity);
}
public async Task<{EntityName}Dto> CreateAsync(Create{EntityName}Dto dto)
{
var currentOrgId = _httpContextAccessor.HttpContext!.GetCurrentOrgId();
var entity = new {EntityName}Entity
{
OrgId = currentOrgId, // CRITICAL: Set OrgId
// Map properties from dto
CreatedAt = DateTime.UtcNow,
UpdatedAt = DateTime.UtcNow
};
_context.{EntityName}s.Add(entity);
await _context.SaveChangesAsync();
return MapToDto(entity);
}
public async Task<{EntityName}Dto> UpdateAsync(long id, Update{EntityName}Dto dto)
{
var currentOrgId = _httpContextAccessor.HttpContext!.GetCurrentOrgId();
var entity = await _context.{EntityName}s
.Where(x => x.Id == id && x.OrgId == currentOrgId) // CRITICAL: Verify ownership
.FirstOrDefaultAsync();
if (entity == null)
throw new Exception("{EntityName} not found or access denied");
// Update properties from dto
entity.UpdatedAt = DateTime.UtcNow;
await _context.SaveChangesAsync();
return MapToDto(entity);
}
public async Task DeleteAsync(long id)
{
var currentOrgId = _httpContextAccessor.HttpContext!.GetCurrentOrgId();
var entity = await _context.{EntityName}s
.Where(x => x.Id == id && x.OrgId == currentOrgId) // CRITICAL: Verify ownership
.FirstOrDefaultAsync();
if (entity == null)
throw new Exception("{EntityName} not found or access denied");
_context.{EntityName}s.Remove(entity);
await _context.SaveChangesAsync();
}
private static {EntityName}Dto MapToDto({EntityName}Entity entity)
{
return new {EntityName}Dto
{
Id = entity.Id,
OrgId = entity.OrgId,
// Map properties
CreatedAt = entity.CreatedAt,
UpdatedAt = entity.UpdatedAt
};
}
}
}
Location: backend/omsapi/Controllers/{EntityName}Controller.cs
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace omsapi.Controllers
{
/// <summary>
/// {EntityName} management API
/// </summary>
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class {EntityName}Controller : ControllerBase
{
private readonly I{EntityName}Service _service;
public {EntityName}Controller(I{EntityName}Service service)
{
_service = service;
}
/// <summary>
/// Get {entity} list
/// </summary>
[HttpGet]
public async Task<ApiResponse<List<{EntityName}Dto>>> GetList()
{
var data = await _service.GetListAsync();
return ApiResponse<List<{EntityName}Dto>>.Success(data);
}
/// <summary>
/// Get {entity} by ID
/// </summary>
[HttpGet("{id}")]
public async Task<ApiResponse<{EntityName}Dto>> GetById(long id)
{
var data = await _service.GetByIdAsync(id);
if (data == null)
return ApiResponse<{EntityName}Dto>.Error("Not found");
return ApiResponse<{EntityName}Dto>.Success(data);
}
/// <summary>
/// Create {entity}
/// </summary>
[HttpPost]
public async Task<ApiResponse<{EntityName}Dto>> Create([FromBody] Create{EntityName}Dto dto)
{
var data = await _service.CreateAsync(dto);
return ApiResponse<{EntityName}Dto>.Success(data);
}
/// <summary>
/// Update {entity}
/// </summary>
[HttpPut("{id}")]
public async Task<ApiResponse<{EntityName}Dto>> Update(long id, [FromBody] Update{EntityName}Dto dto)
{
var data = await _service.UpdateAsync(id, dto);
return ApiResponse<{EntityName}Dto>.Success(data);
}
/// <summary>
/// Delete {entity}
/// </summary>
[HttpDelete("{id}")]
public async Task<ApiResponse<object>> Delete(long id)
{
await _service.DeleteAsync(id);
return ApiResponse<object>.Success(null);
}
}
}
[AutoInject] attributeApiResponse<T>.Result or .Wait() calls[Authorize] attribute