Update console gql schema and resolver

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-02-05 14:50:10 +04:00
parent f8744100e2
commit ae6c6719d2
24 changed files with 851 additions and 3000 deletions

View File

@@ -25,27 +25,41 @@ import (
"go.gearno.de/kit/pg"
"go.probo.inc/probo/pkg/gid"
"go.probo.inc/probo/pkg/mail"
"go.probo.inc/probo/pkg/page"
)
type (
MembershipProfile struct {
ID gid.GID `db:"id"`
IdentityID gid.GID `db:"identity_id"`
MembershipID gid.GID `db:"membership_id"`
EmailAddress mail.Addr `db:"email_address"`
FullName string `db:"full_name"`
Kind PeopleKind `db:"kind"`
AdditionalEmailAddresses mail.Addrs `db:"additional_email_addresses"`
Position *string `db:"position"`
ContractStartDate *time.Time `db:"contract_start_date"`
ContractEndDate *time.Time `db:"contract_end_date"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
ID gid.GID `db:"id"`
IdentityID gid.GID `db:"identity_id"`
MembershipID gid.GID `db:"membership_id"`
EmailAddress mail.Addr `db:"email_address"`
FullName string `db:"full_name"`
Kind MembershipProfileKind `db:"kind"`
AdditionalEmailAddresses mail.Addrs `db:"additional_email_addresses"`
Position *string `db:"position"`
ContractStartDate *time.Time `db:"contract_start_date"`
ContractEndDate *time.Time `db:"contract_end_date"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
}
MembershipProfiles []*MembershipProfile
)
func (p MembershipProfile) CursorKey(orderBy MembershipProfileOrderField) page.CursorKey {
switch orderBy {
case MembershipProfileOrderFieldCreatedAt:
return page.NewCursorKey(p.ID, p.CreatedAt)
case MembershipProfileOrderFieldFullName:
return page.NewCursorKey(p.ID, p.FullName)
case MembershipProfileOrderFieldKind:
return page.NewCursorKey(p.ID, p.Kind)
}
panic(fmt.Sprintf("unsupported order by: %s", orderBy))
}
func (p *MembershipProfile) AuthorizationAttributes(ctx context.Context, conn pg.Conn) (map[string]string, error) {
q := `SELECT m.organization_id FROM iam_membership_profiles mp JOIN iam_memberships m ON mp.membership_id = m.id WHERE mp.id = $1 LIMIT 1;`

View File

@@ -0,0 +1,53 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package coredata
import (
"time"
"github.com/jackc/pgx/v5"
)
type (
MembershipProfileFilter struct {
excludeContractEnded *bool
currentDate time.Time
}
)
func NewMembershipProfileFilter(excludeContractEnded *bool) *MembershipProfileFilter {
return &MembershipProfileFilter{
excludeContractEnded: excludeContractEnded,
currentDate: time.Now(),
}
}
func (f *MembershipProfileFilter) SQLArguments() pgx.StrictNamedArgs {
return pgx.StrictNamedArgs{
"exclude_contract_ended": f.excludeContractEnded,
"current_date": f.currentDate,
}
}
func (f *MembershipProfileFilter) SQLFragment() string {
return `
(
CASE
WHEN @exclude_contract_ended::boolean IS NOT NULL AND @exclude_contract_ended::boolean = true THEN
(contract_end_date IS NULL OR contract_end_date >= @current_date::date)
ELSE TRUE
END
)`
}

View File

@@ -0,0 +1,87 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package coredata
import (
"database/sql/driver"
"fmt"
)
type (
MembershipProfileKind uint8
)
const (
MembershipProfileKindEmployee MembershipProfileKind = iota
MembershipProfileKindContractor
MembershipProfileKindServiceAccount
)
func MembershipProfileKinds() []MembershipProfileKind {
return []MembershipProfileKind{
MembershipProfileKindEmployee,
MembershipProfileKindContractor,
MembershipProfileKindServiceAccount,
}
}
func (mpk MembershipProfileKind) MarshalText() ([]byte, error) {
return []byte(mpk.String()), nil
}
func (mpk *MembershipProfileKind) UnmarshalText(data []byte) error {
val := string(data)
switch val {
case MembershipProfileKindEmployee.String():
*mpk = MembershipProfileKindEmployee
case MembershipProfileKindContractor.String():
*mpk = MembershipProfileKindContractor
case MembershipProfileKindServiceAccount.String():
*mpk = MembershipProfileKindServiceAccount
default:
return fmt.Errorf("invalid MembershipProfileKind value: %q", val)
}
return nil
}
func (mpk MembershipProfileKind) String() string {
var val string
switch mpk {
case MembershipProfileKindEmployee:
val = "EMPLOYEE"
case MembershipProfileKindContractor:
val = "CONTRACTOR"
case MembershipProfileKindServiceAccount:
val = "SERVICE_ACCOUNT"
}
return val
}
func (mpk *MembershipProfileKind) Scan(value any) error {
val, ok := value.(string)
if !ok {
return fmt.Errorf("invalid scan source for MembershipProfileKind, expected string got %T", value)
}
return mpk.UnmarshalText([]byte(val))
}
func (mpk MembershipProfileKind) Value() (driver.Value, error) {
return mpk.String(), nil
}

View File

@@ -0,0 +1,42 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package coredata
type (
MembershipProfileOrderField string
)
const (
MembershipProfileOrderFieldCreatedAt MembershipProfileOrderField = "CREATED_AT"
MembershipProfileOrderFieldFullName MembershipProfileOrderField = "FULL_NAME"
MembershipProfileOrderFieldKind MembershipProfileOrderField = "KIND"
)
func (p MembershipProfileOrderField) Column() string {
return string(p)
}
func (p MembershipProfileOrderField) String() string {
return string(p)
}
func (p MembershipProfileOrderField) MarshalText() ([]byte, error) {
return []byte(p.String()), nil
}
func (p *MembershipProfileOrderField) UnmarshalText(text []byte) error {
*p = MembershipProfileOrderField(text)
return nil
}