vacationlabs / haskell-webapps

Proof-of-concept code for a typical webapp implemented in various Haskell libraries/frameworks
MIT License
134 stars 21 forks source link

Feature/appcore package #61

Closed sras closed 7 years ago

sras commented 7 years ago

I have moved some of the implementation details to a separate package called AppCore in this branch.

sras commented 7 years ago

@saurabhnanda

Why does UserId TenantId stuff need to be in a different module?

To break cyclic imports.

use the lens setter?

I was not able to use a lens setter here because HasPassword class (made by TH functions) constrains the value of password to be of type Text and results in the error...

        * Couldn't match type `Data.Text.Internal.Text'
                         with `BcryptPassword'
            arising from a functional dependency between:
              constraint `HasPassword UserIncoming BcryptPassword'

I have now made a helper function in the AppCore that fills in the password for incoming user requests.

saurabhnanda commented 7 years ago

Why does UserId TenantId stuff need to be in a different module?

To break cyclic imports.

Please explain a little more.

I was not able to use a lens setter here because HasPassword class (made by TH functions) constrains the value of password to be of type Text and results in the error...

Do we need a BcryptPassword <> Bytea Opaleye bridge instead?

sras commented 7 years ago

@saurabhnanda

Please explain a little more.

TenantDefs need to refer to UserId data type to define ownerId field in a Tenant record. UserDefs need to refer to TenantId for defining tenantId field of the User record.

This means, if we include definitions of UserId and TenantId in UserDefs and TenantDefs, they will have to import each other. Ie UserDefs will have to import TenantDefs and TenantDefs will have to import UserDefs. This will create an import cycle and the build fails with "module imports form a cycle" error.

So by keeping the definition of TenantId and UserId in a separate module, TenantDefs and UserDefs can just import these modules, breaking the cycle.

sras commented 7 years ago

@saurabhnanda

Do we need a BcryptPassword <> Bytea Opaleye bridge instead?

I am not sure. How is this related to Opaleye? The type mismatch arises from the Has* type classes generated by the makeLensesWith function.

saurabhnanda commented 7 years ago

So by keeping the definition of TenantId and UserId in a separate module, TenantDefs and UserDefs can just import these modules, breaking the cycle.

Easier to have a single package for all these ID definitions (which IMO should either be part of Opaleye itself, or should be reduced to a single TH statement by us)?