@err0r500 thanks for your amazing work! Go is just a hobby for me and I'm having fun. I'm learning a lot from your project.
I'm trying to understand if multi-tenancy column/table based is something to be "included", if it is "related to" the repository, usecase or handler level.
Example
Adding tenant.go
model like this:
package domain
type Tenant struct {
ID int64 `json:"id"`
Name string `json:"name"`
}
to other models like this:
package domain
type User struct {
Address string
TenantID int64 `json:"tenant_id"` // <--- here
Tenant *Tenant // <--- here
UserAddressChecker
}
Question
Let's say my tenant_id
is a field of a User
struct in context
on every request (authenticated by a third party middleware).
Where do you think I should do something like below? In handler, usecase or repository?
tenantID := GetTenantIDFromUserInContext()
article.TenantID = tenantID
Doubts about fetch queries
Today, before I discover the amazing "clean architecture", I'm using a where
clause in my SQL queries (go-pg/pg#1179), like this:
// Used as: "q.Apply(FilterByTenant(ctx))"
func FilterByTenant(ctx context.Context) func(q *orm.Query) (*orm.Query, error) {
user := ctx.Value(auth.CTXKeyUser).(*models.User)
return func(q *orm.Query) (*orm.Query, error) {
q = q.Where("tenant_id = ?", user.TenantID)
return q, nil
}
}
I think maybe the concept of FilterByTenant
in the usecase layer is an unnecessary repetition and should belong to lower levels like repositories?
But I also think that the main multi-tenancy logic does not change with the change of possible repository types (Postgres, Mysql, Mongo, microservices).
What do you think about it?