This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git


The following commit(s) were added to refs/heads/master by this push:
     new 634f9524b2a [feat] add weekly report (#3966)
634f9524b2a is described below

commit 634f9524b2a932ae7b89ad888e3a898ff6421782
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Sun Jul 5 21:04:22 2026 +0800

    [feat] add weekly report (#3966)
    
    Co-authored-by: Claude Opus 4.8 <[email protected]>
---
 .../materialized-view/intro-link.mdx               |  13 +
 .../materialized-view/intro-link.mdx               |  13 +
 .../materialized-view/intro-link.mdx               |  13 +
 scripts/check_move.js                              |  99 ++-
 scripts/check_move.test.js                         |  62 ++
 sidebars.ts                                        |  43 +-
 .../community-report-next/CommunityReportNext.scss | 176 +++++
 .../community-report-next/CommunityReportNext.tsx  | 489 ++++++++++++++
 .../community-report-next/WeeklyReport.scss        | 726 +++++++++++++++++++++
 src/components/home-next/NavbarNext.tsx            |  13 +-
 src/pages/community-report/_reports/2026-06-29.mdx | 205 ++++++
 src/pages/community-report/_reports/_TEMPLATE.mdx  |  35 +
 src/pages/community-report/index.tsx               |  33 +
 .../materialized-view/intro-link.mdx               |  13 +
 versioned_sidebars/version-4.x-sidebars.json       |  55 +-
 15 files changed, 1938 insertions(+), 50 deletions(-)

diff --git a/docs/query-acceleration/materialized-view/intro-link.mdx 
b/docs/query-acceleration/materialized-view/intro-link.mdx
new file mode 100644
index 00000000000..0c7f678d3d8
--- /dev/null
+++ b/docs/query-acceleration/materialized-view/intro-link.mdx
@@ -0,0 +1,13 @@
+---
+{
+    "title": "Materialized View",
+    "language": "en",
+    "description": "Apache Doris materialized view chapter navigation: covers 
concepts, synchronous materialized views, asynchronous materialized views, 
transparent rewriting, and FAQs."
+}
+---
+
+import GettingStartedCard from 
'@site/src/components/getting-started-card/getting-started-card';
+
+A materialized view is an entity that contains both computation logic and 
data. You can use it for query acceleration, lightweight ETL modeling, and 
lakehouse federated query acceleration. Start by understanding the concepts, 
then choose between synchronous and asynchronous materialized views based on 
your freshness requirements.
+
+Please refer to the [materialized view](./intro) related documentation.
diff --git 
a/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/intro-link.mdx
 
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/intro-link.mdx
new file mode 100644
index 00000000000..a87f3adecc7
--- /dev/null
+++ 
b/i18n/zh-CN/docusaurus-plugin-content-docs/current/query-acceleration/materialized-view/intro-link.mdx
@@ -0,0 +1,13 @@
+---
+{
+    "title": "物化视图",
+    "language": "zh-CN",
+    "description": "Apache Doris 物化视图章节导航:覆盖概念、同步物化视图、异步物化视图、透明改写与常见问题。"
+}
+---
+
+import GettingStartedCard from 
'@site/src/components/getting-started-card/getting-started-card';
+
+物化视图是既包含计算逻辑、也包含数据的实体,可用于查询加速、轻量化 ETL 建模以及湖仓联邦查询加速。建议先理解概念,再根据时效性需求选择同步或异步物化视图。
+
+请参阅[物化视图](./intro)相关文档。
diff --git 
a/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/query-acceleration/materialized-view/intro-link.mdx
 
b/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/query-acceleration/materialized-view/intro-link.mdx
new file mode 100644
index 00000000000..a87f3adecc7
--- /dev/null
+++ 
b/i18n/zh-CN/docusaurus-plugin-content-docs/version-4.x/query-acceleration/materialized-view/intro-link.mdx
@@ -0,0 +1,13 @@
+---
+{
+    "title": "物化视图",
+    "language": "zh-CN",
+    "description": "Apache Doris 物化视图章节导航:覆盖概念、同步物化视图、异步物化视图、透明改写与常见问题。"
+}
+---
+
+import GettingStartedCard from 
'@site/src/components/getting-started-card/getting-started-card';
+
+物化视图是既包含计算逻辑、也包含数据的实体,可用于查询加速、轻量化 ETL 建模以及湖仓联邦查询加速。建议先理解概念,再根据时效性需求选择同步或异步物化视图。
+
+请参阅[物化视图](./intro)相关文档。
diff --git a/scripts/check_move.js b/scripts/check_move.js
index 198e645ce7e..3e4520c043d 100644
--- a/scripts/check_move.js
+++ b/scripts/check_move.js
@@ -95,13 +95,110 @@ function removeCodeBlocks(content) {
   return result;
 }
 
+function findEsmStatementEnd(content, start) {
+  let depth = 0;
+  let quote = null;
+  let escaping = false;
+  let inLineComment = false;
+  let inBlockComment = false;
+
+  for (let i = start; i < content.length; i++) {
+    const ch = content[i];
+    const next = content[i + 1];
+
+    if (quote) {
+      if (escaping) {
+        escaping = false;
+      } else if (ch === "\\") {
+        escaping = true;
+      } else if (ch === quote) {
+        quote = null;
+      }
+      continue;
+    }
+
+    if (inLineComment) {
+      if (ch === "\n") {
+        inLineComment = false;
+      }
+      continue;
+    }
+
+    if (inBlockComment) {
+      if (ch === "*" && next === "/") {
+        inBlockComment = false;
+        i++;
+      }
+      continue;
+    }
+
+    if (ch === "/" && next === "/") {
+      inLineComment = true;
+      i++;
+      continue;
+    }
+
+    if (ch === "/" && next === "*") {
+      inBlockComment = true;
+      i++;
+      continue;
+    }
+
+    if (ch === "\"" || ch === "'" || ch === "`") {
+      quote = ch;
+      continue;
+    }
+
+    if (ch === "{" || ch === "[" || ch === "(") {
+      depth++;
+      continue;
+    }
+
+    if (ch === "}" || ch === "]" || ch === ")") {
+      depth = Math.max(0, depth - 1);
+      continue;
+    }
+
+    if (ch === ";" && depth === 0) {
+      return i + 1;
+    }
+  }
+
+  return content.length;
+}
+
+function removeMdxEsmBlocks(content) {
+  const esmStartRegex = /^[ 
\t]*(?:import(?:\s|["'{*])|export\s+(?:const|let|var|function|class|default|\{|\*))/;
+  let result = "";
+  let cursor = 0;
+  let index = 0;
+
+  while (index < content.length) {
+    const lineEnd = content.indexOf("\n", index);
+    const end = lineEnd === -1 ? content.length : lineEnd;
+    const line = content.slice(index, end);
+
+    if (esmStartRegex.test(line)) {
+      const statementEnd = findEsmStatementEnd(content, index);
+      result += content.slice(cursor, index);
+      result += content.slice(index, statementEnd).replace(/[^\n]/g, "");
+      cursor = statementEnd;
+      index = statementEnd;
+      continue;
+    }
+
+    index = lineEnd === -1 ? content.length : lineEnd + 1;
+  }
+
+  return result + content.slice(cursor);
+}
 
 // Check links in files
 function checkFileLinks(filePath) {
   const content = fs.readFileSync(filePath, "utf-8");
   const dir = path.dirname(filePath);
 
-  const cleanedContent = removeCodeBlocks(content); 
+  const cleanedContent = removeMdxEsmBlocks(removeCodeBlocks(content));
   const matches = [...cleanedContent.matchAll(linkRegex)];
   for (const match of matches) {
     const rawLink = match[1].split("#")[0]; // Remove anchor point
diff --git a/scripts/check_move.test.js b/scripts/check_move.test.js
new file mode 100644
index 00000000000..ee6a9265221
--- /dev/null
+++ b/scripts/check_move.test.js
@@ -0,0 +1,62 @@
+const assert = require('node:assert/strict');
+const fs = require('node:fs');
+const os = require('node:os');
+const path = require('node:path');
+const test = require('node:test');
+const { execFileSync, spawnSync } = require('node:child_process');
+
+const scriptPath = path.join(__dirname, 'check_move.js');
+
+function createRepo(files) {
+  const repoDir = fs.mkdtempSync(path.join(os.tmpdir(), 'check-move-'));
+  execFileSync('git', ['init'], { cwd: repoDir, stdio: 'ignore' });
+  execFileSync('git', ['config', 'user.email', '[email protected]'], { cwd: 
repoDir });
+  execFileSync('git', ['config', 'user.name', 'Test User'], { cwd: repoDir });
+
+  for (const [filePath, content] of Object.entries(files)) {
+    const absolutePath = path.join(repoDir, filePath);
+    fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
+    fs.writeFileSync(absolutePath, content);
+  }
+
+  execFileSync('git', ['add', '.'], { cwd: repoDir });
+  execFileSync('git', ['commit', '-m', 'fixture'], { cwd: repoDir, stdio: 
'ignore' });
+  return repoDir;
+}
+
+test('ignores markdown-like PR titles inside MDX ESM exports', () => {
+  const repoDir = createRepo({
+    'src/pages/community-report/_reports/2026-06-29.mdx': `
+export const report = {
+  "prs": [
+    {
+      "title": "[feature](be) Add file scanner v2 readers",
+      "url": "https://github.com/apache/doris/pull/65046";
+    }
+  ]
+};
+`,
+  });
+
+  const result = spawnSync(process.execPath, [scriptPath, 'HEAD'], {
+    cwd: repoDir,
+    encoding: 'utf8',
+  });
+
+  assert.equal(result.status, 0, result.stderr || result.stdout);
+  assert.match(result.stdout, /All links are OK/);
+});
+
+test('reports broken local links in markdown prose', () => {
+  const repoDir = createRepo({
+    'docs/example.mdx': 'See [missing page](missing-page).\n',
+  });
+
+  const result = spawnSync(process.execPath, [scriptPath, 'HEAD'], {
+    cwd: repoDir,
+    encoding: 'utf8',
+  });
+
+  assert.equal(result.status, 1, result.stdout);
+  assert.match(result.stderr, /Broken link -> missing-page/);
+});
diff --git a/sidebars.ts b/sidebars.ts
index 80034d7c609..d784a1e332e 100644
--- a/sidebars.ts
+++ b/sidebars.ts
@@ -505,6 +505,27 @@ const sidebars: SidebarsConfig = {
                 'query-data/lateral-view',
             ],
         },
+        {
+            type: 'category',
+            label: 'Materialized View',
+            link: {type: 'doc', id: 
'query-acceleration/materialized-view/intro'},
+            items: [
+                'query-acceleration/materialized-view/overview',
+                'query-acceleration/materialized-view/sync-materialized-view',
+                
'query-acceleration/tuning/tuning-plan/transparent-rewriting-with-sync-mv',
+                {
+                    type: 'category',
+                    label: 'Async Materialized View',
+                    link: {type: 'doc', id: 
'query-acceleration/materialized-view/async-materialized-view/overview'},
+                    items: [
+                        
'query-acceleration/materialized-view/async-materialized-view/functions-and-demands',
+                        
'query-acceleration/materialized-view/async-materialized-view/use-guide',
+                        
'query-acceleration/tuning/tuning-plan/transparent-rewriting-with-async-mv',
+                        
'query-acceleration/materialized-view/async-materialized-view/faq',
+                    ],
+                },
+            ],
+        },
         {
             type: 'category',
             label: 'Performance & Tuning',
@@ -535,27 +556,7 @@ const sidebars: SidebarsConfig = {
                                 
'query-acceleration/tuning/tuning-plan/optimizing-table-scanning',
                             ],
                         },
-                        {
-                            type: 'category',
-                            label: 'Materialized View',
-                            link: {type: 'doc', id: 
'query-acceleration/materialized-view/intro'},
-                            items: [
-                                
'query-acceleration/materialized-view/overview',
-                                
'query-acceleration/materialized-view/sync-materialized-view',
-                                
'query-acceleration/tuning/tuning-plan/transparent-rewriting-with-sync-mv',
-                                {
-                                    type: 'category',
-                                    label: 'Async Materialized View',
-                                    link: {type: 'doc', id: 
'query-acceleration/materialized-view/async-materialized-view/overview'},
-                                    items: [
-                                        
'query-acceleration/materialized-view/async-materialized-view/functions-and-demands',
-                                        
'query-acceleration/materialized-view/async-materialized-view/use-guide',
-                                        
'query-acceleration/tuning/tuning-plan/transparent-rewriting-with-async-mv',
-                                        
'query-acceleration/materialized-view/async-materialized-view/faq',
-                                    ],
-                                },
-                            ],
-                        },
+                        'query-acceleration/materialized-view/intro-link',
                         {
                             type: 'category',
                             label: 'Join Optimization',
diff --git a/src/components/community-report-next/CommunityReportNext.scss 
b/src/components/community-report-next/CommunityReportNext.scss
new file mode 100644
index 00000000000..ea10173ba47
--- /dev/null
+++ b/src/components/community-report-next/CommunityReportNext.scss
@@ -0,0 +1,176 @@
+// Doc-style layout for the Community Report page: a sticky left sidebar
+// (Weekly Report section) plus a content area that renders the selected 
report.
+
+.community-report {
+    --cr-green: #06805F;
+    --cr-green-dark: #054C39;
+    --cr-ink: #0F1A14;
+    --cr-muted: #5A6472;
+    --cr-paper: #FFFCF5;
+    --cr-cream: #FAF6EE;
+    --cr-line: rgba(15, 26, 20, 0.10);
+    --cr-yellow: #FFD23F;
+    --cr-sidebar-w: 280px;
+    --cr-navbar-h: 64px;
+
+    min-height: 100vh;
+    background: var(--cr-paper);
+    color: var(--cr-ink);
+    font-family: var(--font-family-base);
+
+    * {
+        box-sizing: border-box;
+    }
+}
+
+.community-report__layout {
+    max-width: 1280px;
+    margin: 0 auto;
+    display: flex;
+    align-items: flex-start;
+    gap: clamp(28px, 4vw, 56px);
+    padding: clamp(96px, 8vw, 120px) clamp(20px, 4vw, 56px) 96px;
+}
+
+/* ---------------- Sidebar ---------------- */
+
+.community-report__sidebar {
+    width: var(--cr-sidebar-w);
+    flex: 0 0 var(--cr-sidebar-w);
+    position: sticky;
+    top: calc(var(--cr-navbar-h) + 24px);
+    align-self: flex-start;
+}
+
+.community-report__section {
+    padding: 20px;
+    background: #fff;
+    border: 1px solid var(--cr-line);
+    border-radius: 14px;
+    box-shadow: 0 1px 4px rgba(0, 89, 68, 0.06);
+}
+
+.community-report__section-title {
+    margin: 0 0 14px;
+    font-family: var(--font-mono);
+    font-size: 12px;
+    font-weight: 700;
+    letter-spacing: 0.12em;
+    text-transform: uppercase;
+    color: var(--cr-green);
+}
+
+.community-report__entry {
+    display: flex;
+    flex-direction: column;
+    gap: 6px;
+    width: 100%;
+    text-align: left;
+    cursor: pointer;
+    padding: 12px 14px;
+    border: 1px solid transparent;
+    border-radius: 10px;
+    background: var(--cr-cream);
+    color: var(--cr-ink);
+    transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s 
ease;
+}
+
+.community-report__entry:hover {
+    background: #F3ECDD;
+}
+
+.community-report__entry--active {
+    background: rgba(6, 128, 95, 0.08);
+    border-color: rgba(6, 128, 95, 0.35);
+    box-shadow: inset 3px 0 0 var(--cr-green);
+}
+
+.community-report__entry-badge {
+    align-self: flex-start;
+    padding: 1px 8px;
+    border-radius: 4px;
+    font-family: var(--font-mono);
+    font-size: 10px;
+    font-weight: 700;
+    letter-spacing: 0.08em;
+    text-transform: uppercase;
+    color: var(--cr-green-dark);
+    background: var(--cr-yellow);
+}
+
+.community-report__entry-label {
+    font-size: 15px;
+    font-weight: 600;
+    line-height: 1.3;
+}
+
+/* ---------------- Past-reports dropdown ---------------- */
+
+.community-report__select-wrap {
+    position: relative;
+    margin-top: 12px;
+}
+
+.community-report__select-wrap::after {
+    // Custom chevron (native arrow is hidden via appearance:none).
+    content: '';
+    position: absolute;
+    right: 14px;
+    top: 50%;
+    width: 10px;
+    height: 10px;
+    transform: translateY(-60%) rotate(45deg);
+    border-right: 2px solid var(--cr-muted);
+    border-bottom: 2px solid var(--cr-muted);
+    pointer-events: none;
+}
+
+.community-report__select {
+    -webkit-appearance: none;
+    -moz-appearance: none;
+    appearance: none;
+    width: 100%;
+    cursor: pointer;
+    padding: 11px 36px 11px 14px;
+    font-family: var(--font-family-base);
+    font-size: 14px;
+    color: var(--cr-ink);
+    background: #fff;
+    border: 1px solid var(--cr-line);
+    border-radius: 10px;
+    transition: border-color 0.2s ease, box-shadow 0.2s ease;
+}
+
+.community-report__select:hover {
+    border-color: rgba(6, 128, 95, 0.4);
+}
+
+.community-report__select:focus-visible {
+    outline: none;
+    border-color: var(--cr-green);
+    box-shadow: 0 0 0 3px rgba(6, 128, 95, 0.15);
+}
+
+/* ---------------- Content ---------------- */
+
+.community-report__content {
+    flex: 1 1 auto;
+    min-width: 0;
+    padding-top: 4px;
+}
+
+/* ---------------- Responsive ---------------- */
+
+@media (max-width: 900px) {
+    .community-report__layout {
+        flex-direction: column;
+        gap: 28px;
+        padding-top: clamp(84px, 16vw, 100px);
+    }
+
+    .community-report__sidebar {
+        position: static;
+        width: 100%;
+        flex-basis: auto;
+    }
+}
diff --git a/src/components/community-report-next/CommunityReportNext.tsx 
b/src/components/community-report-next/CommunityReportNext.tsx
new file mode 100644
index 00000000000..f913a2610ad
--- /dev/null
+++ b/src/components/community-report-next/CommunityReportNext.tsx
@@ -0,0 +1,489 @@
+import React, { JSX, useEffect, useState } from 'react';
+import { LayoutNext } from '../home-next/LayoutNext';
+import './CommunityReportNext.scss';
+import './WeeklyReport.scss';
+
+export interface WeeklyReportStat {
+    num: string;
+    label: string;
+}
+
+/** One PR / issue reference, rendered as a linked `#<num>`. */
+export interface WeeklyReportRef {
+    num: number;
+    title: string;
+    url: string;
+    /** Open PR opened within the report week (in-progress only). */
+    isNew?: boolean;
+}
+
+/** One scenario line inside the new community-radar website export. */
+export interface WeeklyReportScenario {
+    name: string;
+    mergedNarrative?: string;
+    inProgressNarrative?: string;
+    merged?: WeeklyReportRef[];
+    inProgress?: WeeklyReportRef[];
+}
+
+/** Legacy section shape from the first structured MDX export. */
+export interface WeeklyReportLegacyScenario {
+    name: string;
+    narrative?: string;
+    prs?: WeeklyReportRef[];
+    refs?: WeeklyReportRef[];
+}
+
+export interface WeeklyReportHighlight {
+    title: string;
+    narrative: string;
+    prs?: WeeklyReportRef[];
+}
+
+export interface WeeklyReportDemand {
+    name: string;
+    narrative?: string;
+    refs?: WeeklyReportRef[];
+}
+
+/** One repository's chapter: the three scenario sections. */
+export interface WeeklyReportRepo {
+    repo: string;
+    scenarios?: WeeklyReportScenario[];
+    demand?: WeeklyReportDemand[];
+    /** Backward-compatible fields for already-published structured reports. */
+    merged?: WeeklyReportLegacyScenario[];
+    inProgress?: WeeklyReportLegacyScenario[];
+}
+
+/**
+ * Structured report body exported by community-radar (`export const report`).
+ * When present it is laid out by this component; otherwise the compiled 
Markdown
+ * body is rendered instead (the legacy / hand-authored path).
+ */
+export interface WeeklyReportData {
+    summary: {
+        lead: string;
+        highlights: Array<string | WeeklyReportHighlight>;
+        numbers?: { mergedPrs: number; newIssues: number; contributors: number 
};
+    };
+    repos: WeeklyReportRepo[];
+}
+
+export interface WeeklyReportEntry {
+    /** Stable id (the markdown filename without extension); used as the URL 
hash. */
+    id: string;
+    /** Date range shown in the sidebar and page title, e.g. "Jun 29 – Jul 5, 
2026". */
+    label: string;
+    /** Optional subtitle, e.g. "Week 27, 2026". */
+    week?: string;
+    /** Optional summary cards rendered above the report body. */
+    stats?: WeeklyReportStat[];
+    /** Structured body (from community-radar's export); takes precedence over 
Component. */
+    report?: WeeklyReportData;
+    /** The compiled markdown body as a React component (fallback when no 
`report`). */
+    Component: React.ComponentType;
+}
+
+interface CommunityReportNextProps {
+    /** All reports, ordered newest-first (see the page's loadReports()). */
+    reports: WeeklyReportEntry[];
+}
+
+export default function CommunityReportNext({ reports }: 
CommunityReportNextProps): JSX.Element {
+    const latest = reports[0];
+    const historical = reports.slice(1);
+    const [selectedId, setSelectedId] = useState<string>(latest?.id ?? '');
+
+    // Allow deep-linking to a specific report via URL hash, e.g.
+    // /community-report#2026-06-22. Read on mount (client-only; window is
+    // undefined during SSR) and fall back to the latest report.
+    useEffect(() => {
+        const hash = window.location.hash.replace(/^#/, '');
+        if (hash && reports.some(r => r.id === hash)) {
+            setSelectedId(hash);
+        }
+    }, [reports]);
+
+    const select = (id: string) => {
+        setSelectedId(id);
+        if (typeof window !== 'undefined') {
+            window.history.replaceState(null, '', `#${id}`);
+        }
+    };
+
+    const selected = reports.find(r => r.id === selectedId) ?? latest;
+    const isHistoricalSelected = historical.some(r => r.id === selectedId);
+    const SelectedReport = selected?.Component;
+
+    return (
+        <LayoutNext
+            title="Community Report — Apache Doris"
+            description="Weekly reports from the Apache Doris community: 
merged features, fixes, new contributors, and notable discussions."
+        >
+            <div className="community-report">
+                <div className="community-report__layout">
+                    <aside className="community-report__sidebar" 
aria-label="Reports">
+                        <div className="community-report__section">
+                            <h2 
className="community-report__section-title">Weekly Report</h2>
+
+                            {latest && (
+                                <button
+                                    type="button"
+                                    className={
+                                        'community-report__entry' +
+                                        (selectedId === latest.id ? ' 
community-report__entry--active' : '')
+                                    }
+                                    onClick={() => select(latest.id)}
+                                >
+                                    <span 
className="community-report__entry-badge">Latest</span>
+                                    <span 
className="community-report__entry-label">{latest.label}</span>
+                                </button>
+                            )}
+
+                            {historical.length > 0 && (
+                                <div className="community-report__select-wrap">
+                                    <select
+                                        className="community-report__select"
+                                        aria-label="Browse past weekly reports"
+                                        value={isHistoricalSelected ? 
selectedId : ''}
+                                        onChange={e => select(e.target.value)}
+                                    >
+                                        <option value="" disabled>
+                                            Past reports…
+                                        </option>
+                                        {historical.map(r => (
+                                            <option key={r.id} value={r.id}>
+                                                {r.label}
+                                            </option>
+                                        ))}
+                                    </select>
+                                </div>
+                            )}
+                        </div>
+                    </aside>
+
+                    <main className="community-report__content">
+                        {selected && (
+                            <article className="weekly-report">
+                                <header className="weekly-report__header">
+                                    <p 
className="weekly-report__eyebrow">Community Weekly Report</p>
+                                    <h1 
className="weekly-report__title">{selected.label}</h1>
+                                    {selected.week && <p 
className="weekly-report__meta">{selected.week}</p>}
+                                </header>
+
+                                {selected.stats && selected.stats.length > 0 
&& !selected.report?.summary.numbers && (
+                                    <div className="weekly-report__stats">
+                                        {selected.stats.map((stat, i) => (
+                                            <div 
className="weekly-report__stat" key={`${stat.label}-${i}`}>
+                                                <span 
className="weekly-report__stat-num">{stat.num}</span>
+                                                <span 
className="weekly-report__stat-label">{stat.label}</span>
+                                            </div>
+                                        ))}
+                                    </div>
+                                )}
+
+                                {selected.report ? (
+                                    <StructuredBody key={selected.id} 
report={selected.report} />
+                                ) : (
+                                    <div className="weekly-report__body">
+                                        {SelectedReport && <SelectedReport />}
+                                    </div>
+                                )}
+                            </article>
+                        )}
+                    </main>
+                </div>
+            </div>
+        </LayoutNext>
+    );
+}
+
+// ---------------------------------------------------------------------------
+// Structured body — the community-radar website layout:
+// overview -> highlights -> by scenario -> community pulse -> demand signals.
+// It is rendered under this site's visual language. Hand-authored Markdown
+// reports fall back to __body above.
+// ---------------------------------------------------------------------------
+
+function StructuredBody({ report }: { report: WeeklyReportData }): JSX.Element 
{
+    const { summary, repos } = report;
+    const [activeRepo, setActiveRepo] = useState(0);
+    const [activeHighlight, setActiveHighlight] = useState<number | 
null>(null);
+    const [activeScenario, setActiveScenario] = useState(0);
+    const repo = repos[Math.min(activeRepo, repos.length - 1)];
+    const highlights = summary.highlights ?? [];
+    const scenarios = repo ? normalizeScenarios(repo) : [];
+    const activeScenarioIndex = scenarios.length > 0 ? 
Math.min(activeScenario, scenarios.length - 1) : 0;
+    const selectedScenario = scenarios[activeScenarioIndex];
+
+    return (
+        <div className="wr-structured">
+            {summary.lead && (
+                <section className="wr-section">
+                    <SectionTitle index="00" title="Overview" />
+                    <p className="wr-pulse__lead">{summary.lead}</p>
+                </section>
+            )}
+
+            {highlights.length > 0 && (
+                <section className="wr-section">
+                    <SectionTitle index="01" title="Highlights" />
+                    <div className="wr-highlights">
+                        {highlights.map((h, i) => (
+                            <HighlightCard
+                                key={i}
+                                highlight={h}
+                                index={i + 1}
+                                expanded={activeHighlight === i}
+                                onToggle={() => 
setActiveHighlight(activeHighlight === i ? null : i)}
+                            />
+                        ))}
+                    </div>
+                </section>
+            )}
+
+            {repos.length > 1 && (
+                <nav className="wr-tabs" aria-label="Repositories">
+                    {repos.map((r, i) => (
+                        <button
+                            key={r.repo}
+                            type="button"
+                            className={'wr-tab' + (i === activeRepo ? ' 
wr-tab--active' : '')}
+                            onClick={() => {
+                                setActiveRepo(i);
+                                setActiveScenario(0);
+                            }}
+                        >
+                            {r.repo}
+                        </button>
+                    ))}
+                </nav>
+            )}
+
+            {repo && (
+                <>
+                    <section className="wr-section">
+                        <SectionTitle index="02" title="By Scenario" />
+                        {scenarios.length === 0 ? (
+                            <p className="wr-empty">Nothing to report this 
week.</p>
+                        ) : (
+                            <div className="wr-scenarios-tabs">
+                                <div className="wr-scenario-tabs" 
role="tablist" aria-label={`${repo.repo} scenarios`}>
+                                    {scenarios.map((s, i) => (
+                                        <button
+                                            key={s.name + i}
+                                            type="button"
+                                            id={`wr-scenario-tab-${i}`}
+                                            role="tab"
+                                            aria-selected={i === 
activeScenarioIndex}
+                                            
aria-controls={`wr-scenario-panel-${i}`}
+                                            className={
+                                                'wr-scenario-tab' +
+                                                (i === activeScenarioIndex ? ' 
wr-scenario-tab--active' : '')
+                                            }
+                                            onClick={() => 
setActiveScenario(i)}
+                                        >
+                                            <span 
className="wr-scenario-tab__idx">
+                                                {String(i + 1).padStart(2, 
'0')}
+                                            </span>
+                                            <span 
className="wr-scenario-tab__label">{s.name}</span>
+                                        </button>
+                                    ))}
+                                </div>
+                                {selectedScenario && (
+                                    <div
+                                        
id={`wr-scenario-panel-${activeScenarioIndex}`}
+                                        role="tabpanel"
+                                        
aria-labelledby={`wr-scenario-tab-${activeScenarioIndex}`}
+                                        className="wr-scenario-panel"
+                                    >
+                                        <ScenarioCard 
scenario={selectedScenario} index={activeScenarioIndex + 1} />
+                                    </div>
+                                )}
+                            </div>
+                        )}
+                    </section>
+
+                    {summary.numbers && (
+                        <section className="wr-section">
+                            <SectionTitle index="03" title="Community Pulse" />
+                            <div className="wr-pulse">
+                                <PulseFigure num={summary.numbers.mergedPrs} 
label="Merged PRs" />
+                                <PulseFigure num={summary.numbers.newIssues} 
label="New issues" />
+                                <PulseFigure 
num={summary.numbers.contributors} label="Contributors" />
+                            </div>
+                        </section>
+                    )}
+                </>
+            )}
+        </div>
+    );
+}
+
+function SectionTitle({ index, title }: { index: string; title: string }): 
JSX.Element {
+    return (
+        <h2 className="wr-section__title">
+            <span className="wr-section__index">{index}</span>
+            {title}
+        </h2>
+    );
+}
+
+function HighlightCard({
+    highlight,
+    index,
+    expanded,
+    onToggle,
+}: {
+    highlight: string | WeeklyReportHighlight;
+    index: number;
+    expanded: boolean;
+    onToggle: () => void;
+}): JSX.Element {
+    const title = typeof highlight === 'string' ? highlight : highlight.title;
+    const narrative = typeof highlight === 'string' ? undefined : 
highlight.narrative;
+    const prs = typeof highlight === 'string' ? [] : highlight.prs ?? [];
+    const panelId = `wr-highlight-panel-${index}`;
+
+    if (typeof highlight === 'string') {
+        return (
+            <article className="wr-highlight">
+                <button type="button" className="wr-highlight__trigger" 
disabled>
+                    <span 
className="wr-highlight__idx">{String(index).padStart(2, '0')}</span>
+                    <span className="wr-highlight__title">{title}</span>
+                </button>
+            </article>
+        );
+    }
+
+    return (
+        <article className={'wr-highlight' + (expanded ? ' wr-highlight--open' 
: '')}>
+            <h3 className="wr-highlight__heading">
+                <button
+                    type="button"
+                    className="wr-highlight__trigger"
+                    aria-expanded={expanded}
+                    aria-controls={panelId}
+                    onClick={onToggle}
+                >
+                    <span 
className="wr-highlight__idx">{String(index).padStart(2, '0')}</span>
+                    <span className="wr-highlight__title">{title}</span>
+                    <span className="wr-highlight__chevron" aria-hidden="true" 
/>
+                </button>
+            </h3>
+            {expanded && (
+                <div className="wr-highlight__panel" id={panelId}>
+                    {narrative && <p 
className="wr-highlight__text">{narrative}</p>}
+                    <RefList items={prs} />
+                </div>
+            )}
+        </article>
+    );
+}
+
+function PulseFigure({ num, label }: { num: number; label: string }): 
JSX.Element {
+    return (
+        <div className="wr-pulse__figure">
+            <span className="wr-pulse__num">{num}</span>
+            <span className="wr-pulse__label">{label}</span>
+        </div>
+    );
+}
+
+function normalizeScenarios(repo: WeeklyReportRepo): WeeklyReportScenario[] {
+    if (repo.scenarios) {
+        return repo.scenarios;
+    }
+    const byName = new Map<string, WeeklyReportScenario>();
+
+    const ensure = (name: string): WeeklyReportScenario => {
+        const existing = byName.get(name);
+        if (existing) {
+            return existing;
+        }
+        const next = { name };
+        byName.set(name, next);
+        return next;
+    };
+
+    (repo.merged ?? []).forEach(s => {
+        const target = ensure(s.name);
+        target.mergedNarrative = s.narrative;
+        target.merged = s.prs ?? [];
+    });
+    (repo.inProgress ?? []).forEach(s => {
+        const target = ensure(s.name);
+        target.inProgressNarrative = s.narrative;
+        target.inProgress = s.prs ?? [];
+    });
+
+    return Array.from(byName.values());
+}
+
+function ScenarioCard({
+    scenario,
+    index,
+}: {
+    scenario: WeeklyReportScenario;
+    index: number;
+}): JSX.Element {
+    return (
+        <article className="wr-scn">
+            <div className="wr-scn__head">
+                <h3 className="wr-scn__name">{scenario.name}</h3>
+                <span className="wr-scn__idx">{String(index).padStart(2, 
'0')}</span>
+            </div>
+            {scenario.mergedNarrative && (
+                <ScenarioBlock label="Merged" 
narrative={scenario.mergedNarrative} items={scenario.merged ?? []} />
+            )}
+            {scenario.inProgressNarrative && (
+                <ScenarioBlock
+                    label="In progress"
+                    narrative={scenario.inProgressNarrative}
+                    items={scenario.inProgress ?? []}
+                />
+            )}
+        </article>
+    );
+}
+
+function ScenarioBlock({
+    label,
+    narrative,
+    items,
+}: {
+    label: string;
+    narrative: string;
+    items: WeeklyReportRef[];
+}): JSX.Element {
+    return (
+        <div className="wr-scn__block">
+            <div className="wr-scn__label">{label}</div>
+            <p className="wr-scn__narr">{narrative}</p>
+            <RefList items={items} />
+        </div>
+    );
+}
+
+function RefList({ items }: { items: WeeklyReportRef[] }): JSX.Element | null {
+    if (items.length === 0) {
+        return null;
+    }
+
+    return (
+        <ul className="wr-scn__prs">
+            {items.map(it => (
+                <li className="wr-scn__pr" key={it.num}>
+                    <span className="wr-scn__pr-title">{it.title}</span>
+                    <span className="wr-scn__pr-meta">
+                        {it.isNew && <span className="wr-scn__new">Newly 
opened</span>}
+                        <a className="wr-scn__pr-num" href={it.url} 
target="_blank" rel="noopener noreferrer">
+                            #{it.num}
+                        </a>
+                    </span>
+                </li>
+            ))}
+        </ul>
+    );
+}
diff --git a/src/components/community-report-next/WeeklyReport.scss 
b/src/components/community-report-next/WeeklyReport.scss
new file mode 100644
index 00000000000..44222f17901
--- /dev/null
+++ b/src/components/community-report-next/WeeklyReport.scss
@@ -0,0 +1,726 @@
+// Unified styles for every weekly report.
+//
+// The header and stat cards are rendered by CommunityReportNext.tsx from each
+// report's frontmatter (label / week / stats). The `__body` block wraps the
+// Markdown compiled by Docusaurus's MDX loader, so its rules target the plain
+// semantic tags (h2, ul, p, code, table…) that Markdown produces.
+
+.weekly-report {
+    --wr-green: #06805F;
+    --wr-green-dark: #054C39;
+    --wr-ink: #0F1A14;
+    --wr-muted: #5A6472;
+    --wr-paper: #FFFCF5;
+    --wr-cream: #FAF6EE;
+    --wr-line: rgba(15, 26, 20, 0.10);
+    --wr-yellow: #FFD23F;
+
+    color: var(--wr-ink);
+    font-family: var(--font-family-base);
+    max-width: 820px;
+
+    * {
+        box-sizing: border-box;
+    }
+}
+
+/* ---------------- Header (from frontmatter) ---------------- */
+
+.weekly-report__header {
+    padding-bottom: 28px;
+    border-bottom: 1px solid var(--wr-line);
+    margin-bottom: 32px;
+}
+
+.weekly-report__eyebrow {
+    margin: 0 0 10px;
+    font-family: var(--font-mono);
+    font-size: 12px;
+    font-weight: 700;
+    letter-spacing: 0.12em;
+    text-transform: uppercase;
+    color: var(--wr-green);
+}
+
+.weekly-report__title {
+    margin: 0;
+    font-size: clamp(28px, 2rem + 1vw, 40px);
+    font-weight: 700;
+    letter-spacing: -0.02em;
+    line-height: 1.1;
+    color: var(--wr-ink);
+}
+
+.weekly-report__meta {
+    margin: 10px 0 0;
+    font-size: 14px;
+    color: var(--wr-muted);
+}
+
+/* ---------------- Stats (from frontmatter) ---------------- */
+
+.weekly-report__stats {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    gap: 16px;
+    margin-bottom: 40px;
+}
+
+.weekly-report__stat {
+    display: flex;
+    flex-direction: column;
+    gap: 4px;
+    padding: 18px 20px;
+    background: var(--wr-cream);
+    border: 1px solid var(--wr-line);
+    border-radius: 12px;
+}
+
+.weekly-report__stat-num {
+    font-family: var(--font-mono);
+    font-size: 30px;
+    font-weight: 700;
+    line-height: 1;
+    color: var(--wr-green);
+}
+
+.weekly-report__stat-label {
+    font-size: 13px;
+    color: var(--wr-muted);
+}
+
+/* ---------------- Markdown body ---------------- */
+
+.weekly-report__body {
+    font-size: 15px;
+    line-height: 1.7;
+    color: #2A3441;
+}
+
+.weekly-report__body > :first-child {
+    margin-top: 0;
+}
+
+.weekly-report__body h2 {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+    margin: 34px 0 16px;
+    font-size: 20px;
+    font-weight: 700;
+    letter-spacing: -0.01em;
+    color: var(--wr-ink);
+    scroll-margin-top: 88px;
+}
+
+.weekly-report__body h2::before {
+    content: '';
+    flex: 0 0 auto;
+    width: 8px;
+    height: 20px;
+    border-radius: 3px;
+    background: var(--wr-yellow);
+}
+
+.weekly-report__body h3 {
+    margin: 26px 0 12px;
+    font-size: 16px;
+    font-weight: 700;
+    color: var(--wr-ink);
+    scroll-margin-top: 88px;
+}
+
+.weekly-report__body p {
+    margin: 0 0 16px;
+}
+
+.weekly-report__body ul,
+.weekly-report__body ol {
+    margin: 0 0 16px;
+    padding-left: 22px;
+    display: flex;
+    flex-direction: column;
+    gap: 8px;
+}
+
+.weekly-report__body li {
+    line-height: 1.6;
+}
+
+.weekly-report__body li::marker {
+    color: var(--wr-green);
+}
+
+.weekly-report__body a {
+    color: var(--wr-green);
+    text-decoration: none;
+    border-bottom: 1px solid rgba(6, 128, 95, 0.3);
+    transition: border-color 0.15s ease;
+}
+
+.weekly-report__body a:hover {
+    border-bottom-color: var(--wr-green);
+}
+
+.weekly-report__body strong {
+    font-weight: 700;
+    color: var(--wr-ink);
+}
+
+.weekly-report__body em {
+    font-style: italic;
+    color: #B08800;
+}
+
+// Inline code. Fenced code blocks are rendered by Docusaurus's own CodeBlock
+// theme component, so they keep the site-wide code styling untouched here.
+.weekly-report__body :not(pre) > code {
+    font-family: var(--font-mono);
+    font-size: 0.88em;
+    padding: 1px 6px;
+    border-radius: 4px;
+    background: rgba(15, 26, 20, 0.06);
+    color: var(--wr-green-dark);
+}
+
+.weekly-report__body blockquote {
+    margin: 0 0 18px;
+    padding: 4px 16px;
+    border-left: 3px solid var(--wr-green);
+    background: var(--wr-cream);
+    border-radius: 0 8px 8px 0;
+    color: var(--wr-muted);
+}
+
+.weekly-report__body table {
+    width: 100%;
+    border-collapse: collapse;
+    margin: 0 0 18px;
+    font-size: 14px;
+    display: block;
+    overflow-x: auto;
+}
+
+.weekly-report__body th,
+.weekly-report__body td {
+    text-align: left;
+    padding: 8px 12px;
+    border: 1px solid var(--wr-line);
+}
+
+.weekly-report__body th {
+    background: var(--wr-cream);
+    font-weight: 700;
+}
+
+.weekly-report__body img {
+    max-width: 100%;
+    border-radius: 8px;
+}
+
+.weekly-report__body hr {
+    border: 0;
+    border-top: 1px solid var(--wr-line);
+    margin: 28px 0;
+}
+
+/* ---------------- Structured body ---------------- */
+//
+// Rendered by StructuredBody (CommunityReportNext.tsx) from `export const 
report`.
+// The information architecture mirrors community-radar's report flow while the
+// colors, typography scale, and card treatment stay aligned with 
doris.apache.org.
+
+.wr-section {
+    margin: 0;
+}
+
+.wr-section__title {
+    display: flex;
+    align-items: center;
+    gap: 10px;
+    margin: 48px 0 20px;
+    font-size: 20px;
+    font-weight: 700;
+    letter-spacing: 0;
+    color: var(--wr-ink);
+}
+
+.wr-section__title::before {
+    content: '';
+    flex: 0 0 auto;
+    width: 22px;
+    height: 3px;
+    border-radius: 999px;
+    background: var(--wr-yellow);
+}
+
+.wr-section__index {
+    font-family: var(--font-mono);
+    font-size: 1em;
+    line-height: 1;
+    letter-spacing: 0.08em;
+    color: var(--wr-green);
+}
+
+.wr-structured > .wr-section:first-child .wr-section__title {
+    margin-top: 0;
+}
+
+.wr-empty {
+    margin: 0;
+    font-size: 14px;
+    font-style: italic;
+    color: var(--wr-muted);
+}
+
+/* Overview */
+
+.wr-pulse__lead {
+    margin: 0;
+    font-size: 18px;
+    font-weight: 500;
+    line-height: 1.65;
+    color: var(--wr-ink);
+}
+
+/* Highlights */
+
+.wr-highlights {
+    display: grid;
+    gap: 10px;
+}
+
+.wr-highlight {
+    background: var(--wr-green);
+    border: 1px solid rgba(5, 76, 57, 0.22);
+    border-radius: 10px;
+    box-shadow: 0 8px 24px rgba(0, 89, 68, 0.12);
+    overflow: hidden;
+    transition: border-color 0.18s ease, box-shadow 0.18s ease, background 
0.18s ease;
+}
+
+.wr-highlight--open {
+    border-color: rgba(5, 76, 57, 0.34);
+    box-shadow: 0 12px 28px rgba(0, 89, 68, 0.16);
+}
+
+.wr-highlight__heading {
+    margin: 0;
+}
+
+.wr-highlight__trigger {
+    display: grid;
+    grid-template-columns: auto minmax(0, 1fr) auto;
+    align-items: center;
+    gap: 14px;
+    width: 100%;
+    padding: 17px 20px;
+    border: 0;
+    background: transparent;
+    color: inherit;
+    text-align: left;
+    cursor: pointer;
+}
+
+.wr-highlight__trigger:disabled {
+    cursor: default;
+}
+
+.wr-highlight__trigger:focus-visible {
+    outline: none;
+    box-shadow: inset 0 0 0 3px rgba(255, 210, 63, 0.36);
+}
+
+.wr-highlight__idx {
+    font-family: var(--font-mono);
+    font-size: 13px;
+    font-weight: 700;
+    color: var(--wr-yellow);
+}
+
+.wr-highlight__title {
+    margin: 0;
+    font-size: 16px;
+    line-height: 1.35;
+    color: var(--wr-paper);
+}
+
+.wr-highlight__chevron {
+    width: 9px;
+    height: 9px;
+    border-right: 2px solid var(--wr-paper);
+    border-bottom: 2px solid var(--wr-paper);
+    transform: rotate(45deg);
+    transition: transform 0.18s ease;
+}
+
+.wr-highlight--open .wr-highlight__chevron {
+    transform: rotate(225deg);
+}
+
+.wr-highlight__panel {
+    padding: 0 20px 20px 47px;
+}
+
+.wr-highlight__text {
+    margin: 0;
+    font-size: 15px;
+    line-height: 1.68;
+    color: rgba(255, 252, 245, 0.88);
+}
+
+.wr-highlight__panel .wr-scn__prs {
+    margin-top: 14px;
+    border-top-color: rgba(255, 252, 245, 0.18);
+}
+
+.wr-highlight__panel .wr-scn__pr {
+    border-top-color: rgba(255, 252, 245, 0.18);
+}
+
+.wr-highlight__panel .wr-scn__pr-title {
+    color: rgba(255, 252, 245, 0.92);
+}
+
+.wr-highlight__panel .wr-scn__pr-num {
+    color: var(--wr-yellow);
+    border-bottom-color: rgba(255, 210, 63, 0.5);
+}
+
+.wr-highlight__panel .wr-scn__pr-num:hover {
+    border-bottom-color: var(--wr-yellow);
+}
+
+.wr-highlight__panel .wr-scn__new {
+    color: var(--wr-paper);
+    background: rgba(255, 252, 245, 0.16);
+}
+
+/* Repo tabs (only shown when a report covers more than one repository) */
+
+.wr-tabs {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 2px;
+    margin: 8px 0 28px;
+    border-bottom: 1px solid var(--wr-line);
+}
+
+.wr-tab {
+    font-family: var(--font-mono);
+    font-size: 12.5px;
+    letter-spacing: 0.02em;
+    border: 0;
+    background: transparent;
+    color: var(--wr-muted);
+    padding: 11px 16px;
+    cursor: pointer;
+    border-bottom: 2px solid transparent;
+    margin-bottom: -1px;
+    transition: color 0.15s ease, border-color 0.15s ease;
+}
+
+.wr-tab:hover {
+    color: var(--wr-green);
+}
+
+.wr-tab--active {
+    color: var(--wr-ink);
+    border-bottom-color: var(--wr-green);
+    font-weight: 700;
+}
+
+/* Scenario tabs */
+
+.wr-scenarios-tabs {
+    display: flex;
+    flex-direction: column;
+    gap: 18px;
+}
+
+.wr-scenario-tabs {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 8px;
+    padding: 6px;
+    background: rgba(250, 246, 238, 0.72);
+    border: 1px solid var(--wr-line);
+    border-radius: 12px;
+}
+
+.wr-scenario-tab {
+    display: inline-flex;
+    align-items: center;
+    gap: 8px;
+    min-height: 38px;
+    max-width: 100%;
+    padding: 8px 12px;
+    border: 1px solid transparent;
+    border-radius: 8px;
+    background: transparent;
+    color: var(--wr-muted);
+    font-family: var(--font-family-base);
+    font-size: 13px;
+    font-weight: 700;
+    line-height: 1.2;
+    text-align: left;
+    cursor: pointer;
+    transition: background 0.16s ease, border-color 0.16s ease, color 0.16s 
ease, box-shadow 0.16s ease;
+}
+
+.wr-scenario-tab:hover {
+    color: var(--wr-green-dark);
+    background: rgba(255, 255, 255, 0.72);
+}
+
+.wr-scenario-tab:focus-visible {
+    outline: none;
+    box-shadow: 0 0 0 3px rgba(6, 128, 95, 0.16);
+}
+
+.wr-scenario-tab--active {
+    color: var(--wr-paper);
+    background: var(--wr-green);
+    border-color: rgba(5, 76, 57, 0.28);
+    box-shadow: 0 8px 18px rgba(0, 89, 68, 0.16);
+}
+
+.wr-scenario-tab__idx {
+    font-family: var(--font-mono);
+    font-size: 11px;
+    color: var(--wr-green);
+}
+
+.wr-scenario-tab--active .wr-scenario-tab__idx {
+    color: var(--wr-yellow);
+}
+
+.wr-scenario-tab__label {
+    min-width: 0;
+}
+
+.wr-scenario-panel {
+    min-width: 0;
+}
+
+/* Scenario cards */
+
+.wr-scn {
+    background: #fff;
+    border: 1px solid var(--wr-line);
+    border-top: 3px solid var(--wr-green);
+    border-radius: 12px;
+    padding: 24px;
+    box-shadow: 0 1px 4px rgba(0, 89, 68, 0.06);
+}
+
+.wr-scn__head {
+    display: flex;
+    align-items: flex-start;
+    justify-content: space-between;
+    gap: 16px;
+}
+
+.wr-scn__name {
+    margin: 0;
+    font-size: 17px;
+    font-weight: 700;
+    line-height: 1.25;
+    color: var(--wr-ink);
+}
+
+.wr-scn__idx {
+    font-family: var(--font-mono);
+    font-size: 22px;
+    font-weight: 700;
+    line-height: 1;
+    color: var(--wr-green);
+    opacity: 0.35;
+}
+
+.wr-scn__block {
+    margin-top: 18px;
+    padding-top: 18px;
+    border-top: 1px solid var(--wr-line);
+}
+
+.wr-scn__block:first-of-type {
+    margin-top: 16px;
+}
+
+.wr-scn__label {
+    display: inline-flex;
+    align-items: center;
+    min-height: 22px;
+    padding: 2px 10px;
+    border-radius: 999px;
+    background: var(--wr-cream);
+    color: var(--wr-green-dark);
+    font-family: var(--font-mono);
+    font-size: 11px;
+    font-weight: 700;
+    letter-spacing: 0.06em;
+    text-transform: uppercase;
+}
+
+.wr-scn__narr {
+    margin: 12px 0 0;
+    font-size: 15px;
+    line-height: 1.7;
+    color: #2A3441;
+}
+
+.wr-scn__prs {
+    list-style: none;
+    margin: 16px 0 0;
+    padding: 16px 0 0;
+    border-top: 1px solid var(--wr-line);
+    display: flex;
+    flex-direction: column;
+}
+
+.wr-scn__pr {
+    display: flex;
+    align-items: baseline;
+    justify-content: space-between;
+    gap: 16px;
+    padding: 9px 0;
+    border-top: 1px dashed var(--wr-line);
+}
+
+.wr-scn__pr:first-child {
+    border-top: 0;
+    padding-top: 0;
+}
+
+.wr-scn__pr-title {
+    flex: 1;
+    font-size: 14px;
+    line-height: 1.5;
+    color: var(--wr-ink);
+}
+
+.wr-scn__pr-meta {
+    display: inline-flex;
+    align-items: center;
+    gap: 10px;
+    flex-shrink: 0;
+}
+
+.wr-scn__pr-num {
+    font-family: var(--font-mono);
+    font-size: 12.5px;
+    font-weight: 700;
+    color: var(--wr-green);
+    text-decoration: none;
+    border-bottom: 1px solid rgba(6, 128, 95, 0.3);
+    transition: border-color 0.15s ease;
+}
+
+.wr-scn__pr-num:hover {
+    border-bottom-color: var(--wr-green);
+}
+
+.wr-scn__new {
+    font-family: var(--font-mono);
+    font-size: 10px;
+    font-weight: 700;
+    letter-spacing: 0.04em;
+    text-transform: uppercase;
+    color: var(--wr-green-dark);
+    background: rgba(6, 128, 95, 0.12);
+    border-radius: 999px;
+    padding: 2px 8px;
+    white-space: nowrap;
+}
+
+/* Community Pulse */
+
+.wr-pulse {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    gap: 16px;
+    padding: 26px 28px;
+    background: var(--wr-green-dark);
+    border-radius: 14px;
+}
+
+.wr-pulse__figure {
+    border-left: 1px solid rgba(255, 252, 245, 0.18);
+    padding-left: 20px;
+}
+
+.wr-pulse__figure:first-child {
+    border-left: 0;
+    padding-left: 0;
+}
+
+.wr-pulse__num {
+    display: block;
+    font-family: var(--font-mono);
+    font-size: 36px;
+    font-weight: 700;
+    line-height: 1;
+    color: var(--wr-yellow);
+}
+
+.wr-pulse__label {
+    display: block;
+    margin-top: 10px;
+    font-size: 12px;
+    font-weight: 700;
+    letter-spacing: 0.08em;
+    text-transform: uppercase;
+    color: rgba(255, 252, 245, 0.72);
+}
+
+/* ---------------- Responsive ---------------- */
+
+@media (max-width: 640px) {
+    .weekly-report__stats {
+        grid-template-columns: 1fr;
+        gap: 12px;
+    }
+
+    .wr-scn {
+        padding: 18px 18px;
+    }
+
+    .wr-scn__pr {
+        flex-direction: column;
+        align-items: flex-start;
+        gap: 6px;
+    }
+
+    .wr-highlight {
+        border-radius: 10px;
+    }
+
+    .wr-highlight__trigger {
+        grid-template-columns: auto minmax(0, 1fr) auto;
+        gap: 10px;
+        padding: 15px 16px;
+    }
+
+    .wr-highlight__panel {
+        padding: 0 16px 17px 42px;
+    }
+
+    .wr-scenario-tabs {
+        gap: 6px;
+    }
+
+    .wr-scenario-tab {
+        width: 100%;
+    }
+
+    .wr-pulse {
+        grid-template-columns: 1fr;
+    }
+
+    .wr-pulse__figure,
+    .wr-pulse__figure:first-child {
+        border-left: 0;
+        padding-left: 0;
+    }
+}
diff --git a/src/components/home-next/NavbarNext.tsx 
b/src/components/home-next/NavbarNext.tsx
index b56d49cab30..95dd70cf37d 100644
--- a/src/components/home-next/NavbarNext.tsx
+++ b/src/components/home-next/NavbarNext.tsx
@@ -27,6 +27,7 @@ function buildNavItems(
     v21DocsHref: string,
     releasesHref: string,
     joinCommunityHref: string,
+    communityReportHref: string,
 ): NavItem[] {
     return [
         {
@@ -67,6 +68,7 @@ function buildNavItems(
         {
             label: 'Community',
             items: [
+                { label: 'Community Report', href: communityReportHref },
                 { label: 'Roadmap', href: 
'https://github.com/apache/doris/issues/60036', external: true },
                 { label: 'Build with Us', href: joinCommunityHref },
                 { label: 'Join GitHub Discussions', href: 
'https://github.com/apache/doris/discussions', external: true },
@@ -124,7 +126,16 @@ export function NavbarNext(): JSX.Element {
     const v21DocsHref = 
`${localePrefix}/docs/2.1/gettingStarted/what-is-apache-doris`;
     const releasesHref = `${localePrefix}/releases/all-release`;
     const joinCommunityHref = `${localePrefix}/community/join-community`;
-    const navItems = buildNavItems(devDocsHref, stableDocsHref, v3xDocsHref, 
v21DocsHref, releasesHref, joinCommunityHref);
+    const communityReportHref = `${localePrefix}/community-report`;
+    const navItems = buildNavItems(
+        devDocsHref,
+        stableDocsHref,
+        v3xDocsHref,
+        v21DocsHref,
+        releasesHref,
+        joinCommunityHref,
+        communityReportHref,
+    );
     const [expandedMobileItem, setExpandedMobileItem] = 
useState(navItems[0]?.label ?? '');
     const homeHref = `${getLocalePrefix(currentLocale, defaultLocale)}/`;
 
diff --git a/src/pages/community-report/_reports/2026-06-29.mdx 
b/src/pages/community-report/_reports/2026-06-29.mdx
new file mode 100644
index 00000000000..af9553c6d87
--- /dev/null
+++ b/src/pages/community-report/_reports/2026-06-29.mdx
@@ -0,0 +1,205 @@
+{/* Auto-generated by community-radar `report export-mdx` — do not edit by 
hand.
+    `report` is English-only structured data laid out by doris-website. */}
+
+export const label = "Jun 29 – Jul 5, 2026";
+export const week = "Week 27, 2026";
+export const stats = [
+  {
+    "num": "113",
+    "label": "Merged PRs"
+  },
+  {
+    "num": "5",
+    "label": "New issues"
+  },
+  {
+    "num": "42",
+    "label": "Contributors"
+  }
+];
+
+export const report = {
+  "summary": {
+    "lead": "This week Apache Doris merged 113 PRs with 42 contributors 
active, with the community concentrating on real-time data warehousing and 
kernel engineering while advancing the multi-modal lakehouse and cloud-native 
compute-storage separation tracks. Core capabilities deepened around Catalog 
SPI decoupling, scan execution optimization, inverted index evolution, and peer 
routing with cache tiering, alongside reinforced security/governance and 
observability—signaling a clear direc [...]
+    "highlights": [
+      {
+        "title": "Catalog SPI decoupling and external data source expansion",
+        "narrative": "FE connectors move to a loadable Catalog SPI, easing new 
data-source onboarding and upgrades, while BE gains a unified File Scanner v2 
for Parquet, CSV, JSON and similar external files. Paimon write support and 
OIDC session credentials for Iceberg REST close the lakehouse read-write and 
secure-access loop, making Doris easier",
+        "prs": [
+          {
+            "num": 65185,
+            "title": "[Tracking][Catalog] Catalog SPI migration — decouple 
built-in connectors from FE core into loadable plugins",
+            "url": "https://github.com/apache/doris/issues/65185";
+          },
+          {
+            "num": 65086,
+            "title": "Support writing to Apache Paimon tables",
+            "url": "https://github.com/apache/doris/issues/65086";
+          },
+          {
+            "num": 65046,
+            "title": "[feature](be) Add file scanner v2 readers ",
+            "url": "https://github.com/apache/doris/pull/65046";
+          },
+          {
+            "num": 63068,
+            "title": "[feature](fe) Support OIDC session credentials for 
Iceberg REST catalog",
+            "url": "https://github.com/apache/doris/pull/63068";
+          }
+        ]
+      },
+      {
+        "title": "Cloud-native compute-storage separation: peer routing and 
cache tiering",
+        "narrative": "Cross-compute-group peer read routing enables data 
sharing across groups, while a new write-index-only cache config curbs IO 
amplification under hot writes. Tenant-level colocation trims replica 
redundancy in multi-tenant deployments, together pushing the 
separation-of-storage-and-compute architecture toward higher elasticity and 
finer resource control.",
+        "prs": [
+          {
+            "num": 63818,
+            "title": "[feat](cloud) cross compute group peer read routing with 
peer cache I/O optimization",
+            "url": "https://github.com/apache/doris/pull/63818";
+          },
+          {
+            "num": 64995,
+            "title": "[feature](cloud) Support file cache write index only",
+            "url": "https://github.com/apache/doris/pull/64995";
+          },
+          {
+            "num": 64167,
+            "title": "[feat](colocate) support tenant-level colocation",
+            "url": "https://github.com/apache/doris/pull/64167";
+          }
+        ]
+      },
+      {
+        "title": "Scan and query execution: pruning, lazy read, and runtime 
filters",
+        "narrative": "Lazy reads for pruned complex-type subcolumns and 
expression-based ZoneMap pruning cut IO across internal and Parquet scans. 
Global runtime filters now publish through an adaptive tree, removing duplicate 
broadcasts of large filters in big clusters, while dynamic table snapshot reads 
keep extending real-time warehouse capabilities.",
+        "prs": [
+          {
+            "num": 59263,
+            "title": "[feat](olap) Support lazy reading mode for pruned 
complex columns",
+            "url": "https://github.com/apache/doris/pull/59263";
+          },
+          {
+            "num": 63389,
+            "title": "[feature](be) Support expression zonemap pruning",
+            "url": "https://github.com/apache/doris/pull/63389";
+          },
+          {
+            "num": 64851,
+            "title": "[feature](runtime-filter) Add adaptive global runtime 
filter tree publish",
+            "url": "https://github.com/apache/doris/pull/64851";
+          },
+          {
+            "num": 64891,
+            "title": "[enhancement](Multi-stage lm) Multi-Stage Predicate Lazy 
Materialization",
+            "url": "https://github.com/apache/doris/pull/64891";
+          },
+          {
+            "num": 64776,
+            "title": " [feat](dynamic table) support table stream part 4: 
support snapshot read",
+            "url": "https://github.com/apache/doris/pull/64776";
+          }
+        ]
+      },
+      {
+        "title": "Inverted index evolution: Japanese tokenizer and SNII 
format",
+        "narrative": "A new Kuromoji morphological analyzer closes Doris's gap 
on space-less Japanese text, while the SNII inverted-index storage format lands 
as an alternative path for better compression and extensibility. Together they 
strengthen full-text search and observability for multi-language corpora and 
AI-agent workloads.",
+        "prs": [
+          {
+            "num": 64667,
+            "title": "[feature](inverted-index) Add Japanese (Kuromoji) 
morphological analyzer",
+            "url": "https://github.com/apache/doris/pull/64667";
+          },
+          {
+            "num": 64909,
+            "title": "[feature](be) Add SNII inverted index storage format",
+            "url": "https://github.com/apache/doris/pull/64909";
+          }
+        ]
+      },
+      {
+        "title": "Security and governance hardening across FE and TDE",
+        "narrative": "Intra-FE RPC now switches to HTTPS when TLS is enabled, 
removing the plaintext fallback in hardened deployments. TDE gains Aliyun KMS 
and Ranger KMS provider metadata, letting transparent encryption plug into 
enterprise key management. The combined effect raises Doris's default security 
posture for compliance-sensitive workloads.",
+        "prs": [
+          {
+            "num": 60921,
+            "title": "[Enhancement] (FE) Convert intra FE-to-FE calls to HTTPS 
when enabled",
+            "url": "https://github.com/apache/doris/pull/60921";
+          },
+          {
+            "num": 64561,
+            "title": "[feat](tde) Add Aliyun and Ranger KMS provider metadata",
+            "url": "https://github.com/apache/doris/pull/64561";
+          }
+        ]
+      }
+    ],
+    "numbers": {
+      "mergedPrs": 113,
+      "newIssues": 5,
+      "contributors": 42
+    }
+  },
+  "repos": [
+    {
+      "repo": "apache/doris",
+      "scenarios": [
+        {
+          "name": "Multi-modal Lakehouse",
+          "mergedNarrative": "The multi-modal lakehouse scenario stabilized 
Iceberg/Hive/external-write paths. Iceberg v3 row-lineage columns are rejected 
to avoid hidden conflicts; COUNT(*) pushdown tolerates missing snapshot summary 
counters; LZ4 compression now ships to Iceberg/Hive Parquet/ORC writers; binary 
columns are emitted with correct Arrow types; nested decimal precision 
promotion is supported; external writers clean up",
+          "merged": [],
+          "inProgressNarrative": "Multi-modal Lakehouse work strengthens 
external read/write paths: Paimon write P0, Iceberg position-deletes system 
table, ORC format v2 reader, Parquet dict bounds checks, Arrow Flight 
coordinator lifecycle, OSS/HTTP FS SPI normalization, MaxCompute 
partition-by-name parsing, Iceberg REST OAuth re-auth on 401, S3 load complex 
types for Parquet/ORC, and Hive-ORC column-name default —",
+          "inProgress": []
+        },
+        {
+          "name": "Real-time Data Warehouse",
+          "mergedNarrative": "Real-time data warehouse work targeted P0 
stability and correctness. Group commit recovers from missing block queues and 
load_id reuse that dropped rows; SimplifyAggGroupBy now verifies injectivity; 
local shuffle eliminates the bucket-shuffle serial bottleneck and upgrades 
parallelism; local runtime filter merge deadlocks, pipeline-task 
wake-after-finalize crashes, and variable-length column overflows across 
sorted-run",
+          "merged": [],
+          "inProgressNarrative": "Real-time DWH advances the optimizer, load 
pipeline, and ops visibility: Nereids adds expression defaults, named 
BloomFilter, regexp rewrite, FD-redundant group-by elimination, stats-driven 
distinct/eager-agg pushdown, anti/outer-join conversion, bucket shuffle for set 
ops; loads gain routine-load target swap, stream-load progress observability, 
UTF-8 validation toggle, Arrow case-sensitive columns, label-aware abort, 
binlog hidden keys,",
+          "inProgress": []
+        },
+        {
+          "name": "Compute-Storage Separation & Cloud-Native",
+          "mergedNarrative": "Compute-storage separation and cloud-native 
reliability advanced this week. Queries hitting E-230 now force a fresh version 
cache; start.sh accepts multiple config files; version reads use snapshot 
transactions to avoid write conflicts with update_table_version; S3FileWriter 
now recovers from async submit failures; file-cache evict metrics are aligned 
with the FileCacheType enum; Azure",
+          "merged": [],
+          "inProgressNarrative": "Compute-storage separation and cloud-native 
work keeps hardening meta service, filesystem, and cache reliability and 
observability: capability-gated MS_TOO_BUSY, warm-up job count bvar, recycler 
S3 timeout fix, LRU restore speedup, file-cache skip-after-threshold, 
post-alter tablet meta sync, label-aware transaction abort, Azure glob 
pushdown, HDFS property migration, HTTP FS SPI scaffolding, segment id list,",
+          "inProgress": []
+        },
+        {
+          "name": "Agent Observability",
+          "mergedNarrative": "This scenario hardens observability across 
Variant, inverted-index, and Delete paths. Variant compaction now distinguishes 
empty keys from the root to prevent misrouting into sparse columns; 
tokenization rejects invalid char_filter replacements; DELETE supports 
generated-column partial updates; inverted-index predicates no longer crash on 
null literals; and regression-side pinning plus bool-output normalization 
reduce",
+          "merged": [],
+          "inProgressNarrative": "Agent Observability work is hardening legacy 
index paths by blocking creation of inverted index V1 in FE, preventing the 
small-file merge and packed-file path bypass that could amplify issues during 
agent monitoring and export.",
+          "inProgress": []
+        },
+        {
+          "name": "Ecosystem Integration",
+          "mergedNarrative": "Ecosystem-integration work reconciled 
client-side protocol differences. The regression suite now skips 
Arrow-incompatible map cast cases with null keys and asserts bitmaps via 
bitmap_to_string so Arrow Flight SQL and JDBC return semantically consistent 
results without spurious failures.",
+          "merged": [],
+          "inProgressNarrative": "Ecosystem Integration is restoring the 
dbt-doris adapter dev loop by fixing long-broken test dependencies so 
contributors can run adapter tests from a clean checkout (new this month).",
+          "inProgress": []
+        },
+        {
+          "name": "Security & Governance",
+          "mergedNarrative": "Security governance closed loopholes across 
credentials, gateway, and REST APIs. Kafka routine load properties are now 
masked in SHOW/metadata; the _stream_load_forward endpoint is gated by a new BE 
config and requires auth to block SSRF; brpc disables an SSL BIO buffer to 
avoid mTLS write issues on large responses; and",
+          "merged": [],
+          "inProgressNarrative": "Security & Governance tightens TLS and 
supply-chain hygiene: enabling cert verification by default in the Go SDK, 
pinning Python deps with known CVEs across doris-compose/dbt-doris/cost_model, 
and normalizing FE-internal HTTP calls to https when enable_https is on (all 
new this month).",
+          "inProgress": []
+        },
+        {
+          "name": "Kernel & Engineering",
+          "mergedNarrative": "Kernel and engineering foundations received 
broad hardening. Key fixes address bvar SIGSEGV under high EPS, NaN propagation 
in PERCENTILE, SIGFPE on BIGINT_MIN/-1, sliced FixedSizeBinary reads, redundant 
partition keys in PartitionTopN sort, AuditLoader concurrent assembly, and 
AsyncIO workers without ThreadContext. Refactors moved array functions to 
ColumnArrayView and split const vs. mutable",
+          "merged": [],
+          "inProgressNarrative": "Kernel & Engineering spans core correctness 
and infra: the key change is adaptive random-bucket load routing for cloud 
mode, alongside bitmap/Prometheus/TabletStatMgr/Broker-Load fixes, stable 
`now()` folding, DECIMAL-returning round functions, rollback handling, Arrow 
buffer validation, ORC SerDe decoding, UDF rollback, SetPreAggStatus stack 
refactor, bucketed hash aggregate plan refactor, and many regression/Docker/CI 
stabilizations",
+          "inProgress": [
+            {
+              "num": 62661,
+              "title": "[feature](load) introduce adaptive random bucket load 
routing",
+              "url": "https://github.com/apache/doris/pull/62661";
+            }
+          ]
+        }
+      ],
+      "demand": []
+    }
+  ]
+};
diff --git a/src/pages/community-report/_reports/_TEMPLATE.mdx 
b/src/pages/community-report/_reports/_TEMPLATE.mdx
new file mode 100644
index 00000000000..a0603fa8ca6
--- /dev/null
+++ b/src/pages/community-report/_reports/_TEMPLATE.mdx
@@ -0,0 +1,35 @@
+{/*
+  Standard weekly-report template.
+
+  To publish a new report:
+    1. Copy this file and rename it to the report's start date: YYYY-MM-DD.mdx
+       (the filename sets the order — the newest date shows first).
+    2. Edit the exports below and write the body in Markdown.
+
+  Files whose name starts with "_" (like this one) are ignored by the build.
+  Metadata is carried as `export const` (not YAML frontmatter) because these
+  files are compiled as MDX partials, which may not contain front matter.
+*/}
+
+export const label = 'Mon DD – Mon DD, YYYY';   // sidebar entry + page title
+export const week = 'Week NN, YYYY';            // optional subtitle — remove 
if unused
+export const stats = [                          // optional summary cards — 
remove if unused
+    { num: '0', label: 'PRs merged' },
+    { num: '0', label: 'New contributors' },
+    { num: '0', label: 'Issues closed' },
+];
+
+One or two sentences introducing the week.
+
+## Highlights
+
+- First highlight.
+- Second highlight.
+
+## Development
+
+- Something that was built or fixed.
+
+## Notable Discussions
+
+- A discussion worth reading.
diff --git a/src/pages/community-report/index.tsx 
b/src/pages/community-report/index.tsx
new file mode 100644
index 00000000000..614e6850745
--- /dev/null
+++ b/src/pages/community-report/index.tsx
@@ -0,0 +1,33 @@
+import React, { JSX } from 'react';
+import CommunityReportNext, { WeeklyReportEntry } from 
'@site/src/components/community-report-next/CommunityReportNext';
+
+// Build-time glob of every report in ./_reports. The files live under
+// src/pages inside an underscore folder, so Docusaurus compiles each one as an
+// MDX partial: a React component (`default`) plus any `export const` metadata
+// (label / week / stats). The regex skips files whose name starts with "_"
+// (e.g. _TEMPLATE.mdx).
+function loadReports(): WeeklyReportEntry[] {
+    // require.context is a webpack build-time API and is not typed on 
`require`.
+    const ctx = (require as any).context('./_reports', false, 
/^\.\/[^_].*\.mdx?$/);
+    const entries = ctx.keys().map((key: string): WeeklyReportEntry => {
+        const mod = ctx(key);
+        const id = key.replace(/^\.\//, '').replace(/\.mdx?$/, '');
+        return {
+            id,
+            label: mod.label ?? id,
+            week: mod.week,
+            stats: Array.isArray(mod.stats) ? mod.stats : undefined,
+            report: mod.report,
+            Component: mod.default,
+        };
+    });
+    // Filenames follow YYYY-MM-DD, so a descending sort puts the latest first.
+    entries.sort((a, b) => (a.id < b.id ? 1 : -1));
+    return entries;
+}
+
+const REPORTS = loadReports();
+
+export default function CommunityReportPage(): JSX.Element {
+    return <CommunityReportNext reports={REPORTS} />;
+}
diff --git 
a/versioned_docs/version-4.x/query-acceleration/materialized-view/intro-link.mdx
 
b/versioned_docs/version-4.x/query-acceleration/materialized-view/intro-link.mdx
new file mode 100644
index 00000000000..0c7f678d3d8
--- /dev/null
+++ 
b/versioned_docs/version-4.x/query-acceleration/materialized-view/intro-link.mdx
@@ -0,0 +1,13 @@
+---
+{
+    "title": "Materialized View",
+    "language": "en",
+    "description": "Apache Doris materialized view chapter navigation: covers 
concepts, synchronous materialized views, asynchronous materialized views, 
transparent rewriting, and FAQs."
+}
+---
+
+import GettingStartedCard from 
'@site/src/components/getting-started-card/getting-started-card';
+
+A materialized view is an entity that contains both computation logic and 
data. You can use it for query acceleration, lightweight ETL modeling, and 
lakehouse federated query acceleration. Start by understanding the concepts, 
then choose between synchronous and asynchronous materialized views based on 
your freshness requirements.
+
+Please refer to the [materialized view](./intro) related documentation.
diff --git a/versioned_sidebars/version-4.x-sidebars.json 
b/versioned_sidebars/version-4.x-sidebars.json
index 99b2ca4935b..fc882dfbab8 100644
--- a/versioned_sidebars/version-4.x-sidebars.json
+++ b/versioned_sidebars/version-4.x-sidebars.json
@@ -580,6 +580,33 @@
             "query-data/lateral-view"
           ]
         },
+        {
+          "type": "category",
+          "label": "Materialized View",
+          "link": {
+            "type": "doc",
+            "id": "query-acceleration/materialized-view/intro"
+          },
+          "items": [
+            "query-acceleration/materialized-view/overview",
+            "query-acceleration/materialized-view/sync-materialized-view",
+            
"query-acceleration/tuning/tuning-plan/transparent-rewriting-with-sync-mv",
+            {
+              "type": "category",
+              "label": "Async Materialized View",
+              "link": {
+                "type": "doc",
+                "id": 
"query-acceleration/materialized-view/async-materialized-view/overview"
+              },
+              "items": [
+                
"query-acceleration/materialized-view/async-materialized-view/functions-and-demands",
+                
"query-acceleration/materialized-view/async-materialized-view/use-guide",
+                
"query-acceleration/tuning/tuning-plan/transparent-rewriting-with-async-mv",
+                
"query-acceleration/materialized-view/async-materialized-view/faq"
+              ]
+            }
+          ]
+        },
         {
           "type": "category",
           "label": "Performance & Tuning",
@@ -619,33 +646,7 @@
                     
"query-acceleration/tuning/tuning-plan/optimizing-table-scanning"
                   ]
                 },
-                {
-                  "type": "category",
-                  "label": "Materialized View",
-                  "link": {
-                    "type": "doc",
-                    "id": "query-acceleration/materialized-view/intro"
-                  },
-                  "items": [
-                    "query-acceleration/materialized-view/overview",
-                    
"query-acceleration/materialized-view/sync-materialized-view",
-                    
"query-acceleration/tuning/tuning-plan/transparent-rewriting-with-sync-mv",
-                    {
-                      "type": "category",
-                      "label": "Async Materialized View",
-                      "link": {
-                        "type": "doc",
-                        "id": 
"query-acceleration/materialized-view/async-materialized-view/overview"
-                      },
-                      "items": [
-                        
"query-acceleration/materialized-view/async-materialized-view/functions-and-demands",
-                        
"query-acceleration/materialized-view/async-materialized-view/use-guide",
-                        
"query-acceleration/tuning/tuning-plan/transparent-rewriting-with-async-mv",
-                        
"query-acceleration/materialized-view/async-materialized-view/faq"
-                      ]
-                    }
-                  ]
-                },
+                "query-acceleration/materialized-view/intro-link",
                 {
                   "type": "category",
                   "label": "Join Optimization",


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to