openapi: "3.0.3"
info:
  title: "Financial Planning API"
  description: "An API for financial planning services."
  version: "1.0.0"
servers:
  - url: "https://api.example.com/v1"
paths:
  /financial-plan:
    post:
      summary: "Create a financial plan"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FinancialPlanInput"
      responses:
        '201':
          description: "Financial plan created successfully."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FinancialPlanOutput"
        '400':
          description: "Bad request. Invalid input data."
  /users/register:
    post:
      summary: "User registration"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UserRegistration"
      responses:
        '201':
          description: "User registered successfully."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserResponse"
        '400':
          description: "Bad request. Invalid input data."

  /users/login:
    post:
      summary: "User login"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UserLogin"
      responses:
        '200':
          description: "User login successful."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserResponse"
        '400':
          description: "Bad request. Invalid input data."
        '401':
          description: "Unauthorized. Invalid email or password."
  /users/{userId}/expenses:
    post:
      summary: "Add a new expense"
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Expense"
      responses:
        '201':
          description: "Expense added successfully."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Expense"
        '400':
          description: "Bad request. Invalid input data."

  /users/{userId}/incomes:
    post:
      summary: "Add a new income"
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Income"
      responses:
        '201':
          description: "Income added successfully."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Income"
        '400':
          description: "Bad request. Invalid input data."
  /users/{userId}/transactions/summary:
    get:
      summary: "Get monthly transaction summaries (expenses and incomes)"
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
        - name: year
          in: query
          required: true
          schema:
            type: integer
            minimum: 1900
            maximum: 2100
          description: "The year for which the summary is requested."
      responses:
        '200':
          description: "Transaction summaries retrieved successfully."
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/MonthlyTransactionSummary"
        '400':
          description: "Bad request. Invalid input data."
        '404':
          description: "Not found. User not found."
  /users/{userId}/transactions/details:
    get:
      summary: "Get detailed transactions (expenses and incomes) for a specific month"
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
        - name: year
          in: query
          required: true
          schema:
            type: integer
            minimum: 1900
            maximum: 2100
          description: "The year for which the transactions are requested."
        - name: month
          in: query
          required: true
          schema:
            type: integer
            minimum: 1
            maximum: 12
          description: "The month for which the transactions are requested."
      responses:
        '200':
          description: "Detailed transactions retrieved successfully."
          content:
            application/json:
              schema:
                type: object
                properties:
                  expenses:
                    type: array
                    items:
                      $ref: "#/components/schemas/Expense"
                  incomes:
                    type: array
                    items:
                      $ref: "#/components/schemas/Income"
        '400':
          description: "Bad request. Invalid input data."
        '404':
          description: "Not found. User not found."
  /users/{userId}/recommendations:
    get:
      summary: "Get recommendations based on user's expenses and incomes"
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: "Recommendations retrieved successfully."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Recommendations"
        '404':
          description: "Not found. User not found."
  /users/{userId}/advisor-recommendations:
    post:
      summary: "Advisor submits recommendations for a user"
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AdvisorRecommendations"
      responses:
        '201':
          description: "Recommendations submitted successfully."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AdvisorRecommendations"
        '400':
          description: "Bad request. Invalid input data."
        '404':
          description: "Not found. User not found."
  /users/{userId}/goals:
    post:
      summary: "Create a financial goal for a user"
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FinancialGoal"
      responses:
        '201':
          description: "Financial goal created successfully."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/FinancialGoal"
        '400':
          description: "Bad request. Invalid input data."
        '404':
          description: "Not found. User not found."

