Skip to content

Commit a472abf

Browse files
AchoArnoldCopilot
andauthored
feat: replace libSQL/Turso with MongoDB Atlas for heartbeat storage (#891)
* feat: replace libSQL/Turso with MongoDB Atlas for heartbeat storage - Add MongoDB Go driver v2 repository implementations for HeartbeatRepository and HeartbeatMonitorRepository interfaces - Create mongodb.go connection helper with Atlas support and index creation - Update DI container to wire MongoDB as the hedging secondary backend - Replace 'turso' case with 'mongodb' case for standalone MongoDB usage - Update integration test docker-compose to use mongo:7 instead of sqld - Update .env.test with MongoDB connection string HEARTBEAT_DB_BACKEND options: - 'hedging': PostgreSQL primary, MongoDB secondary (fail-open writes) - 'mongodb': MongoDB only - default: PostgreSQL only (GORM) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: remove unused libSQL/Turso files and dependencies - Delete libsql.go, libsql_heartbeat_repository.go, libsql_heartbeat_monitor_repository.go - Remove TursoDB() method and tursoDB field from DI container - Remove unused database/sql import from container - Run go mod tidy to remove libsql-client-go dependency Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor: use entity structs directly with bson tags instead of document types - Add bson struct tags to entities.Heartbeat and entities.HeartbeatMonitor - Register custom UUID codec so uuid.UUID is stored as string _id in MongoDB - Remove intermediate heartbeatDocument/heartbeatMonitorDocument structs - MongoDB repositories now marshal/unmarshal entities directly Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor: derive MongoDB database name from URI appName parameter - Remove hardcoded mongoDBName constant - Parse appName query parameter from MONGODB_URI as the database name - NewMongoDB now returns (client, dbName, error) - Repository constructors accept dbName parameter - DI container caches and passes the DB name to repositories - Update test .env to include appName=httpsms in URI Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor: pass *mongo.Database directly to repository constructors - NewMongoDB now returns *mongo.Database instead of (*mongo.Client, dbName) - Repository constructors accept *mongo.Database instead of client + dbName - DI container caches the *mongo.Database singleton directly - Removes MongoDBName() helper - no longer needed Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: correct outgoing message queue docs URL in settings Fix typo in URL: outgiong -> outgoing Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: add OpenTelemetry tracing to MongoDB client Use otelmongo.NewMonitor() as the command monitor on the MongoDB client to automatically trace all database operations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: address PR review comments - Remove MongoDB URI from Ping error message to prevent credential exposure in logs and error aggregators - Use separate contexts for Ping (10s) and index creation (30s) so they don't share a timeout budget Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: update send schedule docs link to correct URL Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: update CI workflow to check MongoDB instead of sqld Replace the sqld health check with a MongoDB mongosh ping check since the test infrastructure now uses mongo:7 instead of sqld. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 5ffdcb0 commit a472abf

15 files changed

Lines changed: 539 additions & 524 deletions

.github/workflows/api.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,18 @@ jobs:
3737
- name: Wait for services to be healthy
3838
working-directory: ./tests
3939
run: |
40-
echo "Waiting for sqld to be healthy..."
40+
echo "Waiting for MongoDB to be healthy..."
4141
for i in $(seq 1 20); do
42-
if curl -sf http://localhost:8090/health >/dev/null 2>&1; then
43-
echo "sqld is healthy!"
42+
if docker compose exec mongodb mongosh --eval "db.runCommand('ping').ok" --quiet >/dev/null 2>&1; then
43+
echo "MongoDB is healthy!"
4444
break
4545
fi
4646
if [ $i -eq 20 ]; then
47-
echo "sqld failed to become healthy"
48-
docker compose logs sqld
47+
echo "MongoDB failed to become healthy"
48+
docker compose logs mongodb
4949
exit 1
5050
fi
51-
echo "sqld attempt $i/20 - waiting 3s..."
51+
echo "MongoDB attempt $i/20 - waiting 3s..."
5252
sleep 3
5353
done
5454

api/go.mod

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ require (
4444
github.com/stretchr/testify v1.11.1
4545
github.com/swaggo/swag v1.16.6
4646
github.com/thedevsaddam/govalidator v1.9.10
47-
github.com/tursodatabase/libsql-client-go v0.0.0-20260514053736-a9a8fadfe885
4847
github.com/uptrace/uptrace-go v1.43.0
4948
github.com/xuri/excelize/v2 v2.10.1
49+
go.mongodb.org/mongo-driver/v2 v2.6.0
50+
go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo v0.0.0-20260513205827-ba143fc95a5e
5051
go.opentelemetry.io/otel v1.43.0
5152
go.opentelemetry.io/otel/metric v1.43.0
5253
go.opentelemetry.io/otel/sdk v1.43.0
@@ -94,13 +95,11 @@ require (
9495
github.com/PuerkitoBio/goquery v1.12.0 // indirect
9596
github.com/andybalholm/brotli v1.2.1 // indirect
9697
github.com/andybalholm/cascadia v1.3.3 // indirect
97-
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
9898
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
9999
github.com/cespare/xxhash/v2 v2.3.0 // indirect
100100
github.com/clipperhouse/displaywidth v0.11.0 // indirect
101101
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
102102
github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 // indirect
103-
github.com/coder/websocket v1.8.12 // indirect
104103
github.com/envoyproxy/go-control-plane/envoy v1.37.0 // indirect
105104
github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect
106105
github.com/fatih/color v1.19.0 // indirect
@@ -164,8 +163,12 @@ require (
164163
github.com/valyala/fasthttp v1.71.0 // indirect
165164
github.com/vanng822/css v1.0.1 // indirect
166165
github.com/vanng822/go-premailer v1.33.0 // indirect
166+
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
167+
github.com/xdg-go/scram v1.2.0 // indirect
168+
github.com/xdg-go/stringprep v1.0.4 // indirect
167169
github.com/xuri/efp v0.0.1 // indirect
168170
github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 // indirect
171+
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
169172
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
170173
go.opentelemetry.io/contrib v1.43.0 // indirect
171174
go.opentelemetry.io/contrib/detectors/gcp v1.43.0 // indirect
@@ -185,13 +188,12 @@ require (
185188
go.uber.org/multierr v1.11.0 // indirect
186189
go.uber.org/zap v1.28.0 // indirect
187190
go.yaml.in/yaml/v3 v3.0.4 // indirect
188-
golang.org/x/crypto v0.50.0 // indirect
189-
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect
191+
golang.org/x/crypto v0.51.0 // indirect
190192
golang.org/x/mod v0.35.0 // indirect
191193
golang.org/x/net v0.53.0 // indirect
192194
golang.org/x/oauth2 v0.36.0 // indirect
193-
golang.org/x/sys v0.43.0 // indirect
194-
golang.org/x/text v0.36.0 // indirect
195+
golang.org/x/sys v0.44.0 // indirect
196+
golang.org/x/text v0.37.0 // indirect
195197
golang.org/x/time v0.15.0 // indirect
196198
golang.org/x/tools v0.44.0 // indirect
197199
google.golang.org/appengine v1.6.8 // indirect

api/go.sum

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ github.com/andybalholm/brotli v1.2.1 h1:R+f5xP285VArJDRgowrfb9DqL18yVK0gKAW/F+eT
6666
github.com/andybalholm/brotli v1.2.1/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
6767
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
6868
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
69-
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
70-
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
7169
github.com/avast/retry-go/v5 v5.0.0 h1:kf1Qc2UsTZ4qq8elDymqfbISvkyMuhgRxuJqX2NHP7k=
7270
github.com/avast/retry-go/v5 v5.0.0/go.mod h1://d+usmKWio1agtZfS1H/ltTqwtIfBnRq9zEwjc3eH8=
7371
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
@@ -90,8 +88,6 @@ github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os
9088
github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4=
9189
github.com/cockroachdb/cockroach-go/v2 v2.4.3 h1:LJO3K3jC5WXvMePRQSJE1NsIGoFGcEx1LW83W6RAlhw=
9290
github.com/cockroachdb/cockroach-go/v2 v2.4.3/go.mod h1:9U179XbCx4qFWtNhc7BiWLPfuyMVQ7qdAhfrwLz1vH0=
93-
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
94-
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
9591
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9692
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9793
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -324,8 +320,6 @@ github.com/thedevsaddam/govalidator v1.9.10 h1:m3dLRbSZ5Hts3VUWYe+vxLMG+FdyQuWOj
324320
github.com/thedevsaddam/govalidator v1.9.10/go.mod h1:Ilx8u7cg5g3LXbSS943cx5kczyNuUn7LH/cK5MYuE90=
325321
github.com/tiendc/go-deepcopy v1.7.2 h1:Ut2yYR7W9tWjTQitganoIue4UGxZwCcJy3orjrrIj44=
326322
github.com/tiendc/go-deepcopy v1.7.2/go.mod h1:4bKjNC2r7boYOkD2IOuZpYjmlDdzjbpTRyCx+goBCJQ=
327-
github.com/tursodatabase/libsql-client-go v0.0.0-20260514053736-a9a8fadfe885 h1:YssVXwM/9nUAjGNmUWdgvb05JVcsaBrDn5yr+MaJTn0=
328-
github.com/tursodatabase/libsql-client-go v0.0.0-20260514053736-a9a8fadfe885/go.mod h1:08inkKyguB6CGGssc/JzhmQWwBgFQBgjlYFjxjRh7nU=
329323
github.com/uptrace/uptrace-go v1.43.0 h1:5QuCdyFJdWUEXx6Fr6sYfezdgO6n6lnkOvUTLlyQO7U=
330324
github.com/uptrace/uptrace-go v1.43.0/go.mod h1:ehDTIdtBSolg4Z0CCvg1C8yR6VX1YFDqBcg2KmsXWn0=
331325
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
@@ -336,6 +330,12 @@ github.com/vanng822/css v1.0.1 h1:10yiXc4e8NI8ldU6mSrWmSWMuyWgPr9DZ63RSlsgDw8=
336330
github.com/vanng822/css v1.0.1/go.mod h1:tcnB1voG49QhCrwq1W0w5hhGasvOg+VQp9i9H1rCM1w=
337331
github.com/vanng822/go-premailer v1.33.0 h1:nglIpKn/7e3kIAwYByiH5xpauFur7RwAucqyZ59hcic=
338332
github.com/vanng822/go-premailer v1.33.0/go.mod h1:LGYI7ym6FQ7KcHN16LiQRF+tlan7qwhP1KEhpTINFpo=
333+
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
334+
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
335+
github.com/xdg-go/scram v1.2.0 h1:bYKF2AEwG5rqd1BumT4gAnvwU/M9nBp2pTSxeZw7Wvs=
336+
github.com/xdg-go/scram v1.2.0/go.mod h1:3dlrS0iBaWKYVt2ZfA4cj48umJZ+cAEbR6/SjLA88I8=
337+
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
338+
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
339339
github.com/xuri/efp v0.0.1 h1:fws5Rv3myXyYni8uwj2qKjVaRP30PdjeYe2Y6FDsCL8=
340340
github.com/xuri/efp v0.0.1/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
341341
github.com/xuri/excelize/v2 v2.10.1 h1:V62UlqopMqha3kOpnlHy2CcRVw1V8E63jFoWUmMzxN0=
@@ -344,17 +344,23 @@ github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 h1:+C0TIdyyYmzadGaL/HBL
344344
github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
345345
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
346346
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
347+
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
348+
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
347349
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
348350
github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE=
349351
github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
350352
github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=
351353
github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s=
354+
go.mongodb.org/mongo-driver/v2 v2.6.0 h1:b9sJOYrkmt4l8bY43ZenFBcPlhYIjaOfYHLtbB/5qi8=
355+
go.mongodb.org/mongo-driver/v2 v2.6.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
352356
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
353357
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
354358
go.opentelemetry.io/contrib v1.43.0 h1:rv+pngknCr4qpZDxSpEvEoRioutgfbkk82x6MChJQ3U=
355359
go.opentelemetry.io/contrib v1.43.0/go.mod h1:JYdNU7Pl/2ckKMGp8/G7zeyhEbtRmy9Q8bcrtv75Znk=
356360
go.opentelemetry.io/contrib/detectors/gcp v1.43.0 h1:62yY3dT7/ShwOxzA0RsKRgshBmfElKI4d/Myu2OxDFU=
357361
go.opentelemetry.io/contrib/detectors/gcp v1.43.0/go.mod h1:RyaZMFY7yi1kAs45S6mbFGz8O8rqB0dTY14uzvG4LCs=
362+
go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo v0.0.0-20260513205827-ba143fc95a5e h1:OX282aWfZNOrSVUPF59HlRhyA+MDcyi4kI8WWXt6A8I=
363+
go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo v0.0.0-20260513205827-ba143fc95a5e/go.mod h1:lw7VQzmNsmkZBRQqOQiREGxO3GtzG/pOVEmKufablmA=
358364
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0 h1:0Qx7VGBacMm9ZENQ7TnNObTYI4ShC+lHI16seduaxZo=
359365
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0/go.mod h1:Sje3i3MjSPKTSPvVWCaL8ugBzJwik3u4smCjUeuupqg=
360366
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 h1:CqXxU8VOmDefoh0+ztfGaymYbhdB/tT3zs79QaZTNGY=
@@ -414,10 +420,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
414420
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
415421
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
416422
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
417-
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
418-
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
419-
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw=
420-
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ=
423+
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
424+
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
421425
golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ=
422426
golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs=
423427
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -462,8 +466,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
462466
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
463467
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
464468
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
465-
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
466-
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
469+
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
470+
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
467471
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
468472
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
469473
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -483,8 +487,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
483487
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
484488
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
485489
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
486-
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
487-
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
490+
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
491+
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
488492
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
489493
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
490494
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

api/pkg/di/container.go

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package di
33
import (
44
"context"
55
"crypto/tls"
6-
"database/sql"
76
"fmt"
87
"net/http"
98
"os"
@@ -74,6 +73,7 @@ import (
7473
"github.com/NdoleStudio/httpsms/pkg/handlers"
7574
"github.com/NdoleStudio/httpsms/pkg/telemetry"
7675
"github.com/NdoleStudio/httpsms/pkg/validators"
76+
mongoDriver "go.mongodb.org/mongo-driver/v2/mongo"
7777
"gorm.io/driver/postgres"
7878
gormLogger "gorm.io/gorm/logger"
7979
)
@@ -83,7 +83,7 @@ type Container struct {
8383
projectID string
8484
db *gorm.DB
8585
dedicatedDB *gorm.DB
86-
tursoDB *sql.DB
86+
mongoDB *mongoDriver.Database
8787
version string
8888
app *fiber.App
8989
eventDispatcher *services.EventDispatcher
@@ -293,21 +293,21 @@ func (container *Container) DedicatedDB() (db *gorm.DB) {
293293
return container.dedicatedDB
294294
}
295295

296-
// TursoDB creates a *sql.DB connection to a Turso/libSQL database
297-
func (container *Container) TursoDB() *sql.DB {
298-
if container.tursoDB != nil {
299-
return container.tursoDB
296+
// MongoDB creates a *mongo.Database connection to MongoDB Atlas
297+
func (container *Container) MongoDB() *mongoDriver.Database {
298+
if container.mongoDB != nil {
299+
return container.mongoDB
300300
}
301301

302-
container.logger.Debug("creating Turso *sql.DB connection")
302+
container.logger.Debug("creating MongoDB *mongo.Database connection")
303303

304-
db, err := repositories.NewTursoDB(os.Getenv("TURSO_DATABASE_DSN"))
304+
db, err := repositories.NewMongoDB(os.Getenv("MONGODB_URI"))
305305
if err != nil {
306306
container.logger.Fatal(err)
307307
}
308308

309-
container.tursoDB = db
310-
return container.tursoDB
309+
container.mongoDB = db
310+
return container.mongoDB
311311
}
312312

313313
// HedgingFailureCounter creates an OTel counter for hedging secondary write failures
@@ -922,20 +922,20 @@ func (container *Container) MessageThreadRepository() (repository repositories.M
922922
// HeartbeatMonitorRepository creates a new instance of repositories.HeartbeatMonitorRepository
923923
func (container *Container) HeartbeatMonitorRepository() (repository repositories.HeartbeatMonitorRepository) {
924924
switch os.Getenv("HEARTBEAT_DB_BACKEND") {
925-
case "turso":
926-
container.logger.Debug("creating libSQL repositories.HeartbeatMonitorRepository")
927-
return repositories.NewLibsqlHeartbeatMonitorRepository(
925+
case "mongodb":
926+
container.logger.Debug("creating MongoDB repositories.HeartbeatMonitorRepository")
927+
return repositories.NewMongoHeartbeatMonitorRepository(
928928
container.Logger(),
929929
container.Tracer(),
930-
container.TursoDB(),
930+
container.MongoDB(),
931931
)
932932
case "hedging":
933933
container.logger.Debug("creating hedging repositories.HeartbeatMonitorRepository")
934934
return repositories.NewHedgingHeartbeatMonitorRepository(
935935
container.Logger(),
936936
container.Tracer(),
937937
repositories.NewGormHeartbeatMonitorRepository(container.Logger(), container.Tracer(), container.DedicatedDB()),
938-
repositories.NewLibsqlHeartbeatMonitorRepository(container.Logger(), container.Tracer(), container.TursoDB()),
938+
repositories.NewMongoHeartbeatMonitorRepository(container.Logger(), container.Tracer(), container.MongoDB()),
939939
container.HedgingFailureCounter(),
940940
)
941941
default:
@@ -1760,20 +1760,20 @@ func (container *Container) RegisterSwaggerRoutes() {
17601760
// HeartbeatRepository registers a new instance of repositories.HeartbeatRepository
17611761
func (container *Container) HeartbeatRepository() repositories.HeartbeatRepository {
17621762
switch os.Getenv("HEARTBEAT_DB_BACKEND") {
1763-
case "turso":
1764-
container.logger.Debug("creating libSQL repositories.HeartbeatRepository")
1765-
return repositories.NewLibsqlHeartbeatRepository(
1763+
case "mongodb":
1764+
container.logger.Debug("creating MongoDB repositories.HeartbeatRepository")
1765+
return repositories.NewMongoHeartbeatRepository(
17661766
container.Logger(),
17671767
container.Tracer(),
1768-
container.TursoDB(),
1768+
container.MongoDB(),
17691769
)
17701770
case "hedging":
17711771
container.logger.Debug("creating hedging repositories.HeartbeatRepository")
17721772
return repositories.NewHedgingHeartbeatRepository(
17731773
container.Logger(),
17741774
container.Tracer(),
17751775
repositories.NewGormHeartbeatRepository(container.Logger(), container.Tracer(), container.DedicatedDB()),
1776-
repositories.NewLibsqlHeartbeatRepository(container.Logger(), container.Tracer(), container.TursoDB()),
1776+
repositories.NewMongoHeartbeatRepository(container.Logger(), container.Tracer(), container.MongoDB()),
17771777
container.HedgingFailureCounter(),
17781778
)
17791779
default:

api/pkg/entities/heartbeat.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import (
88

99
// Heartbeat represents is a pulse from an active phone
1010
type Heartbeat struct {
11-
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid;" example:"32343a19-da5e-4b1b-a767-3298a73703cb"`
12-
Owner string `json:"owner" gorm:"index:idx_heartbeats_owner_timestamp" example:"+18005550199"`
13-
Version string `json:"version" example:"344c10f"`
14-
Charging bool `json:"charging" example:"true"`
15-
UserID UserID `json:"user_id" example:"WB7DRDWrJZRGbYrv2CKGkqbzvqdC"`
16-
Timestamp time.Time `json:"timestamp" gorm:"index:idx_heartbeats_owner_timestamp" example:"2022-06-05T14:26:01.520828+03:00"`
11+
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid;" bson:"_id" example:"32343a19-da5e-4b1b-a767-3298a73703cb"`
12+
Owner string `json:"owner" gorm:"index:idx_heartbeats_owner_timestamp" bson:"owner" example:"+18005550199"`
13+
Version string `json:"version" bson:"version" example:"344c10f"`
14+
Charging bool `json:"charging" bson:"charging" example:"true"`
15+
UserID UserID `json:"user_id" bson:"user_id" example:"WB7DRDWrJZRGbYrv2CKGkqbzvqdC"`
16+
Timestamp time.Time `json:"timestamp" gorm:"index:idx_heartbeats_owner_timestamp" bson:"timestamp" example:"2022-06-05T14:26:01.520828+03:00"`
1717
}

api/pkg/entities/heartbeat_monitor.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ import (
88

99
// HeartbeatMonitor is used to monitor heartbeats of a phone
1010
type HeartbeatMonitor struct {
11-
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid;" example:"32343a19-da5e-4b1b-a767-3298a73703cb"`
12-
PhoneID uuid.UUID `json:"phone_id" example:"32343a19-da5e-4b1b-a767-3298a73703cb"`
13-
UserID UserID `json:"user_id" example:"WB7DRDWrJZRGbYrv2CKGkqbzvqdC"`
14-
QueueID string `json:"queue_id" example:"0360259236613675274"`
15-
Owner string `json:"owner" example:"+18005550199"`
16-
PhoneOnline bool `json:"phone_online" example:"true" default:"true"`
17-
CreatedAt time.Time `json:"created_at" example:"2022-06-05T14:26:02.302718+03:00"`
18-
UpdatedAt time.Time `json:"updated_at" example:"2022-06-05T14:26:10.303278+03:00"`
11+
ID uuid.UUID `json:"id" gorm:"primaryKey;type:uuid;" bson:"_id" example:"32343a19-da5e-4b1b-a767-3298a73703cb"`
12+
PhoneID uuid.UUID `json:"phone_id" bson:"phone_id" example:"32343a19-da5e-4b1b-a767-3298a73703cb"`
13+
UserID UserID `json:"user_id" bson:"user_id" example:"WB7DRDWrJZRGbYrv2CKGkqbzvqdC"`
14+
QueueID string `json:"queue_id" bson:"queue_id" example:"0360259236613675274"`
15+
Owner string `json:"owner" bson:"owner" example:"+18005550199"`
16+
PhoneOnline bool `json:"phone_online" bson:"phone_online" example:"true" default:"true"`
17+
CreatedAt time.Time `json:"created_at" bson:"created_at" example:"2022-06-05T14:26:02.302718+03:00"`
18+
UpdatedAt time.Time `json:"updated_at" bson:"updated_at" example:"2022-06-05T14:26:10.303278+03:00"`
1919
}
2020

2121
// RequiresCheck returns true if the heartbeat monitor requires a check

0 commit comments

Comments
 (0)