// engine/spec-templates/templates-domain-specific.ts — Domain-specific spec templates A (SPEC-513).
// Auth login, auth OAuth, Stripe payment, and CRUD resource templates.
// Templates 5-8 (REST API integration, webhook, file upload, background job) are in
// templates-domain-specific-b.ts.
import { REST_API_INTEGRATION_TEMPLATE, WEBHOOK_CONSUMER_TEMPLATE, FILE_UPLOAD_TEMPLATE, BACKGROUND_JOB_TEMPLATE, } from './templates-domain-specific-b.js';
export { REST_API_INTEGRATION_TEMPLATE, WEBHOOK_CONSUMER_TEMPLATE, FILE_UPLOAD_TEMPLATE, BACKGROUND_JOB_TEMPLATE, };
/** Auth Login spec template — credential validation, session, rate limiting, lockout. */
export const AUTH_LOGIN_TEMPLATE = {
    id: 'auth-login',
    name: 'Auth: Login',
    category: 'auth',
    description: 'Credential validation, session creation, rate limiting, and failed-attempt account locking.',
    tags: ['auth', 'security', 'login', 'session', 'rate-limiting'],
    complexityScore: 'M',
    estimationBase: {
        hoursMin: 12,
        hoursMax: 24,
        notes: 'Includes rate limiting middleware, lockout storage, and session token management',
    },
    criteria: [
        { id: 'AC-1', title: 'Invalid credentials return 401', required: true },
        { id: 'AC-2', title: 'Session token created on success', required: true },
        { id: 'AC-3', title: 'Account locked after 5 failed attempts', required: true },
        { id: 'AC-4', title: 'Rate limit: 10 req/min per IP', required: true },
    ],
    variables: [
        {
            key: 'EntityName',
            label: 'Entity name',
            description: 'The entity that authenticates (e.g. User, Admin)',
            example: 'User',
            required: true,
        },
        {
            key: 'LockoutDuration',
            label: 'Lockout duration',
            description: 'How long an account stays locked after max failed attempts',
            example: '15 minutes',
            required: false,
            defaultValue: '15 minutes',
        },
    ],
    huTemplate: `# HU: Login for {{EntityName}}

## User Story
As a {{EntityName}}, I want to log in with my credentials so that I can access protected resources securely.

## Acceptance Criteria

### AC-1: Invalid credentials return 401
- GIVEN a {{EntityName}} provides wrong email or password
- WHEN the login endpoint is called
- THEN it returns HTTP 401 with a generic error message (no detail about which field is wrong)

### AC-2: Session token created on success
- GIVEN a {{EntityName}} provides correct credentials
- WHEN the login endpoint is called
- THEN an access token and refresh token are returned
- AND the session is persisted server-side with an expiry

### AC-3: Account locked after 5 failed attempts
- GIVEN a {{EntityName}} has failed login 5 consecutive times
- WHEN the next login attempt occurs within {{LockoutDuration}}
- THEN the account is locked and returns HTTP 423 with lock duration
- AND the lock is released automatically after {{LockoutDuration}}

### AC-4: Rate limit — 10 req/min per IP
- GIVEN any client IP
- WHEN more than 10 login requests are made within 1 minute
- THEN subsequent requests return HTTP 429 with Retry-After header
- AND the rate limit counter resets after 60 seconds

## Out of Scope
- Password reset flow (create separate spec)
- Multi-factor authentication (create separate spec)
`,
    fichaTecnicaTemplate: `# FICHA TÉCNICA: Login for {{EntityName}}

## Affected Files
- auth/login-handler
- auth/rate-limiter (middleware)
- auth/lockout-tracker (storage or cache)
- auth/session-store
- config/auth-config (lockout threshold, window, TTLs)

## Types / Entities
- \`LoginInput\`: email, password
- \`SessionToken\`: accessToken, refreshToken, expiresAt
- \`LockoutRecord\`: entityId, failedCount, lockedUntil

## Risks
- Timing attack on credential comparison → use constant-time compare
- Lockout DoS → require CAPTCHA after 3 failures (future spec)
- Distributed rate limit bypass → use shared cache (Redis) not in-memory

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

## Status: draft

## Criteria
- [ ] AC-1: Invalid credentials return 401
- [ ] AC-2: Session token created on success
- [ ] AC-3: Account locked after 5 failed attempts
- [ ] AC-4: Rate limit — 10 req/min per IP
`,
};
/** Auth OAuth spec template — callback, state validation, token storage. */
export const AUTH_OAUTH_TEMPLATE = {
    id: 'auth-oauth',
    name: 'Auth: OAuth 2.0',
    category: 'auth',
    description: 'OAuth 2.0 callback handling, state validation, token storage, and token rotation.',
    tags: ['auth', 'oauth', 'security', 'social-login', 'csrf'],
    complexityScore: 'M',
    estimationBase: {
        hoursMin: 16,
        hoursMax: 32,
        notes: 'Includes CSRF protection, encrypted token storage, and refresh rotation',
    },
    criteria: [
        { id: 'AC-1', title: 'State param validated to prevent CSRF', required: true },
        { id: 'AC-2', title: 'Access token stored encrypted', required: true },
        { id: 'AC-3', title: 'Refresh token rotation enabled', required: true },
        { id: 'AC-4', title: 'Revoked tokens rejected within 60s', required: true },
    ],
    variables: [
        {
            key: 'Provider',
            label: 'OAuth provider',
            description: 'The OAuth provider to integrate (e.g. Google, GitHub, Microsoft)',
            example: 'Google',
            required: true,
        },
        {
            key: 'CallbackPath',
            label: 'Callback path',
            description: 'The redirect URI path for the OAuth callback',
            example: '/auth/callback',
            required: false,
            defaultValue: '/auth/callback',
        },
    ],
    huTemplate: `# HU: {{Provider}} OAuth 2.0 Authentication

## User Story
As a user, I want to log in with my {{Provider}} account so that I do not need a separate password.

## Acceptance Criteria

### AC-1: State param validated to prevent CSRF
- GIVEN the OAuth flow is initiated
- WHEN the application redirects to {{Provider}}
- THEN a cryptographically random state param is stored server-side (short TTL)
- AND on callback at {{CallbackPath}}, the state in the query string MUST match the stored value
- IF they do not match, the request is rejected with HTTP 400

### AC-2: Access token stored encrypted
- GIVEN the OAuth callback succeeds and an access token is received
- WHEN the token is persisted
- THEN it is stored using AES-256 encryption (or equivalent)
- AND the raw token is never written to logs or returned in API responses

### AC-3: Refresh token rotation enabled
- GIVEN a refresh token is used to obtain a new access token
- WHEN the new tokens are issued
- THEN the old refresh token is immediately invalidated
- AND only the new refresh token is valid for future renewals

### AC-4: Revoked tokens rejected within 60s
- GIVEN a {{Provider}} token is revoked (user disconnects or deauthorizes)
- WHEN the application calls {{Provider}} APIs with that token
- THEN the rejection is detected and the local session is invalidated
- AND the revocation propagation is detectable within 60 seconds

## Out of Scope
- Password-based login (create separate spec)
- Token refresh caching strategies (create separate spec)
`,
    fichaTecnicaTemplate: `# FICHA TÉCNICA: {{Provider}} OAuth 2.0 Authentication

## Affected Files
- auth/oauth-initiate-handler
- auth/oauth-callback-handler ({{CallbackPath}})
- auth/state-store (CSRF state management)
- auth/token-encryptor (AES-256 or equivalent)
- auth/token-store (encrypted token persistence)
- config/oauth-config (client ID, secret, scopes)

## Types / Entities
- \`OAuthState\`: stateToken, createdAt, ttl
- \`OAuthTokenPair\`: accessToken (encrypted), refreshToken (encrypted), expiresAt
- \`OAuthSession\`: userId, provider, tokenPairId, createdAt

## Risks
- State replay attack → short TTL (5 min), single-use, stored in fast cache
- Token leakage in logs → never log raw tokens, use redacted placeholders
- Refresh rotation desync → atomic swap or lock required

## Estimation (rough)
- Dev: 16–32 hours
- Review: 3–5 hours
- Difficulty: 4/5
`,
    progressTemplate: `# PROGRESS: {{Provider}} OAuth 2.0 Authentication

## Status: draft

## Criteria
- [ ] AC-1: State param validated to prevent CSRF
- [ ] AC-2: Access token stored encrypted
- [ ] AC-3: Refresh token rotation enabled
- [ ] AC-4: Revoked tokens rejected within 60s
`,
};
/** Stripe Payment spec template — checkout, webhook verification, refund, retry. */
export const STRIPE_PAYMENT_TEMPLATE = {
    id: 'stripe-payment',
    name: 'Stripe Payment',
    category: 'integration',
    description: 'Stripe checkout sessions, webhook signature verification, refunds, and failed payment retry.',
    tags: ['payments', 'stripe', 'webhook', 'idempotency', 'backend'],
    complexityScore: 'M',
    estimationBase: {
        hoursMin: 20,
        hoursMax: 40,
        notes: 'Includes webhook verification, idempotency, refund flow, and exponential backoff retry',
    },
    criteria: [
        { id: 'AC-1', title: 'Webhook signature validated with Stripe secret', required: true },
        { id: 'AC-2', title: 'Idempotency key prevents duplicate charges', required: true },
        { id: 'AC-3', title: 'Refund creates reversal record', required: true },
        { id: 'AC-4', title: 'Failed payment triggers retry with exponential backoff', required: true },
    ],
    variables: [
        {
            key: 'ProductName',
            label: 'Product or plan name',
            description: 'The product or subscription plan being sold',
            example: 'Pro Plan',
            required: true,
        },
        {
            key: 'WebhookPath',
            label: 'Webhook endpoint path',
            description: 'URL path where Stripe sends webhook events',
            example: '/api/webhooks/stripe',
            required: false,
            defaultValue: '/api/webhooks/stripe',
        },
    ],
    huTemplate: `# HU: Stripe Payment for {{ProductName}}

## User Story
As a customer, I want to pay for {{ProductName}} with Stripe so that my payment is processed securely.

## Acceptance Criteria

### AC-1: Webhook signature validated with Stripe secret
- GIVEN a webhook event arrives at {{WebhookPath}}
- WHEN the handler processes the request
- THEN the Stripe-Signature header is verified using the Stripe signing secret
- AND unverified payloads are rejected with HTTP 400 before any processing

### AC-2: Idempotency key prevents duplicate charges
- GIVEN a checkout session creation request
- WHEN the same idempotency key is sent more than once (e.g. network retry)
- THEN Stripe returns the same session without creating a new charge
- AND the idempotency key is derived from a stable, user-specific value

### AC-3: Refund creates reversal record
- GIVEN a completed payment for {{ProductName}}
- WHEN a refund is issued via the Stripe API
- THEN a reversal record is persisted locally with: originalChargeId, refundId, amount, reason
- AND the user's access or entitlements are updated accordingly

### AC-4: Failed payment triggers retry with exponential backoff
- GIVEN a payment attempt for {{ProductName}} fails (e.g. insufficient funds)
- WHEN the failure webhook is received
- THEN the system schedules a retry with exponential backoff (1h, 2h, 4h)
- AND after 3 failed retries the subscription is suspended and the user notified

## Out of Scope
- Frontend Stripe Elements integration (create separate spec)
- Invoice generation (create separate spec)
`,
    fichaTecnicaTemplate: `# FICHA TÉCNICA: Stripe Payment for {{ProductName}}

## Affected Files
- payments/stripe-client (SDK initialization)
- payments/checkout-handler (session creation)
- payments/webhook-handler ({{WebhookPath}})
- payments/refund-handler
- payments/retry-scheduler (exponential backoff)
- storage/payment-records
- config/stripe-config (keys, webhook secret)

## Types / Entities
- \`CheckoutSession\`: sessionId, customerId, productId, status, idempotencyKey
- \`PaymentRecord\`: chargeId, amount, currency, status, createdAt
- \`RefundRecord\`: refundId, originalChargeId, amount, reason, createdAt
- \`RetryJob\`: paymentId, attemptCount, nextRetryAt, status

## Risks
- Webhook replay → idempotent handlers required for all event types
- Signing secret exposure → environment variable only, never hardcoded
- Double charge on network error → idempotency key mandatory

## Estimation (rough)
- Dev: 20–40 hours
- Review: 4–6 hours
- Difficulty: 4/5
`,
    progressTemplate: `# PROGRESS: Stripe Payment for {{ProductName}}

## Status: draft

## Criteria
- [ ] AC-1: Webhook signature validated with Stripe secret
- [ ] AC-2: Idempotency key prevents duplicate charges
- [ ] AC-3: Refund creates reversal record
- [ ] AC-4: Failed payment triggers retry with exponential backoff
`,
};
/** CRUD Resource spec template — full lifecycle with pagination. */
export const CRUD_RESOURCE_TEMPLATE = {
    id: 'crud-resource',
    name: 'CRUD Resource',
    category: 'crud',
    description: 'Create/read/update/delete with field validation, idempotent updates, soft-delete, and pagination.',
    tags: ['crud', 'rest', 'api', 'pagination', 'soft-delete'],
    complexityScore: 'S',
    estimationBase: {
        hoursMin: 8,
        hoursMax: 16,
        notes: 'Includes field validation (422), soft-delete, and pagination with max 100 items',
    },
    criteria: [
        {
            id: 'AC-1',
            title: 'Create validates required fields, returns 422 on failure',
            required: true,
        },
        { id: 'AC-2', title: 'List supports page/limit params', required: true },
        { id: 'AC-3', title: 'Update is idempotent', required: true },
        { id: 'AC-4', title: 'Delete is soft-delete with deletedAt timestamp', required: true },
        { id: 'AC-5', title: 'Pagination: max 100 items per page', required: true },
    ],
    variables: [
        {
            key: 'ResourceName',
            label: 'Resource name',
            description: 'Singular name of the resource (PascalCase)',
            example: 'Article',
            required: true,
        },
        {
            key: 'ResourcePlural',
            label: 'Resource plural',
            description: 'Plural name of the resource (lowercase, used in URL path)',
            example: 'articles',
            required: true,
        },
    ],
    huTemplate: `# HU: CRUD for {{ResourceName}}

## User Story
As a user, I want to manage {{ResourceName}} records so that I can create, view, update, and remove them.

## Acceptance Criteria

### AC-1: Create validates required fields, returns 422 on failure
- GIVEN a client sends POST /{{ResourcePlural}}
- WHEN any required field is missing or invalid
- THEN the response is HTTP 422 with per-field error messages
- AND when all fields are valid, the created record is returned with its generated ID and timestamps

### AC-2: List supports page/limit params
- GIVEN a client sends GET /{{ResourcePlural}}
- WHEN page and limit query params are provided
- THEN only the requested page slice is returned
- AND the response includes total count and current page metadata

### AC-3: Update is idempotent
- GIVEN a client sends PATCH /{{ResourcePlural}}/:id with the same payload twice
- WHEN the resource has not changed between the two requests
- THEN both return HTTP 200 with the same resource state
- AND no duplicate audit events are created

### AC-4: Delete is soft-delete with deletedAt timestamp
- GIVEN a client sends DELETE /{{ResourcePlural}}/:id
- WHEN the request succeeds
- THEN the record is NOT removed from the database — deletedAt is set to now
- AND subsequent GET /{{ResourcePlural}}/:id returns HTTP 404

### AC-5: Pagination — max 100 items per page
- GIVEN a client requests more than 100 items per page (limit > 100)
- WHEN the list endpoint processes the request
- THEN it returns at most 100 items and ignores the excess limit value
- AND the response metadata indicates the enforced limit

## Out of Scope
- Authorization rules (create separate spec)
- Search/filtering (create separate spec)
`,
    fichaTecnicaTemplate: `# FICHA TÉCNICA: CRUD for {{ResourceName}}

## Affected Files
- handlers/{{ResourcePlural}}/create
- handlers/{{ResourcePlural}}/list
- handlers/{{ResourcePlural}}/get
- handlers/{{ResourcePlural}}/update
- handlers/{{ResourcePlural}}/delete
- storage/{{ResourcePlural}}-repository
- types/{{ResourceName}}
- validation/{{ResourceName}}-schema

## Types / Entities
- \`{{ResourceName}}\`: id, createdAt, updatedAt, deletedAt (nullable)
- \`Create{{ResourceName}}Input\`: validated required + optional fields
- \`Update{{ResourceName}}Input\`: partial fields
- \`List{{ResourceName}}Query\`: page, limit (max 100), sortBy, order

## Risks
- Missing soft-delete → unrecoverable data loss
- No pagination cap → unbounded query performance risk
- Non-idempotent PATCH → duplicate side effects on client retry

## Estimation (rough)
- Dev: 8–16 hours
- Review: 2–3 hours
- Difficulty: 2/5
`,
    progressTemplate: `# PROGRESS: CRUD for {{ResourceName}}

## Status: draft

## Criteria
- [ ] AC-1: Create validates required fields, returns 422 on failure
- [ ] AC-2: List supports page/limit params
- [ ] AC-3: Update is idempotent
- [ ] AC-4: Delete is soft-delete with deletedAt timestamp
- [ ] AC-5: Pagination — max 100 items per page
`,
};
/** All 8 domain-specific templates for SPEC-513. */
export const DOMAIN_SPECIFIC_TEMPLATES = [
    AUTH_LOGIN_TEMPLATE,
    AUTH_OAUTH_TEMPLATE,
    STRIPE_PAYMENT_TEMPLATE,
    CRUD_RESOURCE_TEMPLATE,
    REST_API_INTEGRATION_TEMPLATE,
    WEBHOOK_CONSUMER_TEMPLATE,
    FILE_UPLOAD_TEMPLATE,
    BACKGROUND_JOB_TEMPLATE,
];
//# sourceMappingURL=templates-domain-specific.js.map