blink icon indicating copy to clipboard operation
blink copied to clipboard

feat: add account custom fields

Open dolcalmi opened this issue 2 years ago • 2 comments

How to test

Follow instructions here https://gist.github.com/dolcalmi/42f1622f797b1734e356315c517084d5


PR Tasks

  • [x] create account information config
  • [x] add dynamic fields to graphql
  • [x] choose naming (metadata, custom fields, dynamic fields, information, account extra info, ...) and graphql structure
  • [x] add dynamic fields repository (query, update)
  • [x] update app layer + graphql resolvers
  • [x] add admin queries
  • [x] add support to array fields
  • [x] allow empty schema
  • [x] add default values support
  • [x] add list accounts by custom field

dolcalmi avatar Jul 22 '22 04:07 dolcalmi

I have doubts about exposing the fields individually over GQL I was thinking something much simpler like a string field that accepts a JSON blob. We should probably discuss this at standup / code review.

The downside I see is that a simple config change could mean a breaking API change - who is going to be responsible for this? Also what about the data already in the database - it could easily become inconsistent with the GQL definition.

bodymindarts avatar Jul 22 '22 18:07 bodymindarts

I have doubts about exposing the fields individually over GQL I was thinking something much simpler like a string field that accepts a JSON blob. We should probably discuss this at standup / code review.

Initially this is what I had in mind also, but I like the more stronger consistency of what @dolcalmi is suggesting. It make the API more self explanatory and really harness the power of Graphql here I think.

The downside I see is that a simple config change could mean a breaking API change - who is going to be responsible for this? Also what about the data already in the database - it could easily become inconsistent with the GQL definition.

This would put the burden on consistency on the operator of the instance/backend. But it gives guarantees to the API client.

The JSON as a string opinion would put the burden on the client.

nicolasburtey avatar Jul 23 '22 10:07 nicolasburtey

Wonder if these tools can help: https://github.com/thenativeweb/get-graphql-from-jsonschema https://github.com/lifeomic/json-schema-to-graphql-types

bodymindarts avatar Aug 15 '22 18:08 bodymindarts

@bodymindarts highlighted that a benefits of the api that would be specific to the use case, as opposed to the more generic interface where one has to pass a key/value pair like in this PR, is that it will help to make it work/break at compile time, instead of run time.

nicolasburtey avatar Aug 15 '22 19:08 nicolasburtey

@dolcalmi can you add related documentation in /doc?

nicolasburtey avatar Aug 18 '22 11:08 nicolasburtey

@dolcalmi can you add related documentation in /doc?

maybe something like that: https://github.com/GaloyMoney/galoy/blob/3744882b7cc03b34cb5081716c47158b597b812a/docs/swap.md

nicolasburtey avatar Aug 18 '22 11:08 nicolasburtey

note: in the admin API, there is a key, value pair query that we could change with a more specific query.

instead of

type Query { 
  accountsDetailsByCustomField(field: CustomField, value: String!): [Account!]!
}

we could have

type Query { 
  accountsDetailsByCustomFieldFirstName(value: String!): [Account!]!
  accountsDetailsByCustomFieldLastName(value: String!): [Account!]!
  accountsDetailsByCustomFieldID(value: String!): Account! # not need for an array if ID is unique
}

nicolasburtey avatar Aug 18 '22 13:08 nicolasburtey

note: in the admin API, there is a key, value pair query that we could change with a more specific query.

instead of

type Query { 
  accountsDetailsByCustomField(field: CustomField, value: String!): [Account!]!
}

we could have

type Query { 
  accountsDetailsByCustomFieldFirstName(value: String!): [Account!]!
  accountsDetailsByCustomFieldLastName(value: String!): [Account!]!
  accountsDetailsByCustomFieldID(value: String!): Account! # not need for an array if ID is unique
}

Another reason to remove the Array usage from this PR: we can't pass an array in this query

Also, the value could be Int? or Boolean? here it's hardcoded as String

nicolasburtey avatar Aug 18 '22 13:08 nicolasburtey

note: in the admin API, there is a key, value pair query that we could change with a more specific query. instead of

type Query { 
  accountsDetailsByCustomField(field: CustomField, value: String!): [Account!]!
}

we could have

type Query { 
  accountsDetailsByCustomFieldFirstName(value: String!): [Account!]!
  accountsDetailsByCustomFieldLastName(value: String!): [Account!]!
  accountsDetailsByCustomFieldID(value: String!): Account! # not need for an array if ID is unique
}

Another reason to remove the Array usage from this PR: we can't pass an array in this query

Also, the value could be Int? or Boolean? here it's hardcoded as String

I know we already talked about this but for clarification:

  • field param validation is enforced by grapqhl schema
  • the suggested approach is ok for few fields but if we have 20 will be really difficult to implement in the frontend
  • we search by string because we need to do partial searches. This is not possible for numbers by default (or other field types)

dolcalmi avatar Aug 24 '22 00:08 dolcalmi

I've made some comments on the documentation.

should we had another field visible or viewable?

still a big question for me whether we should have default value imo. (I think not, maybe we should sync up on this)

And I know it might be late to think about this, but as we want to use Postgres, I'm wondering if this is not a use case that we should integrate directly into postgres?

It would be a bit more work now, but ultimately, it would avoid a migration from this new collection to a table.

(not saying we should do this now, but just opening the topic)

nicolasburtey avatar Aug 31 '22 11:08 nicolasburtey

I've made some comments on the documentation. should we had another field visible or viewable? still a big question for me whether we should have default value imo. (I think not, maybe we should sync up on this)

And I know it might be late to think about this, but as we want to use Postgres, I'm wondering if this is not a use case that we should integrate directly into postgres?

It would be a bit more work now, but ultimately, it would avoid a migration from this new collection to a table.

(not saying we should do this now, but just opening the topic)

This is as good as any time - if we can handle the delay. At the latest when I continue my work with casbin we would add it https://github.com/GaloyMoney/galoy/pull/1352

bodymindarts avatar Aug 31 '22 11:08 bodymindarts

I'm reading https://www.ory.sh/docs/kratos/manage-identities/overview and I'm wondering if the right data store for the custom field is actually not kratos? maybe we can discuss this in a call (still learning about kratos, but seeing how they managed identities seems like a potential good/better fit than mongodb?)

nicolasburtey avatar Sep 02 '22 13:09 nicolasburtey

I'm reading https://www.ory.sh/docs/kratos/manage-identities/overview and I'm wondering if the right data store for the custom field is actually not kratos? maybe we can discuss this in a call (still learning about kratos, but seeing how they managed identities seems like a potential good/better fit than mongodb?)

Additional fields in the identity are only intended for user-editable content. We could not support the only-set-once or hide from user use cases.

bodymindarts avatar Sep 02 '22 13:09 bodymindarts

closed until we decide a better architecture

dolcalmi avatar Sep 19 '22 16:09 dolcalmi

re-opening @dolcalmi. we may still need this soon. now that I have a better understand of the data flow of kratos I can have another view on this.

nicolasburtey avatar Sep 28 '22 17:09 nicolasburtey