Files
archivdms/internal/storage/compliance.go
T
patrick 9a24ea29e1 FDN-01: repository & projektgerüst
Git-Repository für bestehenden archivdms-Code initialisiert, Branch-/Commit-Konvention (feature/<ticket>-<slug>-Branches, Ticket-Prefix in Commit-Nachricht) etabliert.
2026-08-11 21:27:53 +02:00

75 lines
2.8 KiB
Go

// Read-only aggregate queries backing the GoBD "Verfahrensdokumentation"
// draft generator (internal/api/compliance_handlers.go). No schema of its own —
// nothing here writes, so there is no initSchema and no migration file.
//
// Every query is strictly scoped to one tenant_id (application-side
// multi-tenancy, no Postgres RLS): the generated document is a per-tenant
// artefact and must never mix data of two tenants.
package storage
import (
"context"
"fmt"
)
// ComplianceStats are the aggregate key figures embedded in the generated
// Verfahrensdokumentation draft. All counters refer to exactly one tenant.
type ComplianceStats struct {
Documents int64 // active documents (deleted_at IS NULL)
DocumentsInTrash int64 // soft-deleted, not yet finally deleted
DocumentsWithRetain int64 // active documents carrying a retain_until date
PermissionGroups int64
DocTypeGrants int64
TagGrants int64
DocumentGrants int64
DeleteRequestsByStat map[string]int64 // status -> count
}
// ComplianceStatsForTenant collects the aggregate figures for one tenant.
func (s *Store) ComplianceStatsForTenant(ctx context.Context, tenantID int64) (*ComplianceStats, error) {
st := &ComplianceStats{DeleteRequestsByStat: map[string]int64{}}
err := s.db.QueryRow(ctx, `
SELECT
COUNT(*) FILTER (WHERE deleted_at IS NULL),
COUNT(*) FILTER (WHERE deleted_at IS NOT NULL),
COUNT(*) FILTER (WHERE deleted_at IS NULL AND retain_until IS NOT NULL)
FROM documents WHERE tenant_id = $1
`, tenantID).Scan(&st.Documents, &st.DocumentsInTrash, &st.DocumentsWithRetain)
if err != nil {
return nil, fmt.Errorf("storage: compliance document stats: %w", err)
}
err = s.db.QueryRow(ctx, `
SELECT
(SELECT COUNT(*) FROM permission_groups WHERE tenant_id = $1),
(SELECT COUNT(*) FROM document_type_grants WHERE tenant_id = $1),
(SELECT COUNT(*) FROM tag_grants WHERE tenant_id = $1),
(SELECT COUNT(*) FROM document_grants WHERE tenant_id = $1)
`, tenantID).Scan(&st.PermissionGroups, &st.DocTypeGrants, &st.TagGrants, &st.DocumentGrants)
if err != nil {
return nil, fmt.Errorf("storage: compliance grant stats: %w", err)
}
rows, err := s.db.Query(ctx, `
SELECT status, COUNT(*) FROM document_delete_requests
WHERE tenant_id = $1 GROUP BY status ORDER BY status
`, tenantID)
if err != nil {
return nil, fmt.Errorf("storage: compliance delete-request stats: %w", err)
}
defer rows.Close()
for rows.Next() {
var status string
var n int64
if err := rows.Scan(&status, &n); err != nil {
return nil, fmt.Errorf("storage: scan compliance delete-request stats: %w", err)
}
st.DeleteRequestsByStat[status] = n
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("storage: compliance delete-request stats: %w", err)
}
return st, nil
}