codeflash-internal/tiles/codeflash-internal-skills/skills/add-api-endpoint/SKILL.md
Kevin Turcios dfc56f19a0 feat: add Tessl tiles for codeflash-internal (rules, docs, skills)
Three private tiles published to the codeflash workspace:
- codeflash-internal-rules: 6 eager rules (code-style, architecture,
  optimization-patterns, git-conventions, testing-rules, multi-language-handlers)
- codeflash-internal-docs: 8 lazy doc pages (domain-types, optimization-pipeline,
  test-generation-pipeline, context-extraction, aiservice/cf-api endpoints,
  configuration-thresholds, llm-provider-abstraction)
- codeflash-internal-skills: 4 on-demand skills (debug-optimization-failure,
  add-language-support, add-api-endpoint, debug-test-generation)
2026-02-14 22:16:33 -05:00

5.3 KiB

name description
add-api-endpoint Guide for adding a new API endpoint to the codeflash-internal system. Use when adding a new endpoint, creating a route, or implementing a new API. Covers both aiservice (Django-Ninja) and cf-api (Express) endpoints including schemas, routers, authentication, URL registration, and tests.

Add API Endpoint

Use this workflow when adding a new endpoint to either the aiservice backend or the cf-api middleware. Follow the section that matches your target service.

Part A: AIService Endpoint (Django-Ninja)

Step 1: Define Schemas

Create request and response schemas.

  1. Create or update schemas in the appropriate module (e.g., core/shared/ for shared, core/languages/python/ for Python-specific)
  2. Use ninja.Schema for all request/response types:
    from ninja import Schema
    
    class MyRequestSchema(Schema):
        source_code: str
        trace_id: str
        language: str = "python"
    
    class MyResponseSchema(Schema):
        results: list[str]
    
    class MyErrorResponseSchema(Schema):
        message: str
    
  3. Follow existing patterns in core/shared/optimizer_models.py

Checkpoint: Schemas should use Pydantic validation. Test with MyRequestSchema.model_validate(data).

Step 2: Create the Router

Create a NinjaAPI router for the endpoint.

  1. Create a new module (e.g., core/shared/my_feature.py or core/languages/python/my_feature/my_feature.py)
  2. Define the router and endpoint:
    from ninja import NinjaAPI
    from authapp.auth import AuthenticatedRequest
    
    my_feature_api = NinjaAPI(urls_namespace="my_feature")
    
    @my_feature_api.post(
        "/", response={200: MyResponseSchema, 400: MyErrorResponseSchema, 500: MyErrorResponseSchema}
    )
    async def my_endpoint(
        request: AuthenticatedRequest, data: MyRequestSchema
    ) -> tuple[int, MyResponseSchema | MyErrorResponseSchema]:
        # Implementation here
        return 200, MyResponseSchema(results=[])
    
  3. All endpoints must be async def
  4. Use AuthenticatedRequest for authenticated endpoints
  5. For multi-language endpoints, add dispatch by data.language with lazy imports

Checkpoint: The endpoint should handle success and error cases with proper status codes.

Step 3: Register in urls.py

Add the endpoint to aiservice/urls.py.

  1. Import the API object:
    from core.shared.my_feature import my_feature_api
    
  2. Add to urlpatterns:
    path("ai/my-feature", my_feature_api.urls),
    
  3. Follow the naming convention: ai/<kebab-case-name>

Checkpoint: The endpoint should be accessible at /ai/my-feature/.

Step 4: Add Tests

Write tests for the endpoint.

  1. Create test file in tests/ matching the source structure
  2. Test the handler function directly (not via HTTP):
    @pytest.mark.asyncio
    async def test_my_endpoint():
        # Mock request and data
        result = await my_endpoint(mock_request, mock_data)
        assert result[0] == 200
    
  3. Run: uv run pytest tests/path/test_file.py -v

Checkpoint: Tests pass. Run uv run prek run --all-files.

Part B: CF-API Endpoint (Express)

Step 1: Create Endpoint Handler

Create the endpoint handler in js/cf-api/endpoints/.

  1. Create js/cf-api/endpoints/my-feature.ts:
    import { Request, Response } from "express"
    
    export async function myFeature(req: Request, res: Response) {
        // Implementation
        res.status(200).json({ results: [] })
    }
    
  2. Follow existing patterns in endpoints/

Checkpoint: Handler should return appropriate status codes and JSON responses.

Step 2: Create Route File or Add to Existing

Add the route to the appropriate route file.

  1. If it's a new domain, create js/cf-api/routes/my-feature.routes.ts:
    import { Router } from "express"
    import { addAsync } from "@awaitjs/express"
    import { myFeature } from "../endpoints/my-feature.js"
    import { ROUTES } from "../constants/index.js"
    
    const router = addAsync(Router()) as any
    router.postAsync(ROUTES.MY_FEATURE, myFeature)
    export default router
    
  2. If it belongs to an existing domain, add to the corresponding route file
  3. Add the route constant to constants/index.ts

Checkpoint: Route file exports a router with the endpoint registered.

Step 3: Register in Route Index

Register the route in js/cf-api/routes/index.ts.

  1. Import the route module
  2. Register in the correct section:
    • Before body parser: webhook routes only
    • Public routes: no auth required
    • Protected routes: after checkForValidAPIKey middleware
  3. Apply middleware as needed (trackUsage, idLimiter, etc.)

Checkpoint: The endpoint should be accessible with proper authentication.

Step 4: Add Tests

Write tests using the dependency injection pattern.

  1. Create test file in js/cf-api/__tests__/
  2. Use setXxxDependencies() / resetXxxDependencies() for mocking
  3. Follow existing test patterns

Checkpoint: Tests pass with npm test.

Key Files Reference

File What to modify
core/shared/optimizer_models.py Schema patterns
aiservice/urls.py AIService endpoint registration
js/cf-api/routes/index.ts CF-API route registration
js/cf-api/constants/index.ts Route constants
authapp/auth.py Authentication patterns