1package server
2
3import (
4 "errors"
5 "sync"
6
7 "github.com/bluesky-social/indigo/atproto/syntax"
8 "github.com/haileyok/cocoon/internal/helpers"
9 "github.com/haileyok/cocoon/models"
10 "github.com/ipfs/go-cid"
11 "github.com/labstack/echo/v4"
12)
13
14type ComAtprotoServerCheckAccountStatusResponse struct {
15 Activated bool `json:"activated"`
16 ValidDid bool `json:"validDid"`
17 RepoCommit string `json:"repoCommit"`
18 RepoRev string `json:"repoRev"`
19 RepoBlocks int64 `json:"repoBlocks"`
20 IndexedRecords int64 `json:"indexedRecords"`
21 PrivateStateValues int64 `json:"privateStateValues"`
22 ExpectedBlobs int64 `json:"expectedBlobs"`
23 ImportedBlobs int64 `json:"importedBlobs"`
24}
25
26func (s *Server) handleServerCheckAccountStatus(e echo.Context) error {
27 urepo := e.Get("repo").(*models.RepoActor)
28
29 _, didErr := syntax.ParseDID(urepo.Repo.Did)
30 if didErr != nil {
31 s.logger.Error("error validating did", "err", didErr)
32 }
33
34 resp := ComAtprotoServerCheckAccountStatusResponse{
35 Activated: true, // TODO: should allow for deactivation etc.
36 ValidDid: didErr == nil,
37 RepoRev: urepo.Rev,
38 ImportedBlobs: 0, // TODO: ???
39 }
40
41 rootcid, err := cid.Cast(urepo.Root)
42 if err != nil {
43 s.logger.Error("error casting cid", "error", err)
44 return helpers.ServerError(e, nil)
45 }
46
47 resp.RepoCommit = rootcid.String()
48
49 type CountResp struct {
50 Ct int64
51 }
52
53 var blockCtResp CountResp
54 var recCtResp CountResp
55 var blobCtResp CountResp
56
57 var wg sync.WaitGroup
58 var procErr error
59
60 wg.Add(1)
61 go func() {
62 defer wg.Done()
63 if err := s.db.Raw("SELECT COUNT(*) AS ct FROM blocks WHERE did = ?", nil, urepo.Repo.Did).Scan(&blockCtResp).Error; err != nil {
64 s.logger.Error("error getting block count", "error", err)
65 procErr = errors.Join(procErr, err)
66 }
67 }()
68
69 wg.Add(1)
70 go func() {
71 defer wg.Done()
72 if err := s.db.Raw("SELECT COUNT(*) AS ct FROM records WHERE did = ?", nil, urepo.Repo.Did).Scan(&recCtResp).Error; err != nil {
73 s.logger.Error("error getting record count", "error", err)
74 procErr = errors.Join(procErr, err)
75 }
76 }()
77
78 wg.Add(1)
79 go func() {
80 if err := s.db.Raw("SELECT COUNT(*) AS ct FROM blobs WHERE did = ?", nil, urepo.Repo.Did).Scan(&blobCtResp).Error; err != nil {
81 s.logger.Error("error getting expected blobs count", "error", err)
82 procErr = errors.Join(procErr, err)
83 }
84 }()
85
86 wg.Wait()
87 if procErr != nil {
88 return helpers.ServerError(e, nil)
89 }
90
91 resp.RepoBlocks = blockCtResp.Ct
92 resp.IndexedRecords = recCtResp.Ct
93 resp.ExpectedBlobs = blobCtResp.Ct
94
95 return e.JSON(200, resp)
96}