Skip to content

Commit 9c1a252

Browse files
Merge pull request #2934 from appwrite/chore/usage-update
feat: add realtime connections and messages metrics to usage reports
2 parents 68af21b + 36336c5 commit 9c1a252

File tree

14 files changed

+377
-17
lines changed

14 files changed

+377
-17
lines changed

bun.lock

Lines changed: 10 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
},
2121
"dependencies": {
2222
"@ai-sdk/svelte": "^1.1.24",
23-
"@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@83fd10c",
23+
"@appwrite.io/console": "https://pkg.vc/-/@appwrite/@appwrite.io/console@d223f36",
2424
"@appwrite.io/pink-icons": "0.25.0",
2525
"@appwrite.io/pink-icons-svelte": "https://pkg.vc/-/@appwrite/@appwrite.io/pink-icons-svelte@bfe7ce3",
2626
"@appwrite.io/pink-legacy": "^1.0.3",
@@ -41,7 +41,7 @@
4141
"flatted": "^3.4.2",
4242
"ignore": "^6.0.2",
4343
"nanoid": "^5.1.7",
44-
"nanotar": "^0.1.1",
44+
"nanotar": "^0.3.0",
4545
"pretty-bytes": "^6.1.1",
4646
"remarkable": "^2.0.1",
4747
"svelte-confetti": "^1.4.0",
@@ -91,8 +91,11 @@
9191
"overrides": {
9292
"vite": "npm:rolldown-vite@latest",
9393
"minimatch": "10.2.3",
94+
"brace-expansion": ">=5.0.5",
9495
"immutable": "^5.1.5",
9596
"flatted": "^3.4.2",
96-
"picomatch": "^2.3.2"
97+
"yaml": "^1.10.3",
98+
"picomatch": "^2.3.2",
99+
"cookie": "^0.7.0"
97100
}
98101
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<script lang="ts">
2+
import { base } from '$app/paths';
3+
import { browser } from '$app/environment';
4+
import { HeaderAlert } from '$lib/layout';
5+
import { organization, currentPlan } from '$lib/stores/organization';
6+
import { Button } from '$lib/elements/forms';
7+
8+
const DISMISS_KEY = 'realtimePricingDismissed';
9+
10+
let dismissed = browser && localStorage.getItem(DISMISS_KEY) === 'true';
11+
12+
function handleDismiss() {
13+
dismissed = true;
14+
if (browser) {
15+
localStorage.setItem(DISMISS_KEY, 'true');
16+
}
17+
}
18+
19+
$: href = $currentPlan?.usagePerProject
20+
? `${base}/organization-${$organization.$id}/billing`
21+
: `${base}/organization-${$organization.$id}/usage`;
22+
</script>
23+
24+
{#if $organization?.$id && !dismissed}
25+
<HeaderAlert
26+
type="info"
27+
title="Realtime pricing enforcement starting April 30th"
28+
dismissible
29+
on:dismiss={handleDismiss}>
30+
<svelte:fragment>
31+
Starting April 30th, realtime usage (connections, messages, and bandwidth) will be
32+
charged based on your plan's rates. Review your usage to avoid unexpected charges.
33+
</svelte:fragment>
34+
<svelte:fragment slot="buttons">
35+
<Button {href} text fullWidthMobile>
36+
<span class="text">View usage</span>
37+
</Button>
38+
</svelte:fragment>
39+
</HeaderAlert>
40+
{/if}

src/lib/components/billing/usageRates.svelte

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,7 @@
6767
{/each}
6868
{#each Object.entries(org.billingPlanDetails.usage) as [key, usage]}
6969
{@const limit = getPlanLimit(key)}
70-
{@const show = limit !== false}
71-
{#if show}
70+
{#if limit !== false}
7271
<Table.Row.Base {root}>
7372
<Table.Cell column="resource" {root}>{usage.name}</Table.Cell>
7473
<Table.Cell column="limit" {root}>
@@ -82,6 +81,18 @@
8281
</Table.Cell>
8382
{/if}
8483
</Table.Row.Base>
84+
{:else if usage.price > 0}
85+
<Table.Row.Base {root}>
86+
<Table.Cell column="resource" {root}>{usage.name}</Table.Cell>
87+
<Table.Cell column="limit" {root}>Pay-as-you-go</Table.Cell>
88+
{#if !isFree}
89+
<Table.Cell column="rate" {root}>
90+
{formatCurrency(usage.price)}/{abbreviateNumber(
91+
usage.value
92+
)}{usage.unit}
93+
</Table.Cell>
94+
{/if}
95+
</Table.Row.Base>
8596
{/if}
8697
{/each}
8798
</Table.Root>

src/lib/components/git/selectRootModal.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
113113
const iconName =
114114
product === 'sites'
115-
? detection.framework
115+
? (detection as unknown as Models.DetectionFramework).framework
116116
: (detection as unknown as Models.DetectionRuntime).runtime;
117117
const resolved = resolveIconUrl(iconName);
118118
iconCache.set(path, resolved);

src/lib/stores/billing.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ export type PlanServices =
191191
| 'platforms'
192192
| 'realtime'
193193
| 'realtimeAddon'
194+
| 'realtimeMessages'
194195
| 'storage'
195196
| 'storageAddon'
196197
| 'teams'
@@ -274,6 +275,7 @@ export function checkForUsageFees(plan: string, id: PlanServices) {
274275
case 'users':
275276
case 'executions':
276277
case 'realtime':
278+
case 'realtimeMessages':
277279
return true;
278280

279281
default:

src/routes/(console)/organization-[organization]/+layout.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Breadcrumbs from './breadcrumbs.svelte';
88
import Header from './header.svelte';
99
import { headerAlert } from '$lib/stores/headerAlert';
1010
import ProjectsAtRisk from '$lib/components/billing/alerts/projectsAtRisk.svelte';
11+
import RealtimePricing from '$lib/components/billing/alerts/realtimePricing.svelte';
1112
import { get } from 'svelte/store';
1213
import { preferences } from '$lib/stores/preferences';
1314
import { defaultRoles, defaultScopes } from '$lib/constants';
@@ -64,6 +65,15 @@ export const load: LayoutLoad = async ({ params, depends, parent }) => {
6465
loadAvailableRegions(params.organization)
6566
]);
6667

68+
if (isCloud && new Date() < new Date('2026-04-22')) {
69+
headerAlert.add({
70+
show: true,
71+
component: RealtimePricing,
72+
id: 'realtimePricing',
73+
importance: 1
74+
});
75+
}
76+
6777
return {
6878
header: Header,
6979
breadcrumbs: Breadcrumbs,

src/routes/(console)/organization-[organization]/billing/planSummary.svelte

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,27 @@
361361
getResource(resources, 'GBHours'),
362362
currentPlan?.GBHours
363363
),
364+
createResourceRow(
365+
'realtime',
366+
'Realtime connections',
367+
getResource(resources, 'realtime'),
368+
currentPlan?.realtime
369+
),
370+
createResourceRow(
371+
'realtime-messages',
372+
'Realtime messages',
373+
getResource(resources, 'realtimeMessages'),
374+
currentPlan?.realtimeMessages
375+
),
376+
createRow({
377+
id: 'realtime-bandwidth',
378+
label: 'Realtime bandwidth',
379+
resource: getResource(resources, 'realtimeBandwidth'),
380+
usageFormatter: ({ value }) =>
381+
humanFileSize(value).value + humanFileSize(value).unit,
382+
priceFormatter: ({ amount }) => formatCurrency(amount),
383+
includeProgress: false
384+
}),
364385
createRow({
365386
id: 'sms',
366387
label: 'Phone OTP',

0 commit comments

Comments
 (0)