Remove document version from trust API

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-08-04 13:30:50 +02:00
parent 994ec7b67f
commit 9afb80d5e8
10 changed files with 204 additions and 1069 deletions

View File

@@ -321,6 +321,59 @@ LIMIT 1;
return nil
}
func (p *DocumentVersion) LoadLatestPublishedVersion(
ctx context.Context,
conn pg.Conn,
scope Scoper,
documentID gid.GID,
) error {
q := `
SELECT
id,
document_id,
title,
owner_id,
version_number,
content,
changelog,
created_by,
status,
published_by,
published_at,
created_at,
updated_at
FROM
document_versions
WHERE
%s
AND document_id = @document_id
AND status = @status
ORDER BY published_at DESC
LIMIT 1;
`
q = fmt.Sprintf(q, scope.SQLFragment())
args := pgx.StrictNamedArgs{
"document_id": documentID,
"status": DocumentStatusPublished,
}
maps.Copy(args, scope.SQLArguments())
rows, err := conn.Query(ctx, q, args)
if err != nil {
return fmt.Errorf("cannot query document versions: %w", err)
}
documentVersion, err := pgx.CollectExactlyOneRow(rows, pgx.RowToStructByName[DocumentVersion])
if err != nil {
return fmt.Errorf("cannot collect document version: %w", err)
}
*p = documentVersion
return nil
}
func (p DocumentVersion) Update(
ctx context.Context,
conn pg.Conn,

View File

@@ -48,20 +48,10 @@ enum DocumentType
@goEnum(value: "github.com/getprobo/probo/pkg/coredata.DocumentTypePolicy")
}
type DocumentVersion implements Node {
id: ID!
}
type Document implements Node {
id: ID!
title: String!
documentType: DocumentType!
versions(
first: Int
after: CursorKey
last: Int
before: CursorKey
): DocumentVersionConnection! @goField(forceResolver: true)
}
type DocumentConnection {
@@ -74,16 +64,6 @@ type DocumentEdge {
node: Document!
}
type DocumentVersionConnection {
edges: [DocumentVersionEdge!]!
pageInfo: PageInfo!
}
type DocumentVersionEdge {
cursor: CursorKey!
node: DocumentVersion!
}
type Framework implements Node {
id: ID!
@@ -244,11 +224,11 @@ type TrustCenter implements Node {
): VendorConnection! @goField(forceResolver: true)
}
input ExportDocumentVersionPDFInput {
documentVersionId: ID!
input ExportDocumentPDFInput {
documentId: ID!
}
type ExportDocumentVersionPDFPayload {
type ExportDocumentPDFPayload {
data: String!
}
@@ -257,7 +237,7 @@ type Query {
}
type Mutation {
exportDocumentVersionPDF(
input: ExportDocumentVersionPDFInput!
): ExportDocumentVersionPDFPayload! @mustBeAuthenticated(role: USER)
exportDocumentPDF(
input: ExportDocumentPDFInput!
): ExportDocumentPDFPayload! @mustBeAuthenticated(role: USER)
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,47 +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 types
import (
"github.com/getprobo/probo/pkg/coredata"
"github.com/getprobo/probo/pkg/page"
)
func NewDocumentVersionConnection(
p *page.Page[*coredata.DocumentVersion, coredata.DocumentVersionOrderField],
) *DocumentVersionConnection {
edges := make([]*DocumentVersionEdge, len(p.Data))
for i, documentVersion := range p.Data {
edges[i] = NewDocumentVersionEdge(documentVersion, p.Cursor.OrderBy.Field)
}
return &DocumentVersionConnection{
Edges: edges,
PageInfo: NewPageInfo(p),
}
}
func NewDocumentVersion(dv *coredata.DocumentVersion) *DocumentVersion {
return &DocumentVersion{
ID: dv.ID,
}
}
func NewDocumentVersionEdge(dv *coredata.DocumentVersion, orderField coredata.DocumentVersionOrderField) *DocumentVersionEdge {
return &DocumentVersionEdge{
Node: NewDocumentVersion(dv),
Cursor: dv.CursorKey(orderField),
}
}

View File

@@ -39,10 +39,9 @@ type AuditEdge struct {
}
type Document struct {
ID gid.GID `json:"id"`
Title string `json:"title"`
DocumentType coredata.DocumentType `json:"documentType"`
Versions *DocumentVersionConnection `json:"versions"`
ID gid.GID `json:"id"`
Title string `json:"title"`
DocumentType coredata.DocumentType `json:"documentType"`
}
func (Document) IsNode() {}
@@ -58,28 +57,11 @@ type DocumentEdge struct {
Node *Document `json:"node"`
}
type DocumentVersion struct {
ID gid.GID `json:"id"`
type ExportDocumentPDFInput struct {
DocumentID gid.GID `json:"documentId"`
}
func (DocumentVersion) IsNode() {}
func (this DocumentVersion) GetID() gid.GID { return this.ID }
type DocumentVersionConnection struct {
Edges []*DocumentVersionEdge `json:"edges"`
PageInfo *PageInfo `json:"pageInfo"`
}
type DocumentVersionEdge struct {
Cursor page.CursorKey `json:"cursor"`
Node *DocumentVersion `json:"node"`
}
type ExportDocumentVersionPDFInput struct {
DocumentVersionID gid.GID `json:"documentVersionId"`
}
type ExportDocumentVersionPDFPayload struct {
type ExportDocumentPDFPayload struct {
Data string `json:"data"`
}

View File

@@ -76,50 +76,16 @@ func (r *auditResolver) ReportURL(ctx context.Context, obj *types.Audit) (*strin
return url, nil
}
// Versions is the resolver for the versions field.
func (r *documentResolver) Versions(ctx context.Context, obj *types.Document, first *int, after *page.CursorKey, last *int, before *page.CursorKey) (*types.DocumentVersionConnection, error) {
trust := r.TrustService(ctx, obj.ID.TenantID())
// ExportDocumentPDF is the resolver for the exportDocumentPDF field.
func (r *mutationResolver) ExportDocumentPDF(ctx context.Context, input types.ExportDocumentPDFInput) (*types.ExportDocumentPDFPayload, error) {
trust := r.trustCenterSvc.WithTenant(input.DocumentID.TenantID())
pageOrderBy := page.OrderBy[coredata.DocumentVersionOrderField]{
Field: coredata.DocumentVersionOrderFieldCreatedAt,
Direction: page.OrderDirectionDesc,
}
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
// For the public trust API, only return published versions
page, err := trust.Documents.ListVersions(ctx, obj.ID, cursor)
pdf, err := trust.Documents.ExportPDF(ctx, input.DocumentID)
if err != nil {
return nil, fmt.Errorf("cannot list document versions: %w", err)
return nil, fmt.Errorf("cannot export document PDF: %w", err)
}
// Filter to only published versions and create edges directly
publishedEdges := make([]*types.DocumentVersionEdge, 0)
for _, version := range page.Data {
if version.Status == coredata.DocumentStatusPublished {
edge := &types.DocumentVersionEdge{
Cursor: version.CursorKey(pageOrderBy.Field),
Node: types.NewDocumentVersion(version),
}
publishedEdges = append(publishedEdges, edge)
}
}
return &types.DocumentVersionConnection{
Edges: publishedEdges,
PageInfo: types.NewPageInfo(page),
}, nil
}
// ExportDocumentVersionPDF is the resolver for the exportDocumentVersionPDF field.
func (r *mutationResolver) ExportDocumentVersionPDF(ctx context.Context, input types.ExportDocumentVersionPDFInput) (*types.ExportDocumentVersionPDFPayload, error) {
trust := r.trustCenterSvc.WithTenant(input.DocumentVersionID.TenantID())
pdf, err := trust.Documents.ExportPDF(ctx, input.DocumentVersionID)
if err != nil {
return nil, fmt.Errorf("cannot export document version PDF: %w", err)
}
return &types.ExportDocumentVersionPDFPayload{
return &types.ExportDocumentPDFPayload{
Data: fmt.Sprintf("data:application/pdf;base64,%s", base64.StdEncoding.EncodeToString(pdf)),
}, nil
}
@@ -231,9 +197,6 @@ func (r *trustCenterResolver) Vendors(ctx context.Context, obj *types.TrustCente
// Audit returns schema.AuditResolver implementation.
func (r *Resolver) Audit() schema.AuditResolver { return &auditResolver{r} }
// Document returns schema.DocumentResolver implementation.
func (r *Resolver) Document() schema.DocumentResolver { return &documentResolver{r} }
// Mutation returns schema.MutationResolver implementation.
func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver{r} }
@@ -250,7 +213,6 @@ func (r *Resolver) Report() schema.ReportResolver { return &reportResolver{r} }
func (r *Resolver) TrustCenter() schema.TrustCenterResolver { return &trustCenterResolver{r} }
type auditResolver struct{ *Resolver }
type documentResolver struct{ *Resolver }
type mutationResolver struct{ *Resolver }
type organizationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }

View File

@@ -85,7 +85,7 @@ func (s *DocumentService) ListForOrganizationId(
func (s *DocumentService) ExportPDF(
ctx context.Context,
documentVersionID gid.GID,
documentID gid.GID,
) ([]byte, error) {
document := &coredata.Document{}
version := &coredata.DocumentVersion{}
@@ -97,11 +97,7 @@ func (s *DocumentService) ExportPDF(
err := s.svc.pg.WithConn(
ctx,
func(conn pg.Conn) error {
if err := version.LoadByID(ctx, conn, s.svc.scope, documentVersionID); err != nil {
return fmt.Errorf("cannot load document version: %w", err)
}
if err := document.LoadByID(ctx, conn, s.svc.scope, version.DocumentID); err != nil {
if err := document.LoadByID(ctx, conn, s.svc.scope, documentID); err != nil {
return fmt.Errorf("cannot load document: %w", err)
}
@@ -109,6 +105,10 @@ func (s *DocumentService) ExportPDF(
return fmt.Errorf("document not visible on trust center")
}
if err := version.LoadLatestPublishedVersion(ctx, conn, s.svc.scope, documentID); err != nil {
return fmt.Errorf("cannot load latest published document version: %w", err)
}
if version.PublishedBy != nil {
if err := publishedBy.LoadByID(ctx, conn, s.svc.scope, *version.PublishedBy); err != nil {
return fmt.Errorf("cannot load published by person: %w", err)
@@ -125,7 +125,7 @@ func (s *DocumentService) ExportPDF(
},
)
if err := signatures.LoadByDocumentVersionID(ctx, conn, s.svc.scope, documentVersionID, cursor); err != nil {
if err := signatures.LoadByDocumentVersionID(ctx, conn, s.svc.scope, version.ID, cursor); err != nil {
return fmt.Errorf("cannot load document version signatures: %w", err)
}