بنقرة واحدة
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