components:
  schemas:
    FinancialPlanInput:
      type: object
      properties:
        userId:
          type: string
          description: "The unique identifier for the user."
        age:
          type: integer
          description: "The current age of the user."
        retirementAge:
          type: integer
          description: "The desired retirement age of the user."
        annualIncome:
          type: number
          format: double
          description: "The user's current annual income."
        savings:
          type: number
          format: double
          description: "The user's current savings."
        annualSavingsRate:
          type: number
          format: double
          description: "The user's annual savings rate as a percentage of their income."
        investmentRate:
          type: number
          format: double
          description: "The user's expected annual investment return rate as a percentage."
      required:
        - userId
        - age
        - retirementAge
        - annualIncome
        - savings
        - annualSavingsRate
        - investmentRate

    FinancialPlanOutput:
      type: object
      properties:
        userId:
          type: string
          description: "The unique identifier for the user."
        plan:
          type: object
          properties:
            retirementAge:
              type: integer
              description: "The desired retirement age of the user."
            retirementSavings:
              type: number
              format: double
              description: "The projected savings at retirement age."
            yearlyRetirementIncome:
              type: number
              format: double
              description: "The projected yearly income during retirement."
            successProbability:
              type: number
              format: double
              description: "The probability of successfully reaching the financial goals based on the provided inputs."
    UserRegistration:
      type: object
      properties:
        email:
          type: string
          format: email
          description: "The user's email address."
        password:
          type: string
          format: password
          description: "The user's password."
        fullName:
          type: string
          description: "The user's full name."
      required:
        - email
        - password
        - fullName

    UserLogin:
      type: object
      properties:
        email:
          type: string
          format: email
          description: "The user's email address."
        password:
          type: string
          format: password
          description: "The user's password."
      required:
        - email
        - password

    UserResponse:
      type: object
      properties:
        id:
          type: string
          description: "The unique identifier for the user."
        email:
          type: string
          format: email
          description: "The user's email address."
        fullName:
          type: string
          description: "The user's full name."
        token:
          type: string
          description: "The user's authentication token."

    Expense:
      type: object
      properties:
        id:
          type: string
          description: "The unique identifier for the expense."
        date:
          type: string
          format: date
          description: "The date of the expense."
        category:
          type: string
          description: "The category of the expense."
        amount:
          type: number
          format: double
          description: "The amount of the expense."
      required:
        - date
        - category
        - amount

    Income:
      type: object
      properties:
        id:
          type: string
          description: "The unique identifier for the income."
        date:
          type: string
          format: date
          description: "The date of the income."
        source:
          type: string
          description: "The source of the income."
        amount:
          type: number
          format: double
          description: "The amount of the income."
      required:
        - date
        - source
        - amount
    MonthlyTransactionSummary:
      type: object
      properties:
        month:
          type: integer
          minimum: 1
          maximum: 12
          description: "The month for which the summary is provided."
        totalExpenses:
          type: number
          format: double
          description: "The total expenses for the month."
        totalIncomes:
          type: number
          format: double
          description: "The total incomes for the month."
      required:
        - month
        - totalExpenses
        - totalIncomes
    Recommendations:
      type: object
      properties:
        savingsRecommendation:
          type: object
          properties:
            message:
              type: string
              description: "A recommendation message for improving savings."
            suggestedSavingsRate:
              type: number
              format: double
              description: "The suggested savings rate as a percentage of income."
        expenseRecommendation:
          type: array
          items:
            type: object
            properties:
              category:
                type: string
                description: "The category of the expense."
              message:
                type: string
                description: "A recommendation message for reducing expenses in the category."
              suggestedAmount:
                type: number
                format: double
                description: "The suggested expense amount for the category."
    AdvisorRecommendations:
      type: object
      properties:
        savingsRecommendation:
          type: object
          properties:
            message:
              type: string
              description: "A recommendation message for improving savings."
            suggestedSavingsRate:
              type: number
              format: double
              description: "The suggested savings rate as a percentage of income."
        expenseRecommendations:
          type: array
          items:
            type: object
            properties:
              category:
                type: string
                description: "The category of the expense."
              message:
                type: string
                description: "A recommendation message for reducing expenses in the category."
              suggestedAmount:
                type: number
                format: double
                description: "The suggested expense amount for the category."
      required:
        - savingsRecommendation
        - expenseRecommendations
    FinancialGoal:
      type: object
      properties:
        id:
          type: string
          description: "The unique identifier for the financial goal."
        title:
          type: string
          description: "A title or short description of the financial goal."
        targetAmount:
          type: number
          format: double
          description: "The target amount to achieve the financial goal."
        targetDate:
          type: string
          format: date
          description: "The date by which the user wants to achieve the financial goal."
        progress:
          type: number
          format: double
          description: "The current progress towards the financial goal. This can be updated as the user saves towards the goal."
      required:
        - title
        - targetAmount
        - targetDate
