-
Notifications
You must be signed in to change notification settings - Fork 197
Add charts for sites/functions usage #2517
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
🚅 Deployed to the console-pr-2517 environment in Imagine
|
ConsoleProject ID: Tip Cursor pagination performs better than offset pagination when loading further pages. |
|
Warning Rate limit exceeded@hmacr has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 44 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (4)
WalkthroughReplaces stacked total+label layout with a horizontally row-aligned stack and adds an explicit empty-state UI (icon + "No data to show") when datasets are empty in src/lib/layout/usage.svelte. Multiple route pages under src/routes/(console) changed to derive paths via resolve, switch metrics from deployments/builds to executions, compute GB-hours by converting buildsMbSeconds + executionsMbSeconds to hours (totals and per-sample counts), and aggregate bandwidth from inbound/outbound. Pages now render additional Usage blocks for GB hours and a bandwidth Card with a BarChart that conditionally shows data or the empty-state. Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/lib/layout/usage.svelte (2)
43-47: TS type mismatch: parameter defaults to null but typed as Date.This won’t type-check under strict TS.
-export function accumulateFromEndingTotal( - metrics: Models.Metric[], - endingTotal: number, - startingDayToFillZero: Date = null -): Array<[string, number]> { +export function accumulateFromEndingTotal( + metrics: Models.Metric[], + endingTotal: number, + startingDayToFillZero: Date | null = null +): Array<[string, number]> {Also, strongly type the accumulator’s data array:
- { - total: endingTotal, - data: [] - } + { + total: endingTotal, + data: [] as Array<[string, number]> + }
5-32: Fix UTC/local mixing in periodToDates function—confirmed bugs at lines 11, 16, 19.The code mixes local timezone getters (
getHours(),getDate()) with UTC setters (setUTCHours(),setUTCDate()), causing incorrect date calculations:
- Line 11:
start.setUTCHours(start.getHours() - 24)— getHours() is local, not UTC- Line 16:
start.setUTCDate(start.getDate() - 30)— getDate() is local, not UTC- Line 19: Same issue for 90d case
Use
getUTC*()methods ornew Date(now.getTime() - offset)arithmetic instead.Regarding the 24h end boundary: the review suggests
end=nowinstead ofend=next_UTC_midnight. This change requires verification against the API contract forproject.getUsage()to ensure it accepts aligned vs. real-time boundaries for theOneHourperiod type.export function periodToDates(period: UsagePeriods): { start: string; end: string; period: ProjectUsageRange; } { - const start = new Date(); - switch (period) { - case '24h': - start.setUTCHours(start.getHours() - 24); - break; - case '30d': - start.setUTCHours(0, 0, 0, 0); - start.setUTCDate(start.getDate() - 30); - break; - case '90d': - start.setUTCHours(0, 0, 0, 0); - start.setUTCDate(start.getDate() - 90); - break; - } - const end = new Date(); - end.setUTCDate(end.getUTCDate() + 1); - end.setUTCHours(0, 0, 0, 0); - return { - start: start.toISOString(), - end: end.toISOString(), - period: period === '24h' ? ProjectUsageRange.OneHour : ProjectUsageRange.OneDay - }; + const now = new Date(); + if (period === '24h') { + const start = new Date(now.getTime() - 24 * 60 * 60 * 1000); + return { + start: start.toISOString(), + end: now.toISOString(), + period: ProjectUsageRange.OneHour + }; + } + // daily buckets + const end = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1, 0, 0, 0, 0)); + const start = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 0, 0, 0, 0)); + start.setUTCDate(start.getUTCDate() - (period === '30d' ? 30 : 90)); + return { + start: start.toISOString(), + end: end.toISOString(), + period: ProjectUsageRange.OneDay + }; }
🧹 Nitpick comments (8)
src/lib/layout/usage.svelte (2)
34-41: Align helper signatures with nullish usage.Both helpers guard against undefined/null but are typed as non-null arrays.
-export function last(set: Models.Metric[]): Models.Metric | null { - if (!set) return null; - return set.slice(-1)[0] ?? null; -} - -export function total(set: Models.Metric[]): number { - return set?.reduce((prev, curr) => prev + curr.value, 0) ?? 0; -} +export function last(set: Models.Metric[] | null | undefined): Models.Metric | null { + if (!set?.length) return null; + return set[set.length - 1]; +} + +export function total(set: Models.Metric[] | null | undefined): number { + return set?.reduce((prev, curr) => prev + curr.value, 0) ?? 0; +}
138-143: Empty state UX is clear and consistent.Icon + concise copy looks good. Consider adding aria-hidden on the icon if not already handled by the component.
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte (2)
22-22: Avoid rendering a bandwidth card with permanent “No data”.
bandwidth = []renders an empty-state card always. Either wire real data or conditionally hide the card.-$: bandwidth = []; +$: bandwidth = data.bandwidth ?? [];Optionally gate the entire Card with
{#if bandwidth.length}.
1-1: Prettier is failing CI.Run repository formatter to unblock CI:
- pnpm:
pnpm exec prettier --write .- npm:
npx prettier --write .[pipeline_failures]
src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte (1)
1-1: Prettier is failing CI.Run:
pnpm exec prettier --write .(ornpx prettier --write .).
[pipeline_failures]src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte (1)
1-1: Prettier is failing CI.Run:
pnpm exec prettier --write ..
[pipeline_failures]src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte (2)
21-21: Bandwidth card renders permanent empty state.Wire real data or hide the card when unavailable.
-$: bandwidth = []; +$: bandwidth = data.bandwidth ?? [];Optionally wrap the Card in
{#if bandwidth.length}to avoid UI noise.
1-1: Prettier is failing CI.Run:
pnpm exec prettier --write ..
[pipeline_failures]
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/lib/layout/usage.svelte(3 hunks)src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte(1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Tests
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte
[error] 1-1: Prettier formatting check failed. Run 'prettier --write' to fix code style issues in this file.
src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte
[error] 1-1: Prettier formatting check failed. Run 'prettier --write' to fix code style issues in this file.
src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte
[error] 1-1: Prettier formatting check failed. Run 'prettier --write' to fix code style issues in this file.
src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte
[error] 1-1: Prettier formatting check failed. Run 'prettier --write' to fix code style issues in this file.
🔇 Additional comments (4)
src/lib/layout/usage.svelte (1)
121-125: Nice horizontal alignment for headline/label.Readability improves with row layout and baseline alignment.
src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte (1)
15-22: Verify data structures and intended aggregation behavior before applying fix.The review raises a valid structural concern: if
buildsMbSecondsandexecutionsMbSecondscontain entries for the same dates, concatenating them would duplicate those dates. However, verification depends on the actual data:
- Overlapping dates: Do both arrays contain entries for the same dates? (If builds and executions are tracked per-date, they likely do.)
- Intended aggregation: Should the chart display merged totals per date, or separate builds/executions series? The
Usagecomponent receives a singlecountarray, suggesting merge intent.- MB-to-GB conversion: The constant
1000is correct per SI standard;1024(binary/IEC) is not standard for network/storage metrics.The same concatenation pattern appears in:
src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte(line 16)src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte(line 16)src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte(line 16)src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte(line 16)And for bandwidth:
- Line 23:
[...data.inbound, ...data.outbound]uses the same pattern.Confirm whether these should be merged per date or if separate series are intentional.
src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte (1)
15-21: Add missing.filter()call; verify date-merging requirement with API response structure.The code snippet in the review is incomplete. The target file is missing
.filter(({ value }) => value);that appears in analogous usage pages (/functions/usage,/sites/usage,/sites/site-[site]/usage). This filter should be added after the map on line 20.Regarding the suggested
mergeByDatelogic: this assumes overlapping dates exist in bothdata.buildsMbSecondsanddata.executionsMbSecondsarrays. Verify with the API response structure whether the two arrays can share the same dates before implementing aggregation. If they do, the merge-by-date approach is valid; otherwise, the current spread pattern may be sufficient.Constants
MB_PER_GB(1000) andSECONDS_PER_HOUR(3600) are correct.src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte (1)
15-22: Same GB-hours aggregation issue: merge per date + sort before scaling.-$: gbHoursTotal = (data.buildsMbSecondsTotal + data.executionsMbSecondsTotal) / 1000 / 3600; -$: gbHoursCount = [...data.buildsMbSeconds, ...data.executionsMbSeconds] - ?.map((metric) => ({ - ...metric, - value: metric.value / 1000 / 3600 - })) - .filter(({ value }) => value); +const mergeByDate = (...sets: { date: string; value: number }[][]) => { + const acc = new Map<string, number>(); + for (const s of sets) for (const m of s ?? []) acc.set(m.date, (acc.get(m.date) ?? 0) + m.value); + return [...acc.entries()] + .map(([date, value]) => ({ date, value })) + .sort((a, b) => Date.parse(a.date) - Date.parse(b.date)); +}; +const MB_PER_GB = 1000; // verify 1000 vs 1024 +const SECONDS_PER_HOUR = 3600; +$: gbHoursTotal = (data.buildsMbSecondsTotal + data.executionsMbSecondsTotal) / MB_PER_GB / SECONDS_PER_HOUR; +$: gbHoursCount = mergeByDate(data.buildsMbSeconds, data.executionsMbSeconds).map(({ date, value }) => ({ + date, + value: value / MB_PER_GB / SECONDS_PER_HOUR +}));
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte
Outdated
Show resolved
Hide resolved
src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte
Outdated
Show resolved
Hide resolved
src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte
Outdated
Show resolved
Hide resolved
...sole)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte
Show resolved
Hide resolved
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte
Show resolved
Hide resolved
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte
Outdated
Show resolved
Hide resolved
src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (5)
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte (2)
15-22: Resolve GB-hours aggregation defects.The GB-hours series is still built by concatenating two datasets, creating duplicate dates, removing zeroes, and leaving the chart unsorted. Please reuse the merge-by-date helper so the chart reflects accurate totals.
22-22: Aggregate bandwidth per date.
bandwidth = [...data.inbound, ...data.outbound]duplicates categories instead of summing inbound+outbound per day. Reuse the same merge helper so each date has one combined value.src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte (1)
22-22: Combine inbound/outbound bandwidth instead of concatenating.Just spreading
data.inboundanddata.outboundyields two bars for the same day. Sum them per date via the merge helper so bandwidth totals are meaningful.src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte (1)
22-22: Deduplicate bandwidth categories.The bandwidth card still concatenates inbound/outbound arrays, producing duplicate categories. Aggregate by date (sum inbound+outbound) so users see the true total per day.
src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte (1)
15-22: Fix GB-hours series aggregation and ordering.Lines 15-22 concatenate
buildsMbSecondsandexecutionsMbSeconds, duplicate dates, drop zero values, and leave the chart unsorted. The totals/visualization become incorrect. Merge by date, keep zero entries, and sort chronologically before converting to GB-hours.- let gbHoursTotal = $derived((data.buildsMbSecondsTotal + data.executionsMbSecondsTotal) / 1000 / 3600); - let gbHoursCount = $derived([...data.buildsMbSeconds, ...data.executionsMbSeconds] - ?.map((metric) => ({ - ...metric, - value: metric.value / 1000 / 3600 - })) - .filter(({ value }) => value)); + const MB_PER_GB = 1000; + const SECONDS_PER_HOUR = 3600; + const mergeByDate = (...sets: { date: string; value: number }[][]) => { + const acc = new Map<string, number>(); + for (const set of sets ?? []) { + for (const metric of set ?? []) { + acc.set(metric.date, (acc.get(metric.date) ?? 0) + metric.value); + } + } + return [...acc.entries()] + .map(([date, value]) => ({ date, value })) + .sort((a, b) => Date.parse(a.date) - Date.parse(b.date)); + }; + + let gbHoursTotal = $derived( + (data.buildsMbSecondsTotal + data.executionsMbSecondsTotal) / MB_PER_GB / SECONDS_PER_HOUR + ); + let gbHoursCount = $derived( + mergeByDate(data.buildsMbSeconds, data.executionsMbSeconds).map(({ date, value }) => ({ + date, + value: value / MB_PER_GB / SECONDS_PER_HOUR + })) + );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-08-31T05:32:42.285Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2284
File: src/lib/components/searchQuery.svelte:26-27
Timestamp: 2025-08-31T05:32:42.285Z
Learning: SvelteKit automatically enables Svelte 5 runes without requiring explicit "use runes" directive or runes: true configuration when using Svelte 5.
Applied to files:
src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte
📚 Learning: 2025-10-13T05:16:07.656Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte:54-58
Timestamp: 2025-10-13T05:16:07.656Z
Learning: In SvelteKit apps, shared layout components (like headers) that use `$derived(page.data.*)` should use optional chaining when accessing properties that may not be present on all routes. During page transitions, reactive statements can briefly evaluate with different page.data structures, so optional chaining prevents runtime errors when navigating between routes with different data shapes (e.g., between `/databases` and `/databases/database-[database]`).
Applied to files:
src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte
📚 Learning: 2025-10-26T10:24:30.198Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2509
File: src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte:106-127
Timestamp: 2025-10-26T10:24:30.198Z
Learning: In Svelte, string attributes support direct variable interpolation using `{variable}` syntax within quoted strings. For example, `href="https://example.com/{slug}"` and `target="{label} key"` are valid Svelte syntax and will interpolate the variables correctly. This is different from JSX/React which requires template literals.
Applied to files:
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte
🪛 GitHub Actions: Tests
src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte
[warning] 1-1: Code style issues found by Prettier. Run 'prettier --write' to fix.
src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte
[warning] 1-1: Code style issues found by Prettier. Run 'prettier --write' to fix.
src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte
[warning] 1-1: Code style issues found by Prettier. Run 'prettier --write' to fix.
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte
[warning] 1-1: Code style issues found by Prettier. Run 'prettier --write' to fix.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: e2e
...sole)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte
Outdated
Show resolved
Hide resolved
src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte
Outdated
Show resolved
Hide resolved
src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (3)
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte (1)
9-15: Merge series by date and sort before converting to GB-hours.This is the same issue flagged in the previous review: concatenating
buildsMbSecondsandexecutionsMbSecondscreates duplicate dates when both arrays have entries for the same date, leading to incorrect totals. Additionally, filtering zero values breaks chart continuity, and the lack of sorting can scramble the chronological order.Apply the fix from the previous review across all affected files.
src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte (2)
15-21: Merge series by date and sort before converting to GB-hours.This is the same issue flagged in the previous review: concatenating
buildsMbSecondsandexecutionsMbSecondscreates duplicate dates when both arrays have entries for the same date, leading to incorrect totals. Additionally, filtering zero values breaks chart continuity, and the lack of sorting can scramble the chronological order.Apply the fix from the previous review across all affected files.
22-22: Aggregate inbound and outbound bandwidth by date.This is the same issue flagged in the previous review: concatenating
inboundandoutboundarrays without merging by date produces duplicate date entries when both arrays contain data for the same dates, leading to incorrect visualizations.Apply the merge-by-date fix from the previous review.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte(1 hunks)src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- src/routes/(console)/project-[region]-[project]/sites/usage/[[period]]/+page.svelte
- src/routes/(console)/project-[region]-[project]/functions/function-[function]/usage/[[period]]/+page.svelte
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte:54-58
Timestamp: 2025-10-13T05:16:07.656Z
Learning: In SvelteKit apps, shared layout components (like headers) that use `$derived(page.data.*)` should use optional chaining when accessing properties that may not be present on all routes. During page transitions, reactive statements can briefly evaluate with different page.data structures, so optional chaining prevents runtime errors when navigating between routes with different data shapes (e.g., between `/databases` and `/databases/database-[database]`).
📚 Learning: 2025-10-26T10:24:30.198Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2509
File: src/routes/(console)/project-[region]-[project]/overview/(components)/table.svelte:106-127
Timestamp: 2025-10-26T10:24:30.198Z
Learning: In Svelte, string attributes support direct variable interpolation using `{variable}` syntax within quoted strings. For example, `href="https://example.com/{slug}"` and `target="{label} key"` are valid Svelte syntax and will interpolate the variables correctly. This is different from JSX/React which requires template literals.
Applied to files:
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte
📚 Learning: 2025-10-13T05:16:07.656Z
Learnt from: ItzNotABug
Repo: appwrite/console PR: 2413
File: src/routes/(console)/project-[region]-[project]/databases/database-[database]/header.svelte:54-58
Timestamp: 2025-10-13T05:16:07.656Z
Learning: In SvelteKit apps, shared layout components (like headers) that use `$derived(page.data.*)` should use optional chaining when accessing properties that may not be present on all routes. During page transitions, reactive statements can briefly evaluate with different page.data structures, so optional chaining prevents runtime errors when navigating between routes with different data shapes (e.g., between `/databases` and `/databases/database-[database]`).
Applied to files:
src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte
🪛 GitHub Actions: Tests
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte
[error] 1-1: Prettier formatting issues detected. Run 'prettier --write' to fix.
src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte
[error] 1-1: Prettier formatting issues detected. Run 'prettier --write' to fix.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: e2e
🔇 Additional comments (3)
src/routes/(console)/project-[region]-[project]/functions/usage/[[period]]/+page.svelte (1)
17-20: LGTM! Path derivation usingresolveis type-safe and follows best practices.Using
resolvewith route parameters provides type safety and autocompletion, as requested in previous feedback.src/routes/(console)/project-[region]-[project]/sites/site-[site]/usage/[[period]]/+page.svelte (2)
24-28: LGTM! Path derivation usingresolveis type-safe and follows best practices.Using
resolvewith route parameters provides type safety and autocompletion, as requested in previous feedback.
51-91: Bandwidth Card implementation looks good overall.The Card correctly displays humanized bandwidth totals and conditionally renders either a BarChart with proper formatting or an empty state. The use of
{@const}for the humanized value is appropriate, and the tooltip/axis formatters ensure consistent display.However, the underlying
bandwidthdata has the concatenation issue flagged separately (Line 22), which will affect this visualization.Once the bandwidth merge-by-date fix is applied, verify that the BarChart correctly displays aggregated bandwidth over time.

Task: https://linear.app/appwrite/issue/SER-476/add-charts-for-sitesfunctions-usage
Summary by CodeRabbit
New Features
Improvements