Search code examples
mongodbmicroservicesspring-webflux

How to structure these requirements? (microservices)


I have a customer microservice (customer document) and a bank account microservice (bank account document). How do I structure these requirements?

There are two types of clients: personal and business.

  • A personal client can only have a maximum of one savings account, one checking account or fixed term accounts.

  • A business client may not have one savings or fixed-term account but may have multiple checking accounts.

In the customers document I have an ID attribute that identifies the bank account and that could fulfill the first requirement, however, the second one indicates that you can have multiple checking accounts if it is a business type.

----------------------

EDIT:

More requirements were added.

  • Business bank accounts may have one or more account holders and zero or more authorized signatories.

  • The system must allow to consult all the movements of a bank account that a client has and the type (withdrawal or deposit).


Solution

  • db

    db={
      "clients": [
        {
          "_id": 1,
          "type": "personal",
          "name": "Tom",
          "createAt": ISODate("2022-01-10T11:23:25.184Z")
        },
        {
          "_id": 2,
          "type": "business",
          "name": "Apple",
          "createAt": ISODate("2022-01-12T05:10:42.220Z")
        }
      ],
      "accounts": [
        {
          "_id": 1,
          "client_id": 1,
          "type": "saving",
          "money": 12000
        },
        {
          "_id": 2,
          "client_id": 1,
          "type": "checking",
          "money": 8000
        },
        {
          "_id": 3,
          "client_id": 2,
          "type": "checking",
          "money": 6000
        },
        {
          "_id": 4,
          "client_id": 2,
          "type": "checking",
          "money": 7000
        }
      ]
    }
    

    aggregate

    db.clients.aggregate([
      {
        "$lookup": {
          "from": "accounts",
          "localField": "_id",
          "foreignField": "client_id",
          "as": "account_docs"
        }
      }
    ])
    

    mongoplayground


    db

    db={
      "clients": [
        {
          "_id": 1,
          "type": "personal",
          "name": "Tom",
          "createAt": ISODate("2022-01-10T11:23:25.184Z")
        },
        {
          "_id": 2,
          "type": "business",
          "name": "Apple",
          "createAt": ISODate("2022-01-12T05:10:42.220Z")
        },
        {
          "_id": 3,
          "type": "business",
          "name": "Apple2",
          "createAt": ISODate("2022-01-13T05:10:42.220Z")
        }
      ],
      "accounts": [
        {
          "_id": 1,
          "type": "saving",
          "money": 12000
        },
        {
          "_id": 2,
          "type": "checking",
          "money": 8000
        },
        {
          "_id": 3,
          "type": "checking",
          "money": 6000
        },
        {
          "_id": 4,
          "type": "checking",
          "money": 7000
        }
      ],
      "clientRoles": [
        {
          "_id": 1,
          "client_id": 1,
          "account_id": 1,
          "type": "holder"
        },
        {
          "_id": 2,
          "client_id": 2,
          "account_id": 3,
          "type": "holder"
        },
        {
          "_id": 3,
          "client_id": 3,
          "account_id": 3,
          "type": "signatory"
        }
      ],
      "clientMovements": [
        {
          "_id": 1,
          "client_id": 1,
          "account_id": 1,
          "type": "deposit",
          "money": 20000
        },
        {
          "_id": 2,
          "client_id": 1,
          "account_id": 1,
          "type": "withdraw",
          "money": 8000
        }
      ]
    }
    

    aggregate

    db.clients.aggregate([
      {
        "$match": {
          "_id": 1
        }
      },
      {
        "$lookup": {
          "from": "clientMovements",
          "localField": "_id",
          "foreignField": "client_id",
          "as": "movement_docs"
        }
      }
    ])
    

    mongoplayground