Files
classroomio/apps/docs/blume.config.ts
T
Rotimi BestandRotimi Best 2ebb544a81 fix(dashboard): cache org stats in Redis with versioned invalidation (#883)
* fix(dashboard): cache org stats in Redis with versioned invalidation

Replace the never-expiring process-local cache in the org dashboard page
load with API-side Redis caching keyed per org. A version stamp prevents
slow reads from writing pre-purge data back into the cache.

Invalidate on course create/update/delete, student enroll/remove, certificate
claim, and progress reset. Remove the dashboard SSR module cache so every
page load reads through the API cache layer.

Fixes #852

Co-authored-by: Rotimi Best <[email protected]>

* fix(dashboard): address PR review on stats cache invalidation

- Validate bust via ZDashStats instead of raw query access
- Use import type for OrganisationAnalytics
- Resolve orgId before course delete so invalidation is reliable
- Invalidate immediately after persisted writes, before fallible side effects
- Invalidate on member role changes and program course access enrollment

Co-authored-by: Rotimi Best <[email protected]>

* fix(dashboard): complete stats cache invalidation coverage

Wire org stats cache purge on lesson completion (manual toggle and
video-watch auto-complete) so topCourses completion percentages stay
fresh. Harden bulk member adds with sequential inserts and a finally
invalidation boundary, and only purge org invite enrollments when new
group memberships were actually inserted.

Co-authored-by: Rotimi Best <[email protected]>

* fix(core): make lesson completion stats purge best-effort

Wrap org stats cache invalidation in try/catch so a lookup or Redis
failure cannot turn a successful lesson completion into a 500.

Co-authored-by: Rotimi Best <[email protected]>

* fix(dashboard): keep org stats cache through lesson completion

Lesson complete is a high-frequency event and usually does not change
the rounded dashboard percentages. Rely on a 10 minute TTL instead of
purging the snapshot on every completion.

Co-authored-by: Rotimi Best <[email protected]>

* docs: explain how admin dashboard numbers are calculated

Add a user-facing guide covering headline counts, top courses,
certificates, login activity, and when the 10 minute snapshot refreshes.

Co-authored-by: Rotimi Best <[email protected]>

---------
2026-08-16 22:15:34 +01:00

219 lines
6.3 KiB
TypeScript

import { defineConfig } from 'blume';
/**
* The site is served at classroomio.com/docs, proxied to this worker by the
* marketing site (apps/website/src/hooks.server.ts). `deployment.base` only
* rewrites URLs in the emitted HTML — it does not nest the build output, so
* scripts/package-assets.mjs moves dist/ under docs/ to match the served path.
*
* Redirects are NOT declared here: under a base, Astro prefixes a redirect's
* source but not its target, so it would emit `url=/guides` instead of
* `/docs/guides`. They live in scripts/package-assets.mjs as a `_redirects` file.
*/
export default defineConfig({
title: 'ClassroomIO Docs | Customer, Partner, and Employee Education',
description:
'Learn how to create customer academies, partner certification programs, and employee training workflows in ClassroomIO.',
logo: {
text: 'ClassroomIO',
image: '/docs/logo-192.png',
href: '/docs'
},
content: {
root: 'content/docs'
},
deployment: {
output: 'static',
site: 'https://classroomio.com',
base: '/docs'
},
github: {
owner: 'classroomio',
repo: 'classroomio',
dir: 'apps/docs'
},
theme: {
mode: 'system'
},
search: {
provider: 'orama'
},
ai: {
llmsTxt: true
},
seo: {
x: {
creator: '@classroomio',
handle: '@classroomio'
}
},
openapi: {
enabled: true,
renderer: 'scalar',
route: '/api',
sources: [{ label: 'API', spec: './openapi/public-api.json' }]
},
navigation: {
tabs: [
{ label: 'Platform', path: '/', icon: 'house' },
{ label: 'Guides', path: '/guides', icon: 'book-open' },
{ label: 'Self Hosting', path: '/self-hosted', icon: 'server' },
{ label: 'API', path: '/api', icon: 'code' }
],
sidebar: [
{
label: 'Platform',
items: [
'/',
{
label: 'Introduction',
items: [
'/what-is-classroomio',
'/terminology',
{
label: 'Quickstart',
items: ['/quickstart/signup', '/quickstart/onboarding']
}
]
},
{
label: 'Core Features',
items: [
'/course',
'/cohorts',
'/mcp',
'/tags',
'/audience',
'/community',
'/organization',
'/student-dashboard',
'/enterprise-sso',
'/token-auth'
]
}
]
},
{
label: 'Guides',
root: '/guides',
items: [
'/guides',
{
label: '', // User Guides
items: [
{
label: 'Get started',
items: ['/guides/create-first-course']
},
{
label: 'Build a course',
items: [
'/guides/course-types',
'/guides/create-exercise',
'/guides/grade-exercise',
'/guides/course-progression',
'/guides/use-math-in-editor',
'/guides/certificates'
]
},
{
label: 'Live classes',
items: ['/guides/live-class', '/guides/take-attendance']
},
{
label: 'Enrollment & students',
items: [
'/guides/course-enrollment',
'/guides/welcome-email',
'/guides/invite-students'
]
},
{
label: 'Publish your academy',
items: [
'/guides/course-landingpage',
'/guides/org-landing-page',
'/guides/academy-sharing-and-branding',
'/guides/custom-domain'
]
},
{
label: 'Organization & team',
items: [
'/guides/admin-dashboard',
'/guides/customize-organization',
'/guides/invite-team-member',
'/guides/roles-and-permissions'
]
}
]
},
{
label: 'Developer Guides',
items: [
'/guides/contributing',
'/guides/contributing/devs',
'/guides/contributing/design',
'/guides/contributing/cloudflare-setup',
'/guides/contributing/org-site-opengraph-and-favicon',
'/guides/contributing/gitpod',
'/guides/contributing/demo-accounts',
'/guides/contributing/student-dashboard',
'/guides/contributing/adding-translation-to-code'
]
}
]
},
{
label: 'Self Hosting',
root: '/self-hosted',
items: [
'/self-hosted',
'/self-hosted/101',
'/self-hosted/architecture',
{
label: 'Install',
display: 'group',
// Pinned open — it's what most visitors came for. The other groups
// start collapsed (and auto-expand when they contain the current page).
collapsed: false,
items: [
'/self-hosted/docker',
'/self-hosted/digitalocean',
'/self-hosted/railway',
'/self-hosted/coolify',
'/self-hosted/dokploy'
]
},
{
label: 'Configure',
display: 'group',
collapsed: true,
items: [
'/self-hosted/configuration',
'/self-hosted/configuration/secrets',
'/self-hosted/configuration/email',
'/self-hosted/configuration/storage',
'/self-hosted/configuration/csp',
'/self-hosted/configuration/integrations',
'/self-hosted/enterprise'
]
},
{
label: 'Manage',
display: 'group',
collapsed: true,
items: ['/self-hosted/configuration/versions', '/self-hosted/backups']
},
{
label: 'Troubleshoot',
display: 'group',
collapsed: true,
items: ['/self-hosted/troubleshooting']
}
]
}
]
}
});