Fix referenced columns used in certain SQL queries + minor front fixes

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-02-09 10:13:57 +04:00
parent d235f4a86b
commit 29371662e2
14 changed files with 29 additions and 162 deletions

View File

@@ -19,7 +19,7 @@ function UserPageQueryLoader() {
if (!queryRef) {
loadQuery({ userId });
}
}, [loadQuery, queryRef, userId]);
});
if (!queryRef) return <LinkCardSkeleton />;

View File

@@ -80,7 +80,7 @@ export function MemberList(props: { fKey: MemberListFragment$key }) {
{membersPagination.data.members.totalCount === 0
? (
<Tr>
<Td colSpan={5} className="text-center text-txt-secondary">
<Td colSpan={7} className="text-center text-txt-secondary">
{__("No members")}
</Td>
</Tr>

View File

@@ -713,14 +713,14 @@ WITH last_signable_version AS (
FROM documents d
INNER JOIN document_versions dv ON dv.document_id = d.id
INNER JOIN document_version_signatures dvs ON dvs.document_version_id = dv.id
INNER JOIN peoples p ON dvs.signed_by = p.id
INNER JOIN iam_membership_profiles p ON dvs.signed_by_profile_id = p.id
WHERE d.id = @document_id
AND p.primary_email_address = @user_email
AND dv.version_number = (
SELECT MAX(dv2.version_number)
FROM document_versions dv2
INNER JOIN document_version_signatures dvs2 ON dvs2.document_version_id = dv2.id
INNER JOIN peoples p2 ON dvs2.signed_by = p2.id
INNER JOIN iam_membership_profiles p2 ON dvs2.signed_by_profile_id = p2.id
WHERE dv2.document_id = d.id
AND p2.primary_email_address = @user_email
)

View File

@@ -99,7 +99,7 @@ func (f *DocumentFilter) SQLFragment() string {
SELECT 1
FROM document_versions dv
INNER JOIN document_version_signatures dvs ON dv.id = dvs.document_version_id
INNER JOIN peoples p ON dvs.signed_by = p.id
INNER JOIN iam_membership_profiles p ON dvs.signed_by_profile_id = p.id
WHERE dv.document_id = documents.id
AND dv.status = 'PUBLISHED'
AND p.primary_email_address = @user_email::text

View File

@@ -47,7 +47,7 @@ func (f *DocumentVersionFilter) SQLFragment() string {
OR EXISTS (
SELECT 1
FROM document_version_signatures dvs
INNER JOIN peoples p ON dvs.signed_by = p.id
INNER JOIN iam_membership_profiles p ON dvs.signed_by_profile_id = p.id
WHERE dvs.document_version_id = document_versions.id
AND p.primary_email_address = @user_email::text
AND dvs.state IN ('REQUESTED', 'SIGNED')

View File

@@ -364,7 +364,7 @@ WITH sigs AS (
FROM
document_version_signatures dvs
INNER JOIN
peoples p ON dvs.signed_by_profile_id = p.id
iam_membership_profile_id p ON dvs.signed_by_profile_id = p.id
WHERE
dvs.document_version_id = @document_version_id
ORDER BY
@@ -422,7 +422,7 @@ func (pvs *DocumentVersionSignature) IsSignedByUserEmail(
SELECT EXISTS (
SELECT 1
FROM document_version_signatures dvs
INNER JOIN peoples p ON dvs.signed_by_profile_id = p.id
INNER JOIN iam_membership_profiles p ON dvs.signed_by_profile_id = p.id
WHERE dvs.document_version_id = @document_version_id
AND p.primary_email_address = @user_email
AND dvs.state = 'SIGNED'

View File

@@ -53,8 +53,8 @@ func (f *DocumentVersionSignatureFilter) SQLFragment() string {
THEN TRUE
ELSE EXISTS (
SELECT 1
FROM peoples p
WHERE p.id = signed_by
FROM iam_membership_profiles p
WHERE p.id = signed_by_profile_id
AND (
(
@active_contract::boolean = TRUE

View File

@@ -451,14 +451,14 @@ func (p *MembershipProfiles) LoadAwaitingSigning(
q := `
WITH signatories AS (
SELECT
signed_by
signed_by_profile_id
FROM
document_version_signatures
WHERE
%s
AND state = 'REQUESTED'
GROUP BY
signed_by
signed_by_profile_id
)
SELECT
p.id,

View File

@@ -74,9 +74,14 @@ func (mpk MembershipProfileKind) String() string {
}
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)
var val string
switch v := value.(type) {
case string:
val = v
case []byte:
val = string(v)
default:
return fmt.Errorf("unsupported type for MembershipProfileKind: %T", value)
}
return mpk.UnmarshalText([]byte(val))

View File

@@ -1,53 +0,0 @@
// 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 (
PeopleFilter struct {
excludeContractEnded *bool
currentDate time.Time
}
)
func NewPeopleFilter(excludeContractEnded *bool) *PeopleFilter {
return &PeopleFilter{
excludeContractEnded: excludeContractEnded,
currentDate: time.Now(),
}
}
func (f *PeopleFilter) SQLArguments() pgx.StrictNamedArgs {
return pgx.StrictNamedArgs{
"exclude_contract_ended": f.excludeContractEnded,
"current_date": f.currentDate,
}
}
func (f *PeopleFilter) 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

@@ -1,87 +0,0 @@
// 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 (
PeopleKind uint8
)
const (
PeopleKindEmployee PeopleKind = iota
PeopleKindContractor
PeopleKindServiceAccount
)
func PeopleKinds() []PeopleKind {
return []PeopleKind{
PeopleKindEmployee,
PeopleKindContractor,
PeopleKindServiceAccount,
}
}
func (ps PeopleKind) MarshalText() ([]byte, error) {
return []byte(ps.String()), nil
}
func (ps *PeopleKind) UnmarshalText(data []byte) error {
val := string(data)
switch val {
case PeopleKindEmployee.String():
*ps = PeopleKindEmployee
case PeopleKindContractor.String():
*ps = PeopleKindContractor
case PeopleKindServiceAccount.String():
*ps = PeopleKindServiceAccount
default:
return fmt.Errorf("invalid PeopleKind value: %q", val)
}
return nil
}
func (ts PeopleKind) String() string {
var val string
switch ts {
case PeopleKindEmployee:
val = "EMPLOYEE"
case PeopleKindContractor:
val = "CONTRACTOR"
case PeopleKindServiceAccount:
val = "SERVICE_ACCOUNT"
}
return val
}
func (pk *PeopleKind) Scan(value any) error {
val, ok := value.(string)
if !ok {
return fmt.Errorf("invalid scan source for PeopleKind, expected string got %T", value)
}
return pk.UnmarshalText([]byte(val))
}
func (pk PeopleKind) Value() (driver.Value, error) {
return pk.String(), nil
}

View File

@@ -175,7 +175,7 @@ WITH rsks AS (
INNER JOIN
risks_measures rm ON r.id = rm.risk_id
LEFT JOIN
peoples p ON r.owner_profile_id = p.id
iam_membership_profiles p ON r.owner_profile_id = p.id
WHERE
rm.measure_id = @measure_id
)
@@ -293,7 +293,7 @@ WITH rsks AS (
FROM
risks r
LEFT JOIN
peoples p ON r.owner_profile_id = p.id
iam_membership_profiles p ON r.owner_profile_id = p.id
WHERE
r.organization_id = @organization_id
)

View File

@@ -196,7 +196,7 @@ func (upr *UpdateProfileRequest) Validate() error {
v := validator.New()
v.Check(upr.ID, "id", validator.Required(), validator.GID(coredata.MembershipProfileEntityType))
v.Check(upr.Kind, "kind", validator.OneOfSlice(coredata.PeopleKinds()))
v.Check(upr.Kind, "kind", validator.OneOfSlice(coredata.MembershipProfileKinds()))
v.Check(upr.FullName, "full_name", validator.SafeTextNoNewLine(NameMaxLength))
v.CheckEach(upr.AdditionalEmailAddresses, "additional_email_addresses", func(index int, item any) {
v.Check(item, fmt.Sprintf("additional_email_addresses[%d]", index), validator.Required(), validator.NotEmpty())
@@ -996,7 +996,9 @@ func (s *OrganizationService) UpdateProfile(ctx context.Context, req *UpdateProf
profile.AdditionalEmailAddresses = req.AdditionalEmailAddresses
profile.Position = *req.Position
if req.Position != nil {
profile.Position = *req.Position
}
if req.ContractStartDate != nil {
profile.ContractStartDate = *req.ContractStartDate

View File

@@ -462,7 +462,7 @@ func (s *DocumentService) Create(
func (s *DocumentService) ListSigningRequests(
ctx context.Context,
organizationID gid.GID,
peopleID gid.GID,
profileID gid.GID,
) ([]map[string]any, error) {
q := `
SELECT
@@ -476,7 +476,7 @@ FROM
INNER JOIN organizations o ON o.id = p.organization_id
WHERE
p.tenant_id = $1
AND pvs.signed_by = $2
AND pvs.signed_by_profile_id = $2
AND pvs.signed_at IS NULL
AND pv.status = 'PUBLISHED'
AND pv.version_number = (
@@ -491,7 +491,7 @@ WHERE
err := s.svc.pg.WithConn(
ctx,
func(conn pg.Conn) error {
rows, err := conn.Query(ctx, q, s.svc.scope.GetTenantID(), peopleID)
rows, err := conn.Query(ctx, q, s.svc.scope.GetTenantID(), profileID)
if err != nil {
return fmt.Errorf("cannot query documents: %w", err)
}