Compare commits

...
406 Commits
Author SHA1 Message Date
Quaternions f62b114119 update deps
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-10-08 12:20:33 -07:00
Quaternions f573b63a3a update rbx_loader to fix union AssetId->Content migration
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-10-03 14:14:12 -07:00
Quaternions 76b0114ff1 rbx_asset: drop unused cookie feature 2026-10-03 13:42:01 -07:00
Quaternions 50b0aa460e combobulator: fix local-only unions
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-10-03 12:58:01 -07:00
Quaternions 6b0a27a4c2 Fix print typo 2026-10-03 12:43:15 -07:00
Quaternions 1a5fd56a2b update snf
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-10-03 10:32:15 -07:00
Quaternions eae8c067ba update deps 2026-10-03 10:31:01 -07:00
Quaternions 49bafd503d update snf
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2026-09-28 17:05:09 -07:00
Quaternions 50161e120f update deps
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-09-28 16:54:00 -07:00
Quaternions 1ef0c56d0b update snf 2026-09-28 16:53:56 -07:00
Quaternions b500491706 update deps
continuous-integration/drone/push Build is passing
2026-09-24 14:02:26 -07:00
Quaternions b912cdfaf9 update strafesnet deps 2026-09-24 14:02:26 -07:00
Quaternions 1205d1c847 backend: work around surprising data-service behaviour
continuous-integration/drone/pr Build was killed
continuous-integration/drone/push Build is passing
2026-07-22 17:08:30 -07:00
Quaternions 80cf3131d1 Update Rust (#381)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Reviewed-on: #381
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-07-17 21:10:36 +00:00
Quaternions 65215ce6db Update Web (#380)
continuous-integration/drone/push Build is passing
We wouldn't want web vulnerabilities now would we

Reviewed-on: #380
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-07-17 21:09:22 +00:00
Quaternions f3700e3d4b Update Go Dependencies (#379)
continuous-integration/drone/push Build is passing
I have no idea what I am doing, I used ai to help fix an issue.

This is my process:
`go get -u ./...`
error:
```
        google.golang.org/grpc/status imports
        google.golang.org/genproto/googleapis/rpc/status: ambiguous import: found package google.golang.org/genproto/googleapis/rpc/status in multiple modules:
        google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 (/home/quat/go/pkg/mod/google.golang.org/genproto@v0.0.0-20200526211855-cb27e3aa2013/googleapis/rpc/status)
        google.golang.org/genproto/googleapis/rpc v0.0.0-20260715232425-e75dac1f907d (/home/quat/go/pkg/mod/google.golang.org/genproto/googleapis/rpc@v0.0.0-20260715232425-e75dac1f907d/status)
```

ai said to do this:
`go mod edit -replace google.golang.org/genproto=google.golang.org/genproto/googleapis/rpc@latest`
which added a line to the go.mod:
```
replace google.golang.org/genproto => google.golang.org/genproto/googleapis/rpc v0.0.0-20260715232425-e75dac1f907d
```

after running `go get -u ./...` successfully, I removed the 'replace' line manually and things still seem to work.  Ai thinks that "This happened because Google split google.golang.org/genproto into multiple smaller modules (like genproto/googleapis/rpc, genproto/googleapis/api, etc.) starting around 2023"

Reviewed-on: #379
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-07-17 21:01:51 +00:00
Quaternions 636fe79b63 Add Submission,Mapfix Delete Endpoint (#378)
continuous-integration/drone/push Build is passing
Closes #270.

Does not implement any webui.  The goal is to block duplicates well enough during creation to not need a extensive implementation of this feature.

Reviewed-on: #378
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-07-17 20:38:29 +00:00
Quaternions 5bdd460d88 Identify more submission issues early (duplicate, same name) (#377)
continuous-integration/drone/push Build is passing
Stop people from making duplicate submissions or picking a name already in use.

Reviewed-on: #377
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-07-17 20:17:10 +00:00
Quaternions d28024d9d3 update deps
continuous-integration/drone/push Build is passing
2026-07-10 13:34:28 -07:00
Quaternions f4425835a1 combobulator: delete leading newline 2026-07-10 13:34:19 -07:00
Quaternions c6b20d3742 Drop map-tool dependency (#375)
continuous-integration/drone/push Build is passing
Paste the 80 lines of utility functions and drop the heavy dependency.

Reviewed-on: #375
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-07-10 20:30:00 +00:00
Quaternions 5aecf33d36 update deps
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-07-09 15:28:38 -07:00
Quaternions 18814754dd Refactor Asset Loader (#373)
continuous-integration/drone/push Build is failing
Use the refactored deferred_loader api which removes the janky Loader trait.  This moves a bunch of implementation details into upstream code.

Reviewed-on: #373
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-07-09 22:27:43 +00:00
Quaternions 274ccb2786 validator: use WeakDom::full_path_of
continuous-integration/drone/push Build is passing
2026-07-08 09:55:07 -07:00
Quaternions e7b967f90d Allow admin to see any operation (#371)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Reviewed-on: #371
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-07-03 18:45:41 +00:00
Quaternions dc4c4d6f9d update deps
continuous-integration/drone/push Build is passing
2026-07-03 11:32:10 -07:00
Quaternions 4f25ba026f update rbx-dom 2026-07-03 11:31:10 -07:00
Quaternions a2168a11f8 update deps
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2026-06-11 11:26:27 -07:00
Quaternions 29e391bae6 Check that mapfixes do not change DisplayName, Creator, GameID (#324)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
- Depends on #323
- Closes #189

Good lord this code is horrible.  The nested check() functions constantly swapping argument order back and forth bruh

Reviewed-on: #324
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-06-11 18:23:48 +00:00
Quaternions f53b30dbb6 sign ci
continuous-integration/drone/push Build is passing
2026-05-25 22:36:26 -07:00
Quaternions 4ad10f70e0 combobulator: add new roblox properties to loader
continuous-integration/drone/push Build is pending
2026-05-25 22:33:15 -07:00
Quaternions ff01bf66b3 use rust 1.95 in ci 2026-05-25 22:31:24 -07:00
Quaternions 821d4d35d2 add strings to mesh loader
continuous-integration/drone/push Build is failing
2026-05-25 14:59:24 -07:00
Quaternions f59277f2cd combobulator: tweak union loader 2026-05-25 11:30:09 -07:00
Quaternions 52b93e4663 update deps 2026-05-25 11:26:31 -07:00
Quaternions 274f4049fe update deps
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2026-05-23 17:17:48 -07:00
Quaternions db260961aa update deps
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2026-05-23 16:35:38 -07:00
Quaternions 2d7a554782 update deps
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2026-05-23 16:26:31 -07:00
Quaternions 9063e3b689 readme: delete RBXCOOKIE
continuous-integration/drone/push Build is passing
2026-05-14 17:48:09 -07:00
Quaternions cd02e45af0 box large error variants
continuous-integration/drone/push Build is passing
2026-05-11 13:50:58 -07:00
Quaternions 32c25854ef clippy fixes 2026-05-11 13:48:04 -07:00
Quaternions 40d914a320 update deps 2026-05-11 13:40:55 -07:00
Quaternions e38d4c0971 style 2026-05-11 13:26:54 -07:00
Quaternions 4d15cbf024 combobulator: begin new error matching
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
2026-05-01 15:38:23 -07:00
Quaternions 5290677730 cargo workspace: use resolver 3 2026-05-01 15:31:42 -07:00
Quaternions fadd1910f7 combobulator: Update map tool to use cloud api (#363)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Fixes combobulator asset download.

Reviewed-on: #363
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-04-29 21:04:40 +00:00
Quaternions e81844bdfd combobulator: update rbx_loader (#362)
continuous-integration/drone/push Build is passing
Fixes #361

Reviewed-on: #362
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-04-29 20:59:56 +00:00
Quaternions c2444c67ea update map_tool
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2026-04-17 12:12:14 -07:00
Quaternions 9032553974 combobulator uses cookie api
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2026-04-17 11:59:21 -07:00
Quaternions fc6ce24ece update rbx_asset
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2026-04-17 11:50:03 -07:00
Quaternions 1c8dab46bf Revert "debug asset operation"
continuous-integration/drone/push Build is passing
This reverts commit 52bd9d7c5a.
2026-04-17 10:57:20 -07:00
Quaternions 52bd9d7c5a debug asset operation
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2026-04-17 10:47:13 -07:00
Quaternions d7b0fc829d validator: remove cookie api (#354)
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
Fixes #353

Roblox finally added the missing pieces of the cloud api.  Funnily enough they didn't get the message out loud enough before deprecating the old api and breaking our api usage.

Reviewed-on: #354
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-04-17 04:26:38 +00:00
Quaternions 36bf831159 update strafesnet deps
continuous-integration/drone/push Build is passing
2026-04-14 13:33:41 -07:00
Quaternions a5711cdc30 backend: test for exact DisplayName match
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
- The ListMaps method is unexpectedly finding DisplayName substrings
2026-03-24 19:39:27 -07:00
Quaternions 4a399cc2ea format
continuous-integration/drone/push Build is failing
2026-03-24 19:37:53 -07:00
itzaname f46bdfc87f Merge pull request 'Tweak Reviewer Cards' (#345) from review-cards into staging
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Reviewed-on: #345
Reviewed-by: itzaname <itzaname@noreply@itzana.me>
2026-03-08 00:18:12 +00:00
Quaternions d7823a82c0 web: fix script review card style
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-07 16:14:01 -08:00
Quaternions ad8be22b87 web: use pointer for review cards 2026-03-07 16:13:47 -08:00
itzaname 2f2c51be36 Merge pull request 'Update style to match other StrafesNET sites' (#343) from feature/style-update into staging
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Reviewed-on: #343
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
2026-03-07 23:54:58 +00:00
itzaname 9f952d7e54 Update style to match other sites
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-07 18:35:51 -05:00
Quaternions d26126c9d3 combobulator: use up to 16 parallel requests
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-06 10:07:26 -08:00
Quaternions b6ac6ce47f validator: switch futures to leaner futures-util 2026-03-06 09:50:12 -08:00
Quaternions 4e8ebd826a combobulator: skip 403
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-06 07:39:28 -08:00
Quaternions 0005a55ae0 combobulator: don't give up for conversion errors
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2026-03-05 09:45:30 -08:00
Quaternions 4e3048e272 Add Combobulate Endpoint (#338)
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
Adds the ability to seed a single map for combobulation.

Reviewed-on: #338
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-03-05 17:12:05 +00:00
Quaternions 5549a123a2 update deps, notable rbx_loader
continuous-integration/drone/push Build is passing
2026-03-05 08:57:33 -08:00
Quaternions 77d43e1e25 combobulator: skip 404
continuous-integration/drone/push Build is passing
2026-03-04 16:26:45 -08:00
Quaternions 6d9fb5bca6 update deps, notably rbx_loader
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-04 09:30:20 -08:00
itzaname 2118a8ab35 Add string search for display_name
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-03 20:55:05 -05:00
Quaternions 277cd819c2 Categorize Errors to avoid HTTP 500 (#326)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
- Depends on #325 (lazyness)
- Closes #148

No guarantees we won't see 500s, but I tried ok

Reviewed-on: #326
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-03-03 17:51:58 +00:00
Quaternions c22717831d Check for maps with the exact same name on submit (#325)
continuous-integration/drone/push Build is passing
Closes #273.
Could be better but meh.

Reviewed-on: #325
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-03-03 17:49:08 +00:00
Quaternions ed8a54370c Limit DisplayName and Creator to 50 characters (#323)
continuous-integration/drone/push Build is failing
Closes #276

Reviewed-on: #323
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-03-03 17:48:10 +00:00
Quaternions 7756bbb06d update deps, notably rbx_loader & map_tool
continuous-integration/drone/push Build is passing
2026-03-03 09:38:20 -08:00
Quaternions 3b8da9a8a3 list workspace dependencies 2026-03-03 09:33:58 -08:00
Quaternions 46290834c3 combobulator: save a clone in cold path
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-02 17:28:20 -08:00
Quaternions ec4e0cf6fa combobulator: use cached assets
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2026-03-02 17:19:38 -08:00
Quaternions 3dff802bb1 update roblox_emulator to fix infinite luau loops
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2026-03-02 16:54:59 -08:00
Quaternions a6ff551bee combobulator: skip "Asset is not approved for the requester"
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-02 16:24:20 -08:00
Quaternions dbd28ea87b Rework Combobulator Texture Loading (#329)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
rbx_loader was attempting to load textures and other assets from disk.  Rework the system to stop implicitly loading from disk.

Reviewed-on: #329
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-03-02 23:59:40 +00:00
Quaternions 0efb07b52a Merge remote-tracking branch 'origin/master' into staging
continuous-integration/drone/push Build is passing
2026-03-02 10:24:12 -08:00
itzaname d4e50c2d37 Add SNFM download endpoints and batch seed endpoint (#328)
continuous-integration/drone/push Build is passing
Adds download endpoint to RPC and Public API
Adds bulk seed endpoint: POST /v1/maps-admin/seed-combobulator

Reviewed-on: #328
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2026-03-02 02:39:41 +00:00
itzaname 501b0933e6 Remove unused struct
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
2026-03-01 20:11:22 -05:00
itzaname 078a3e4c4a Add map seed endpoint
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-01 17:41:11 -05:00
itzaname 02873e82b6 Just use normal asset download
continuous-integration/drone/push Build is passing
2026-03-01 17:10:53 -05:00
itzaname 0e2ffcd570 Doc updates
continuous-integration/drone/push Build is passing
2026-03-01 16:39:58 -05:00
itzaname c788344bf3 Add snfm download endpoints
continuous-integration/drone/push Build is passing
2026-03-01 16:28:37 -05:00
itzaname 0711774153 Merge pull request 'Deploy staging' (#327) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #327
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
2026-03-01 20:48:31 +00:00
itzaname a8f44179a3 Don't version maps
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-03-01 15:21:34 -05:00
itzaname e1862d3917 Handle archived assets
continuous-integration/drone/push Build is failing
2026-03-01 15:05:10 -05:00
itzaname da96f1a090 I love gzip
continuous-integration/drone/push Build is failing
2026-03-01 14:49:16 -05:00
itzaname 05c1107e91 Validator fixes
continuous-integration/drone/push Build is failing
2026-03-01 13:55:33 -05:00
itzaname 83e257a4d5 Change rettention policy
continuous-integration/drone/push Build is failing
2026-03-01 13:39:02 -05:00
itzaname b197791509 Debian fix
continuous-integration/drone/push Build is failing
2026-03-01 13:24:10 -05:00
itzaname 91c2d87d2f ssl fix
continuous-integration/drone/push Build is failing
2026-03-01 13:18:50 -05:00
itzaname 225e095c92 Why do I do this to myself
continuous-integration/drone/push Build is failing
2026-03-01 01:41:44 -05:00
itzaname 2a6099480e Drop alpine
continuous-integration/drone/push Build is failing
2026-03-01 01:37:48 -05:00
itzaname d6074c4b78 Compile fixes
continuous-integration/drone/push Build is failing
2026-03-01 01:33:41 -05:00
itzaname f3a677dc20 Attempt openssl fixes
continuous-integration/drone/push Build is failing
2026-03-01 01:29:26 -05:00
itzaname f4209ecd0a Increase timeout to 15 min
continuous-integration/drone/push Build is failing
2026-03-01 01:23:09 -05:00
itzaname e83c9db866 Attempt combobulation
continuous-integration/drone/push Build is passing
2026-03-01 01:19:27 -05:00
Quaternions 7bec80a2fe Reviewer Dashboard: Click overview cards to change tab (#322)
continuous-integration/drone/push Build is failing
I keep thinking I can click the cards to select submissions or mapfixes, so make it actually do that.

Reviewed-on: #322
Reviewed-by: itzaname <itzaname@noreply@itzana.me>
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-01-16 21:14:19 +00:00
Quaternions 3e77edb1cc Update Submission Button (#321)
continuous-integration/drone/push Build is failing
Closes #318

Reviewed-on: #321
Reviewed-by: itzaname <itzaname@noreply@itzana.me>
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-01-16 21:12:55 +00:00
Quaternions 0b7ca534f3 Add Maptest Integration GRPC Controllers (#317)
continuous-integration/drone/push Build is failing
Creates a GRPC controller for Submissions and Mapfixes.  This is intended to be used from the AOR group games via game-rpc running in "maptest" mode.

Reviewed-on: #317
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2026-01-07 20:32:10 +00:00
Quaternions de864ac8ef Merge pull request 'Deploy Upload Escape Hatch' (#320) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #320
2026-01-06 19:20:38 +00:00
Quaternions 264ce38c08 Merge pull request 'Upload->Release Escape Hatch' (#319) from reject-upload into staging
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
Reviewed-on: #319
2026-01-06 19:18:18 +00:00
Quaternions b1e10dc50e web: show RequestChanges button in Uploaded status
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2026-01-06 11:13:41 -08:00
Quaternions 755616f46c backend: allow request changes for uploaded models 2026-01-06 11:10:37 -08:00
Quaternions 9d9ab20952 Merge pull request 'Deploy nudges and action confirmation' (#311) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #311
2025-12-28 02:06:18 +00:00
itzaname e41d34dd3d Group buttons and add confirmation dialogues (#310)
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is failing
Reviewer:
<img width="409" alt="image.png" src="attachments/a090c61e-a2d8-4685-ae64-547851d1ee84">
Submitter:
<img width="404" alt="image.png" src="attachments/9205a438-1f1f-4af4-b9a0-6a8d56580afa">
<img width="411" alt="image.png" src="attachments/7ae8115b-3376-4306-b9b9-acc12226abb3">
Admin:
<img width="392" alt="image.png" src="attachments/07a182d1-5375-4195-bfda-c14f09469cbe">
<img width="388" alt="image.png" src="attachments/ce82017d-5c1d-4a93-9247-9b5608f9030e">

Confirmation Dialogue:
<img width="545" alt="image.png" src="attachments/1efff8be-1d41-429e-8c6e-3d36b7dad128">

Example where both groups show up:
<img width="404" alt="image.png" src="attachments/b0ca4be2-7c58-4c0c-9a5f-dcd89e23b08f">

Reviewed-on: #310
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-12-28 00:34:58 +00:00
itzaname f49e27e230 Support editing map fix descriptions (#309)
continuous-integration/drone/push Build is passing
The description can be edited by the **submitter** only if the status is Changes Requested or Under Construction.

<img width="734" alt="image.png" src="attachments/9fd7b838-f946-4091-a396-ef66f5e655bc">
<img width="724" alt="image.png" src="attachments/f65f059e-af97-448a-9627-fee827d30e59">

Reviewed-on: #309
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-12-27 23:40:42 +00:00
itzaname d500462fc7 Add user nudges for certain statuses (#308)
continuous-integration/drone/push Build is failing
Will show a badge icon on the audit tab if there are any validator errors/checklists to direct attention to it. Will show nudge message ONLY to the submitter.

![image.png](/attachments/f5cd9ab6-b996-40b2-ad43-fa5e9b28caf5)
![image.png](/attachments/9aba2132-ec85-4ae9-b0fa-be253ecc2355)

Closes !205

Reviewed-on: #308
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-12-27 23:30:38 +00:00
itzaname ee2bc94312 Add releasing status to the processing list (#307)
continuous-integration/drone/push Build is passing
Closes !269

Reviewed-on: #307
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-12-27 22:25:39 +00:00
Quaternions 67ece176c6 Merge pull request 'Deploy script review update' (#306) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #306
2025-12-27 21:49:28 +00:00
itzaname 84edc71574 Add game name to review page (#305)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Deduped all the game name usage to a single lib. Closes !281

<img width="785" alt="image.png" src="attachments/0f226438-fed1-40b2-81a9-2988dd2d4a33">

Reviewed-on: #305
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-12-27 19:56:33 +00:00
itzaname 7c5d8a2163 Add script review page (#304)
continuous-integration/drone/push Build is passing
Closes !2

Added review dashboard button as well.

<img width="1313" alt="image.png" src="attachments/a2abd430-7ff6-431a-9261-82e026de58f5">

![image.png](/attachments/e1ba3536-2869-4661-b46c-007ddaff8f3e)

Reviewed-on: #304
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-12-27 19:56:19 +00:00
Quaternions b31b3bed5f Merge pull request 'Deploy workflow timeline' (#302) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #302
2025-12-27 08:28:42 +00:00
Quaternions 7eaa84a0ed Change Timeline Text (#301)
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
Some tweaks to the descriptions.  Evidently I didn't read carefully enough.

Reviewed-on: #301
Reviewed-by: itzaname <itzaname@noreply@itzana.me>
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2025-12-27 08:19:17 +00:00
itzaname cf0cf9da7a Add workflow timeline (#300)
continuous-integration/drone/push Build is passing
Closes !232

<img width="763" alt="image.png" src="attachments/559715f5-630e-4029-a19b-c9f4cf4c7270">

Reviewed-on: #300
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-12-27 08:04:02 +00:00
Quaternions 34cd1c7c26 Merge pull request 'Deploy dashboard update' (#299) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #299
Reviewed-by: itzaname <itzaname@noreply@itzana.me>
2025-12-27 05:41:53 +00:00
itzaname 74565e567a Fix "0" displaying in "Review Dashboard" button on user dashboard (#298)
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
The review dashboard link only shows when the user has the correct roles. A normal user would not see the button but instead the text "0".

Reviewed-on: #298
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-12-27 05:39:33 +00:00
Quaternions ea65794255 Cycle before and after images every 1.5 seconds (#295)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
The images should auto cycle now that the thumbnails are working.

I don't know how to test this!  This is what I tried:
```
bun install
bun run build
VITE_API_HOST=https://maps.staging.strafes.net/v1 bun run preview
```
but the mapfixes page won't load the mapfixes.

Reviewed-on: #295
Reviewed-by: itzaname <itzaname@noreply@itzana.me>
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2025-12-27 05:26:04 +00:00
itzaname 58706a5687 Add user/reviewer dashboard (#297)
continuous-integration/drone/push Build is passing
Adds "at a glance" dashboard so life is less painful.

![image.png](/attachments/43e83777-7196-4274-9adc-e1268e43bc0f)
![image.png](/attachments/1cbe99ab-50b8-443a-aa48-ad9107ccfb1e)

Reviewed-on: #297
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-12-27 05:20:45 +00:00
itzaname efeb525e19 Merge pull request 'Add mapfix history on maps page' (#294) from feature/mapfix-list into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #294
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
2025-12-27 04:51:03 +00:00
Quaternions 5a1fe60a7b fix quat docker
continuous-integration/drone/push Build is passing
2025-12-26 19:13:03 -08:00
itzaname 01cfe67848 Just exclude rejected and released for active list
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-26 20:38:18 -05:00
itzaname a19bc4d380 Add mapfix history on maps page
continuous-integration/drone/push Build is passing
2025-12-26 20:32:55 -05:00
itzaname ae006565d6 Merge pull request 'Fix overflow on mapfix/submission' (#293) from fix/overflow into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #293
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
2025-12-27 00:44:26 +00:00
itzaname 57bca99109 Fix overflow
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-26 19:42:36 -05:00
Quaternions 058455efd2 Merge pull request 'Deploy updates' (#291) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #291
2025-12-26 04:46:53 +00:00
itzaname cd09c9b18e Populate username for map fixes by author id
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
2025-12-25 20:42:22 -08:00
itzaname e48cbaff72 Make maps behave like normal link 2025-12-25 20:42:22 -08:00
itzaname 140d58b808 Make comments support newlines 2025-12-25 20:42:22 -08:00
itzaname ba761549b8 Force dark theme 2025-12-25 20:42:22 -08:00
Quaternions 86643fef8d Merge branch 'master' into staging 2025-12-25 20:42:18 -08:00
itzanameandQuaternions 96af864c5e Deploy staging to prod (#286)
continuous-integration/drone/push Build is passing
Pull in validator changes and full ui rework to remove nextjs.

Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Reviewed-on: #286
Reviewed-by: Rhys Lloyd <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-12-26 03:30:36 +00:00
itzaname 7db89fd99b Fix bun lock file
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2025-12-25 22:10:29 -05:00
itzaname f2bb1b078d Fix content width and standardize on skeleton loading
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
2025-12-25 21:37:23 -05:00
itzaname 66878fba4e Switch loading text to skeleton
continuous-integration/drone/push Build is passing
2025-12-25 21:02:15 -05:00
itzaname bda99550be Fix submission icon 2025-12-25 21:00:28 -05:00
itzaname 8a216c7e82 Add username api
continuous-integration/drone/push Build is passing
2025-12-25 20:55:15 -05:00
itzaname e5277c05a1 Avatar image loading
continuous-integration/drone/push Build is passing
2025-12-25 20:38:17 -05:00
itzaname e4af76cfd4 Fix api endpoint
continuous-integration/drone/push Build is passing
2025-12-25 20:22:24 -05:00
itzaname 30db1cc375 Fix the build issues
continuous-integration/drone/push Build is passing
2025-12-25 19:52:01 -05:00
itzaname b50c84f8cf Use port 3000
continuous-integration/drone/push Build is failing
2025-12-25 19:49:52 -05:00
itzaname 7589ef7df6 Fix dockerfile for spa
continuous-integration/drone/push Build was killed
2025-12-25 19:49:06 -05:00
itzaname 8ab8c441b0 Home page and header fixes
continuous-integration/drone/push Build is passing
2025-12-25 19:45:16 -05:00
itzaname a26b228ebe Add 404 page 2025-12-25 19:45:16 -05:00
itzaname 3654755540 Thumbnail/nav cleanup 2025-12-25 19:45:16 -05:00
itzaname c2b50ffab2 Cleanup home/nav 2025-12-25 19:45:16 -05:00
itzaname 75756917b1 some theming 2025-12-25 19:45:16 -05:00
itzaname 8989c08857 theme 2025-12-25 19:45:16 -05:00
itzaname b2232f4177 Initial work to nuke nextjs 2025-12-25 19:45:16 -05:00
itzaname 7d1c4d2b6c Add stats endpoint
continuous-integration/drone Build was killed
continuous-integration/drone/push Build is passing
2025-12-25 18:58:52 -05:00
itzaname ca401d4b96 Add batch thumbnail endpoint (#285)
continuous-integration/drone/push Build is passing
Step 1 of eliminating nextjs is adding a way to query thumbnails from roblox since nextjs handles that. This implements a batch endpoint and caching to do that. Bonus: thumbnails will actually work once we start using this.

Reviewed-on: #285
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-12-25 22:56:59 +00:00
Quaternions 9ab80931bf remove unfulfilled lints
continuous-integration/drone/push Build is passing
2025-12-09 14:34:39 -08:00
Quaternions 09022e7292 change allow to expect 2025-12-09 14:34:16 -08:00
Quaternions 3400056c23 submissions-api: v0.10.1 audit events
continuous-integration/drone/push Build is passing
2025-12-08 18:10:32 -08:00
Quaternions 57501d446f submissions-api: add audit events 2025-12-08 18:09:54 -08:00
Quaternions 47c0fff0ec Merge pull request 'Update javascript' (#283) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #283
2025-12-06 04:48:21 +00:00
Quaternions e6ef4e33ac mui
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-12-05 20:44:16 -08:00
Quaternions aeba355d6c format
continuous-integration/drone/push Build is failing
2025-12-05 20:27:02 -08:00
Quaternions 8ad94bcdc8 bug 2025-12-05 20:27:02 -08:00
Quaternions 66f02a2f45 docker: update bun
continuous-integration/drone/push Build is failing
2025-12-05 20:16:51 -08:00
Quaternions c6a685310e bun update
continuous-integration/drone/push Build is failing
2025-12-05 20:14:19 -08:00
Quaternions 72b95ae271 drone: update bun 2025-12-05 20:13:51 -08:00
Quaternions 7c04cc5c23 drone: update rust
continuous-integration/drone/push Build is passing
2025-11-27 16:36:25 -08:00
Quaternions a3bf111b4e update deps
continuous-integration/drone/push Build is failing
2025-11-27 15:56:03 -08:00
Quaternions d82f44e9d2 remove unused type
continuous-integration/drone/push Build is passing
2025-11-09 09:30:03 -08:00
Quaternions 4c5a8c39c1 update deps
continuous-integration/drone/push Build is passing
2025-11-09 06:00:03 -08:00
Quaternions 4e55b1d665 drop lazy_regex dep 2025-11-09 05:56:58 -08:00
Quaternions 63d7bec3a3 validation: fix variable names
continuous-integration/drone/push Build is passing
2025-11-07 10:00:16 -08:00
Quaternions b7c28616ad Merge pull request 'submissions: Fix Maps.Update Date + Release Date Mixup' (#282) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #282
2025-09-29 02:14:51 +00:00
Quaternions ce9b26378c submissions: Fix Maps.Update Date
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-28 19:09:59 -07:00
Quaternions df8f6463da bruh
continuous-integration/drone/push Build is passing
2025-09-23 17:26:03 -07:00
Quaternions 6ccc56cc55 submissions: fix release date mixup
continuous-integration/drone/push Build is passing
2025-09-23 16:31:50 -07:00
Quaternions 89ab25dfb9 Merge pull request 'deploy fixes' (#279) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #279
2025-09-23 22:41:35 +00:00
Quaternions ffa1308e73 update deps
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-09-23 15:33:11 -07:00
Quaternions b5a367e159 Return OperationID from release-submissions (#278)
The release-submissions endpoint creates an operation, but does not return it.

Reviewed-on: #278
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2025-09-23 15:31:34 -07:00
Quaternions 6b05836a56 openapi: increase max script path length
continuous-integration/drone/push Build is passing
2025-09-23 15:12:20 -07:00
Quaternions 8abee39d15 web: do not show Admin Submit button on mapfixes
continuous-integration/drone/push Build is passing
2025-09-17 14:24:25 -07:00
Quaternions b0b5ff0725 Merge pull request 'web: add missing button lost in refactor' (#275) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #275
2025-09-17 00:12:15 +00:00
Quaternions 456b62104b web: add missing button lost in refactor
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
This was lost in 8f2a0b53e4
2025-09-16 16:56:31 -07:00
Quaternions 574a05424d update readme
continuous-integration/drone/push Build is passing
2025-08-18 15:54:46 -07:00
Quaternions 0532965d37 Merge pull request 'Maps Metadata Maintenance' (#267) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #267
2025-08-16 06:24:19 +00:00
Quaternions 51ba05df69 backend: remove mapfixes migrate endpoint
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2025-08-15 23:20:08 -07:00
Quaternions 30b594b345 backend: fix completely wrong gorm thing
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-15 23:05:40 -07:00
Quaternions ab361dffd1 backend: fix completely wrong gorm thing
continuous-integration/drone/push Build is passing
2025-08-15 23:01:37 -07:00
Quaternions d30a94e42d backend: add mission interface method
continuous-integration/drone/push Build is passing
2025-08-15 22:34:22 -07:00
Quaternions dae378a188 backend: update go-grpc 2025-08-15 22:31:26 -07:00
Quaternions cd912d683e validation: remove table from luau execution script
continuous-integration/drone/push Build is passing
2025-08-15 22:23:29 -07:00
Quaternions f5dfd5a163 Revert "validation: spend way to much time saving 1 microsecond"
This reverts commit 18d51af7ca.
2025-08-15 22:19:17 -07:00
Quaternions 18d51af7ca validation: spend way to much time saving 1 microsecond
continuous-integration/drone/push Build is passing
2025-08-15 22:17:54 -07:00
Quaternions a45aa700d8 make: frontend image builds from scratch
continuous-integration/drone/push Build is passing
2025-08-15 20:13:01 -07:00
Quaternions 907b6d2034 web: fix Releasing statusChip 2025-08-15 20:08:02 -07:00
Quaternions a454ea01b6 web: fix unknown status
continuous-integration/drone/push Build is passing
2025-08-15 19:59:17 -07:00
Quaternions 7f8c9210a5 docker: move auth so non-editor-searchable location 2025-08-15 19:57:47 -07:00
Quaternions f76f8cd136 Merge pull request 'Mapfix Release' (#264) from mapfix-release into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #264
2025-08-16 02:47:28 +00:00
Quaternions 55b79b8f9b backend: typo
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
2025-08-15 19:40:24 -07:00
Quaternions 1ce09e3f9b docker: add env vars to compose.yml
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-15 19:35:39 -07:00
Quaternions 2878467cbf backend: add forgotten permission 2025-08-15 19:35:28 -07:00
Quaternions 2639abc7c8 submissions-api-rs: v0.9.1 fixes
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-15 19:02:00 -07:00
Quaternions 231c11632b openapi: add missing fields 2025-08-15 19:01:20 -07:00
Quaternions 877f5c024f submissions-api-rs: fix MapfixResponse 2025-08-15 19:01:20 -07:00
Quaternions 18ca6de7d3 submissions-api-rs: v0.9.0 get_mapfixes
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-15 18:41:04 -07:00
Quaternions 6ee8816eed submissions-api-rs: add get_mapfixes endpoint
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-15 18:39:43 -07:00
Quaternions de6163093f backend: add missing list query 2025-08-15 18:39:43 -07:00
Quaternions d7456d500b backend: create mapfixes migration code UPLOADED -> RELEASED
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-15 17:48:45 -07:00
Quaternions 1a558f35cf openapi: generate 2025-08-15 17:14:05 -07:00
Quaternions b5b07ec1ce openapi: create migration endpoint 2025-08-15 17:13:59 -07:00
Quaternions efd60f45df validator: respond correctly to upload failure
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-14 19:48:08 -07:00
Quaternions 10507c62ab openapi: generate 2025-08-14 19:48:07 -07:00
Quaternions 0d18167b03 remove SubmissionStatusReleasing 2025-08-14 19:48:07 -07:00
Quaternions e90cc425ba validator: perform unnecessary allocation to appease borrow checker 2025-08-14 19:48:07 -07:00
Quaternions 76512bec0d validator: update deps 2025-08-14 19:48:07 -07:00
Quaternions 412dadfc3e validator: add mapfix and submission release 2025-08-14 19:48:07 -07:00
Quaternions 31cca0d450 validator: update rust-grpc 2025-08-14 19:48:07 -07:00
Quaternions cfb7461c5a validator: remove implicit map update 2025-08-14 19:48:07 -07:00
Quaternions 0cb419430a backend: make release pipeline internals 2025-08-14 19:48:07 -07:00
Quaternions 807d394646 web: add release buttons 2025-08-12 17:46:42 -07:00
Quaternions 3c9d04d637 openapi: generate 2025-08-12 16:18:15 -07:00
Quaternions 94ad0ff774 openapi: add new status endpoints 2025-08-12 16:18:01 -07:00
Quaternions 25f6c9e086 backend: tweak status sets to reflect new statuses
continuous-integration/drone/push Build is passing
2025-08-12 16:05:33 -07:00
Quaternions a62a231b0a backend: new statuses for mapfix and submission 2025-08-12 16:05:13 -07:00
Quaternions 468204b299 validator: dedicated api key for luau execution
continuous-integration/drone/push Build is passing
2025-08-12 15:48:59 -07:00
Quaternions 63458aee09 Merge pull request 'Update Metadata on Mapfix' (#263) from metadata-maintenance into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #263
2025-08-12 21:56:07 +00:00
Quaternions 8297ed165b readme: document env vars
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-11 17:50:39 -07:00
Quaternions c98c3fe47e validator: update modes on mapfix
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-08-11 17:40:14 -07:00
Quaternions 9c1e1e4347 validator: move count_sequential fn 2025-08-11 17:40:02 -07:00
Quaternions d37a8b9030 validator: call Luau Execution API to get LoadAssetVersion
continuous-integration/drone/push Build is passing
2025-08-11 17:02:44 -07:00
Quaternions 75682a2375 validator: connect to maps_extended 2025-08-11 17:02:28 -07:00
Quaternions 8f6012c7ef validator: remove MessageHandler constructor (too many arguments) 2025-08-11 16:33:37 -07:00
Quaternions f59979987f Merge pull request 'Deploy Public API' (#256) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #256
2025-08-08 22:07:37 +00:00
Quaternions 295b1d842b Sequential Modes Check (#260)
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
Closes #242

Reviewed-on: #260
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2025-08-07 19:48:16 -07:00
Quaternions 93147060d6 drone: re-sign pipeline after self-inflicted catastrophe
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
2025-08-07 19:22:12 -07:00
Quaternions fe539bf190 move rust submissions api 2025-08-07 17:37:15 -07:00
Quaternions 759ac08aef swagger: generate 2025-08-07 16:13:42 -07:00
Quaternions 34bc623ce6 make UserInfoHandle.HasRoles public 2025-08-07 16:08:47 -07:00
Quaternions 9999d1ff87 fix docs redirect
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
2025-08-06 20:15:53 -07:00
Quaternions 8a0cd50b68 fix public api
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
2025-08-06 20:04:33 -07:00
Quaternions 08753d36b4 Cut Down Maps Fields (#257)
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
Remove usages of Creator & Date, add Thumbnail.

Reviewed-on: #257
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2025-08-07 02:32:22 +00:00
Quaternions 5dce0f2017 docker: do not run build-frontend on push
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
2025-08-05 23:08:21 -07:00
Quaternions d196da949c Public API (#253)
Closes #229

This is a MVP and only includes maps.

Reviewed-on: #253
Reviewed-by: itzaname <itzaname@noreply@itzana.me>
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2025-08-05 23:08:18 -07:00
Quaternions b0c723be1b docker: fix validator context 2025-08-05 22:58:41 -07:00
Quaternions 48314f5d18 Refactor Docker (#254)
continuous-integration/drone/push Build is failing
Refactor docker to use makefile build commands

Reviewed-on: #254
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2025-08-06 05:49:30 +00:00
Quaternions 1e4e513dc1 web: update deps
continuous-integration/drone/push Build is passing
2025-08-05 22:16:31 -07:00
Quaternions f9455e7317 validator: update deps
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2025-08-05 21:30:44 -07:00
Quaternions 69ebef5fb8 validator: use rustls 2025-08-05 21:30:44 -07:00
Quaternions a9258136da Merge pull request 'Remove Migration Code' (#251) from rm-migrate into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #251
2025-07-28 12:04:50 +00:00
Quaternions ac05f4acdc submissions: remove migration operation
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-07-25 23:09:03 -07:00
Quaternions 061b7b2a01 openapi: generate 2025-07-25 23:08:07 -07:00
Quaternions b4a0041fb5 openapi: remove migration operation 2025-07-25 23:07:50 -07:00
Quaternions a232269d54 Merge pull request 'Extend Web API Maps With New Fields' (#250) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #250
2025-07-26 03:29:09 +00:00
Quaternions 692c915af8 Merge pull request 'Extend Maps With New Fields' (#249) from webapi-maps into staging
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Reviewed-on: #249
2025-07-26 02:31:24 +00:00
Quaternions d35c331b76 submissions: fill out new fields
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-07-25 19:19:39 -07:00
Quaternions 9ce8b75f0f openapi: generate
continuous-integration/drone/push Build is passing
2025-07-25 19:16:21 -07:00
Quaternions f5d41ab672 openapi: extend Map with new fields 2025-07-25 19:15:12 -07:00
Quaternions a7c4ca4b49 Merge pull request 'Implement Maps' (#248) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #248
2025-07-26 01:26:26 +00:00
Quaternions 2578a74ddb submissions: use unsigned ints in maps struct
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-07-23 23:18:54 -07:00
Quaternions 45a58145ed Merge pull request 'Fix Null Pointer Deref' (#246) from maps into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #246
2025-07-24 05:21:14 +00:00
Quaternions a4cefd263d submissions: maps: guard against null pointers
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-07-23 22:19:42 -07:00
Quaternions 1b18649cb6 Merge pull request 'Implement Maps' (#241) from maps into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #241
2025-07-24 04:29:01 +00:00
Quaternions bdfd1a0b23 submissions: temporary migration endpoint
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-07-23 20:04:39 -07:00
Quaternions 859004f264 openapi: generate 2025-07-23 20:04:39 -07:00
Quaternions 89ef254b72 openapi: maps migration endpoint 2025-07-23 20:04:39 -07:00
Quaternions 36f9e2db5f submissions: grpc controller 2025-07-23 20:04:39 -07:00
Quaternions ce4e37dc64 submissions: update go-grpc for maps_extended 2025-07-23 20:04:32 -07:00
Quaternions f417111bcf submissions: switch maps to maps-service 2025-07-23 20:04:32 -07:00
Quaternions 1826a51ebd submissions: maps db 2025-07-23 20:03:55 -07:00
Quaternions ca9f82a5aa Merge pull request 'Set Download File Name' (#245) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #245
2025-07-23 09:32:27 +00:00
Quaternions 76903656c2 Merge pull request 'Change to Proxy Download' (#208) from pr1 into staging
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Reviewed-on: #208
2025-07-23 09:17:21 +00:00
Quaternions 3e353b2ec6 web: change to proxy download
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-07-23 02:10:37 -07:00
Quaternions 749ea7e57d submissions: change to proxy download 2025-07-23 02:10:37 -07:00
Quaternions 03ec0b0183 openapi: generate 2025-07-23 01:55:21 -07:00
Quaternions cc93776c25 openapi: change to proxy download 2025-07-23 01:55:21 -07:00
Quaternions a8ad9f7de0 ai thinking Rust while doing golang lol 2025-07-23 01:55:21 -07:00
Quaternions d5d794703b submissions: missing inner service AuditEvent functions
continuous-integration/drone/push Build is passing
currently unused
2025-07-23 01:54:04 -07:00
Quaternions e1a2f6f075 Merge pull request 'Fix gRPC' (#244) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #244
2025-07-23 04:53:29 +00:00
Quaternions 70bbba6003 submissions: fix gRPC (the code is completely wrong)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
I blame the programming language, wouldn't have happened in Rust
2025-07-22 21:42:14 -07:00
Quaternions 39ba12edd9 web: add missing ResetSubmitting review button
continuous-integration/drone/push Build is passing
2025-07-22 21:30:33 -07:00
Quaternions 1cfdb3668a validator: connect_lazy
continuous-integration/drone/push Build is passing
2025-07-22 21:01:39 -07:00
Quaternions dad904cd86 Merge pull request 'Convert Validator API to gRPC' (#239) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #239
2025-07-22 04:32:04 +00:00
Quaternions 740e6368b1 Merge pull request 'Convert Internal API to gRPC' (#238) from grpc into staging
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
Reviewed-on: #238
2025-07-22 02:25:12 +00:00
Quaternions 746ac8e8a7 validator: convert to gRPC
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-07-19 04:07:28 -07:00
Quaternions bdfe16ed39 validator: extend grpc 2025-07-19 04:07:28 -07:00
Quaternions 3c21d8948a validator: grpc 2025-07-19 04:07:28 -07:00
Quaternions eaa8f704ea validator: add rust-grpc dep 2025-07-19 04:07:28 -07:00
Quaternions d50ae0e664 submissions-api: remove internal api 2025-07-19 04:07:28 -07:00
Quaternions f95d8b1665 validator: bump edition 2025-07-19 04:07:28 -07:00
Quaternions 524c56b6b5 submissions: convert validator backend to gRPC 2025-07-19 04:07:28 -07:00
Quaternions ad7117a69c Merge pull request 'Scream Test Backend Overhaul' (#237) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #237
2025-07-18 06:28:18 +00:00
Quaternions e05f69ef7d submissions: delete internal api 2025-07-17 23:13:22 -07:00
Quaternions a45fbb370c submissions: rename services
continuous-integration/drone/push Build is passing
2025-07-17 20:51:03 -07:00
Quaternions 27a646c006 openapi: fix up tags
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-07-17 19:28:02 -07:00
Quaternions dde6f3ebdb submissions: rename services
continuous-integration/drone/push Build is passing
2025-07-17 19:07:59 -07:00
Quaternions 3d08b144b1 submissions: move Roles to model
continuous-integration/drone/push Build is passing
2025-07-16 20:27:04 -07:00
Quaternions 63b701eb72 submissions: rename services 2025-07-16 20:27:04 -07:00
Quaternions 07e08af5ed De-monolithificate Services (#236)
continuous-integration/drone/push Build is passing
Closes #204.

The branch is called dedup but the patch adds code...

- Services both use an inner service that implements the underlying operations
- Struct fields are made private, preventing code cross-contamination
- Filter & Update structures are clearly defined, gaining clarity and type safety

Reviewed-on: #236
Co-authored-by: Rhys Lloyd <krakow20@gmail.com>
Co-committed-by: Rhys Lloyd <krakow20@gmail.com>
2025-07-17 03:18:01 +00:00
Quaternions d566591ea6 Merge pull request 'Fix Audit Event Order + Check Unanchored Parts' (#234) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #234
2025-07-16 06:47:29 +00:00
Quaternions 391a0fe6f9 Maps Data Model (#233)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Create a data model to be used for maps.

Reviewed-on: #233
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-07-15 04:37:20 +00:00
Quaternions 0e06d00c21 validation: check for unanchored parts (#230)
continuous-integration/drone/push Build is passing
Unanchored parts are always invalid.  Make a check to detect them.

Reviewed-on: #230
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-07-08 00:07:27 +00:00
Quaternions cd0bfbaeb2 validation: check: use &Instance instead of &str
continuous-integration/drone/push Build is passing
2025-07-07 16:33:17 -07:00
Quaternions 70cb80ab9b submissions: order audit events by id ascending
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
2025-07-05 06:07:50 -07:00
Quaternions 6d0af22485 submissions-api: v0.8.2 derive Hash for ID newtypes
continuous-integration/drone/push Build is passing
2025-07-05 02:16:09 -07:00
Quaternions c08fdddf36 submissions-api: add Hash,Eq,PartialEq to ID newtypes 2025-07-05 02:15:22 -07:00
Quaternions 424ef6238b Merge pull request 'Prevent Mapfix Duplicates + Correctly Report Transaction Errors' (#221) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #221
2025-07-01 12:40:26 +00:00
Quaternions 727b823fef update rbx_asset
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-07-01 04:57:29 -07:00
Quaternions efefaa5e62 submissions: check rows affected (#220)
continuous-integration/drone/push Build is passing
Closes #218.

Reviewed-on: #220
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-07-01 11:37:29 +00:00
Quaternions c6ce9b8f82 submissions: Check for duplicate mapfix (#219)
continuous-integration/drone/push Build is passing
Mapfixes should check to see if you already have a mapfix for the target asset upon creation.

Reviewed-on: #219
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-07-01 11:31:06 +00:00
Quaternions 0f0ab4d3e0 Merge pull request 'Update Roblox Api + Update Deps' (#217) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #217
2025-07-01 08:47:27 +00:00
Quaternions ca008f8fcf Update Roblox Api (#216)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Same api different language

Reviewed-on: #216
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-07-01 08:40:03 +00:00
Quaternions e9affea859 Update Roblox Api + Update Deps (#215)
continuous-integration/drone/push Build is passing
Roblox api changed, see 9f1bdd6a1f

Reviewed-on: #215
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-07-01 08:19:50 +00:00
Quaternions 3e2d782289 Merge pull request 'QoL Web Changes + Map Download Permission Fix' (#214) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #214
2025-06-30 10:20:03 +00:00
Quaternions a31a92f131 Merge pull request 'submissions: check role for map location' (#213) from pr2 into staging
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Reviewed-on: #213
2025-06-30 09:46:50 +00:00
Quaternions a5187be8a6 submissions: check role for map location
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-30 02:42:19 -07:00
ic3w0lf22andic3w0lf 825b2aa91a Clickable titles and show active mapfix (#211)
continuous-integration/drone/push Build is passing
Closes #144

Co-authored-by: ic3w0lf <bob@ic3.space>
Reviewed-on: #211
Reviewed-by: itzaname <itzaname@noreply@itzana.me>
Co-authored-by: ic3w0lf22 <ic3w0lf22@noreply@itzana.me>
Co-committed-by: ic3w0lf22 <ic3w0lf22@noreply@itzana.me>
2025-06-29 19:06:52 +00:00
ic3w0lf22andic3w0lf 6f9cd952d4 Taking care of some issues & QOL changes (#209)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
Co-authored-by: ic3w0lf <bob@ic3.space>
Reviewed-on: #209
Reviewed-by: Quaternions <quaternions@noreply@itzana.me>
Co-authored-by: ic3w0lf22 <ic3w0lf22@noreply@itzana.me>
Co-committed-by: ic3w0lf22 <ic3w0lf22@noreply@itzana.me>
2025-06-28 07:44:59 +00:00
Quaternions abb3cf3076 web: remove cursed ai code
continuous-integration/drone/push Build is passing
2025-06-24 05:07:03 -07:00
Quaternions dc446c545f Fix Bypass Submit + Audit Checklist + Map Download Button (#207)
continuous-integration/drone/push Build is passing
Reviewed-on: #207
2025-06-24 06:41:56 +00:00
Quaternions e234a87d05 Replace Bypass Submit With Submit Unchecked + Error Endpoint (#200)
continuous-integration/drone/push Build is running
Reviewed-on: #200
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-23 23:39:18 -07:00
Quaternions 40b0af0063 Revert "Validation: Make Assets Loadable on Maptest (#198)"
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
This reverts commit abd233ce65.
2025-06-23 23:34:58 -07:00
Quaternions 976adf2b66 Move Download Button Below Title (#206)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
Senior itzaname envisioned the button existing elsewhere.

Reviewed-on: #206
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-24 06:05:50 +00:00
Quaternions 53cc4b9e9e Map Download Button (#201)
continuous-integration/drone/push Build is passing
Closes #145.

All the backend should be implemented here, ~~I just don't know how to make a download button on the frontend.~~ I made a button, we'll see if it works.

- [x] ~~Add asset download api key to infra~~ this was never required

Reviewed-on: #201
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-24 05:09:51 +00:00
Quaternions 51f62f039b submissions-api: report script IDs not the whole thing
continuous-integration/drone/push Build is passing
2025-06-18 03:55:03 -07:00
Quaternions 42cc783887 validation: fixups
continuous-integration/drone/push Build is passing
2025-06-13 22:04:25 -07:00
Quaternions ed7109270f Audit Event CheckList (#181)
continuous-integration/drone/push Build is failing
Depends on #160, #196, #197.

Closes #147.

This introduces a new type of audit event: the CheckList.  This is a list of map checks that the validator performed.  The intention is to update the web interface to display ✅ check marks for every check passed and ❌ for every check failed, and also include the summary of why the check failed.  ~~The `Details` field would be the complete internal structure of the check in json, but I'm thinking it's unnecessary and should just be omitted.~~ The `Details` field has been removed.

```go
type Check struct {
	Name    string `json:"name"`
	Summary string `json:"summary"`
	Passed  bool   `json:"passed"`
}

type AuditEventDataCheckList struct {
	CheckList []Check `json:"check_list"`
}
```

This is created instead of the Error audit event when the validator requests changes, but the Error audit event can still be created for other purposes.

- [x] Make a proper error instead of hijacking a CheckList

Reviewed-on: #181
Reviewed-by: itzaname <itzaname@noreply@itzana.me>
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-14 02:33:19 +00:00
Quaternions abd233ce65 Validation: Make Assets Loadable on Maptest (#198)
continuous-integration/drone/push Build is passing
Closes #43.

This is a very bare bones implementation, but gets us started on https://git.itzana.me/StrafesNET/maps-service/milestone/3

This will break production as written!  A proper implementation requires a separate api key since the maptest places are to be hosted on a different group.

Edit: It will actually not break, because it is using cookie access. The staging cookie has permission to edit StrafesNET Maptest asset permissions via StrafesNET_CI3, while prod also has access via StrafesNET_CI2.  Both staging and prod versions of the website will add maptest asset access to the same places on StrafesNET Maptest.
Reviewed-on: #198
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-13 03:58:01 +00:00
Quaternions 215c39000b Replace bypass-submit with trigger-submit-unchecked (#199)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Bypassing the submit process means that the map revision is not updated.  Change the endpoint and include a flag to skip the map checks but update the revision.

Reviewed-on: #199
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-13 00:15:16 +00:00
Quaternions c4d97b6537 Change Error to Explicit Endpoint (#197)
continuous-integration/drone/push Build is passing
This changes the way that the internal api works.  The backend used to implicitly create an error for specifc endpoints, but now the validator explicitly creates the error itself.

Reviewed-on: #197
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-12 00:55:09 +00:00
Quaternions 0834400c05 Compartmentalize Monolith (#196)
continuous-integration/drone/push Build is passing
This isn't the full job, notably Operations are still sprinkled about, and having some code sharing between `service` and `service_internal` would be nice, but that is sketchy without the explicitness of Rust's traits.

Reviewed-on: #196
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-12 00:19:56 +00:00
Quaternions 463d14d2b5 submissions-api: type all ids (#195)
continuous-integration/drone/push Build is passing
Reviewed-on: #195
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-11 05:11:14 +00:00
Quaternions 6a52166901 submissions-api: Add Releaser Endpoints (#194)
continuous-integration/drone/push Build is passing
Also uses enums over ints for GameID.

Reviewed-on: #194
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-11 04:11:21 +00:00
Quaternions 8ab772ea81 Validate Asset Version + Website QoL + Script Names Fix (#193)
continuous-integration/drone/push Build is passing
Reviewed-on: #193
2025-06-10 23:53:07 +00:00
Quaternions d7c2ad3dde submissions: actually fix script names (#192)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Actually closes #165.

Reviewed-on: #192
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-10 04:15:27 +00:00
Quaternions f54bf1dc34 submissions: fix script names (#191)
continuous-integration/drone/push Build is passing
Closes #165.

Reviewed-on: #191
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-10 04:08:32 +00:00
itzaname 644c04c133 First wave of QOL impovementss (#190)
continuous-integration/drone/push Build is passing
- Updated all avatars/thumbnails to just 307 to the roblox cdn
- Moved data loading for submissions and mapfixes into a common hook
- Data will now auto refresh every 5 seconds if state Validating, Submitting, Uploading (ing Statuses) #102
- A loading icon will also show when on a "ing" status
- You don't have to be logged in to see the submissions/mapfixes
- Added text if there are no comments
- Hide comment box if not logged in

Reviewed-on: #190
Reviewed-by: Quaternions <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-06-10 02:18:55 +00:00
Quaternions 8006e3efbc validation: refuse to validate if model has updates (#188)
continuous-integration/drone/push Build is passing
Closes #187.

Reviewed-on: #188
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-09 03:04:33 +00:00
Quaternions 9b58b1d26a Frontend Rework (#185)
continuous-integration/drone/push Build is passing
Reviewed-on: #185
2025-06-09 01:09:17 +00:00
Quaternions b60d2b6186 Submissions: Fix Comments (#184)
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Closes #163.

Reviewed-on: #184
Reviewed-by: itzaname <itzaname@noreply@itzana.me>
Co-authored-by: Quaternions <krakow20@gmail.com>
Co-committed-by: Quaternions <krakow20@gmail.com>
2025-06-09 01:03:55 +00:00
itzaname 8f2a0b53e4 Refactor remaining frontend pages (#183)
continuous-integration/drone/push Build is passing
Reviewed-on: #183
Reviewed-by: Quaternions <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-06-09 00:33:27 +00:00
Quaternions 70dd8502f4 Merge pull request 'submissions: add missing audit even when requesting changes for a mapfix' (#180) from pr2 into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #180
2025-06-08 05:49:28 +00:00
Quaternions 5b977289e7 Merge pull request 'validation: include more details in duplicates error' (#179) from dupes into staging
continuous-integration/drone/push Build is running
Reviewed-on: #179
2025-06-08 05:49:11 +00:00
Quaternions 7b3af95f3d Merge pull request 'Remove class_is_a' (#178) from pr1 into staging
continuous-integration/drone/push Build is running
Reviewed-on: #178
2025-06-08 05:48:55 +00:00
Quaternions 4d78a9b2c5 submissions: add missing audit even when requesting changes for a mapfix
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-07 22:42:39 -07:00
Quaternions ec59a83379 validation: include more details in duplicates error
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-07 22:34:57 -07:00
itzaname 54bf3f55a0 Rework submission/mapfix/maps list views (#173)
continuous-integration/drone/push Build is passing
Refactored maps/landing/mapfix/submission and navbar

Reviewed-on: #173
Reviewed-by: Quaternions <quaternions@noreply@itzana.me>
Co-authored-by: itzaname <me@sliving.io>
Co-committed-by: itzaname <me@sliving.io>
2025-06-08 03:41:36 +00:00
Quaternions 14f404ffe3 Merge pull request 'Openapi: Document Enum Fields' (#177) from openapi-doc into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #177
Reviewed-by: itzaname <itzaname@noreply@itzana.me>
2025-06-08 00:21:21 +00:00
Quaternions 0e1d2fe50a openapi: generate
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-07 17:09:51 -07:00
Quaternions ada8c322da openapi: add descriptions to enum fields
continuous-integration/drone/push Build is passing
2025-06-07 17:07:47 -07:00
Quaternions 84d2bfef20 remove class_is_a
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-07 16:29:06 -07:00
Quaternions 170e7c64b6 Merge pull request 'submissions-api: add external delete endpoints' (#166) from pr1 into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #166
2025-06-07 05:38:30 +00:00
Quaternions b443866dd6 Merge pull request 'update deps' (#169) from deps into staging
continuous-integration/drone/push Build is running
Reviewed-on: #169
2025-06-07 05:35:45 +00:00
Quaternions ebe37ad6a2 update deps
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-06 22:29:35 -07:00
Quaternions 131dad7ae0 submissions-api: v0.7.2 script policy delete endpoints
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-06 22:28:07 -07:00
Quaternions 7689001e74 Merge pull request '404 / 500 Thumbnails + Fix Regex Capture Groups' (#168) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #168
2025-06-07 04:02:26 +00:00
Quaternions 127402fa77 Merge pull request 'fix regex capture groups' (#167) from pr2 into staging
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Reviewed-on: #167
2025-06-07 03:58:16 +00:00
Quaternions 40f83a4e30 fix regex capture groups
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-06 20:52:17 -07:00
Quaternions b6d4ce4f80 submissions-api: add external delete endpoints
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-06 17:14:27 -07:00
ic3w0lf22 07391a84cb Merge pull request 'thumbnail fix - will this WORK THIS TIME?' (#154) from thumbnail-fix-1 into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #154
Reviewed-by: Quaternions <quaternions@noreply@itzana.me>
2025-06-06 02:51:35 +00:00
ic3w0lf 3f848a35c8 implement cache de-exister
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-05 17:42:34 -06:00
Quaternions e89abed3d5 Merge pull request 'Thumbnail Fixes + Bypass Submit Button' (#161) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #161
2025-06-05 01:34:35 +00:00
Quaternions e5e2387502 Merge pull request 'Refactor MapChecks Summary' (#160) from summary into staging
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Reviewed-on: #160
2025-06-05 01:25:56 +00:00
Quaternions 90d13d28ae use closure instead of iterator
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-04 18:18:18 -07:00
Quaternions 513b9722b1 Merge pull request 'Add Bypass Submit Button' (#159) from force-submit into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #159
2025-06-05 00:56:37 +00:00
Quaternions 3da8e414e6 submissions: fix comment
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-04 17:53:21 -07:00
Quaternions 2acc30e18c submissions: add bypass-submit 2025-06-04 17:53:13 -07:00
Quaternions a990ed458c submissions: optimize trigger-submit 2025-06-04 17:41:40 -07:00
Quaternions 4055ef550e openapi: generate
continuous-integration/drone/push Build is passing
2025-06-04 17:32:44 -07:00
Quaternions 555844e6ee openapi: bypass-submit endpoints
continuous-integration/drone/push Build is passing
2025-06-04 17:30:10 -07:00
Quaternions 80f30d20fa web: introduce Force Submit button 2025-06-04 17:28:51 -07:00
Quaternions 489a8c9c10 web: rename force submit to admin submit 2025-06-04 17:22:53 -07:00
Quaternions 534598ba70 box list to appease clippy
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-04 17:13:33 -07:00
Quaternions fdc0240698 MapCheckSummary
continuous-integration/drone/push Build is passing
2025-06-04 17:05:38 -07:00
Quaternions b0829bc1fc refactor WormholeID
continuous-integration/drone/push Build is passing
2025-06-04 14:52:19 -07:00
Quaternions 845f8e69d9 refactor ModeID 2025-06-04 14:52:19 -07:00
Quaternions 0d8937e896 refactor SpawnID 2025-06-04 14:46:30 -07:00
Quaternions 2927afd848 Merge pull request 'web: use invalid id for submit to invoke error' (#155) from empty-submit into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #155
2025-06-04 05:32:34 +00:00
Quaternions 8f6c543f81 Merge pull request 'validation: log errors' (#156) from log into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #156
2025-06-04 05:09:57 +00:00
Quaternions 7c95f8ddd0 validation: log errors
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-03 22:07:39 -07:00
Quaternions 24964407bd web: use invalid id for submit to invoke error
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-03 21:55:19 -07:00
ic3w0lf 8d5bd9e523 Fix error & include error message in response headers
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-03 20:52:43 -06:00
ic3w0lf e1fc637619 Implement errorImageResponse
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
2025-06-03 20:42:37 -06:00
ic3w0lf 762ee874a0 thumbnail fix - will this WORK THIS TIME?
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-03 20:03:09 -06:00
Quaternions a1c84ff225 Merge pull request 'web: fix api middleware' (#153) from pr1 into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #153
2025-06-04 01:45:36 +00:00
Quaternions cea6242dd7 web: fix api middleware
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-03 18:42:21 -07:00
Quaternions fefe116611 Merge pull request 'Allow Submitter Comments' (#151) from submitter-can-comment into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #151
2025-06-04 00:19:35 +00:00
Quaternions 0ada77421f fix bug
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-03 17:17:59 -07:00
Quaternions fa2d611534 submissions: allow submitter special permission to comment on their posts
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
Previously only map council could comment.
2025-06-03 17:11:53 -07:00
ic3w0lf22 81539a606c Merge pull request 'API_HOST changes, thumbnail fix & cache, "list is empty" fix' (#150) from thumbnail-fix into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #150
Reviewed-by: Quaternions <quaternions@noreply@itzana.me>
2025-06-03 23:54:13 +00:00
ic3w0lf22 32095296c2 Merge branch 'staging' into thumbnail-fix
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-03 23:53:55 +00:00
Quaternions 8ea5ee2d41 use null instead of sentinel value
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-06-03 16:29:29 -07:00
Quaternions 954dbaeac6 env var name change requires deployment configuration change 2025-06-03 16:27:42 -07:00
aidan9382 5b7efa2426 Merge pull request 'Add a favicon (#141)' (#149) from aidan9382/maps-service:favicon into staging
continuous-integration/drone/push Build is passing
Reviewed-on: #149
Reviewed-by: Quaternions <quaternions@noreply@itzana.me>
2025-06-03 23:16:38 +00:00
ic3w0lf 740e3c8932 API_HOST changes, thumbnail fix & cache, "list is empty" fix
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
API_HOST was replaced in order for thumbnail/any redirects to work properly, this also assumes the API will be at `{BASE_URL}/api`, assuming the reverse proxy causes issues with the way redirects were initially setup to work.

Also no more "Submissions list is empty." while it's loading.
2025-06-03 15:58:33 -06:00
aidan9382 4f31f8c75a Add a favicon (#141) 2025-06-03 22:32:43 +01:00
Quaternions b792d33164 Merge pull request 'Update Rust Dependencies (Roblox Format Zstd Support)' (#142) from staging into master
continuous-integration/drone/push Build is passing
Reviewed-on: #142
2025-06-01 23:13:58 +00:00
Quaternions d39a8c0208 submissions-api v0.7.1 make error type smaller
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2025-05-14 00:50:34 -07:00
Quaternions 636282b993 submissions-api: make error type smaller 2025-05-14 00:50:34 -07:00
Quaternions e3667fec0c validation: refactor some goofy roblox functions 2025-05-14 00:50:34 -07:00
Quaternions 0dff464561 validation: checks: write many documentation 2025-05-14 00:50:34 -07:00
Quaternions e30fb5f916 validation: checks: named dummy types for readability 2025-05-14 00:50:34 -07:00
Quaternions 9dd7156f38 validation: avoid passing large struct in Err 2025-05-14 00:50:34 -07:00
Quaternions fc9aae4235 submissions-api: appease clippy 2025-05-14 00:50:34 -07:00
Quaternions a11a0d2fd5 validation: clippy fixes 2025-05-14 00:50:34 -07:00
Quaternions 9dad1a6b4d validation: update deps 2025-05-14 00:50:34 -07:00
Quaternions 929b5949f0 Merge pull request 'Snapshot "Working" Code' (#139) from staging into master
continuous-integration/drone/push Build is failing
Reviewed-on: #139
2025-04-27 21:21:05 +00:00
265 changed files with 44685 additions and 27570 deletions
+89 -57
View File
@@ -7,7 +7,54 @@ platform:
arch: amd64
steps:
- name: api
- name: build-backend
image: golang:1.26.5
environment:
GIT_USER:
from_secret: GIT_USER
GIT_PASS:
from_secret: GIT_PASS
commands:
- echo "machine git.itzana.me login $${GIT_USER} password $${GIT_PASS}" > ~/.netrc
- chmod 600 ~/.netrc
- make build-backend
when:
branch:
- master
- staging
- name: build-validator
image: rust:1.95
commands:
- make build-validator
when:
branch:
- master
- staging
- name: build-combobulator
image: rust:1.95
commands:
- make build-combobulator
when:
branch:
- master
- staging
- name: build-frontend
image: oven/bun:1.3.3
commands:
- apt-get update
- apt-get install make
- make build-frontend
when:
branch:
- master
- staging
event:
- pull_request
- name: image-backend
image: plugins/docker
settings:
registry: registry.itzana.me
@@ -19,8 +66,10 @@ steps:
from_secret: REGISTRY_USER
password:
from_secret: REGISTRY_PASS
dockerfile: Containerfile
dockerfile: Dockerfile
context: .
depends_on:
- build-backend
when:
branch:
- master
@@ -28,7 +77,7 @@ steps:
event:
- push
- name: frontend
- name: image-frontend
image: plugins/docker
settings:
registry: registry.itzana.me
@@ -49,7 +98,7 @@ steps:
event:
- push
- name: validator
- name: image-validator
image: plugins/docker
settings:
registry: registry.itzana.me
@@ -62,7 +111,32 @@ steps:
password:
from_secret: REGISTRY_PASS
dockerfile: validation/Containerfile
context: validation
context: .
depends_on:
- build-validator
when:
branch:
- master
- staging
event:
- push
- name: image-combobulator
image: plugins/docker
settings:
registry: registry.itzana.me
repo: registry.itzana.me/strafesnet/maptest-combobulator
tags:
- ${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
- ${DRONE_BRANCH}
username:
from_secret: REGISTRY_USER
password:
from_secret: REGISTRY_PASS
dockerfile: combobulator/Containerfile
context: .
depends_on:
- build-combobulator
when:
branch:
- master
@@ -77,15 +151,17 @@ steps:
- argocd app --grpc-web set ${DRONE_BRANCH}-maps-service --kustomize-image registry.itzana.me/strafesnet/maptest-api:${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
- argocd app --grpc-web set ${DRONE_BRANCH}-maps-service --kustomize-image registry.itzana.me/strafesnet/maptest-frontend:${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
- argocd app --grpc-web set ${DRONE_BRANCH}-maps-service --kustomize-image registry.itzana.me/strafesnet/maptest-validator:${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
- argocd app --grpc-web set ${DRONE_BRANCH}-maps-service --kustomize-image registry.itzana.me/strafesnet/maptest-combobulator:${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
environment:
USERNAME:
from_secret: ARGO_USER
PASSWORD:
from_secret: ARGO_PASS
depends_on:
- api
- frontend
- validator
- image-backend
- image-frontend
- image-validator
- image-combobulator
when:
branch:
- master
@@ -94,64 +170,20 @@ steps:
- push
# pr dry run
- name: api-pr
image: plugins/docker
settings:
registry: registry.itzana.me
repo: registry.itzana.me/strafesnet/maptest-validator
tags:
- ${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
- ${DRONE_BRANCH}
dockerfile: Containerfile
context: .
dry_run: true
when:
event:
- pull_request
- name: frontend-pr
image: plugins/docker
settings:
registry: registry.itzana.me
repo: registry.itzana.me/strafesnet/maptest-validator
tags:
- ${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
- ${DRONE_BRANCH}
dockerfile: web/Containerfile
context: web
dry_run: true
when:
event:
- pull_request
- name: validator-pr
image: plugins/docker
settings:
registry: registry.itzana.me
repo: registry.itzana.me/strafesnet/maptest-validator
tags:
- ${DRONE_BRANCH}-${DRONE_BUILD_NUMBER}
- ${DRONE_BRANCH}
dockerfile: validation/Containerfile
context: validation
dry_run: true
when:
event:
- pull_request
- name: build-pr
image: alpine
commands:
- echo "Success!"
depends_on:
- api-pr
- frontend-pr
- validator-pr
- build-backend
- build-validator
- build-combobulator
- build-frontend
when:
event:
- pull_request
---
kind: signature
hmac: 11e6d7f1eb839d3798fdcb642ca5523c011bd14c1f3a0343a9c3106bab9ef142
hmac: b84b0fc5de6d553f9f195401f89caab78b47d7aae048e457a5db9acfbc58e047
...
+1
View File
@@ -1,2 +1,3 @@
build
.idea
/target
Generated
+2760 -865
View File
File diff suppressed because it is too large Load Diff
+14 -2
View File
@@ -1,6 +1,18 @@
[workspace]
members = [
"combobulator",
"validation",
"validation/api",
"submissions-api-rs",
]
resolver = "2"
resolver = "3"
[workspace.dependencies]
async-nats = "0.50.0"
futures-util = "0.3.31"
rbx_asset = { version = "0.7.1", features = ["cloud", "gzip", "rustls-tls"], default-features = false, registry = "strafesnet" }
rbx_binary = "3.0.0"
rbx_dom_weak = "4.2.0"
rbx_xml = "3.0.0"
serde = { version = "1.0.215", features = ["derive"] }
serde_json = "1.0.133"
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread", "signal"] }
-33
View File
@@ -1,33 +0,0 @@
# Stage 1: Build
FROM registry.itzana.me/docker-proxy/golang:1.24 AS builder
# Set the working directory in the container
WORKDIR /app
# Copy go.mod and go.sum files
COPY go.mod go.sum ./
# Copy the entire project
COPY . .
# Build the Go application
RUN CGO_ENABLED=0 GOOS=linux go build -o service ./cmd/maps-service/service.go
# Stage 2: Run
FROM registry.itzana.me/docker-proxy/alpine:3.21
# Set up a non-root user for security
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# Set the working directory in the container
WORKDIR /home/appuser
# Copy the built application from the builder stage
COPY --from=builder /app/service .
# Expose application port (adjust if needed)
EXPOSE 8081
# Command to run the application
ENTRYPOINT ["./service"]
+3
View File
@@ -0,0 +1,3 @@
FROM alpine
COPY build/server /
ENTRYPOINT ["/server"]
+46 -8
View File
@@ -1,12 +1,50 @@
submissions:
DOCKER_BUILDKIT=1 docker build . -f Containerfile -t maps-service-submissions
clean:
rm -rf build
rm -rf web/build
web:
docker build web -f web/Containerfile -t maps-service-web
# build
build-backend:
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o build/server cmd/maps-service/service.go
validation:
docker build validation -f validation/Containerfile -t maps-service-validation
build-validator:
cargo build --release --bin maps-validation
all: submissions web validation
build-combobulator:
cargo build --release --bin maps-combobulator
.PHONY: submissions web validation
build-frontend:
rm -rf web/build
cd web && bun install --frozen-lockfile
cd web && bun run build
build: build-backend build-validator build-combobulator build-frontend
# image
image-backend:
docker build . -t maptest-api
image-validator:
docker build . -f validation/Containerfile -t maptest-validator
image-combobulator:
docker build . -f combobulator/Containerfile -t maptest-combobulator
image-frontend:
docker build web -f web/Containerfile -t maptest-frontend
# docker
docker-backend:
make build-backend
make image-backend
docker-validator:
make build-validator
make image-validator
docker-combobulator:
make build-combobulator
make image-combobulator
docker-frontend:
make image-frontend
docker: docker-backend docker-validator docker-combobulator docker-frontend
.PHONY: clean build-backend build-validator build-combobulator build-frontend build image-backend image-validator image-combobulator image-frontend docker-backend docker-validator docker-combobulator docker-frontend docker
+7 -6
View File
@@ -13,11 +13,11 @@ Prerequisite: golang installed
1. Run `go generate` to ensure the generated API is up-to-date. This project uses [ogen](https://github.com/ogen-go/ogen).
```bash
go generate -run "go run github.com/ogen-go/ogen/cmd/ogen@latest --target api --clean openapi.yaml"
go generate
```
2. Build the project.
```bash
go build git.itzana.me/strafesnet/maps-service
make build-backend
```
By default, the project opens at `localhost:8080`.
@@ -29,7 +29,7 @@ Prerequisite: bun installed
The environment variables `API_HOST` and `AUTH_HOST` will need to be set for the middleware.
Example `.env` in web's root:
```
API_HOST="http://localhost:8082/v1/"
API_HOST="http://localhost:8082/"
AUTH_HOST="http://localhost:8083/"
```
@@ -47,14 +47,15 @@ AUTH_HOST="http://localhost:8083/"
Prerequisite: rust installed
1. `cd validation`
2. `cargo run --release`
1. `cargo run --release -p maps-validation`
Environment Variables:
- ROBLOX_GROUP_ID
- RBXCOOKIE
- RBX_API_KEY
- API_HOST_INTERNAL
- NATS_HOST
- LOAD_ASSET_VERSION_PLACE_ID
- LOAD_ASSET_VERSION_UNIVERSE_ID
#### License
+11
View File
@@ -7,6 +7,16 @@ import (
"os"
)
// @title StrafesNET Maps API
// @version 1.0
// @description Obtain an api key at https://dev.strafes.net
// @description Requires Maps:Read permission
// @BasePath /public-api/v1
// @securityDefinitions.apikey ApiKeyAuth
// @in header
// @name X-API-Key
func main() {
log.SetLevel(log.InfoLevel)
log.SetFormatter(&log.JSONFormatter{})
@@ -15,6 +25,7 @@ func main() {
app := cmds.NewApp()
app.Commands = []*cli.Command{
cmds.NewServeCommand(),
cmds.NewApiCommand(),
}
if err := app.Run(os.Args); err != nil {
+24
View File
@@ -0,0 +1,24 @@
[package]
name = "maps-combobulator"
version = "0.1.0"
edition = "2024"
[dependencies]
async-nats.workspace = true
aws-config = { version = "1", features = ["behavior-version-latest"] }
aws-sdk-s3 = "1"
futures-util.workspace = true
image = { version = "0.25.10", features = ["png", "jpeg"], default-features = false }
image_dds = { version = "0.7.2", features = ["ddsfile", "encode"], default-features = false }
rbx_asset.workspace = true
rbx_binary.workspace = true
rbx_dom_weak.workspace = true
rbx_xml.workspace = true
rbxassetid = { version = "0.1.0", registry = "strafesnet" }
serde.workspace = true
serde_json.workspace = true
strafesnet_deferred_loader = { version = "0.9.0", registry = "strafesnet" }
strafesnet_rbx_loader = { version = "0.13.0", registry = "strafesnet" }
strafesnet_snf = { version = "0.7.1", registry = "strafesnet" }
tokio.workspace = true
tokio-stream = "0.1"
+4
View File
@@ -0,0 +1,4 @@
FROM debian:trixie-slim AS runtime
RUN apt-get update && apt-get install -y --no-install-recommends libssl3t64 ca-certificates && rm -rf /var/lib/apt/lists/*
COPY /target/release/maps-combobulator /
ENTRYPOINT ["/maps-combobulator"]
+162
View File
@@ -0,0 +1,162 @@
use tokio_stream::StreamExt;
mod nats_types;
mod process;
mod s3;
mod util;
const SUBJECT_MAPFIX_RELEASE:&str="maptest.mapfixes.release";
const SUBJECT_SUBMISSION_BATCHRELEASE:&str="maptest.submissions.batchrelease";
const SUBJECT_SEED:&str="maptest.combobulator.seed";
#[derive(Debug)]
pub enum StartupError{
NatsConnect(async_nats::ConnectError),
NatsGetStream(async_nats::jetstream::context::GetStreamError),
NatsConsumer(async_nats::jetstream::stream::ConsumerError),
NatsConsumerUpdate(async_nats::jetstream::stream::ConsumerUpdateError),
NatsStream(async_nats::jetstream::consumer::StreamError),
}
impl std::fmt::Display for StartupError{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl std::error::Error for StartupError{}
#[expect(dead_code)]
#[derive(Debug)]
enum HandleMessageError{
Json(serde_json::Error),
UnknownSubject(String),
Process(process::Error),
Ack(async_nats::Error),
Publish(async_nats::jetstream::context::PublishError),
}
impl std::fmt::Display for HandleMessageError{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl std::error::Error for HandleMessageError{}
fn from_slice<'a,T:serde::de::Deserialize<'a>>(slice:&'a [u8])->Result<T,HandleMessageError>{
serde_json::from_slice(slice).map_err(HandleMessageError::Json)
}
async fn handle_message(
processor:&process::Processor,
jetstream:&async_nats::jetstream::Context,
message:async_nats::jetstream::Message,
)->Result<(),HandleMessageError>{
match message.subject.as_str(){
SUBJECT_MAPFIX_RELEASE=>{
let request:nats_types::ReleaseMapfixRequest=from_slice(&message.payload)?;
processor.handle_mapfix_release(request).await.map_err(HandleMessageError::Process)?;
message.ack().await.map_err(HandleMessageError::Ack)?;
},
SUBJECT_SUBMISSION_BATCHRELEASE=>{
// split batch into individual seed messages
let batch:nats_types::ReleaseSubmissionsBatchRequest=from_slice(&message.payload)?;
println!("[combobulator] Splitting batch release (operation {}, {} submissions)",
batch.OperationID,batch.Submissions.len());
for submission in batch.Submissions{
let seed=nats_types::SeedCombobulatorRequest{AssetID:submission.UploadedAssetID};
let payload=serde_json::to_vec(&seed).map_err(HandleMessageError::Json)?;
jetstream.publish(SUBJECT_SEED,payload.into())
.await.map_err(HandleMessageError::Publish)?;
println!("[combobulator] Queued seed for asset {}",seed.AssetID);
}
message.ack().await.map_err(HandleMessageError::Ack)?;
},
SUBJECT_SEED=>{
let request:nats_types::SeedCombobulatorRequest=from_slice(&message.payload)?;
processor.handle_seed(request).await.map_err(HandleMessageError::Process)?;
message.ack().await.map_err(HandleMessageError::Ack)?;
},
other=>return Err(HandleMessageError::UnknownSubject(other.to_owned())),
}
println!("[combobulator] Message processed and acked");
Ok(())
}
#[tokio::main]
async fn main()->Result<(),StartupError>{
// roblox cloud api for downloading assets
let api_key=std::env::var("RBX_API_KEY").expect("RBX_API_KEY env required");
let cloud_context=rbx_asset::cloud::Context::new(rbx_asset::cloud::ApiKey::new(api_key));
// s3
let s3_bucket=std::env::var("S3_BUCKET").expect("S3_BUCKET env required");
let s3_config=aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
let s3_client=aws_sdk_s3::Client::new(&s3_config);
let s3_cache=s3::S3Cache::new(s3_client,s3_bucket);
let processor=process::Processor::new(cloud_context,s3_cache);
// nats
let nats_host=std::env::var("NATS_HOST").expect("NATS_HOST env required");
const STREAM_NAME:&str="maptest";
const DURABLE_NAME:&str="combobulator";
let filter_subjects=vec![
SUBJECT_MAPFIX_RELEASE.to_owned(),
SUBJECT_SUBMISSION_BATCHRELEASE.to_owned(),
SUBJECT_SEED.to_owned(),
];
let nats_config=async_nats::jetstream::consumer::pull::Config{
name:Some(DURABLE_NAME.to_owned()),
durable_name:Some(DURABLE_NAME.to_owned()),
filter_subjects:filter_subjects.clone(),
ack_wait:std::time::Duration::from_secs(900), // 15 minutes for processing
max_deliver:5, // retry up to 5 times
..Default::default()
};
let nasty=async_nats::connect(nats_host).await.map_err(StartupError::NatsConnect)?;
let jetstream=async_nats::jetstream::new(nasty);
let stream=jetstream.get_stream(STREAM_NAME).await.map_err(StartupError::NatsGetStream)?;
let consumer=stream.get_or_create_consumer(DURABLE_NAME,nats_config.clone()).await.map_err(StartupError::NatsConsumer)?;
// update consumer config if filter subjects changed
if consumer.cached_info().config.filter_subjects!=filter_subjects{
stream.update_consumer(nats_config).await.map_err(StartupError::NatsConsumerUpdate)?;
}
let mut messages=consumer.messages().await.map_err(StartupError::NatsStream)?;
// SIGTERM graceful shutdown
let mut sig_term=tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate())
.expect("Failed to create SIGTERM signal listener");
println!("[combobulator] Started, waiting for messages...");
// sequential processing loop - one message at a time
let main_loop=async{
while let Some(message_result)=messages.next().await{
match message_result{
Ok(message)=>{
match handle_message(&processor,&jetstream,message).await{
Ok(())=>println!("[combobulator] Success"),
Err(e)=>println!("[combobulator] Error: {e}"),
}
},
Err(e)=>println!("[combobulator] Message stream error: {e}"),
}
}
};
tokio::select!{
_=sig_term.recv()=>{
println!("[combobulator] Received SIGTERM, shutting down");
},
_=main_loop=>{
println!("[combobulator] Message stream ended");
},
};
Ok(())
}
+35
View File
@@ -0,0 +1,35 @@
#[expect(nonstandard_style,dead_code)]
#[derive(serde::Deserialize)]
pub struct ReleaseMapfixRequest{
pub MapfixID:u64,
pub ModelID:u64,
pub ModelVersion:u64,
pub TargetAssetID:u64,
}
#[expect(nonstandard_style,dead_code)]
#[derive(serde::Deserialize)]
pub struct ReleaseSubmissionRequest{
pub SubmissionID:u64,
pub ReleaseDate:i64,
pub ModelID:u64,
pub ModelVersion:u64,
pub UploadedAssetID:u64,
pub DisplayName:String,
pub Creator:String,
pub GameID:u32,
pub Submitter:u64,
}
#[expect(nonstandard_style)]
#[derive(serde::Deserialize)]
pub struct ReleaseSubmissionsBatchRequest{
pub Submissions:Vec<ReleaseSubmissionRequest>,
pub OperationID:u32,
}
#[expect(nonstandard_style)]
#[derive(serde::Deserialize,serde::Serialize)]
pub struct SeedCombobulatorRequest{
pub AssetID:u64,
}
+251
View File
@@ -0,0 +1,251 @@
use std::io::Cursor;
use crate::nats_types::ReleaseMapfixRequest;
use crate::s3::S3Cache;
use crate::util;
use futures_util::stream::iter as stream_iter;
use futures_util::{StreamExt,TryStreamExt};
use strafesnet_rbx_loader::mesh::MeshWithSize;
use strafesnet_rbx_loader::{MeshIndex,Strings,UnionData};
use strafesnet_deferred_loader::texture::Texture;
const CONCURRENT_REQUESTS:usize=16;
#[expect(dead_code)]
#[derive(Debug)]
pub enum Error{
ArchivedModel,
LoadDom(util::LoadDomError),
DownloadAsset(util::DownloadAssetError),
SNFMap(strafesnet_snf::map::Error),
S3Get(crate::s3::GetError),
S3Put(crate::s3::PutError),
}
impl std::fmt::Display for Error{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl std::error::Error for Error{}
pub struct Processor{
cloud_context:rbx_asset::cloud::Context,
s3:S3Cache,
strings:Strings,
}
impl Processor{
pub fn new(
cloud_context:rbx_asset::cloud::Context,
s3:S3Cache,
)->Self{
Self{
cloud_context,
s3,
strings:Strings::new(),
}
}
/// Download an asset, returning None if the asset is archived.
async fn download_asset(&self,asset_id:u64)->Result<Option<Vec<u8>>,Error>{
match util::download_asset(&self.cloud_context,asset_id).await{
Ok(data)=>Ok(Some(data)),
Err(util::DownloadAssetError::NonFreeModel)=>{
println!("[combobulator] Asset {asset_id} is inaccessible");
Ok(None)
},
Err(e)=>Err(Error::DownloadAsset(e)),
}
}
async fn get_texture(&self,asset_id:u64)->Result<Option<Texture>,Error>{
let dds_key=S3Cache::texture_dds_key(asset_id);
// fetch cached DDS
let dds=if let Some(dds)=self.s3.get(&dds_key).await.map_err(Error::S3Get)?{
dds
}else{
// check raw cache, download if missing
let raw_key=S3Cache::texture_raw_key(asset_id);
let dds_result=if let Some(data)=self.s3.get(&raw_key).await.map_err(Error::S3Get)?{
util::convert_texture_to_dds(&data)
}else{
println!("[combobulator] Downloading texture {asset_id}");
let Some(data)=self.download_asset(asset_id).await? else{
return Ok(None);
};
// decode while we have ownership
let dds_result=util::convert_texture_to_dds(&data);
self.s3.put(&raw_key,data).await.map_err(Error::S3Put)?;
dds_result
};
// handle error after cacheing data
let dds=match dds_result{
Ok(dds)=>dds,
Err(e)=>{
println!("[combobulator] Texture {asset_id} convert error: {e:?}");
return Ok(None);
}
};
self.s3.put(&dds_key,dds.clone()).await.map_err(Error::S3Put)?;
dds
};
println!("[combobulator] Texture {asset_id} processed");
Ok(Some(Texture::ImageDDS(dds.into())))
}
async fn get_mesh(&self,asset_id:u64)->Result<Option<MeshWithSize>,Error>{
let mesh_key=S3Cache::mesh_key(asset_id);
let mesh_result=if let Some(data)=self.s3.get(&mesh_key).await.map_err(Error::S3Get)?{
strafesnet_rbx_loader::mesh::convert(&data)
}else{
println!("[combobulator] Downloading mesh {asset_id}");
let Some(data)=self.download_asset(asset_id).await? else{
return Ok(None);
};
// decode while we have ownership
let mesh_result=strafesnet_rbx_loader::mesh::convert(&data);
self.s3.put(&mesh_key,data.clone()).await.map_err(Error::S3Put)?;
mesh_result
};
println!("[combobulator] Mesh {asset_id} processed");
// handle error after cacheing data
match mesh_result{
Ok(mesh)=>Ok(Some(mesh)),
Err(e)=>{
println!("[combobulator] Mesh {asset_id} convert error: {e}");
Ok(None)
},
}
}
async fn get_union(&self,asset_id:Option<rbxassetid::RobloxAssetId>,mut union_data:UnionData<'_>)->Result<Option<MeshWithSize>,Error>{
let dom;
if let Some(rbxassetid::RobloxAssetId(asset_id))=asset_id{
let union_key=S3Cache::union_key(asset_id);
let union_result=if let Some(data)=self.s3.get(&union_key).await.map_err(Error::S3Get)?{
rbx_binary::from_reader(data.as_slice())
}else{
println!("[combobulator] Downloading union {asset_id}");
let Some(data)=self.download_asset(asset_id).await? else{
return Ok(None);
};
// decode the data while we have ownership
let union_result=rbx_binary::from_reader(data.as_slice());
self.s3.put(&union_key,data).await.map_err(Error::S3Put)?;
union_result
};
println!("[combobulator] Union {asset_id} processed");
// handle error after cacheing data
dom=match union_result{
Ok(dom)=>dom,
Err(e)=>{
println!("[combobulator] Union {asset_id} decode error: {e}");
return Ok(None);
},
};
union_data.extract_union_data(&self.strings,&dom);
}
let union_result=strafesnet_rbx_loader::union::convert(union_data);
match union_result{
Ok(mesh)=>Ok(Some(mesh)),
Err(e)=>{
println!("[combobulator] Union {asset_id:?} convert error: {e}");
Ok(None)
},
}
}
/// Process a single model: extract assets, cache to S3, build SNF.
async fn process_model(&self,asset_id:u64)->Result<(),Error>{
println!("[combobulator] Downloading model {asset_id}");
let rbxl_bytes=self.download_asset(asset_id).await?
.ok_or(Error::ArchivedModel)?;
// decode dom
let dom=util::load_dom(&rbxl_bytes)
.map_err(Error::LoadDom)?;
// run scripts
let model=strafesnet_rbx_loader::Model::new(dom);
let mut place=strafesnet_rbx_loader::Place::from(model);
// TODO: script errors report for burn down chart
let _script_errors=place.run_scripts().unwrap_or_else(|e|vec![e]);
let mut texture_deferred_loader=strafesnet_deferred_loader::deferred_loader::RenderConfigDeferredLoader::new();
let mut mesh_deferred_loader=strafesnet_deferred_loader::deferred_loader::MeshDeferredLoader::new();
// run a partial conversion to ascertain the required meshes and textures
let map_builder=strafesnet_rbx_loader::rbx::convert(
place.as_ref(),
&self.strings,
&mut texture_deferred_loader,
&mut mesh_deferred_loader,
);
// process textures: download, cache, convert to DDS
let textures:Vec<_>=stream_iter(texture_deferred_loader).map(async|id|{
let asset_id=match id{
Some(asset_id)=>asset_id.0,
None=>return Ok(None),
};
self.get_texture(asset_id).await
})
.buffered(CONCURRENT_REQUESTS)
.try_collect().await?;
// process meshes
let meshes:Vec<_>=stream_iter(mesh_deferred_loader).map(async|id|{
match id{
MeshIndex::FileMesh{asset_id}=>self.get_mesh(asset_id.0).await,
MeshIndex::Union{asset_id,union_data}=>self.get_union(asset_id,union_data).await,
}
})
.buffered(CONCURRENT_REQUESTS)
.try_collect().await?;
// TODO: conversion error report for burn down chart
let (map,_convert_errors)=map_builder.build(meshes,textures);
// convert to SNF and upload
println!("[combobulator] Converting to SNF");
let mut snf_buf=Vec::new();
strafesnet_snf::map::write_map(Cursor::new(&mut snf_buf),map).map_err(Error::SNFMap)?;
let snf_key=S3Cache::snf_key(asset_id);
self.s3.put(&snf_key,snf_buf).await.map_err(Error::S3Put)?;
println!("[combobulator] SNF uploaded to {snf_key}");
Ok(())
}
/// Handle a mapfix release message.
pub async fn handle_mapfix_release(&self,request:ReleaseMapfixRequest)->Result<(),Error>{
println!("[combobulator] Processing mapfix {} (asset {})",
request.MapfixID,request.TargetAssetID);
self.process_model(request.TargetAssetID).await
}
/// Handle a seed request (reprocess an existing map).
pub async fn handle_seed(&self,request:crate::nats_types::SeedCombobulatorRequest)->Result<(),Error>{
println!("[combobulator] Seeding asset {}",request.AssetID);
self.process_model(request.AssetID).await
}
}
+94
View File
@@ -0,0 +1,94 @@
use aws_sdk_s3::Client;
use aws_sdk_s3::primitives::ByteStream;
#[expect(dead_code)]
#[derive(Debug)]
pub enum GetError{
Get(Box<aws_sdk_s3::error::SdkError<aws_sdk_s3::operation::get_object::GetObjectError>>),
Collect(aws_sdk_s3::primitives::ByteStreamError),
}
impl std::fmt::Display for GetError{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl std::error::Error for GetError{}
#[expect(dead_code)]
#[derive(Debug)]
pub enum PutError{
Put(Box<aws_sdk_s3::error::SdkError<aws_sdk_s3::operation::put_object::PutObjectError>>),
}
impl std::fmt::Display for PutError{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl std::error::Error for PutError{}
pub struct S3Cache{
client:Client,
bucket:String,
}
impl S3Cache{
pub fn new(client:Client,bucket:String)->Self{
Self{client,bucket}
}
/// Try to get a cached object. Returns None if the key doesn't exist.
pub async fn get(&self,key:&str)->Result<Option<Vec<u8>>,GetError>{
match self.client.get_object()
.bucket(&self.bucket)
.key(key)
.send()
.await
{
Ok(output)=>{
let bytes=output.body.collect().await.map_err(GetError::Collect)?;
Ok(Some(bytes.to_vec()))
},
Err(e)=>{
// check if it's a NoSuchKey error
if let aws_sdk_s3::error::SdkError::ServiceError(ref service_err)=e&&service_err.err().is_no_such_key(){
return Ok(None);
}
Err(GetError::Get(Box::new(e)))
},
}
}
/// Put an object into S3.
pub async fn put(&self,key:&str,data:Vec<u8>)->Result<(),PutError>{
self.client.put_object()
.bucket(&self.bucket)
.key(key)
.body(ByteStream::from(data))
.send()
.await
.map_err(|e|PutError::Put(Box::new(e)))?;
Ok(())
}
// S3 key helpers
pub fn texture_raw_key(asset_id:u64)->String{
format!("assets/textures/{asset_id}.raw")
}
pub fn texture_dds_key(asset_id:u64)->String{
format!("assets/textures/{asset_id}.dds")
}
pub fn mesh_key(asset_id:u64)->String{
format!("assets/meshes/{asset_id}")
}
pub fn union_key(asset_id:u64)->String{
format!("assets/unions/{asset_id}")
}
pub fn snf_key(model_id:u64)->String{
format!("maps/{model_id}.snfm")
}
}
+83
View File
@@ -0,0 +1,83 @@
#[expect(dead_code)]
#[derive(Debug)]
pub enum LoadDomError{
Binary(rbx_binary::DecodeError),
Xml(rbx_xml::DecodeError),
UnknownFormat,
}
impl std::fmt::Display for LoadDomError{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl std::error::Error for LoadDomError{}
pub fn load_dom(data:&[u8])->Result<rbx_dom_weak::WeakDom,LoadDomError>{
match data.get(0..8){
Some(b"<roblox!")=>rbx_binary::from_reader(data).map_err(LoadDomError::Binary),
Some(b"<roblox ")=>rbx_xml::from_reader_default(data).map_err(LoadDomError::Xml),
_=>Err(LoadDomError::UnknownFormat),
}
}
#[expect(dead_code)]
#[derive(Debug)]
pub enum DownloadAssetError{
GetLocation(rbx_asset::cloud::GetError),
NonFreeModel,
GetAsset(rbx_asset::cloud::GetError),
IO(std::io::Error),
}
impl std::fmt::Display for DownloadAssetError{
fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{
write!(f,"{self:?}")
}
}
impl std::error::Error for DownloadAssetError{}
pub async fn download_asset(context:&rbx_asset::cloud::Context,asset_id:u64)->Result<Vec<u8>,DownloadAssetError>{
let asset_location_info=context.get_asset_location(rbx_asset::cloud::GetAssetLatestRequest{
asset_id,
}).await.map_err(DownloadAssetError::GetLocation)?;
let Some(asset_location)=asset_location_info.location else{
return Err(DownloadAssetError::NonFreeModel);
};
let data=context.get_asset(&asset_location).await.map_err(DownloadAssetError::GetAsset)?;
data.to_vec().map_err(DownloadAssetError::IO)
}
#[expect(dead_code)]
#[derive(Debug)]
pub enum ConvertTextureError{
Image(image::ImageError),
DdsEncode(image_dds::error::SurfaceError),
Dds(image_dds::CreateDdsError),
DdsWrite(image_dds::ddsfile::Error),
}
pub fn convert_texture_to_dds(data:&[u8])->Result<Vec<u8>,ConvertTextureError>{
let image=image::load_from_memory(data).map_err(ConvertTextureError::Image)?.to_rgba8();
let format=if image.width()%4!=0||image.height()%4!=0{
image_dds::ImageFormat::Rgba8UnormSrgb
}else{
image_dds::ImageFormat::BC7RgbaUnormSrgb
};
let surface=image_dds::SurfaceRgba8{
width:image.width(),
height:image.height(),
depth:1,
layers:1,
mipmaps:1,
data:image.as_raw(),
}.encode(
format,
image_dds::Quality::Slow,
image_dds::Mipmaps::GeneratedAutomatic
).map_err(ConvertTextureError::DdsEncode)?;
let dds=surface.to_dds().map_err(ConvertTextureError::Dds)?;
let mut buf=Vec::new();
dds.write(&mut buf).map_err(ConvertTextureError::DdsWrite)?;
Ok(buf)
}
+10 -6
View File
@@ -13,7 +13,7 @@ services:
submissions:
image:
maps-service-submissions
maptest-api
container_name: submissions
command: [
# debug
@@ -33,6 +33,8 @@ services:
"--auth-rpc-host","authrpc:8081",
"--data-rpc-host","dataservice:9000",
]
env_file:
- /home/quat/auth-compose/strafesnet_staging.env
depends_on:
- authrpc
- nats
@@ -43,7 +45,7 @@ services:
web:
image:
maps-service-web
maptest-frontend
networks:
- maps-service-network
ports:
@@ -54,14 +56,16 @@ services:
validation:
image:
maps-service-validation
maptest-validator
container_name: validation
env_file:
- ../auth-compose/strafesnet_staging.env
- /home/quat/auth-compose/strafesnet_staging.env
environment:
- ROBLOX_GROUP_ID=17032139 # "None" is special case string value
- API_HOST_INTERNAL=http://submissions:8083/v1
- NATS_HOST=nats:4222
- LOAD_ASSET_VERSION_PLACE_ID=14001440964
- LOAD_ASSET_VERSION_UNIVERSE_ID=4850603885
depends_on:
- nats
# note: this races the submissions which creates a nats stream
@@ -101,7 +105,7 @@ services:
- REDIS_ADDR=authredis:6379
- RBX_GROUP_ID=17032139
env_file:
- ../auth-compose/auth-service.env
- /home/quat/auth-compose/auth-service.env
depends_on:
- authredis
networks:
@@ -115,7 +119,7 @@ services:
environment:
- REDIS_ADDR=authredis:6379
env_file:
- ../auth-compose/auth-service.env
- /home/quat/auth-compose/auth-service.env
depends_on:
- authredis
networks:
+282
View File
@@ -0,0 +1,282 @@
// Package docs Code generated by swaggo/swag. DO NOT EDIT
package docs
import "github.com/swaggo/swag"
const docTemplate = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"contact": {},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/map": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get a list of maps",
"produces": [
"application/json"
],
"tags": [
"maps"
],
"summary": "List maps",
"parameters": [
{
"maximum": 100,
"minimum": 1,
"type": "integer",
"default": 10,
"description": "Page size (max 100)",
"name": "page_size",
"in": "query"
},
{
"minimum": 1,
"type": "integer",
"default": 1,
"description": "Page number",
"name": "page_number",
"in": "query"
},
{
"type": "integer",
"name": "game_id",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/PagedResponse-Map"
}
},
"default": {
"description": "General error response",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/map/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get a specific map by its ID",
"produces": [
"application/json"
],
"tags": [
"maps"
],
"summary": "Get map by ID",
"parameters": [
{
"type": "integer",
"description": "Map ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/Response-Map"
}
},
"404": {
"description": "Map not found",
"schema": {
"$ref": "#/definitions/Error"
}
},
"default": {
"description": "General error response",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/map/{id}/snfm": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Redirects to a signed download URL for a map's SNFM file",
"tags": [
"maps"
],
"summary": "Download SNFM file",
"parameters": [
{
"type": "integer",
"description": "Map ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"307": {
"description": "Redirect to signed S3 URL"
},
"404": {
"description": "Map not found",
"schema": {
"$ref": "#/definitions/Error"
}
},
"default": {
"description": "General error response",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
}
},
"definitions": {
"Error": {
"type": "object",
"properties": {
"error": {
"type": "string"
}
}
},
"Map": {
"type": "object",
"properties": {
"asset_version": {
"type": "integer"
},
"created_at": {
"type": "string"
},
"creator": {
"type": "string"
},
"date": {
"type": "string"
},
"display_name": {
"type": "string"
},
"game_id": {
"type": "integer"
},
"id": {
"type": "integer"
},
"load_count": {
"type": "integer"
},
"modes": {
"type": "integer"
},
"submitter": {
"type": "integer"
},
"thumbnail": {
"type": "integer"
},
"updated_at": {
"type": "string"
}
}
},
"PagedResponse-Map": {
"type": "object",
"properties": {
"data": {
"description": "Data contains the actual response payload",
"type": "array",
"items": {
"$ref": "#/definitions/Map"
}
},
"pagination": {
"description": "Pagination contains information about paging",
"allOf": [
{
"$ref": "#/definitions/Pagination"
}
]
}
}
},
"Pagination": {
"type": "object",
"properties": {
"page": {
"description": "Current page number",
"type": "integer"
},
"page_size": {
"description": "Number of items per page",
"type": "integer"
}
}
},
"Response-Map": {
"type": "object",
"properties": {
"data": {
"description": "Data contains the actual response payload",
"allOf": [
{
"$ref": "#/definitions/Map"
}
]
}
}
}
},
"securityDefinitions": {
"ApiKeyAuth": {
"type": "apiKey",
"name": "X-API-Key",
"in": "header"
}
}
}`
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "1.0",
Host: "",
BasePath: "/public-api/v1",
Schemes: []string{},
Title: "StrafesNET Maps API",
Description: "Obtain an api key at https://dev.strafes.net\nRequires Maps:Read permission",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,
LeftDelim: "{{",
RightDelim: "}}",
}
func init() {
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
}
+257
View File
@@ -0,0 +1,257 @@
{
"swagger": "2.0",
"info": {
"description": "Obtain an api key at https://dev.strafes.net\nRequires Maps:Read permission",
"title": "StrafesNET Maps API",
"contact": {},
"version": "1.0"
},
"basePath": "/public-api/v1",
"paths": {
"/map": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get a list of maps",
"produces": [
"application/json"
],
"tags": [
"maps"
],
"summary": "List maps",
"parameters": [
{
"maximum": 100,
"minimum": 1,
"type": "integer",
"default": 10,
"description": "Page size (max 100)",
"name": "page_size",
"in": "query"
},
{
"minimum": 1,
"type": "integer",
"default": 1,
"description": "Page number",
"name": "page_number",
"in": "query"
},
{
"type": "integer",
"name": "game_id",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/PagedResponse-Map"
}
},
"default": {
"description": "General error response",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/map/{id}": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Get a specific map by its ID",
"produces": [
"application/json"
],
"tags": [
"maps"
],
"summary": "Get map by ID",
"parameters": [
{
"type": "integer",
"description": "Map ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/Response-Map"
}
},
"404": {
"description": "Map not found",
"schema": {
"$ref": "#/definitions/Error"
}
},
"default": {
"description": "General error response",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
},
"/map/{id}/snfm": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "Redirects to a signed download URL for a map's SNFM file",
"tags": [
"maps"
],
"summary": "Download SNFM file",
"parameters": [
{
"type": "integer",
"description": "Map ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"307": {
"description": "Redirect to signed S3 URL"
},
"404": {
"description": "Map not found",
"schema": {
"$ref": "#/definitions/Error"
}
},
"default": {
"description": "General error response",
"schema": {
"$ref": "#/definitions/Error"
}
}
}
}
}
},
"definitions": {
"Error": {
"type": "object",
"properties": {
"error": {
"type": "string"
}
}
},
"Map": {
"type": "object",
"properties": {
"asset_version": {
"type": "integer"
},
"created_at": {
"type": "string"
},
"creator": {
"type": "string"
},
"date": {
"type": "string"
},
"display_name": {
"type": "string"
},
"game_id": {
"type": "integer"
},
"id": {
"type": "integer"
},
"load_count": {
"type": "integer"
},
"modes": {
"type": "integer"
},
"submitter": {
"type": "integer"
},
"thumbnail": {
"type": "integer"
},
"updated_at": {
"type": "string"
}
}
},
"PagedResponse-Map": {
"type": "object",
"properties": {
"data": {
"description": "Data contains the actual response payload",
"type": "array",
"items": {
"$ref": "#/definitions/Map"
}
},
"pagination": {
"description": "Pagination contains information about paging",
"allOf": [
{
"$ref": "#/definitions/Pagination"
}
]
}
}
},
"Pagination": {
"type": "object",
"properties": {
"page": {
"description": "Current page number",
"type": "integer"
},
"page_size": {
"description": "Number of items per page",
"type": "integer"
}
}
},
"Response-Map": {
"type": "object",
"properties": {
"data": {
"description": "Data contains the actual response payload",
"allOf": [
{
"$ref": "#/definitions/Map"
}
]
}
}
}
},
"securityDefinitions": {
"ApiKeyAuth": {
"type": "apiKey",
"name": "X-API-Key",
"in": "header"
}
}
}
+166
View File
@@ -0,0 +1,166 @@
basePath: /public-api/v1
definitions:
Error:
properties:
error:
type: string
type: object
Map:
properties:
asset_version:
type: integer
created_at:
type: string
creator:
type: string
date:
type: string
display_name:
type: string
game_id:
type: integer
id:
type: integer
load_count:
type: integer
modes:
type: integer
submitter:
type: integer
thumbnail:
type: integer
updated_at:
type: string
type: object
PagedResponse-Map:
properties:
data:
description: Data contains the actual response payload
items:
$ref: '#/definitions/Map'
type: array
pagination:
allOf:
- $ref: '#/definitions/Pagination'
description: Pagination contains information about paging
type: object
Pagination:
properties:
page:
description: Current page number
type: integer
page_size:
description: Number of items per page
type: integer
type: object
Response-Map:
properties:
data:
allOf:
- $ref: '#/definitions/Map'
description: Data contains the actual response payload
type: object
info:
contact: {}
description: |-
Obtain an api key at https://dev.strafes.net
Requires Maps:Read permission
title: StrafesNET Maps API
version: "1.0"
paths:
/map:
get:
description: Get a list of maps
parameters:
- default: 10
description: Page size (max 100)
in: query
maximum: 100
minimum: 1
name: page_size
type: integer
- default: 1
description: Page number
in: query
minimum: 1
name: page_number
type: integer
- in: query
name: game_id
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/PagedResponse-Map'
default:
description: General error response
schema:
$ref: '#/definitions/Error'
security:
- ApiKeyAuth: []
summary: List maps
tags:
- maps
/map/{id}:
get:
description: Get a specific map by its ID
parameters:
- description: Map ID
in: path
name: id
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/Response-Map'
"404":
description: Map not found
schema:
$ref: '#/definitions/Error'
default:
description: General error response
schema:
$ref: '#/definitions/Error'
security:
- ApiKeyAuth: []
summary: Get map by ID
tags:
- maps
/map/{id}/snfm:
get:
description: Redirects to a signed download URL for a map's SNFM file
parameters:
- description: Map ID
in: path
name: id
required: true
type: integer
responses:
"307":
description: Redirect to signed S3 URL
"404":
description: Map not found
schema:
$ref: '#/definitions/Error'
default:
description: General error response
schema:
$ref: '#/definitions/Error'
security:
- ApiKeyAuth: []
summary: Download SNFM file
tags:
- maps
securityDefinitions:
ApiKeyAuth:
in: header
name: X-API-Key
type: apiKey
swagger: "2.0"
+1 -1
View File
@@ -1,4 +1,4 @@
package main
//go:generate go run github.com/swaggo/swag/cmd/swag@latest init -g ./cmd/maps-service/service.go
//go:generate go run github.com/ogen-go/ogen/cmd/ogen@latest --target pkg/api --clean openapi.yaml
//go:generate go run github.com/ogen-go/ogen/cmd/ogen@latest --target pkg/internal --clean openapi-internal.yaml
+101 -39
View File
@@ -1,64 +1,126 @@
module git.itzana.me/strafesnet/maps-service
go 1.22
toolchain go1.23.3
go 1.25.0
require (
git.itzana.me/strafesnet/go-grpc v0.0.0-20241129081229-9e166b3d11f7
git.itzana.me/StrafesNET/dev-service v0.0.0-20260307022628-fe71e9dbcb0b
git.itzana.me/strafesnet/go-grpc v0.0.0-20260414205100-57b3171fc3f2
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9
github.com/aws/aws-sdk-go-v2/config v1.32.30
github.com/aws/aws-sdk-go-v2/service/s3 v1.105.2
github.com/dchest/siphash v1.2.3
github.com/gin-gonic/gin v1.12.0
github.com/go-faster/errors v0.7.1
github.com/go-faster/jx v1.1.0
github.com/nats-io/nats.go v1.37.0
github.com/ogen-go/ogen v1.2.1
github.com/sirupsen/logrus v1.9.3
github.com/urfave/cli/v2 v2.27.5
go.opentelemetry.io/otel v1.32.0
go.opentelemetry.io/otel/metric v1.32.0
go.opentelemetry.io/otel/trace v1.32.0
google.golang.org/grpc v1.48.0
gorm.io/driver/postgres v1.5.10
gorm.io/gorm v1.25.10
github.com/go-faster/jx v1.2.0
github.com/nats-io/nats.go v1.52.0
github.com/ogen-go/ogen v1.23.0
github.com/redis/go-redis/v9 v9.21.0
github.com/sirupsen/logrus v1.9.4
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.1
github.com/swaggo/swag v1.16.6
github.com/urfave/cli/v2 v2.27.7
go.opentelemetry.io/otel v1.44.0
go.opentelemetry.io/otel/metric v1.44.0
go.opentelemetry.io/otel/trace v1.44.0
google.golang.org/grpc v1.82.1
gorm.io/driver/postgres v1.6.0
gorm.io/gorm v1.31.2
)
require (
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/aws/aws-sdk-go-v2 v1.42.1 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.14 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.19.29 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.30 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.31 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.13 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.23 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.30 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.31 // indirect
github.com/aws/aws-sdk-go-v2/service/signin v1.4.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.32.1 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.37.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.44.1 // indirect
github.com/aws/smithy-go v1.27.4 // indirect
github.com/bytedance/gopkg v0.1.4 // indirect
github.com/bytedance/sonic v1.15.2 // indirect
github.com/bytedance/sonic/loader v0.5.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cloudwego/base64x v0.1.7 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
github.com/gin-contrib/sse v1.1.1 // indirect
github.com/go-openapi/jsonpointer v1.0.0 // indirect
github.com/go-openapi/jsonreference v1.0.0 // indirect
github.com/go-openapi/spec v0.22.6 // indirect
github.com/go-openapi/swag/conv v0.27.0 // indirect
github.com/go-openapi/swag/jsonname v0.27.0 // indirect
github.com/go-openapi/swag/jsonutils v0.27.0 // indirect
github.com/go-openapi/swag/loading v0.27.0 // indirect
github.com/go-openapi/swag/stringutils v0.27.0 // indirect
github.com/go-openapi/swag/typeutils v0.27.0 // indirect
github.com/go-openapi/swag/yamlutils v0.27.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.30.3 // indirect
github.com/goccy/go-json v0.10.6 // indirect
github.com/goccy/go-yaml v1.19.2 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgx/v5 v5.5.5 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.10.0 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.17.6 // indirect
github.com/nats-io/nkeys v0.4.7 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.19.0 // indirect
github.com/klauspost/cpuid/v2 v2.4.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nats-io/nkeys v0.4.16 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/pelletier/go-toml/v2 v2.4.3 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/quic-go/quic-go v0.60.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
golang.org/x/crypto v0.23.0 // indirect
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
google.golang.org/protobuf v1.28.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.1 // indirect
github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect
go.mongodb.org/mongo-driver/v2 v2.8.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/arch v0.29.0 // indirect
golang.org/x/crypto v0.54.0 // indirect
golang.org/x/mod v0.38.0 // indirect
golang.org/x/tools v0.48.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260715232425-e75dac1f907d // indirect
google.golang.org/protobuf v1.36.11 // indirect
)
require (
github.com/dlclark/regexp2 v1.11.0 // indirect
github.com/fatih/color v1.17.0 // indirect
github.com/dlclark/regexp2 v1.12.0 // indirect
github.com/fatih/color v1.19.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-faster/yaml v0.4.6 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
// github.com/golang/protobuf v1.5.4 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/segmentio/asm v1.2.0 // indirect
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
github.com/mattn/go-colorable v0.1.15 // indirect
github.com/mattn/go-isatty v0.0.23 // indirect
github.com/segmentio/asm v1.2.1 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.28.0 // indirect
golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597 // indirect
golang.org/x/net v0.57.0 // indirect
golang.org/x/sync v0.22.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/text v0.40.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
+267 -182
View File
@@ -1,243 +1,328 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
git.itzana.me/strafesnet/go-grpc v0.0.0-20241129081229-9e166b3d11f7 h1:5XzWd3ZZjSw1M60IfHuILty2vRPBYiqM0FZ+E7uHCi8=
git.itzana.me/strafesnet/go-grpc v0.0.0-20241129081229-9e166b3d11f7/go.mod h1:X7XTRUScRkBWq8q8bplbeso105RPDlnY7J6Wy1IwBMs=
git.itzana.me/StrafesNET/dev-service v0.0.0-20260307022628-fe71e9dbcb0b h1:z0iQFOeFvr8dfsWI8tG3DqMyssHqjU13/p6L9Wrt4MM=
git.itzana.me/StrafesNET/dev-service v0.0.0-20260307022628-fe71e9dbcb0b/go.mod h1:KJal0K++M6HEzSry6JJ2iDPZtOQn5zSstNlDbU3X4Jg=
git.itzana.me/strafesnet/go-grpc v0.0.0-20260414205100-57b3171fc3f2 h1:AIJ6mUohEPblXKk+4oSnWpSokh8C6Jk9MjbzCvHXX1s=
git.itzana.me/strafesnet/go-grpc v0.0.0-20260414205100-57b3171fc3f2/go.mod h1:X7XTRUScRkBWq8q8bplbeso105RPDlnY7J6Wy1IwBMs=
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9 h1:7lU6jyR7S7Rhh1dnUp7GyIRHUTBXZagw8F4n4hOyxLw=
git.itzana.me/strafesnet/utils v0.0.0-20220716194944-d8ca164052f9/go.mod h1:uyYerSieEt4v0MJCdPLppG0LtJ4Yj035vuTetWGsxjY=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/aws/aws-sdk-go-v2 v1.42.1 h1:9eOTgu1z/dVtYpNZ3/8/XbbaX0x/BqE3HUzAzs6K0ek=
github.com/aws/aws-sdk-go-v2 v1.42.1/go.mod h1:5pKeft2eJj+gElQ38Jqg4ibCqh+/AK33/0X3hip7IjM=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.14 h1:3IZY0XAJquT3aHzbkHfPzy4ACPcEjVG0x87KOwtpqGY=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.14/go.mod h1:zwM6veDkhGgQFqkBy+uT28AAYpLu+uFMlPl+rCg/73E=
github.com/aws/aws-sdk-go-v2/config v1.32.30 h1:XwsEzpTJfQYJbFicz/QMLwAZdyeNVVoOEkbF7R3gPJk=
github.com/aws/aws-sdk-go-v2/config v1.32.30/go.mod h1:Ud32SuMc+/9BGxfpSVld7HrE2o05JwKmXY4M3jOQNZU=
github.com/aws/aws-sdk-go-v2/credentials v1.19.29 h1:WHZGssHH887cO0ox07SIQZsFx3MKD4ps6w0xUEmnKYQ=
github.com/aws/aws-sdk-go-v2/credentials v1.19.29/go.mod h1:Mhl0xR6zjguiuj00XRx2wMx22sAltk7oya39sT7fdg8=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.30 h1:/hi1JADLEW9YYryEz1w4GQu0EtP23pP553Cf9KgsDV4=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.30/go.mod h1:/3AOgy4K17Dm4ucMZVC/MJkzy5kmfKUcINRHZyo0koQ=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30 h1:xM/Is9cKMHa8Jj8zkvWhvrFkZsXJV9E+BB4g0HW0duQ=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30/go.mod h1:WueJeNDZvK1fMYEWJIkcivBfEzUkTpBhzlrUKKY8EuA=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30 h1:jn46zC9LdsVR/ZpMIJqMqb8hHv31BlLx3ulVqNspUOk=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30/go.mod h1:1hTMsAgbdS/AtUi4bw8+gUuh1pceo+eXRLfpSuSQj3M=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.31 h1:3GUprIsfmGcC5SACIyB0e7E0BM1O1b3Erl5CePYIAeQ=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.31/go.mod h1:7PuV1yl5e2xnUbm+RqvVg5i2iBM8EyijZNoI9wsOoOc=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.13 h1:mbRIur/BiHK6SKPjoBIXSE/hJ6g6JGRLuxQy1jGjlN4=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.13/go.mod h1:ITg9em2KbJx1s0y4aqRX5OYWG6HBZ5TVR//OdpEZ2CQ=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.23 h1:9Fjh6fi/U5JEStVZijmaMpUwE/gvBJj7x2B/PjbO9To=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.23/go.mod h1:iMoT2f1tClxrWAAnKCXjZQ6LOmfLrMG14wmnWpM+F14=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.30 h1:/Z5jmNrKsSD7EmDjzAPsm/3L9IuOkzaynklJZ1qX7S4=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.30/go.mod h1:lEzEZnOosE7zi8Z6royW1cFJTD9fpab4Ul1SBrllewk=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.31 h1:uao4A3QZ5UmB326V6KF+qRpv9Tjz7IlnlnTbbANntlU=
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.31/go.mod h1:I/1+z0VwL1GhQyLgkoHDlygpUZ+iTAwOQ/NsftiUL2I=
github.com/aws/aws-sdk-go-v2/service/s3 v1.105.2 h1:5C00eQYpTrgQXnp6V3P6P7zPElna3AXvlukbANE6nJI=
github.com/aws/aws-sdk-go-v2/service/s3 v1.105.2/go.mod h1:zdmCoFO/dSI7GlrwsPqFJI+WlFnSU4Tc8TJnlXrM1Do=
github.com/aws/aws-sdk-go-v2/service/signin v1.4.1 h1:V7ZZ300WPXGjvkyore5DGe0ljVPOxCXie/thWdtSBXE=
github.com/aws/aws-sdk-go-v2/service/signin v1.4.1/go.mod h1:mxC0nT/C8wMMS97DemZPzvUZxvIt+2Iq+eS3JdFZGgg=
github.com/aws/aws-sdk-go-v2/service/sso v1.32.1 h1:gYFYh4iLLcAOJRLNPY2aD2g9DIhKn4eof8UkIrr1rTk=
github.com/aws/aws-sdk-go-v2/service/sso v1.32.1/go.mod h1:u8af9Nqkmqnr96f7v9nHqzZT9XBwbXEkTiqT4ROuJSE=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.37.1 h1:arjT9Cm3/WYbGmD5TUZHk4UQn4Lle1fUNZs5FC6CtF0=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.37.1/go.mod h1:DMPWJBjYs6+3+f/qhBFEFPPlQ6NlhWjai3dJNvipJ84=
github.com/aws/aws-sdk-go-v2/service/sts v1.44.1 h1:RvfHDg+xvAeZ+5741vUEjpOVtYSIm93W2zhx10Xtydw=
github.com/aws/aws-sdk-go-v2/service/sts v1.44.1/go.mod h1:9gdl4RrflIdpDb2TlXshWgR1F9TeCkvqDx77Vpr4Z/Q=
github.com/aws/smithy-go v1.27.4 h1:JQcphmBN4f0q/sPqXqROIItRNV/hy10cgu7CsFy616M=
github.com/aws/smithy-go v1.27.4/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/bytedance/gopkg v0.1.4 h1:oZnQwnX82KAIWb7033bEwtxvTqXcYMxDBaQxo5JJHWM=
github.com/bytedance/gopkg v0.1.4/go.mod h1:v1zWfPm21Fb+OsyXN2VAHdL6TBb2L88anLQgdyje6R4=
github.com/bytedance/sonic v1.15.2 h1:90H+rcF/FwLXwfB1cudOLq/je83n683Utf4Cbp0xHCo=
github.com/bytedance/sonic v1.15.2/go.mod h1:mT2NbXunuaEbnZ+mRIX/vYqKISmgEuHFDI4UzmKx2SA=
github.com/bytedance/sonic/loader v0.5.1 h1:Ygpfa9zwRCCKSlrp5bBP/b/Xzc3VxsAW+5NIYXrOOpI=
github.com/bytedance/sonic/loader v0.5.1/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudwego/base64x v0.1.7 h1:NppS+Fgzg5ovhn4NkUXaDT3x9jldgH5ToMCqzBSi2zI=
github.com/cloudwego/base64x v0.1.7/go.mod h1:Cu1PV9zfrSf7ET2tIbWbbEy7jO7HHJ13q4X2SQ8aWYg=
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA=
github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc=
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8=
github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
github.com/gin-contrib/sse v1.1.1 h1:uGYpNwTacv5R68bSGMapo62iLTRa9l5zxGCps4hK6ko=
github.com/gin-contrib/sse v1.1.1/go.mod h1:QXzuVkA0YO7o/gun03UI1Q+FTI8ZV/n5t03kIQAI89s=
github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8=
github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc=
github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg=
github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo=
github.com/go-faster/jx v1.1.0 h1:ZsW3wD+snOdmTDy9eIVgQdjUpXRRV4rqW8NS3t+20bg=
github.com/go-faster/jx v1.1.0/go.mod h1:vKDNikrKoyUmpzaJ0OkIkRQClNHFX/nF3dnTJZb3skg=
github.com/go-faster/jx v1.2.0 h1:T2YHJPrFaYu21fJtUxC9GzmluKu8rVIFDwwGBKTDseI=
github.com/go-faster/jx v1.2.0/go.mod h1:UWLOVDmMG597a5tBFPLIWJdUxz5/2emOpfsj9Neg0PE=
github.com/go-faster/yaml v0.4.6 h1:lOK/EhI04gCpPgPhgt0bChS6bvw7G3WwI8xxVe0sw9I=
github.com/go-faster/yaml v0.4.6/go.mod h1:390dRIvV4zbnO7qC9FGo6YYutc+wyyUSHBgbXL52eXk=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s=
github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y=
github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY=
github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0=
github.com/go-openapi/spec v0.22.6 h1:Tyy1pLaNCM8GBCFLoGYLonjJi6zykqyLCjXLc19ZPic=
github.com/go-openapi/spec v0.22.6/go.mod h1:HZvTHat+iH0PALQRWhrqIHtU/PEqxqd89fu0MxGlMeM=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag/conv v0.27.0 h1:EKOH4feXrvdo8DbSsXSAqRT8fz1epEnS5O2IfXUOzE8=
github.com/go-openapi/swag/conv v0.27.0/go.mod h1:pfiv0uKQTbaGApk8Zs/lZV3uSjmSpa2FO1y183YngN8=
github.com/go-openapi/swag/jsonname v0.27.0 h1:4QVB//CKOdE8IOiBg19JNY2wfDS48MhesIquYBy2rUE=
github.com/go-openapi/swag/jsonname v0.27.0/go.mod h1:I1YsyvvhBuZsFXSW6I7ODfdyq13p7hDil//1T9/pFFk=
github.com/go-openapi/swag/jsonutils v0.27.0 h1:VYtd9jEQYeU4j8q5vdn5KWotF4vKywhGdMBrALtAsfE=
github.com/go-openapi/swag/jsonutils v0.27.0/go.mod h1:U7pb8AGuwhok3RDicHeHwSG4L3PXSq6PAL98Aon632g=
github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.0 h1:+d7C7Ur/SsGg/UZ9G0JEovnfRqtMNZCJQGKc2h/ojoE=
github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.0/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY=
github.com/go-openapi/swag/loading v0.27.0 h1:s8DA9aPEdFH6OluHUYUn3DnIuoTdyWs9RwffXBUfyeI=
github.com/go-openapi/swag/loading v0.27.0/go.mod h1:VOz+Jg6UGGywcmRvYsI4fvtp+bd7NfioseGEPleYdA4=
github.com/go-openapi/swag/stringutils v0.27.0 h1:Of7w/HljWsNZvuxsUAnw3n+hCOyI6HLJOxW2kQRAxio=
github.com/go-openapi/swag/stringutils v0.27.0/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM=
github.com/go-openapi/swag/typeutils v0.27.0 h1:aCf4MSGo8NLwZP8Q6t32DWLJSvl/WwNqgmEG+xJ6v2o=
github.com/go-openapi/swag/typeutils v0.27.0/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ=
github.com/go-openapi/swag/yamlutils v0.27.0 h1:bQ6eAMil5X9tdcf7dMn4t15alzG6jddnrKPuKa/zxKM=
github.com/go-openapi/swag/yamlutils v0.27.0/go.mod h1:yRfIo7qqVkmJRQjX8exjA3AfcI8rH1KDNPsTparoCv4=
github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0=
github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo=
github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug=
github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.30.3 h1:4MU6YkEwx7GbcPJOZxrtbu+QfF3pJLJuaYTeAH0DYy8=
github.com/go-playground/validator/v10 v10.30.3/go.mod h1:4Axh7oCNGcoGkqLoE4YWt6n20mcEIsPRlB7vPk3lpyc=
github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0=
github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4=
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI=
github.com/klauspost/compress v1.17.6/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ=
github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/cpuid/v2 v2.4.0 h1:S6Hrbc7+ywsr0r+RLapfGBHfyefhCTwEh3A0tV913Dw=
github.com/klauspost/cpuid/v2 v2.4.0/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/nats-io/nats.go v1.37.0 h1:07rauXbVnnJvv1gfIyghFEo6lUcYRY0WXc3x7x0vUxE=
github.com/nats-io/nats.go v1.37.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI=
github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY=
github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.23 h1:cYwCQTQf3HB6xUC+BtyCLZNr7IzbOmoZbmssVNzSyiQ=
github.com/mattn/go-isatty v0.0.23/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/nats-io/nats.go v1.52.0 h1:n3avV4VBsCgsdwh71TppsTwtv+QdPs7ntSKM8qJLGsc=
github.com/nats-io/nats.go v1.52.0/go.mod h1:26HypzazeOkyO3/mqd1zZd53STJN0EjCYF9Uy2ZOBno=
github.com/nats-io/nkeys v0.4.16 h1:rd5oAuLOb8mnAycB0xleuEBNS1pVVnN0fv/FF34Eypg=
github.com/nats-io/nkeys v0.4.16/go.mod h1:llLgWoI0o4z/Q57q2R1kHfmocyhGV6VG/U18Glg1Afs=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/ogen-go/ogen v1.2.1 h1:C5A0lvUMu2wl+eWIxnpXMWnuOJ26a2FyzR1CIC2qG0M=
github.com/ogen-go/ogen v1.2.1/go.mod h1:P2zQdEu8UqaVRfD5GEFvl+9q63VjMLvDquq1wVbyInM=
github.com/ogen-go/ogen v1.23.0 h1:QaWeKm2KZ2zy7NkqqO1Vdl5idNqlG+svxdgwVAX+zbo=
github.com/ogen-go/ogen v1.23.0/go.mod h1:bwwvC3AmCV+LrL5lazyQwwof90402mdcSyI0FOzzpfM=
github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY=
github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/quic-go/go-ossfuzz-seeds v0.1.0 h1:APacT+iIaNF6fd8AGEiN3bT/Jtkd2jz4v4TzM7MFjy0=
github.com/quic-go/go-ossfuzz-seeds v0.1.0/go.mod h1:3IOHRbJIc+L6YKMwfDtJAM9Vj9k0YY4muhuyUYk5tbk=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
github.com/quic-go/quic-go v0.60.0 h1:xcQioE8OM66UQLeUMHltK1CCcOu3JbVB4JAQdDQSB+0=
github.com/quic-go/quic-go v0.60.0/go.mod h1:wpKpjmPpftl30sL6pFh7REVpjbcCVy4zt2vDyK1TuJk=
github.com/redis/go-redis/v9 v9.21.0 h1:FPBE4hhbAke+TLmcY3WkpbDffJEomdqPn3HYiqAtL9E=
github.com/redis/go-redis/v9 v9.21.0/go.mod h1:v/M13XI1PVCDcm01VtPFOADfZtHf8YW3baQf57KlIkA=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0=
github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
github.com/swaggo/gin-swagger v1.6.1 h1:Ri06G4gc9N4t4k8hekMigJ9zKTFSlqj/9paAQCQs7cY=
github.com/swaggo/gin-swagger v1.6.1/go.mod h1:LQ+hJStHakCWRiK/YNYtJOu4mR2FP+pxLnILT/qNiTw=
github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI=
github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU=
github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4=
github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 h1:FnBeRrxr7OU4VvAzt5X7s6266i6cSVkkFPS0TuXWbIg=
github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=
github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s=
go.mongodb.org/mongo-driver/v2 v2.8.0 h1:CxWDGQYY8QQwNjAl/aq2sfWakdnWZynnqJ9F4DhHbP8=
go.mongodb.org/mongo-driver/v2 v2.8.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo=
go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/arch v0.29.0 h1:8sSET5wB0+exBm0FGmOtdHMqjlRdV2DRD3/IV6OZgho=
golang.org/x/arch v0.29.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597 h1:qLvzZeaANDgyVOA8pyHCOStGlXn0rseXma+GQjeuv2g=
golang.org/x/exp v0.0.0-20260709172345-9ea1abe57597/go.mod h1:EdfpwwqSu+0Li0mzskwHU6FWDV3t9Q+RZDo3QMUtL3Q=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE=
golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260715232425-e75dac1f907d h1:Jkpk39hlTZOIp3RbfvNX9R8Hv+Sw0X89nlU/xFOErsc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260715232425-e75dac1f907d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.5.10 h1:7Lggqempgy496c0WfHXsYWxk3Th+ZcW66/21QhVFdeE=
gorm.io/driver/postgres v1.5.10/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4=
gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo=
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
gorm.io/gorm v1.21.11/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s=
gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
gorm.io/gorm v1.31.2 h1:3o8FXNo9v9S858gil+3LlZA1LkCOzgb4g5BL64FgaCo=
gorm.io/gorm v1.31.2/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
-862
View File
@@ -1,862 +0,0 @@
openapi: 3.1.0
info:
title: StrafesNET Internal - OpenAPI 3.1
description: Internal operations inaccessible from the public internet.
version: 0.1.0
tags:
- name: Mapfixes
description: Mapfix operations
- name: Submissions
description: Submission operations
paths:
/mapfixes:
post:
summary: Create a mapfix
operationId: createMapfix
tags:
- Mapfixes
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/MapfixCreate'
responses:
"201":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/MapfixID"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/validated-model:
post:
summary: Update validated model
operationId: updateMapfixValidatedModel
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
- name: ValidatedModelID
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
- name: ValidatedModelVersion
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/validator-submitted:
post:
summary: (Internal endpoint) Role Validator changes status from Submitting -> Submitted
operationId: actionMapfixSubmitted
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
- name: ModelVersion
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
- name: DisplayName
in: query
required: true
schema:
type: string
maxLength: 128
- name: Creator
in: query
required: true
schema:
type: string
maxLength: 128
- name: GameID
in: query
required: true
schema:
type: integer
format: int32
minimum: 0
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/validator-request-changes:
post:
summary: (Internal endpoint) Role Validator changes status from Submitting -> ChangesRequested
operationId: actionMapfixRequestChanges
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
- name: ErrorMessage
in: query
required: true
schema:
type: string
minLength: 0
maxLength: 4096
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/validator-validated:
post:
summary: (Internal endpoint) Role Validator changes status from Validating -> Validated
operationId: actionMapfixValidated
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/validator-failed:
post:
summary: (Internal endpoint) Role Validator changes status from Validating -> Accepted
operationId: actionMapfixAccepted
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
- name: ErrorMessage
in: query
required: true
schema:
type: string
minLength: 0
maxLength: 4096
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/validator-uploaded:
post:
summary: (Internal endpoint) Role Validator changes status from Uploading -> Uploaded
operationId: actionMapfixUploaded
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/operations/{OperationID}/status/operation-failed:
post:
summary: (Internal endpoint) Fail an operation and write a StatusMessage
operationId: actionOperationFailed
tags:
- Operations
parameters:
- $ref: '#/components/parameters/OperationID'
- name: StatusMessage
in: query
required: true
schema:
type: string
minLength: 0
maxLength: 4096
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions:
post:
summary: Create a new submission
operationId: createSubmission
tags:
- Submissions
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/SubmissionCreate'
responses:
"201":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/SubmissionID"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/validated-model:
post:
summary: Update validated model
operationId: updateSubmissionValidatedModel
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
- name: ValidatedModelID
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
- name: ValidatedModelVersion
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/validator-submitted:
post:
summary: (Internal endpoint) Role Validator changes status from Submitting -> Submitted
operationId: actionSubmissionSubmitted
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
- name: ModelVersion
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
- name: DisplayName
in: query
required: true
schema:
type: string
maxLength: 128
- name: Creator
in: query
required: true
schema:
type: string
maxLength: 128
- name: GameID
in: query
required: true
schema:
type: integer
format: int32
minimum: 0
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/validator-request-changes:
post:
summary: (Internal endpoint) Role Validator changes status from Submitting -> ChangesRequested
operationId: actionSubmissionRequestChanges
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
- name: ErrorMessage
in: query
required: true
schema:
type: string
minLength: 0
maxLength: 4096
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/validator-validated:
post:
summary: (Internal endpoint) Role Validator changes status from Validating -> Validated
operationId: actionSubmissionValidated
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/validator-failed:
post:
summary: (Internal endpoint) Role Validator changes status from Validating -> Accepted
operationId: actionSubmissionAccepted
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
- name: ErrorMessage
in: query
required: true
schema:
type: string
minLength: 0
maxLength: 4096
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/validator-uploaded:
post:
summary: (Internal endpoint) Role Validator changes status from Uploading -> Uploaded
operationId: actionSubmissionUploaded
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
- name: UploadedAssetID
in: query
required: true
schema:
type: integer
format: int64
minimum: 0
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/script-policy:
get:
summary: Get list of script policies
operationId: listScriptPolicy
tags:
- ScriptPolicy
parameters:
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/Limit"
- name: FromScriptHash
in: query
schema:
type: string
minLength: 16
maxLength: 16
- name: ToScriptID
in: query
schema:
type: integer
format: int64
minimum: 0
- name: Policy
in: query
schema:
type: integer
format: int32
minimum: 0
responses:
"200":
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/ScriptPolicy"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a new script policy
operationId: createScriptPolicy
tags:
- ScriptPolicy
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptPolicyCreate'
responses:
"201":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/ScriptPolicyID"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/scripts:
get:
summary: Get list of scripts
operationId: listScripts
tags:
- Script
parameters:
- $ref: "#/components/parameters/Page"
- $ref: "#/components/parameters/Limit"
- name: Hash
in: query
schema:
type: string
minLength: 16
maxLength: 16
- name: Name
in: query
schema:
type: string
maxLength: 128
- name: Source
in: query
schema:
type: string
maxLength: 1048576
- name: ResourceType
in: query
schema:
type: integer
format: int32
minimum: 0
- name: ResourceID
in: query
schema:
type: integer
format: int64
minimum: 0
responses:
"200":
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Script"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a new script
operationId: createScript
tags:
- Scripts
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptCreate'
responses:
"201":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/ScriptID"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/scripts/{ScriptID}:
get:
summary: Get the specified script by ID
operationId: getScript
tags:
- Scripts
parameters:
- $ref: '#/components/parameters/ScriptID'
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/Script"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
parameters:
MapfixID:
name: MapfixID
in: path
required: true
description: The unique identifier for a submission.
schema:
type: integer
format: int64
minimum: 0
OperationID:
name: OperationID
in: path
required: true
description: The unique identifier for a long-running operation.
schema:
type: integer
format: int32
minimum: 0
SubmissionID:
name: SubmissionID
in: path
required: true
description: The unique identifier for a submission.
schema:
type: integer
format: int64
minimum: 0
ScriptID:
name: ScriptID
in: path
required: true
description: The unique identifier for a script.
schema:
type: integer
format: int64
minimum: 0
Page:
name: Page
in: query
required: true
schema:
type: integer
format: int32
minimum: 1
Limit:
name: Limit
in: query
required: true
schema:
type: integer
format: int32
minimum: 1
maximum: 100
schemas:
MapfixID:
required:
- MapfixID
type: object
properties:
MapfixID:
type: integer
format: int64
minimum: 0
SubmissionID:
required:
- SubmissionID
type: object
properties:
SubmissionID:
type: integer
format: int64
minimum: 0
ScriptID:
required:
- ScriptID
type: object
properties:
ScriptID:
type: integer
format: int64
minimum: 0
ScriptPolicyID:
required:
- ScriptPolicyID
type: object
properties:
ScriptPolicyID:
type: integer
format: int64
minimum: 0
MapfixCreate:
required:
- OperationID
- AssetOwner
- DisplayName
- Creator
- GameID
- AssetID
- AssetVersion
- TargetAssetID
- Description
type: object
properties:
OperationID:
type: integer
format: int32
minimum: 0
AssetOwner:
type: integer
format: int64
minimum: 0
DisplayName:
type: string
maxLength: 128
Creator:
type: string
maxLength: 128
GameID:
type: integer
format: int32
minimum: 0
AssetID:
type: integer
format: int64
minimum: 0
AssetVersion:
type: integer
format: int64
minimum: 0
TargetAssetID:
type: integer
format: int64
minimum: 0
Description:
type: string
maxLength: 256
SubmissionCreate:
required:
- OperationID
- AssetOwner
- DisplayName
- Creator
- GameID
- AssetID
- AssetVersion
- Status
- Roles
type: object
properties:
OperationID:
type: integer
format: int32
minimum: 0
AssetOwner:
type: integer
format: int64
minimum: 0
DisplayName:
type: string
maxLength: 128
Creator:
type: string
maxLength: 128
GameID:
type: integer
format: int32
minimum: 0
AssetID:
type: integer
format: int64
minimum: 0
AssetVersion:
type: integer
format: int64
minimum: 0
Status:
type: integer
format: uint32
minimum: 0
maximum: 9
Roles:
type: integer
format: uint32
Script:
required:
- ID
- Name
- Hash
- Source
- ResourceType
- ResourceID
type: object
properties:
ID:
type: integer
format: int64
minimum: 0
Name:
type: string
maxLength: 128
Hash:
type: string
minLength: 16
maxLength: 16
Source:
type: string
maxLength: 1048576
ResourceType:
type: integer
format: int32
minimum: 0
ResourceID:
type: integer
format: int64
minimum: 0
ScriptCreate:
required:
- Name
- Source
- ResourceType
# - ResourceID
type: object
properties:
Name:
type: string
maxLength: 128
Source:
type: string
maxLength: 1048576
ResourceType:
type: integer
format: int32
minimum: 0
ResourceID:
type: integer
format: int64
minimum: 0
ScriptPolicy:
required:
- ID
- FromScriptHash
- ToScriptID
- Policy
type: object
properties:
ID:
type: integer
format: int64
minimum: 0
FromScriptHash:
type: string
minLength: 16
maxLength: 16
ToScriptID:
type: integer
format: int64
minimum: 0
Policy:
type: integer
format: int32
minimum: 0
ScriptPolicyCreate:
required:
- FromScriptID
- ToScriptID
- Policy
type: object
properties:
FromScriptID:
type: integer
format: int64
minimum: 0
ToScriptID:
type: integer
format: int64
minimum: 0
Policy:
type: integer
format: int32
minimum: 0
Error:
description: Represents error object
type: object
properties:
code:
type: integer
format: int64
minimum: 0
message:
type: string
required:
- code
- message
+601 -6
View File
@@ -14,15 +14,41 @@ tags:
description: Long-running operations
- name: Session
description: Session queries
- name: Stats
description: Statistics queries
- name: Submissions
description: Submission operations
- name: Scripts
description: Script operations
- name: ScriptPolicy
description: Script policy operations
- name: Thumbnails
description: Thumbnail operations
- name: Users
description: User operations
security:
- cookieAuth: []
paths:
/stats:
get:
summary: Get aggregate statistics
operationId: getStats
tags:
- Stats
security: []
responses:
"200":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/Stats"
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/session/user:
get:
summary: Get information about the currently logged in user
@@ -114,6 +140,13 @@ paths:
format: int32
minimum: 0
maximum: 4
description: >
Sort order:
* `0` - Disabled
* `1` - DisplayNameAscending
* `2` - DisplayNameDescending
* `3` - DateAscending
* `4` - DateDescending
responses:
"200":
description: Successful response
@@ -151,6 +184,72 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/maps/{MapID}/combobulate:
post:
summary: Queue a map for combobulator processing
operationId: combobulateMap
tags:
- Maps
parameters:
- name: MapID
in: path
required: true
schema:
type: integer
format: int64
minimum: 0
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/maps/{MapID}/download:
get:
summary: Download the map asset
operationId: downloadMapAsset
tags:
- Maps
parameters:
- name: MapID
in: path
required: true
schema:
type: integer
format: int64
minimum: 0
responses:
"200":
description: Successful response
content:
application/octet-stream:
schema:
type: string
format: binary
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/maps-admin/seed-combobulator:
post:
summary: Queue all maps for combobulator processing
operationId: seedCombobulator
tags:
- Maps
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes:
get:
summary: Get list of mapfixes
@@ -178,6 +277,11 @@ paths:
format: int32
minimum: 1
maximum: 5
description: >
Game ID:
* `1` - Bhop
* `2` - Surf
* `5` - FlyTrials
- name: Sort
in: query
schema:
@@ -185,6 +289,13 @@ paths:
format: int32
minimum: 0
maximum: 4
description: >
Sort order:
* `0` - Disabled
* `1` - DisplayNameAscending
* `2` - DisplayNameDescending
* `3` - DateAscending
* `4` - DateDescending
- name: Submitter
in: query
schema:
@@ -197,6 +308,12 @@ paths:
type: integer
format: int64
minimum: 0
- name: AssetVersion
in: query
schema:
type: integer
format: int64
minimum: 0
- name: TargetAssetID
in: query
schema:
@@ -210,6 +327,24 @@ paths:
format: int32
minimum: 0
maximum: 9
description: >
// Phase: Creation
* `0` - UnderConstruction
* `1` - ChangesRequested
// Phase: Review
* `2` - Submitting
* `3` - Submitted
// Phase: Testing
* `4` - AcceptedUnvalidated // pending script review, can re-trigger validation
* `5` - Validating
* `6` - Validated
* `7` - Uploading
// Phase: Final MapfixStatus
* `8` - Uploaded // uploaded to the group, but pending release
* `9` - Rejected
responses:
"200":
description: Successful response
@@ -269,6 +404,22 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
delete:
summary: Delete a mapfix
operationId: deleteMapfix
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/audit-events:
get:
summary: Retrieve a list of audit events
@@ -350,6 +501,30 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/description:
patch:
summary: Update description (submitter only)
operationId: updateMapfixDescription
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
requestBody:
required: true
content:
text/plain:
schema:
type: string
maxLength: 256
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/completed:
post:
summary: Called by maptest when a player completes the map
@@ -384,6 +559,23 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/trigger-submit-unchecked:
post:
summary: Role Reviewer changes status from ChangesRequested -> Submitting
operationId: actionMapfixTriggerSubmitUnchecked
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/reset-submitting:
post:
summary: Role Submitter manually resets submitting softlock and changes status from Submitting -> UnderConstruction
@@ -505,7 +697,7 @@ paths:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/trigger-upload:
post:
summary: Role Admin changes status from Validated -> Uploading
summary: Role MapfixUpload changes status from Validated -> Uploading
operationId: actionMapfixTriggerUpload
tags:
- Mapfixes
@@ -522,7 +714,7 @@ paths:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/reset-uploading:
post:
summary: Role Admin manually resets uploading softlock and changes status from Uploading -> Validated
summary: Role MapfixUpload manually resets uploading softlock and changes status from Uploading -> Validated
operationId: actionMapfixValidated
tags:
- Mapfixes
@@ -537,6 +729,40 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/trigger-release:
post:
summary: Role MapfixUpload changes status from Uploaded -> Releasing
operationId: actionMapfixTriggerRelease
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/mapfixes/{MapfixID}/status/reset-releasing:
post:
summary: Role MapfixUpload manually resets releasing softlock and changes status from Releasing -> Uploaded
operationId: actionMapfixUploaded
tags:
- Mapfixes
parameters:
- $ref: '#/components/parameters/MapfixID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/operations/{OperationID}:
get:
summary: Retrieve operation with ID
@@ -585,6 +811,11 @@ paths:
format: int32
minimum: 1
maximum: 5
description: >
Game ID:
* `1` - Bhop
* `2` - Surf
* `5` - FlyTrials
- name: Sort
in: query
schema:
@@ -592,6 +823,13 @@ paths:
format: int32
minimum: 0
maximum: 4
description: >
Sort order:
* `0` - Disabled
* `1` - DisplayNameAscending
* `2` - DisplayNameDescending
* `3` - DateAscending
* `4` - DateDescending
- name: Submitter
in: query
schema:
@@ -604,6 +842,12 @@ paths:
type: integer
format: int64
minimum: 0
- name: AssetVersion
in: query
schema:
type: integer
format: int64
minimum: 0
- name: UploadedAssetID
in: query
schema:
@@ -617,6 +861,25 @@ paths:
format: int32
minimum: 0
maximum: 10
description: >
// Phase: Creation
* `0` - UnderConstruction
* `1` - ChangesRequested
// Phase: Review
* `2` - Submitting
* `3` - Submitted
// Phase: Testing
* `4` - AcceptedUnvalidated // pending script review, can re-trigger validation
* `5` - Validating
* `6` - Validated
* `7` - Uploading
* `8` - Uploaded // uploaded to the group, but pending release
// Phase: Final SubmissionStatus
* `9` - Rejected
* `10` - Released
responses:
"200":
description: Successful response
@@ -701,6 +964,22 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
delete:
summary: Delete a submission
operationId: deleteSubmission
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/audit-events:
get:
summary: Retrieve a list of audit events
@@ -816,6 +1095,23 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/trigger-submit-unchecked:
post:
summary: Role Reviewer changes status from ChangesRequested -> Submitting
operationId: actionSubmissionTriggerSubmitUnchecked
tags:
- Submissions
parameters:
- $ref: '#/components/parameters/SubmissionID'
responses:
"204":
description: Successful response
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/reset-submitting:
post:
summary: Role Submitter manually resets submitting softlock and changes status from Submitting -> UnderConstruction
@@ -937,7 +1233,7 @@ paths:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/trigger-upload:
post:
summary: Role Admin changes status from Validated -> Uploading
summary: Role SubmissionUpload changes status from Validated -> Uploading
operationId: actionSubmissionTriggerUpload
tags:
- Submissions
@@ -954,7 +1250,7 @@ paths:
$ref: "#/components/schemas/Error"
/submissions/{SubmissionID}/status/reset-uploading:
post:
summary: Role Admin manually resets uploading softlock and changes status from Uploading -> Validated
summary: Role SubmissionUpload manually resets uploading softlock and changes status from Uploading -> Validated
operationId: actionSubmissionValidated
tags:
- Submissions
@@ -971,7 +1267,7 @@ paths:
$ref: "#/components/schemas/Error"
/release-submissions:
post:
summary: Release a set of uploaded maps
summary: Release a set of uploaded maps. Role SubmissionRelease
operationId: releaseSubmissions
tags:
- Submissions
@@ -988,6 +1284,10 @@ paths:
responses:
"201":
description: Successful response
content:
application/json:
schema:
$ref: "#/components/schemas/OperationID"
default:
description: General Error
content:
@@ -1258,6 +1558,222 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/thumbnails/assets:
post:
summary: Batch fetch asset thumbnails
operationId: batchAssetThumbnails
tags:
- Thumbnails
security: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- assetIds
properties:
assetIds:
type: array
items:
type: integer
format: uint64
maxItems: 100
description: Array of asset IDs (max 100)
size:
type: string
enum:
- "150x150"
- "420x420"
- "768x432"
default: "420x420"
description: Thumbnail size
responses:
"200":
description: Successful response
content:
application/json:
schema:
type: object
properties:
thumbnails:
type: object
additionalProperties:
type: string
description: Map of asset ID to thumbnail URL
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/thumbnails/asset/{AssetID}:
get:
summary: Get single asset thumbnail
operationId: getAssetThumbnail
tags:
- Thumbnails
security: []
parameters:
- name: AssetID
in: path
required: true
schema:
type: integer
format: uint64
- name: size
in: query
schema:
type: string
enum:
- "150x150"
- "420x420"
- "768x432"
default: "420x420"
responses:
"302":
description: Redirect to thumbnail URL
headers:
Location:
description: URL to redirect to
schema:
type: string
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/thumbnails/users:
post:
summary: Batch fetch user avatar thumbnails
operationId: batchUserThumbnails
tags:
- Thumbnails
security: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- userIds
properties:
userIds:
type: array
items:
type: integer
format: uint64
maxItems: 100
description: Array of user IDs (max 100)
size:
type: string
enum:
- "150x150"
- "420x420"
- "768x432"
default: "150x150"
description: Thumbnail size
responses:
"200":
description: Successful response
content:
application/json:
schema:
type: object
properties:
thumbnails:
type: object
additionalProperties:
type: string
description: Map of user ID to thumbnail URL
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/thumbnails/user/{UserID}:
get:
summary: Get single user avatar thumbnail
operationId: getUserThumbnail
tags:
- Thumbnails
security: []
parameters:
- name: UserID
in: path
required: true
schema:
type: integer
format: uint64
- name: size
in: query
schema:
type: string
enum:
- "150x150"
- "420x420"
- "768x432"
default: "150x150"
responses:
"302":
description: Redirect to thumbnail URL
headers:
Location:
description: URL to redirect to
schema:
type: string
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/usernames:
post:
summary: Batch fetch usernames
operationId: batchUsernames
tags:
- Users
security: []
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- userIds
properties:
userIds:
type: array
items:
type: integer
format: uint64
maxItems: 100
description: Array of user IDs (max 100)
responses:
"200":
description: Successful response
content:
application/json:
schema:
type: object
properties:
usernames:
type: object
additionalProperties:
type: string
description: Map of user ID to username
default:
description: General Error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
securitySchemes:
cookieAuth:
@@ -1435,6 +1951,13 @@ components:
- Creator
- GameID
- Date
- CreatedAt
- UpdatedAt
- Submitter
- Thumbnail
- AssetVersion
- LoadCount
- Modes
type: object
properties:
ID:
@@ -1455,6 +1978,27 @@ components:
type: integer
format: int64
minimum: 0
CreatedAt:
type: integer
format: int64
UpdatedAt:
type: integer
format: int64
Submitter:
type: integer
format: uint64
Thumbnail:
type: integer
format: uint64
AssetVersion:
type: integer
format: uint64
LoadCount:
type: integer
format: uint32
Modes:
type: integer
format: uint32
Mapfix:
required:
- ID
@@ -1466,6 +2010,8 @@ components:
- Submitter
- AssetID
- AssetVersion
# - ValidatedAssetID
# - ValidatedAssetVersion
- Completed
- TargetAssetID
- StatusID
@@ -1506,6 +2052,14 @@ components:
type: integer
format: int64
minimum: 0
ValidatedAssetID:
type: integer
format: int64
minimum: 0
ValidatedAssetVersion:
type: integer
format: int64
minimum: 0
Completed:
type: boolean
TargetAssetID:
@@ -1744,7 +2298,7 @@ components:
properties:
Name:
type: string
maxLength: 128
maxLength: 256
Source:
type: string
maxLength: 1048576
@@ -1843,6 +2397,47 @@ components:
type: integer
format: int32
minimum: 0
Stats:
description: Aggregate statistics for submissions and mapfixes
type: object
properties:
TotalSubmissions:
type: integer
format: int64
minimum: 0
description: Total number of submissions
TotalMapfixes:
type: integer
format: int64
minimum: 0
description: Total number of mapfixes
ReleasedSubmissions:
type: integer
format: int64
minimum: 0
description: Number of released submissions
ReleasedMapfixes:
type: integer
format: int64
minimum: 0
description: Number of released mapfixes
SubmittedSubmissions:
type: integer
format: int64
minimum: 0
description: Number of submissions under review
SubmittedMapfixes:
type: integer
format: int64
minimum: 0
description: Number of mapfixes under review
required:
- TotalSubmissions
- TotalMapfixes
- ReleasedSubmissions
- ReleasedMapfixes
- SubmittedSubmissions
- SubmittedMapfixes
Error:
description: Represents error object
type: object
+53 -18
View File
@@ -4,15 +4,16 @@ package api
import (
"net/http"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/trace"
"strings"
ht "github.com/ogen-go/ogen/http"
"github.com/ogen-go/ogen/middleware"
"github.com/ogen-go/ogen/ogenerrors"
"github.com/ogen-go/ogen/otelogen"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/trace"
)
var (
@@ -32,6 +33,7 @@ type otelConfig struct {
Tracer trace.Tracer
MeterProvider metric.MeterProvider
Meter metric.Meter
Attributes []attribute.KeyValue
}
func (cfg *otelConfig) initOTEL() {
@@ -81,18 +83,8 @@ func (o otelOptionFunc) applyServer(c *serverConfig) {
func newServerConfig(opts ...ServerOption) serverConfig {
cfg := serverConfig{
NotFound: http.NotFound,
MethodNotAllowed: func(w http.ResponseWriter, r *http.Request, allowed string) {
status := http.StatusMethodNotAllowed
if r.Method == "OPTIONS" {
w.Header().Set("Access-Control-Allow-Methods", allowed)
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
status = http.StatusNoContent
} else {
w.Header().Set("Allow", allowed)
}
w.WriteHeader(status)
},
NotFound: http.NotFound,
MethodNotAllowed: nil,
ErrorHandler: ogenerrors.DefaultErrorHandler,
Middleware: nil,
MaxMultipartMemory: 32 << 20, // 32 MB
@@ -115,8 +107,44 @@ func (s baseServer) notFound(w http.ResponseWriter, r *http.Request) {
s.cfg.NotFound(w, r)
}
func (s baseServer) notAllowed(w http.ResponseWriter, r *http.Request, allowed string) {
s.cfg.MethodNotAllowed(w, r, allowed)
type notAllowedParams struct {
allowedMethods string
allowedHeaders map[string]string
acceptPost string
acceptPatch string
}
func (s baseServer) notAllowed(w http.ResponseWriter, r *http.Request, params notAllowedParams) {
h := w.Header()
isOptions := r.Method == "OPTIONS"
if isOptions {
h.Set("Access-Control-Allow-Methods", params.allowedMethods)
if params.allowedHeaders != nil {
m := r.Header.Get("Access-Control-Request-Method")
if m != "" {
allowedHeaders, ok := params.allowedHeaders[strings.ToUpper(m)]
if ok {
h.Set("Access-Control-Allow-Headers", allowedHeaders)
}
}
}
if params.acceptPost != "" {
h.Set("Accept-Post", params.acceptPost)
}
if params.acceptPatch != "" {
h.Set("Accept-Patch", params.acceptPatch)
}
}
if s.cfg.MethodNotAllowed != nil {
s.cfg.MethodNotAllowed(w, r, params.allowedMethods)
return
}
status := http.StatusNoContent
if !isOptions {
h.Set("Allow", params.allowedMethods)
status = http.StatusMethodNotAllowed
}
w.WriteHeader(status)
}
func (cfg serverConfig) baseServer() (s baseServer, err error) {
@@ -215,6 +243,13 @@ func WithMeterProvider(provider metric.MeterProvider) Option {
})
}
// WithAttributes specifies default otel attributes.
func WithAttributes(attributes ...attribute.KeyValue) Option {
return otelOptionFunc(func(cfg *otelConfig) {
cfg.Attributes = attributes