Git-Repository für bestehenden archivdms-Code initialisiert, Branch-/Commit-Konvention (feature/<ticket>-<slug>-Branches, Ticket-Prefix in Commit-Nachricht) etabliert.
75 lines
2.8 KiB
Go
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
|
|
}
|