> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thenewscc.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Criar Grupo de Amigos

> Cria um novo grupo de amigos para competições privadas de streak

## Descrição

Cria um novo grupo de amigos para competições privadas de streak. O usuário que cria o grupo automaticamente se torna o primeiro membro e pode convidar outros leitores.

## Autenticação

<Note>
  Esta rota requer autenticação JWT. O usuário autenticado será definido como dono do grupo.
</Note>

## Request Body

<ParamField body="groupName" type="string" required>
  Nome do grupo (máximo 100 caracteres)
</ParamField>

<ParamField body="description" type="string">
  Descrição opcional do grupo (máximo 500 caracteres)
</ParamField>

<ParamField body="isPublic" type="boolean" default="false">
  Se o grupo é público (qualquer um pode ver) ou privado (apenas membros)
</ParamField>

<ParamField body="maxMembers" type="number" default="50">
  Limite máximo de membros (máximo 200)
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  Indica se a criação foi bem-sucedida
</ResponseField>

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="groupId" type="string">
      ID único do grupo (10 caracteres)
    </ResponseField>

    <ResponseField name="groupName" type="string">
      Nome do grupo
    </ResponseField>

    <ResponseField name="description" type="string">
      Descrição do grupo
    </ResponseField>

    <ResponseField name="ownerEmail" type="string">
      Email do criador/dono do grupo
    </ResponseField>

    <ResponseField name="isPublic" type="number">
      Se o grupo é público (1) ou privado (0)
    </ResponseField>

    <ResponseField name="maxMembers" type="number">
      Limite máximo de membros
    </ResponseField>

    <ResponseField name="memberCount" type="number">
      Número atual de membros (sempre 1 na criação)
    </ResponseField>

    <ResponseField name="createdAt" type="number">
      Timestamp de criação (Unix timestamp)
    </ResponseField>

    <ResponseField name="updatedAt" type="number">
      Timestamp da última atualização
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://backend.testeswaffle.org/streaks/groups' \
    --header 'Authorization: Bearer SEU_JWT_TOKEN' \
    --header 'Content-Type: application/json' \
    --data '{
      "groupName": "Leitores do Escritório",
      "description": "Grupo da nossa equipe para competir nos streaks de leitura",
      "isPublic": false,
      "maxMembers": 20
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://backend.testeswaffle.org/streaks/groups', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer SEU_JWT_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      groupName: 'Leitores do Escritório',
      description: 'Grupo da nossa equipe para competir nos streaks de leitura',
      isPublic: false,
      maxMembers: 20
    })
  });
  const data = await response.json();
  console.log(data);
  ```

  ```python Python theme={null}
  import requests

  headers = {
      'Authorization': 'Bearer SEU_JWT_TOKEN',
      'Content-Type': 'application/json'
  }

  payload = {
      'groupName': 'Leitores do Escritório',
      'description': 'Grupo da nossa equipe para competir nos streaks de leitura',
      'isPublic': False,
      'maxMembers': 20
  }

  response = requests.post(
      'https://backend.testeswaffle.org/streaks/groups',
      headers=headers,
      json=payload
  )
  data = response.json()
  print(data)
  ```
</RequestExample>

<ResponseExample>
  ```json Sucesso theme={null}
  {
    "success": true,
    "data": {
      "groupId": "abc123xyz0",
      "groupName": "Leitores do Escritório",
      "description": "Grupo da nossa equipe para competir nos streaks de leitura",
      "ownerEmail": "usuario@exemplo.com",
      "isPublic": 0,
      "maxMembers": 20,
      "memberCount": 1,
      "createdAt": 1642680000,
      "updatedAt": 1642680000
    }
  }
  ```

  ```json Erro - Nome obrigatório theme={null}
  {
    "success": false,
    "error": "Nome do grupo é obrigatório"
  }
  ```

  ```json Erro - Servidor theme={null}
  {
    "success": false,
    "error": "Erro ao criar grupo",
    "details": "Detalhes específicos do erro"
  }
  ```
</ResponseExample>

## Regras de Negócio

### Validações

* **Nome**: Obrigatório, máximo 100 caracteres
* **Descrição**: Opcional, máximo 500 caracteres
* **maxMembers**: Entre 1 e 200 membros
* **Único por usuário**: Um usuário pode criar múltiplos grupos

### Comportamentos

* Criador automaticamente vira primeiro membro
* GroupId é gerado automaticamente (10 caracteres únicos)
* Timestamps em Unix timestamp (segundos)
* isPublic armazenado como integer (0/1) no banco

### Limites

* **Grupos por usuário**: Ilimitado
* **Membros por grupo**: Configurável (padrão 50, máximo 200)
* **Nome do grupo**: Único por usuário recomendado

## Próximos Passos

Após criar o grupo, você pode:

1. **Adicionar membros**: `POST /streaks/groups/:groupId/members`
2. **Ver ranking do grupo**: `GET /streaks/groups/:groupId/ranking`
3. **Listar seus grupos**: `GET /streaks/groups`

## Notas de Implementação

### ID Generation

* Utiliza `nanoid(10)` para IDs únicos e seguros
* IDs são URL-safe e legíveis

### Database

* Armazenado na tabela `friendGroups`
* Índices em `groupId` e `ownerEmail`
* Relacionamento com `friendGroupMembers` para membros


## OpenAPI

````yaml POST /streaks/groups
openapi: 3.1.0
info:
  title: Streaks API
  description: API para gerenciamento de streaks e gamificação de leitura do the news
  version: 1.0.0
servers:
  - url: https://backend.testeswaffle.org
security:
  - bearerAuth: []
paths:
  /streaks/groups:
    post:
      tags:
        - Friend Groups
      summary: Criar Grupo de Amigos
      description: Cria um novo grupo de amigos para competições privadas de streak
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - groupName
              properties:
                groupName:
                  type: string
                  description: Nome do grupo
                description:
                  type: string
                  description: Descrição opcional do grupo
                isPublic:
                  type: boolean
                  default: false
                  description: Se o grupo é público
                maxMembers:
                  type: number
                  default: 50
                  description: Limite máximo de membros
      responses:
        '200':
          description: Grupo criado com sucesso
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      groupId:
                        type: string
                      groupName:
                        type: string
                      description:
                        type: string
                      ownerEmail:
                        type: string
                      isPublic:
                        type: number
                      maxMembers:
                        type: number
                      memberCount:
                        type: number
                      createdAt:
                        type: number
                      updatedAt:
                        type: number
      security:
        - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````