From eeed4e572d9d9c476931af0178ccd797ef598b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois-Xavier=20Talbot?= <108630700+fetchfern@users.noreply.github.com> Date: Mon, 20 Oct 2025 18:35:44 +0100 Subject: [PATCH] Credit subscriptions (#4575) * Implement subscription crediting * chore: query cache, clippy, fmt * Improve code, improve query for next open charge * chore: query cache, clippy, fmt * Move server ID copy button up * Node + region crediting * Make it less ugly * chore: query cache, clippy, fmt * Bugfixes * Fix lint * Adjust migration * Adjust migration * Remove billing change * Move DEFAULT_CREDIT_EMAIL_MESSAGE to utils.ts * Lint * Merge * bump clickhouse, disable validation * tombi fmt * Update cargo lock --- .../src/composables/servers/servers-fetch.ts | 6 +- apps/frontend/src/layouts/default.vue | 7 + .../frontend/src/pages/admin/billing/[id].vue | 87 +++++- .../src/pages/admin/servers/nodes.vue | 277 ++++++++++++++++++ .../emails/account/SubscriptionCredited.vue | 25 ++ apps/frontend/src/templates/emails/index.ts | 1 + ...38164e4d79734c17c07111f8923f2faa517bf.json | 19 ++ ...08ef679e6638e57e4711c2c215f32e691d856.json | 27 ++ ...18fca60c293ad349eaec07b573d22a28301c.json} | 4 +- ...323aa502ce9feb3f439a614bb7759dcb03b23.json | 58 ++++ ...000_subscription-credited-notification.sql | 44 +++ .../src/database/models/charge_item.rs | 5 +- apps/labrinth/src/database/models/mod.rs | 1 + .../database/models/user_subscription_item.rs | 26 ++ .../models/users_subscriptions_credits.rs | 82 ++++++ apps/labrinth/src/lib.rs | 9 +- apps/labrinth/src/models/v2/notifications.rs | 23 ++ apps/labrinth/src/models/v3/notifications.rs | 19 ++ apps/labrinth/src/queue/email/templates.rs | 47 +++ apps/labrinth/src/routes/internal/billing.rs | 237 +++++++++++++++ apps/labrinth/src/util/archon.rs | 54 ++++ packages/utils/utils.ts | 2 + 22 files changed, 1052 insertions(+), 8 deletions(-) create mode 100644 apps/frontend/src/pages/admin/servers/nodes.vue create mode 100644 apps/frontend/src/templates/emails/account/SubscriptionCredited.vue create mode 100644 apps/labrinth/.sqlx/query-3d05de766a0987028d465a3305938164e4d79734c17c07111f8923f2faa517bf.json create mode 100644 apps/labrinth/.sqlx/query-68968755bd5eacce9009d1d873d08ef679e6638e57e4711c2c215f32e691d856.json rename apps/labrinth/.sqlx/{query-ead967d7a8e268a583eb44900a5ef7c45548b4cf3d8cb6545aad801f9fcc5a56.json => query-91866517bf34fb8bf31a7a49832b18fca60c293ad349eaec07b573d22a28301c.json} (92%) create mode 100644 apps/labrinth/.sqlx/query-aafa63e08f9d556dcd55c4687f0323aa502ce9feb3f439a614bb7759dcb03b23.json create mode 100644 apps/labrinth/migrations/20251017120000_subscription-credited-notification.sql create mode 100644 apps/labrinth/src/database/models/users_subscriptions_credits.rs diff --git a/apps/frontend/src/composables/servers/servers-fetch.ts b/apps/frontend/src/composables/servers/servers-fetch.ts index 06340781..b46db7da 100644 --- a/apps/frontend/src/composables/servers/servers-fetch.ts +++ b/apps/frontend/src/composables/servers/servers-fetch.ts @@ -6,7 +6,7 @@ export interface ServersFetchOptions { method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' contentType?: string body?: Record - version?: number + version?: number | 'internal' override?: { url?: string token?: string @@ -82,7 +82,9 @@ export async function useServersFetch( ? `https://${newOverrideUrl}/${path.replace(/^\//, '')}` : version === 0 ? `${base}/modrinth/v${version}/${path.replace(/^\//, '')}` - : `${base}/v${version}/${path.replace(/^\//, '')}` + : version === 'internal' + ? `${base}/_internal/${path.replace(/^\//, '')}` + : `${base}/modrinth/v${version}/${path.replace(/^\//, '')}` const headers: Record = { 'User-Agent': 'Modrinth/1.0 (https://modrinth.com)', diff --git a/apps/frontend/src/layouts/default.vue b/apps/frontend/src/layouts/default.vue index c7031d67..3e75317b 100644 --- a/apps/frontend/src/layouts/default.vue +++ b/apps/frontend/src/layouts/default.vue @@ -461,6 +461,12 @@ link: '/admin/servers/notices', shown: isAdmin(auth.user), }, + { + id: 'servers-nodes', + color: 'primary', + link: '/admin/servers/nodes', + shown: isAdmin(auth.user), + }, ]" >