openapi: 3.0.3
info:
  title: eCosif Auth API
  version: 0.7.05.202606171
  description: |
    API de autenticação do eCosif — emite **JWT ECOSIF** (Modo A) para microsserviços e integrações.
    
    ## Login (sem Bearer)
    
    | Método | Rota | Uso |
    |--------|------|-----|
    | POST | `/api/auth/signin` | Local (usuário/senha) — `ecosif-automations` |
    | POST | `/api/auth/external-login` | Microsoft Entra, Azure Enterprise ou Google (`id_token`) |
    
    **Removidos (MVP3):** `POST /api/auth/signin-azure` (**404**); `signin` com `"azure": true` (**400**).
    
    ## Endpoints protegidos
    
    1. Obtenha `accessToken` em um dos endpoints de login
    2. Envie `Authorization: Bearer <token>`
    
    TTL do JWT: `TOKEN_EXPIRATION` (padrão 30 min). Renovação de sessão no Angular via `GET /ecosif-masterdata/user`.
  contact:
    name: eCosif Team
    email: support@ecosif.net.br
    url: https://www.ecosif.net.br
  license:
    name: Commercial License
    url: https://www.ecosif.net.br/licenses/

servers:
  - url: http://localhost/ecosif-auth
    description: Dev via Traefik (proxy :80)
  - url: http://localhost:8081/ecosif-auth
    description: Dev direto (porta auth)
  - url: https://api.ecosif.net.br/ecosif-auth
    description: Produção (ajustar host)

tags:
  - name: Autenticação
    description: Login local (`signin`)
  - name: Autenticação externa
    description: Login via IdP (`external-login`)
  - name: Admin - Docker Logs
    description: Endpoints administrativos (requer JWT)

components:
  securitySchemes:
    bearer-jwt:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        JWT ECOSIF (HS512). Obtenha via `POST /api/auth/signin` ou `POST /api/auth/external-login`.
        Header: `Authorization: Bearer <accessToken>`
  
  schemas:
    LoginRequest:
      type: object
      required:
        - username
        - password
      properties:
        username:
          type: string
          description: Username/email do usuário
          example: usuario@exemplo.com
        password:
          type: string
          description: Senha do usuário
          example: senha123
        azure:
          type: boolean
          deprecated: true
          description: Legado MVP3. Se true retorna 400 — use external-login.
    
    ExternalLoginRequest:
      type: object
      required:
        - provider
        - token
      properties:
        provider:
          type: string
          enum: [AZURE, AZURE_ENTERPRISE, GOOGLE]
          example: AZURE
        token:
          type: string
          description: id_token do IdP (nunca logar em produção)
        tokenType:
          type: string
          enum: [ID_TOKEN, ACCESS_TOKEN]
          default: ID_TOKEN
          example: ID_TOKEN
    
    JwtAuthenticationResponse:
      type: object
      properties:
        accessToken:
          type: string
          description: Token JWT para autenticação
          example: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3VhcmlvQGV4ZW1wbG8uY29tIiwiaWF0IjoxNjQwMDAwMDAwLCJleHAiOjE2NDAwMTgwMDB9.xyz
        user:
          $ref: '#/components/schemas/UserInfo'
        tenantName:
          type: string
          description: Nome do tenant/empresa do usuário
          example: empresa-exemplo
    
    UserInfo:
      type: object
      properties:
        id:
          type: string
          description: ID do usuário
          example: "1"
        displayName:
          type: string
          description: Nome completo do usuário
          example: João Silva
        email:
          type: string
          description: Email do usuário
          example: joao.silva@exemplo.com
        roles:
          type: array
          items:
            type: string
          description: Lista de roles/perfis do usuário
          example: ["ADMIN"]
        tenant:
          type: string
          description: Tenant/empresa do usuário
          example: empresa-exemplo
    
    ApiResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Indica se a operação foi bem-sucedida
          example: false
        message:
          type: string
          description: Mensagem de resposta
          example: Usuário inativo
    
    Error:
      type: object
      properties:
        error:
          type: string
          description: Mensagem de erro
        availableServices:
          type: array
          items:
            type: string
          description: Lista de serviços disponíveis (para erro de serviço não encontrado)
    
    DockerLogsResponse:
      type: object
      properties:
        service:
          type: string
          description: Nome do serviço solicitado
          example: ecosif-auth
        containerName:
          type: string
          description: Nome do container Docker
          example: ecosif-auth
        lines:
          type: integer
          description: Número de linhas retornadas
          example: 100
        logs:
          type: string
          description: Logs do container
    
    AvailableServicesResponse:
      type: object
      properties:
        services:
          type: array
          items:
            type: string
          description: Lista de serviços disponíveis
        serviceToContainer:
          type: object
          additionalProperties:
            type: string
          description: Mapeamento de serviços para containers

