Claude-skill-registry add-api-endpoint-tassadar2499-novatune

Add a new minimal API endpoint to NovaTune with service, models, and tests

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/add-api-endpoint-tassadar2499-novatune" ~/.claude/skills/majiayu000-claude-skill-registry-add-api-endpoint-tassadar2499-novatune && rm -rf "$T"
manifest: skills/data/add-api-endpoint-tassadar2499-novatune/SKILL.md
source content

Add API Endpoint Skill

Add a new minimal API endpoint to NovaTune.

Steps

1. Create/Update Request and Response Models

Location:

src/NovaTuneApp/NovaTuneApp.ApiService/Models/

// Models/Requests/CreateTrackRequest.cs
public record CreateTrackRequest(
    string Title,
    string? Description);

// Models/Responses/TrackResponse.cs
public record TrackResponse(
    Guid Id,
    string Title,
    string? Description,
    DateTimeOffset CreatedAt);

2. Create/Update Service

Location:

src/NovaTuneApp/NovaTuneApp.ApiService/Services/

public interface ITrackService
{
    Task<Track> CreateAsync(CreateTrackRequest request, CancellationToken ct);
}

public class TrackService : ITrackService
{
    private readonly IDocumentSession _session;

    public TrackService(IDocumentSession session)
    {
        _session = session;
    }

    public async Task<Track> CreateAsync(CreateTrackRequest request, CancellationToken ct)
    {
        var track = new Track
        {
            Title = request.Title,
            Description = request.Description,
            CreatedAt = DateTimeOffset.UtcNow
        };

        await _session.StoreAsync(track, ct);
        await _session.SaveChangesAsync(ct);

        return track;
    }
}

3. Create Endpoint Group

Location:

src/NovaTuneApp/NovaTuneApp.ApiService/Endpoints/

public static class TrackEndpoints
{
    public static void MapTrackEndpoints(this IEndpointRouteBuilder app)
    {
        var group = app.MapGroup("/api/tracks")
            .WithTags("Tracks")
            .WithOpenApi();

        group.MapPost("/", CreateTrack)
            .WithName("CreateTrack")
            .RequireAuthorization();

        group.MapGet("/{id:guid}", GetTrack)
            .WithName("GetTrack");
    }

    private static async Task<IResult> CreateTrack(
        CreateTrackRequest request,
        ITrackService trackService,
        CancellationToken ct)
    {
        var track = await trackService.CreateAsync(request, ct);
        return TypedResults.Created($"/api/tracks/{track.Id}", track.ToResponse());
    }

    private static async Task<IResult> GetTrack(
        Guid id,
        ITrackService trackService,
        CancellationToken ct)
    {
        var track = await trackService.GetByIdAsync(id, ct);
        return track is null
            ? TypedResults.NotFound()
            : TypedResults.Ok(track.ToResponse());
    }
}

4. Register in Program.cs

// Register service
builder.Services.AddScoped<ITrackService, TrackService>();

// Map endpoints (after app.Build())
app.MapTrackEndpoints();

5. Add Tests

Unit test:

src/unit_tests/TrackServiceTests.cs
Integration test:
src/NovaTuneApp/NovaTuneApp.Tests/TrackEndpoints.IntegrationTests.cs

Conventions

  • Use minimal APIs with
    MapGroup
  • Return
    TypedResults
    for proper OpenAPI schema
  • Use
    WithTags
    and
    WithOpenApi
    for Scalar documentation
  • Add
    RequireAuthorization()
    for protected endpoints
  • Use
    CancellationToken
    in all async methods
  • PascalCase for endpoint names

Response Status Codes

OperationSuccessError
Create201 Created400 Bad Request
Get200 OK404 Not Found
Update200 OK / 204 No Content404 Not Found
Delete204 No Content404 Not Found
List200 OK-

API Documentation

Access Scalar UI at

/scalar/v1
when running the API.