// engine/spec-templates/templates-domain-specific-b.ts — Domain-specific templates B (SPEC-513).
// REST API integration, webhook consumer, file upload, and background job templates.
/** REST API Integration spec template — auth header, retry, error mapping, timeout. */
export const REST_API_INTEGRATION_TEMPLATE = {
    id: 'rest-api-integration',
    name: 'REST API Integration',
    category: 'integration',
    description: 'External REST API client with auth header injection, retry on 429, error mapping, and timeout.',
    tags: ['api', 'integration', 'http', 'retry', 'timeout', 'error-handling'],
    complexityScore: 'M',
    estimationBase: {
        hoursMin: 12,
        hoursMax: 24,
        notes: 'Includes retry logic with backoff, timeout enforcement, and error type mapping',
    },
    criteria: [
        { id: 'AC-1', title: 'Auth header injected on every request', required: true },
        { id: 'AC-2', title: '429 responses trigger 60s backoff retry', required: true },
        { id: 'AC-3', title: '5xx errors mapped to internal error type', required: true },
        { id: 'AC-4', title: 'Requests timeout after 10s', required: true },
    ],
    variables: [
        {
            key: 'ServiceName',
            label: 'API service name',
            description: 'Name of the external service being integrated',
            example: 'WeatherAPI',
            required: true,
        },
        {
            key: 'BaseUrl',
            label: 'Base URL',
            description: 'Base URL of the external API',
            example: 'https://api.example.com/v1',
            required: true,
        },
    ],
    huTemplate: `# HU: {{ServiceName}} REST API Integration

## User Story
As a developer, I want to call the {{ServiceName}} API reliably so that failures are handled gracefully.

## Acceptance Criteria

### AC-1: Auth header injected on every request
- GIVEN any outbound request to {{BaseUrl}}
- WHEN the HTTP client is used
- THEN the Authorization header is automatically injected from the configured credentials
- AND no request can be made without a valid auth header

### AC-2: 429 responses trigger 60s backoff retry
- GIVEN the {{ServiceName}} API returns HTTP 429 (Too Many Requests)
- WHEN the client receives the response
- THEN the request is retried after 60 seconds (or Retry-After header value if present)
- AND the retry is transparent to the caller

### AC-3: 5xx errors mapped to internal error type
- GIVEN the {{ServiceName}} API returns any 5xx status code
- WHEN the client receives the response
- THEN it is mapped to an internal \`ExternalServiceError\` type with: statusCode, serviceName, requestId
- AND the original error details are logged for debugging

### AC-4: Requests timeout after 10s
- GIVEN a request to {{BaseUrl}} is in flight
- WHEN no response is received within 10 seconds
- THEN the request is aborted and a \`TimeoutError\` is returned to the caller
- AND the error includes the endpoint and elapsed time

## Out of Scope
- Circuit breaker (create separate spec)
- Response caching (create separate spec)
`,
    fichaTecnicaTemplate: `# FICHA TÉCNICA: {{ServiceName}} REST API Integration

## Affected Files
- integrations/{{ServiceName}}/http-client
- integrations/{{ServiceName}}/auth-interceptor
- integrations/{{ServiceName}}/retry-policy
- integrations/{{ServiceName}}/error-mapper
- config/{{ServiceName}}-config (baseUrl, timeout, credentials)

## Types / Entities
- \`{{ServiceName}}Config\`: baseUrl, authToken, timeoutMs, maxRetries
- \`ExternalServiceError\`: statusCode, serviceName, requestId, message
- \`TimeoutError\`: endpoint, elapsedMs, message

## Risks
- Credentials in code → environment variables only
- No retry cap → infinite retry loop possible
- Missing timeout → thread/connection starvation

## Estimation (rough)
- Dev: 12–24 hours
- Review: 2–4 hours
- Difficulty: 3/5
`,
    progressTemplate: `# PROGRESS: {{ServiceName}} REST API Integration

## Status: draft

## Criteria
- [ ] AC-1: Auth header injected on every request
- [ ] AC-2: 429 responses trigger 60s backoff retry
- [ ] AC-3: 5xx errors mapped to internal error type
- [ ] AC-4: Requests timeout after 10s
`,
};
/** Webhook Consumer spec template — signature, idempotency, dead letter queue. */
export const WEBHOOK_CONSUMER_TEMPLATE = {
    id: 'webhook-consumer',
    name: 'Webhook Consumer',
    category: 'integration',
    description: 'Incoming webhook handling with HMAC-SHA256 signature validation, idempotency, and dead-letter queue.',
    tags: ['webhook', 'security', 'idempotency', 'dlq', 'hmac', 'backend'],
    complexityScore: 'M',
    estimationBase: {
        hoursMin: 14,
        hoursMax: 28,
        notes: 'Includes HMAC validation, event deduplication, retry queue, and DLQ management',
    },
    criteria: [
        {
            id: 'AC-1',
            title: 'HMAC-SHA256 signature validated before processing',
            required: true,
        },
        { id: 'AC-2', title: 'Event ID stored to prevent duplicates', required: true },
        {
            id: 'AC-3',
            title: 'Failed events queued for retry (max 3 attempts)',
            required: true,
        },
        { id: 'AC-4', title: 'Dead-letter queue after max retries', required: true },
    ],
    variables: [
        {
            key: 'ProviderName',
            label: 'Webhook provider name',
            description: 'Name of the service sending the webhooks',
            example: 'GitHub',
            required: true,
        },
        {
            key: 'EndpointPath',
            label: 'Webhook endpoint path',
            description: 'URL path that receives the webhook POST requests',
            example: '/api/webhooks/github',
            required: false,
            defaultValue: '/api/webhooks',
        },
    ],
    huTemplate: `# HU: {{ProviderName}} Webhook Consumer

## User Story
As a backend service, I want to receive {{ProviderName}} webhook events reliably so that they are processed exactly once.

## Acceptance Criteria

### AC-1: HMAC-SHA256 signature validated before processing
- GIVEN a POST request arrives at {{EndpointPath}}
- WHEN the handler processes the request
- THEN the HMAC-SHA256 signature in the header is computed using the shared secret and compared to the payload digest
- AND requests with invalid or missing signatures are rejected with HTTP 401 before any processing

### AC-2: Event ID stored to prevent duplicates
- GIVEN a {{ProviderName}} event with a unique event ID is received
- WHEN the event is processed successfully
- THEN the event ID is stored (e.g. in a seen-events set with TTL)
- AND if the same event ID arrives again, it is acknowledged (HTTP 200) but not reprocessed

### AC-3: Failed events queued for retry (max 3 attempts)
- GIVEN a webhook event processing fails (exception or non-2xx downstream call)
- WHEN the failure is caught
- THEN the event is placed in a retry queue with attempt count
- AND retried up to 3 times with exponential backoff between attempts

### AC-4: Dead-letter queue after max retries
- GIVEN a webhook event has failed 3 consecutive processing attempts
- WHEN the final retry fails
- THEN the event is moved to a dead-letter queue (DLQ)
- AND an alert is triggered so the on-call team can inspect and replay it manually

## Out of Scope
- Webhook registration and management UI (create separate spec)
- Event sourcing / event log (create separate spec)
`,
    fichaTecnicaTemplate: `# FICHA TÉCNICA: {{ProviderName}} Webhook Consumer

## Affected Files
- webhooks/{{ProviderName}}/receiver ({{EndpointPath}})
- webhooks/{{ProviderName}}/signature-validator (HMAC-SHA256)
- webhooks/{{ProviderName}}/deduplicator (seen-events store)
- webhooks/{{ProviderName}}/retry-queue
- webhooks/{{ProviderName}}/dlq-handler
- config/{{ProviderName}}-webhook-config (signing secret, max retries)

## Types / Entities
- \`WebhookEvent\`: eventId, type, payload, receivedAt, signature
- \`ProcessingAttempt\`: eventId, attemptNumber, result, errorMessage, attemptedAt
- \`DeadLetterEntry\`: eventId, payload, failureReason, movedAt

## Risks
- Signature timing attack → constant-time comparison required
- High retry storm → cap concurrency + exponential backoff
- DLQ overflow → alert and cap DLQ size

## Estimation (rough)
- Dev: 14–28 hours
- Review: 3–5 hours
- Difficulty: 3/5
`,
    progressTemplate: `# PROGRESS: {{ProviderName}} Webhook Consumer

## Status: draft

## Criteria
- [ ] AC-1: HMAC-SHA256 signature validated before processing
- [ ] AC-2: Event ID stored to prevent duplicates
- [ ] AC-3: Failed events queued for retry (max 3 attempts)
- [ ] AC-4: Dead-letter queue after max retries
`,
};
/** File Upload spec template — size limits, type validation, secure storage. */
export const FILE_UPLOAD_TEMPLATE = {
    id: 'file-upload',
    name: 'File Upload',
    category: 'api',
    description: 'Secure file upload with size enforcement, MIME type allowlist, UUID naming, and virus scanning.',
    tags: ['file-upload', 'security', 'storage', 'mime', 'virus-scan'],
    complexityScore: 'M',
    estimationBase: {
        hoursMin: 12,
        hoursMax: 24,
        notes: 'Includes size enforcement, MIME validation, UUID renaming, and virus scan integration',
    },
    criteria: [
        { id: 'AC-1', title: 'Max file size 10MB enforced', required: true },
        { id: 'AC-2', title: 'MIME type validated against allowlist', required: true },
        { id: 'AC-3', title: 'File stored with UUID name to prevent path traversal', required: true },
        { id: 'AC-4', title: 'Virus scan before processing', required: false },
    ],
    variables: [
        {
            key: 'ResourceName',
            label: 'Resource that owns the file',
            description: 'The resource the file is attached to (e.g. User, Post, Invoice)',
            example: 'User',
            required: true,
        },
        {
            key: 'AllowedTypes',
            label: 'Allowed MIME types',
            description: 'Comma-separated list of accepted MIME types',
            example: 'image/png, image/jpeg, application/pdf',
            required: false,
            defaultValue: 'image/png, image/jpeg, application/pdf',
        },
    ],
    huTemplate: `# HU: File Upload for {{ResourceName}}

## User Story
As a {{ResourceName}}, I want to upload files securely so that malicious content is rejected before storage.

## Acceptance Criteria

### AC-1: Max file size 10MB enforced
- GIVEN a client uploads a file larger than 10MB
- WHEN the upload request is received
- THEN it is rejected with HTTP 413 and an error message indicating the size limit
- AND the file is never written to disk or object storage

### AC-2: MIME type validated against allowlist
- GIVEN a client uploads a file
- WHEN the server receives it
- THEN the MIME type is validated against the allowlist: {{AllowedTypes}}
- AND the server inspects the file magic bytes (not just the Content-Type header)
- AND unsupported types are rejected with HTTP 415

### AC-3: File stored with UUID name to prevent path traversal
- GIVEN a valid file is accepted
- WHEN it is stored
- THEN the original filename is discarded and replaced with a UUID-based name (e.g. \`{uuid}.{ext}\`)
- AND the storage path does not include any user-supplied path segments

### AC-4: Virus scan before processing
- GIVEN a valid file passes size and MIME checks
- WHEN it is queued for storage
- THEN a ClamAV (or equivalent) scan is performed before the file is made accessible
- AND infected files are quarantined and the upload is rejected with HTTP 422

## Out of Scope
- CDN distribution (create separate spec)
- Image resizing / transcoding (create separate spec)
`,
    fichaTecnicaTemplate: `# FICHA TÉCNICA: File Upload for {{ResourceName}}

## Affected Files
- uploads/upload-handler (size + MIME enforcement)
- uploads/mime-validator (magic bytes inspection)
- uploads/uuid-namer (path traversal prevention)
- uploads/virus-scanner (ClamAV or equivalent adapter)
- storage/file-store (object storage adapter)
- config/upload-config (maxSizeBytes, allowedMimeTypes)

## Types / Entities
- \`UploadRequest\`: originalFilename, mimeType, sizeBytes, content
- \`StoredFile\`: storagePath, uuidName, originalMime, uploadedAt, {{ResourceName}}Id
- \`ScanResult\`: clean | infected | error; quarantinePath?

## Risks
- MIME spoofing via Content-Type header → must inspect file magic bytes
- Path traversal via filename → always use UUID, never trust user input
- Large upload blocking server → streaming multipart, early size rejection

## Estimation (rough)
- Dev: 12–24 hours
- Review: 2–4 hours
- Difficulty: 3/5
`,
    progressTemplate: `# PROGRESS: File Upload for {{ResourceName}}

## Status: draft

## Criteria
- [ ] AC-1: Max file size 10MB enforced
- [ ] AC-2: MIME type validated against allowlist
- [ ] AC-3: File stored with UUID name to prevent path traversal
- [ ] AC-4: Virus scan before processing
`,
};
/** Background Job spec template — retry, failure handling, observability. */
export const BACKGROUND_JOB_TEMPLATE = {
    id: 'background-job',
    name: 'Background Job',
    category: 'infra',
    description: 'Reliable background job execution with retry, failure events, duration tracking, and concurrency limits.',
    tags: ['job', 'queue', 'retry', 'observability', 'concurrency', 'backend'],
    complexityScore: 'M',
    estimationBase: {
        hoursMin: 12,
        hoursMax: 24,
        notes: 'Includes retry with backoff, error events, metrics integration, and per-queue concurrency control',
    },
    criteria: [
        {
            id: 'AC-1',
            title: 'Job retries up to 3 times with exponential backoff',
            required: true,
        },
        {
            id: 'AC-2',
            title: 'Failed jobs emit error event with stack trace',
            required: true,
        },
        { id: 'AC-3', title: 'Job duration tracked in metrics', required: true },
        { id: 'AC-4', title: 'Concurrent job limit enforced per queue', required: true },
    ],
    variables: [
        {
            key: 'JobName',
            label: 'Job name',
            description: 'Name of the background job (e.g. SendEmailJob, ResizeImageJob)',
            example: 'SendEmailJob',
            required: true,
        },
        {
            key: 'QueueName',
            label: 'Queue name',
            description: 'Name of the queue this job runs in',
            example: 'email',
            required: false,
            defaultValue: 'default',
        },
        {
            key: 'MaxConcurrency',
            label: 'Max concurrent jobs',
            description: 'Maximum jobs allowed to run simultaneously in the queue',
            example: '5',
            required: false,
            defaultValue: '5',
        },
    ],
    huTemplate: `# HU: Background Job — {{JobName}}

## User Story
As the platform, I want {{JobName}} to run reliably in the background so that failures are retried and monitored.

## Acceptance Criteria

### AC-1: Job retries up to 3 times with exponential backoff
- GIVEN {{JobName}} fails (throws an exception)
- WHEN the job runner catches the failure
- THEN the job is rescheduled with exponential backoff: attempt 1 → 1min, attempt 2 → 4min, attempt 3 → 16min
- AND after 3 failed attempts, the job is marked as permanently failed (no more retries)

### AC-2: Failed jobs emit error event with stack trace
- GIVEN {{JobName}} reaches its final failure state
- WHEN the failure is recorded
- THEN an \`job.failed\` error event is emitted containing: jobId, jobName, attemptCount, errorMessage, stackTrace
- AND the event is observable via the application's error tracking system

### AC-3: Job duration tracked in metrics
- GIVEN {{JobName}} starts execution
- WHEN it completes (success or failure)
- THEN the execution duration in milliseconds is recorded in the metrics system
- AND the metric is tagged with: jobName={{JobName}}, queue={{QueueName}}, status=success|failed

### AC-4: Concurrent job limit enforced per queue
- GIVEN the "{{QueueName}}" queue already has {{MaxConcurrency}} jobs running
- WHEN a new {{JobName}} is enqueued
- THEN it waits in the queue until a slot is available (no new workers spawned beyond the limit)
- AND the concurrency limit is configurable without code changes

## Out of Scope
- Job scheduling / cron triggers (create separate spec)
- Job result storage / history UI (create separate spec)
`,
    fichaTecnicaTemplate: `# FICHA TÉCNICA: Background Job — {{JobName}}

## Affected Files
- jobs/{{JobName}}/handler
- jobs/{{JobName}}/retry-policy (exponential backoff config)
- jobs/queue-manager (concurrency enforcement for "{{QueueName}}")
- jobs/event-emitter (job.failed event)
- monitoring/job-metrics (duration tracking)
- config/queue-config (maxConcurrency={{MaxConcurrency}}, retryDelays)

## Types / Entities
- \`JobContext\`: jobId, jobName, queue, attemptNumber, enqueuedAt
- \`JobResult\`: status: 'success' | 'failed', durationMs, errorMessage?
- \`JobFailedEvent\`: jobId, jobName, attemptCount, errorMessage, stackTrace, failedAt

## Risks
- Unbounded concurrency → resource exhaustion
- Missing idempotency → duplicate side effects on retry
- Retry storm on mass failure → jitter required in backoff

## Estimation (rough)
- Dev: 12–24 hours
- Review: 2–4 hours
- Difficulty: 3/5
`,
    progressTemplate: `# PROGRESS: Background Job — {{JobName}}

## Status: draft

## Criteria
- [ ] AC-1: Job retries up to 3 times with exponential backoff
- [ ] AC-2: Failed jobs emit error event with stack trace
- [ ] AC-3: Job duration tracked in metrics
- [ ] AC-4: Concurrent job limit enforced per queue
`,
};
//# sourceMappingURL=templates-domain-specific-b.js.map