paths:
  /api/auth/signin:
    post:
      tags:
        - Autenticação
      summary: Autenticar usuário
      description: |
        Autentica um usuário **local** (username + password) e retorna JWT ECOSIF.
        
        Login Microsoft/Google: use `POST /api/auth/external-login`.
        Se enviar `"azure": true` retorna **400** (legado removido).
      operationId: authenticateUser
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
            examples:
              local:
                summary: Autenticação local
                value:
                  username: usuario@exemplo.com
                  password: senha123
      responses:
        '200':
          description: Autenticação bem-sucedida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JwtAuthenticationResponse'
              example:
                accessToken: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c3VhcmlvQGV4ZW1wbG8uY29tIiwiaWF0IjoxNjQwMDAwMDAwLCJleHAiOjE2NDAwMTgwMDB9.xyz
                user:
                  id: "1"
                  displayName: João Silva
                  email: joao.silva@exemplo.com
                  roles: ["ADMIN"]
                  tenant: empresa-exemplo
                tenantName: empresa-exemplo
        '400':
          description: Validação ou legado `"azure": true`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              examples:
                validation:
                  summary: Campo obrigatório ausente
                  value:
                    success: false
                    message: Username é obrigatório
                legacyAzure:
                  summary: Legado azure no signin
                  value:
                    success: false
                    message: Login Azure via signin removido (MVP3). Use POST /api/auth/external-login
        '401':
          description: Credenciais inválidas, usuário inativo ou expirado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              examples:
                invalidCredentials:
                  summary: Credenciais inválidas
                  value:
                    success: false
                    message: Usuário ou senha incorretos
                inactiveUser:
                  summary: Usuário inativo
                  value:
                    success: false
                    message: Usuário inativo
                expiredUser:
                  summary: Usuário expirado
                  value:
                    success: false
                    message: O usuário expirou
        '500':
          description: Erro interno do servidor
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                success: false
                message: Erro interno do servidor
  
  /api/auth/external-login:
    post:
      tags:
        - Autenticação externa
      summary: Autenticar via provedor externo
      description: |
        Valida token do IdP (JWKS) e emite JWT ECOSIF.
        Provedores: `AZURE`, `AZURE_ENTERPRISE`, `GOOGLE`.
        Substitui o legado `POST /api/auth/signin-azure` (404).
      operationId: externalLogin
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExternalLoginRequest'
            example:
              provider: AZURE
              token: "<id_token>"
              tokenType: ID_TOKEN
      responses:
        '200':
          description: Autenticação bem-sucedida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JwtAuthenticationResponse'
        '400':
          description: Body inválido ou provider não habilitado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
        '401':
          description: Token IdP inválido ou usuário inativo/expirado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
        '404':
          description: Usuário não encontrado (auto-provision desligado)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
  
  /api/admin/docker-logs:
    get:
      tags:
        - Admin - Docker Logs
      summary: Obter logs de um container Docker
      description: |
        Retorna os logs do container Docker especificado.
        
        Requer autenticação JWT válida.
        
        Serviços disponíveis: ecosif-auth, ecosif-masterdata, ecosif-moviments, ecosif-querys, ecosif-reports, ecosif-compliance, ecosif-angular, nginx, postgres
      operationId: getDockerLogs
      security:
        - bearer-jwt: []
      parameters:
        - name: service
          in: query
          required: true
          description: Nome do serviço (ex: ecosif-auth, ecosif-masterdata)
          schema:
            type: string
            enum:
              - ecosif-auth
              - ecosif-masterdata
              - ecosif-moviments
              - ecosif-querys
              - ecosif-reports
              - ecosif-compliance
              - ecosif-angular
              - nginx
              - postgres
          example: ecosif-auth
        - name: lines
          in: query
          required: false
          description: Número de linhas a retornar (padrão: 100)
          schema:
            type: integer
            default: 100
            minimum: 1
            maximum: 1000
          example: 100
      responses:
        '200':
          description: Logs obtidos com sucesso
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DockerLogsResponse'
              example:
                service: ecosif-auth
                containerName: ecosif-auth
                lines: 100
                logs: "2024-01-01 10:00:00.000 INFO  [main] Application started..."
        '400':
          description: Serviço não encontrado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Serviço não encontrado: servico-inexistente
                availableServices:
                  - ecosif-auth
                  - ecosif-masterdata
                  - ecosif-moviments
        '401':
          description: Não autenticado - token JWT inválido ou ausente
        '500':
          description: Erro ao executar comando docker logs
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
  
  /api/admin/docker-logs/services:
    get:
      tags:
        - Admin - Docker Logs
      summary: Listar serviços disponíveis
      description: |
        Retorna a lista de serviços disponíveis para visualização de logs.
        
        Requer autenticação JWT válida.
      operationId: getAvailableServices
      security:
        - bearer-jwt: []
      responses:
        '200':
          description: Lista de serviços obtida com sucesso
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AvailableServicesResponse'
              example:
                services:
                  - ecosif-auth
                  - ecosif-masterdata
                  - ecosif-moviments
                  - ecosif-querys
                  - ecosif-reports
                  - ecosif-compliance
                  - ecosif-angular
                  - nginx
                  - postgres
                serviceToContainer:
                  ecosif-auth: ecosif-auth
                  ecosif-masterdata: ecosif-masterdata
                  postgres: ecosif-postgres
        '401':
          description: Não autenticado - token JWT inválido ou ausente

