diff --git a/i18n/de/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md b/i18n/de/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
index 88a9bf37..0a38c188 100644
--- a/i18n/de/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
+++ b/i18n/de/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
@@ -35,7 +35,7 @@ Der vollständige Quellcode ist auf GitHub verfügbar: [https://github.com/DHTML
## Demo-Repository
Ein vollständiges, funktionsfähiges Projekt, das dieser Anleitung entspricht, ist auf GitHub verfügbar:
-- https://github.com/dhtmlx/scheduler-google-auth-demo
+- https://github.com/DHTMLX/scheduler-google-calendar-demo
Die Anleitung erläutert die wichtigsten Schritte und zeigt den relevanten Integrationscode. Das Repository ist die „voll funktionsfähige Referenz“.
@@ -50,8 +50,8 @@ Führen Sie eine der folgenden Optionen aus:
- Das Repository klonen:
~~~bash title="Terminal"
-git clone https://github.com/dhtmlx/scheduler-google-auth-demo.git
-cd scheduler-google-auth-demo
+git clone https://github.com/dhtmlx/scheduler-google-calendar-demo.git
+cd scheduler-google-calendar-demo
~~~
Wenn Ihr Projekt `@dhx/*`-Pakete aus dem privaten Registry installiert, konfigurieren Sie npm:
@@ -164,7 +164,7 @@ In diesem Schritt trennen Sie die Verantwortlichkeiten, sodass Scheduler eine UI
Eine typische Struktur:
~~~text title="Project structure"
-scheduler-google-auth-demo/
+scheduler-google-calendar-demo/
client/
index.ejs
main.ts
diff --git a/i18n/de/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md b/i18n/de/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md
new file mode 100644
index 00000000..8f457ceb
--- /dev/null
+++ b/i18n/de/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md
@@ -0,0 +1,462 @@
+---
+title: React Scheduler und Starhive-Integration
+sidebar_label: Starhive Schnellstart
+description: "DHTMLX React Scheduler mit einem Starhive NoSQL-Backend über Next.js API-Routen verbinden."
+---
+
+# React Scheduler und Starhive-Integration
+
+Diese Anleitung verbindet **React Scheduler** mit einem **Starhive** NoSQL-Backend über Next.js Route-Handler. Starhive bietet ein typisiertes Schema und einen generierten TypeScript-Client, sodass die API-Schicht minimal bleibt: ein Endpunkt lädt Ereignisse und Ressourcen, ein anderer erledigt Create / Update / Delete.
+
+Sie werden Folgendes erstellen:
+
+- eine Next.js-Seite, die den Scheduler in einer Client-Komponente hostet
+- `/api/load` – lädt beim ersten Rendern Ereignisse und Ressourcen von Starhive
+- `/api/event` (POST) und `/api/event/[id]` (PUT, DELETE) – Schreibpfade, die vom Scheduler `dataBridge` verwendet werden
+
+:::note
+Der vollständige Quellcode ist [auf GitHub verfügbar](https://github.com/DHTMLX/react-scheduler-starhive-demo).
+:::
+
+## Voraussetzungen
+
+- Grundlagen zu Next.js + React + TypeScript
+- Node.js 18+
+- Ein [Starhive](https://starhive.com/) Konto (die 30-tägige Testversion reicht aus)
+
+## Schritt 1. Projekt erstellen
+
+```bash
+npx create-next-app@latest react-scheduler-starhive-demo
+cd react-scheduler-starhive-demo
+```
+
+Installieren Sie den React Scheduler wie im [Installationsleitfaden für den React Scheduler](integrations/react/installation.md) beschrieben. Zur Evaluation:
+
+```bash
+npm install @dhtmlx/trial-react-scheduler
+```
+
+Wenn Sie bereits das Professional-Paket verwenden, ersetzen Sie `@dhtmlx/trial-react-scheduler` durch `@dhx/react-scheduler` in Befehlen und Imports.
+
+Außerdem benötigen Sie `axios` – es ist eine Peer-Abhängigkeit des generierten Starhive TypeScript-Clients.
+
+```bash
+npm install axios
+```
+
+## Schritt 2. Starhive Space einrichten
+
+Nach dem Anmelden klicken Sie rechts oben auf **+ Create** und benennen den Space mit `Scheduler`.
+
+Im Space erstellen Sie zwei Typen: `Resources` und `Events`. Resources halten die Zeilen der Timeline (Teams, Personen, Räume usw.). Events beziehen sich jeweils auf eine Resource.
+
+Fügen Sie die folgenden Attribute über die Schaltfläche **+ Attribute** hinzu. Starhive erzeugt automatisch die `id` für jeden Eintrag, daher müssen Sie sie nicht deklarieren.
+
+**Resources type**
+
+| Feld | Typ |
+| ------- | ---- |
+| `label` | Text |
+
+**Events type**
+
+| Feld | Typ |
+| ------------- | -------------------------- |
+| `text` | Text |
+| `start_date` | Datum & Uhrzeit |
+| `end_date` | Datum & Uhrzeit |
+| `resource_id` | Referenz → Resources |
+
+## Schritt 3. Beispieldaten importieren
+
+Erstellen Sie `scheduler_resources.csv`:
+
+```csv
+label
+"Frontend Team"
+"Backend Team"
+"QA Team"
+"DevOps"
+"Security Team"
+```
+
+Und `scheduler_events.csv`:
+
+```csv
+text,start_date,end_date,resource_id
+"Development","2026-04-01T08:00:00","2026-04-01T10:30:00","Frontend Team"
+"Code Review","2026-04-01T09:00:00","2026-04-01T11:30:00","Backend Team"
+"QA Testing","2026-04-01T10:00:00","2026-04-01T13:00:00","QA Team"
+"Deployment","2026-04-01T11:00:00","2026-04-01T13:30:00","DevOps"
+"Incident Response","2026-04-01T12:00:00","2026-04-01T15:00:00","DevOps"
+"Maintenance Window","2026-04-01T08:30:00","2026-04-01T11:00:00","Backend Team"
+"Security Scan","2026-04-01T13:00:00","2026-04-01T15:30:00","Security Team"
+```
+
+Im Starhive UI öffnen Sie den Typ und klicken Sie für jeden Datei den CSV-Import.
+
+## Schritt 4. Schema generieren und kopieren
+
+Gehen Sie zu **Settings → API Connectors**. Wählen Sie den Space `Scheduler`, setzen Sie die Sprache auf TypeScript, klicken Sie auf **Generate**, dann **Download**.
+
+Entpacken Sie das Archiv, lokalisieren Sie den Ordner `starhive` unter `project/src/io/` und kopieren Sie ihn nach `lib/starhive/` in Ihr Next.js-Projekt. Die generierten Dateien enthalten arbeitsbereichsspezifische UUIDs, daher führen Sie diesen Schritt jedes Mal erneut aus, wenn sich das Schema ändert oder Sie zwischen Arbeitsbereichen wechseln.
+
+:::note
+Zum Zeitpunkt des Verfassens erzeugt der Starhive TypeScript-Generator eine Ausgabe, die kein strenges TypeScript erfüllt: ein fehlender `Sla.ts`-Verweis, eine fehlende Implementierung von `visitSlaAttribute` im Inline-`AttributeVisitor`-Literal und ein `client.request
`-Aufruf gegen ein Feld vom Typ `any` (TS2347). Das Begleit-Demo-Repo enthält drei minimale Patches, die diese Probleme umgehen; siehe [`lib/starhive/PATCHES.md`](https://github.com/DHTMLX/react-scheduler-starhive-demo/blob/main/lib/starhive/) für die Diffs. Wenden Sie dieselben Patches erneut an, wenn Sie das Schema regenerieren, bis Starhive einen Fix liefert.
+:::
+
+## Schritt 5. Starhive-Client konfigurieren
+
+Erstellen Sie `lib/starhiveClient.ts`:
+
+```ts title="lib/starhiveClient.ts"
+import { StarhiveClient } from "./starhive/client/StarhiveClient";
+import { JSON_DECODERS } from "./starhive/schema/JsonDecoders";
+
+let starhiveClient: StarhiveClient | null = null;
+
+export function getStarhiveClient() {
+ if (starhiveClient) return starhiveClient;
+
+ const workspaceId = process.env.STARHIVE_WORKSPACE_ID;
+ const apiKey = process.env.STARHIVE_API_TOKEN;
+
+ if (!workspaceId || !apiKey) {
+ throw new Error("Missing Starhive configuration (workspaceId or API token)");
+ }
+
+ starhiveClient = new StarhiveClient(apiKey, workspaceId, JSON_DECODERS);
+ return starhiveClient;
+}
+```
+
+Die Funktion cacht den Client im Modul-Scope, sodass Route-Handler eine einzige Instanz teilen.
+
+Fügen Sie `.env.local` (oder `.env`) im Projektstamm hinzu:
+
+```env title=".env.local"
+STARHIVE_API_TOKEN=your-api-token
+STARHIVE_WORKSPACE_ID=your-workspace-id
+```
+
+Generieren Sie den API-Token unter **Settings → Personal access tokens**. Die Workspace-ID ist der Pfadabschnitt in `https://app.starhive.com/workspace//home`.
+
+## Schritt 6. Ereignisse und Ressourcen laden
+
+Erstellen Sie `app/api/load/route.ts`:
+
+```ts title="app/api/load/route.ts"
+import { NextResponse } from 'next/server';
+import { getStarhiveClient } from '@/lib/starhiveClient';
+import { Events } from '@/lib/starhive/schema/Events';
+import { Resources } from '@/lib/starhive/schema/Resources';
+
+function normalizeEvents(events: Events[]) {
+ return events.map(ev => ({
+ id: ev.getId() || '',
+ text: ev.getText(),
+ start_date: ev.getStartDate(),
+ end_date: ev.getEndDate(),
+ resource_id: ev.getResourceId()?.[0] || null,
+ }));
+}
+
+export async function GET() {
+ try {
+ const client = getStarhiveClient();
+ const [events, resources] = await Promise.all([
+ client.search(Events.TYPE_ID, ""),
+ client.search(Resources.TYPE_ID, "")
+ ]);
+
+ return NextResponse.json({
+ events: normalizeEvents(events.result),
+ resources: resources.result.map((r) => ({
+ key: r.getId(),
+ label: r.getLabel(),
+ })),
+ });
+ } catch (error) {
+ return NextResponse.json({ error: 'Failed to load data' }, { status: 500 });
+ }
+}
+```
+
+`normalizeEvents` wandelt jedes Starhive-Objekt in die Form um, die der React Scheduler erwartet: `{ id, text, start_date, end_date, resource_id }`. Ressourcen werden zu `{ key, label }` zusammengefasst, was von der Timeline-Ansicht als `y_unit` konsumiert wird.
+
+Rufen Sie nach dem Starten des Entwicklungsservers die URL `http://localhost:3000/api/load` auf, um die JSON-Form zu überprüfen.
+
+## Schritt 7. Scheduler rendern und Ereignisse laden
+
+Erstellen Sie `app/page.tsx`:
+
+```tsx title="app/page.tsx"
+'use client';
+
+import { useEffect, useMemo, useState } from 'react';
+import ReactScheduler, {
+ type Event,
+ type SchedulerViewsProp,
+} from '@dhtmlx/trial-react-scheduler';
+import '@dhtmlx/trial-react-scheduler/dist/react-scheduler.css';
+
+type Resource = { key: string; label: string };
+
+export default function Scheduler() {
+ const [resources, setResources] = useState([]);
+ const [events, setEvents] = useState([]);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ fetch('/api/load')
+ .then((response) => response.json())
+ .then((data) => {
+ setResources(data.resources);
+ setEvents(data.events);
+ })
+ .catch((error) => {
+ console.error('Failed to load resources data:', error);
+ })
+ .finally(() => {
+ setLoading(false);
+ });
+ }, []);
+
+ const views: SchedulerViewsProp = useMemo(
+ () => ({
+ timeline: [
+ {
+ name: "timeline",
+ x_unit: "hour",
+ x_date: "%H:%i",
+ x_step: 1,
+ x_start: 8,
+ x_size: 13,
+ x_length: 13,
+ event_dy: 50,
+ event_min_dy: 50,
+ y_property: "resource_id",
+ render: "bar",
+ y_unit: resources,
+ },
+ ],
+ }),
+ [resources]
+ );
+
+ if (loading) {
+ return Loading...
;
+ }
+
+ return (
+
+
+
+ );
+}
+```
+
+Ein `loading`-Flag ist vorzuziehen gegenüber dem Prüfen von `events.length` oder `resources.length`: Ein Workspace, der tatsächlich zero Events hat, sollte dennoch den leeren Scheduler rendern statt in der Ladeanzeige hängen zu bleiben.
+
+Führen Sie `npm run dev` aus – die Timeline erscheint mit den importierten Ereignissen, gruppiert nach Ressource.
+
+## Schritt 8. Die CRUD-Endpunkte implementieren
+
+Die Scheduler-`dataBridge` ruft drei Endpunkte auf – POST für Create, PUT für Update, DELETE für Delete – und erwartet bestimmte Antwortformen:
+
+| HTTP-Methode | Endpoint | Antwort |
+| ----------- | ------------------------- | --------------------------------- |
+| `GET` | `/api/load` | `{ events, resources }` |
+| `POST` | `/api/event` | `{ action: "inserted", tid: id }` |
+| `PUT` | `/api/event/{event_id}` | `{ action: "updated" }` |
+| `DELETE` | `/api/event/{event_id}` | `{ action: "deleted" }` |
+
+Erstellen Sie den POST-Handler unter `app/api/event/route.ts`:
+
+```ts title="app/api/event/route.ts"
+import { NextRequest, NextResponse } from 'next/server';
+import { getStarhiveClient } from '@/lib/starhiveClient';
+import { Events } from '@/lib/starhive/schema/Events';
+
+export async function POST(req: NextRequest) {
+ try {
+ const { text, start_date, end_date, resource_id } = await req.json();
+ const client = getStarhiveClient();
+
+ const event = Events.builder()
+ .text(text)
+ .startDate(new Date(start_date))
+ .endDate(new Date(end_date))
+ .resourceId([resource_id])
+ .build();
+
+ const result = await client.createObject(event);
+ return NextResponse.json({ action: 'inserted', tid: result.getId() });
+ } catch (error) {
+ return NextResponse.json({ error: 'Create failed' }, { status: 500 });
+ }
+}
+```
+
+Und die dynamischen PUT/DELETE-Handler unter `app/api/event/[id]/route.ts`:
+
+```ts title="app/api/event/[id]/route.ts"
+import { NextRequest, NextResponse } from 'next/server';
+import { Events } from "@/lib/starhive/schema/Events";
+import { getStarhiveClient } from "@/lib/starhiveClient";
+
+export async function PUT(
+ request: NextRequest,
+ { params }: { params: Promise<{ id: string }> },
+) {
+ try {
+ const { id } = await params;
+ const body = await request.json();
+ const client = getStarhiveClient();
+
+ const existingEvent = await client.getObject(id, Events.TYPE_ID);
+ if (!existingEvent) {
+ return NextResponse.json({ error: 'Event not found' }, { status: 404 });
+ }
+
+ const updatedEvent = Events.builder()
+ .id(id)
+ .text(body.text)
+ .startDate(new Date(body.start_date))
+ .endDate(new Date(body.end_date))
+ .resourceId([body.resource_id])
+ .build();
+
+ await client.updateObject(updatedEvent);
+ return NextResponse.json({ action: 'updated' });
+ } catch (error: any) {
+ console.error('Update error:', error);
+ return NextResponse.json(
+ { error: 'Update failed', details: error.message },
+ { status: 500 }
+ );
+ }
+}
+
+export async function DELETE(
+ request: NextRequest,
+ { params }: { params: Promise<{ id: string }> },
+) {
+ try {
+ const { id } = await params;
+ const client = getStarhiveClient();
+ await client.deleteObjectsInBulk([id]);
+
+ return NextResponse.json({ action: 'deleted' });
+ } catch (error: any) {
+ console.error('Delete error:', error);
+ return NextResponse.json(
+ { error: 'Delete failed', details: error.message },
+ { status: 500 }
+ );
+ }
+}
+```
+
+:::note
+In Next.js 15+ ist das `params`-Argument dynamischer Routen-Handler ein `Promise`. Typisieren Sie es immer als `Promise<{...}>` und warten Sie darauf, bevor Sie die Segmentwerte lesen – das Weglassen der `Promise<>`-Umhüllung kompiliert in einigen Setups, schlägt aber im Strict-Modus fehlt.
+:::
+
+## Schritt 9. Den dataBridge anschließen
+
+Erstellen Sie eine kleine client-seitige Hilfsfunktion unter `services/scheduler.ts`:
+
+```ts title="services/scheduler.ts"
+import type { Event } from '@dhtmlx/trial-react-scheduler';
+
+async function request(url: string, options: RequestInit): Promise {
+ const res = await fetch(url, options);
+ if (!res.ok) throw new Error(`Request failed: ${res.status}`);
+ return res.json();
+}
+
+export function createEvent(event: Event) {
+ return request('/api/event', {
+ method: 'POST',
+ body: JSON.stringify(event),
+ headers: { 'Content-Type': 'application/json' },
+ });
+}
+
+export function updateEvent(event: Event) {
+ return request(`/api/event/${event.id}`, {
+ method: 'PUT',
+ body: JSON.stringify(event),
+ headers: { 'Content-Type': 'application/json' },
+ });
+}
+
+export function deleteEvent(id: string | number) {
+ return request(`/api/event/${id}`, {
+ method: 'DELETE',
+ });
+}
+```
+
+Schließen Sie den `dataBridge` an die Seite an. Aktualisieren Sie `app/page.tsx` mit den Imports und einer `data`-Eigenschaft auf ``:
+
+```tsx title="app/page.tsx"
+import { createEvent, deleteEvent, updateEvent } from '@/services/scheduler';
+
+// inside the Scheduler component:
+const dataBridge = useMemo(() => ({
+ save: (entity: string, action: string, payload: Event, id: string | number) => {
+ if (entity !== "event") return;
+
+ switch (action) {
+ case "update":
+ return updateEvent(payload);
+ case "create":
+ return createEvent(payload);
+ case "delete":
+ return deleteEvent(id);
+ default:
+ console.warn(`Unknown action: ${action}`);
+ return;
+ }
+ },
+}), []);
+
+// an ReactScheduler übergeben:
+
+```
+
+## Testen
+
+```bash
+npm run dev
+```
+
+Öffnen Sie `http://localhost:3000`, ziehen Sie ein Ereignis in eine neue Zeitspanne, bearbeiten Sie dessen Text und löschen Sie eines. Jede Änderung sollte sofort in der Starhive-Oberfläche unter dem Typ `Events` erscheinen.
+
+## Hinweise zur Starhive-Integration
+
+- **Nur serverseitige Anmeldeinformationen.** `STARHIVE_API_TOKEN` und `STARHIVE_WORKSPACE_ID` werden in Route-Handlern (`getStarhiveClient`) gelesen; sie gelangen nie in das Browser-Bundle. Verschieben Sie den Starhive-Client nicht in eine Client-Komponente oder geben Sie das Token nicht über eine `NEXT_PUBLIC_*`-Variable weiter.
+- **Schema-Neugenerierung.** Wann immer Sie Attribute in Starhive hinzufügen oder umbenennen, regenerieren Sie das TypeScript-Schema und ersetzen Sie `lib/starhive/`. Wenden Sie ggf. die Patches in [`lib/starhive/PATCHES.md`](https://github.com/DHTMLX/react-scheduler-starhive-demo/blob/main/lib/starhive/) erneut an, falls `next build` dieselben upstream-Probleme meldet.
+- **Kein Echtzeit-Sync.** Im Gegensatz zur Firebase-Integration sendet Starhive keine Änderungen sofort an verbundene Clients. Mehrere Benutzer, die denselben Scheduler bearbeiten, überschreiben gegenseitig ihre Änderungen. Für Mehrbenutzer-Szenarien fügen Sie auf dem Client Polling hinzu – oder verbinden Sie Starhive-Webhooks mit SSE/WebSockets, um Invalidation-Ereignisse auszulösen und den `events`-Zustand bei entfernten Änderungen zu aktualisieren.
+- **Dynamisches Laden großer Datensätze.** Die `/api/load`-Route lädt alle Ereignisse im Workspace. Für die Produktion akzeptieren Sie `from` / `to`-Abfrageparameter im GET-Handler, filtern Sie nach `start_date` / `end_date` und rufen Sie `scheduler.setLoadMode("day")` auf dem Client auf, damit nur der sichtbare Bereich abgerufen wird.
+- **Referenzattribute tragen Arrays.** `Events.getResourceId()` gibt `string[] | undefined` zurück, da Starhives Referenzattribute mehrfach vorkommen können. Das Demo-Beispiel flatten dies über `?.[0] || null`. Wenn Sie Ereignisse mehreren Ressourcen zuordnen lassen, passen Sie die Auflösung des Timeline-View-`y_property` sowie die Normalize-/Builder-Aufrufe entsprechend an.
+
+## Verwandte Seiten
+
+- [Datenbindung & Grundlagen der Zustandsverwaltung](integrations/react/state/state-management-basics.md)
+- [React Scheduler Überblick](integrations/react/overview.md#bindingdata)
+- [Server-Integration](guides/server-integration.md)
+- [React Scheduler und Firebase-Integration] (integrations/react/firebase-integration.md) – sibling pattern with realtime sync
\ No newline at end of file
diff --git a/i18n/de/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md b/i18n/de/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
index 78305825..a2e14d3d 100644
--- a/i18n/de/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
+++ b/i18n/de/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
@@ -15,7 +15,7 @@ Am Ende verfügen Sie über einen Scheduler mit:
- snapshotbasierte Undo/Redo (Ereignisse + Konfiguration)
:::note
-Der vollständige Quellcode ist [auf GitHub verfügbar](https://github.com/nicetip/react-scheduler-valtio-starter).
+Der vollständige Quellcode ist [auf GitHub verfügbar](https://github.com/DHTMLX/react-scheduler-valtio-starter).
:::
## Voraussetzungen
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md b/i18n/ko/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md
index 4ef5ef06..b5966319 100644
--- a/i18n/ko/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md
@@ -1,63 +1,89 @@
---
title: "CDN 링크 전체 목록"
-sidebar_label: "CDN 링크 전체 목록"
+sidebar_label: "CDN 링크 목록"
---
# CDN 링크 전체 목록
-이 문서에서는 CDN을 통해 Scheduler 기능을 포함할 수 있는 링크의 전체 모음을 제공합니다. 각 섹션은 특정 Scheduler 버전에 할당되어 있습니다:
+이 문서는 애플리케이션에 **dhtmlxScheduler**를 포함하기 위한 CDN 링크를 나열합니다.
-- 코어 파일 - 주요 기능이 포함된 *dhtmlxscheduler.js* 및 *dhtmlxscheduler.css* 파일
-- 스킨 - 사용 가능한 모든 [스킨](guides/skins.md)에 대한 링크
+Scheduler는 두 개의 핵심 파일로 구성됩니다:
-:::note
-v6.0부터 모든 [확장 기능](guides/extensions-list.md)이 *dhtmlxscheduler.js* 파일에 번들로 포함됩니다. dhtmlxScheduler 5.3 이하 버전을 사용 중인 경우 [마이그레이션 가이드](migration.md#53---60)를 참고하세요.
-:::
+- **자바스크립트:** `dhtmlxscheduler.js`
+- **스타일:** `dhtmlxscheduler.css`
-## 최신 Scheduler 버전
-라이브러리의 최신 버전을 사용하려면, 소스 경로를 **https://cdn.dhtmlx.com/scheduler/edge/...** 로 설정하세요.
+## 최신 Scheduler 버전(edge)
-코어 파일: [JS](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.css)
+다음 형식으로 사용하십시오:
-스킨: [Terrace](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_contrast_white.css).
+`https://cdn.dhtmlx.com/scheduler/edge/...`
-## 최신 Scheduler 버전, 압축 해제됨
+### 핵심 파일
-최신 버전의 압축 해제된 소스를 사용하려면, 경로를 **https://cdn.dhtmlx.com/scheduler/edge/sources/...** 로 설정하세요.
+- JS: https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.css
-코어 파일: [JS](https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.css)
-스킨: [Terrace](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_contrast_white.css).
+## 최신 Scheduler 버전(edge), 비압축
+
+다음 형식으로 사용하십시오:
+
+`https://cdn.dhtmlx.com/scheduler/edge/sources/...`
+
+### 핵심 파일
+
+- JS: https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.css
+
## 특정 Scheduler 버전
-라이브러리의 특정 버전을 참조하려면, 소스 경로를 **https://cdn.dhtmlx.com/scheduler/[version_number]/...** 로 설정하세요.
+다음 형식으로 사용하십시오:
+
+`https://cdn.dhtmlx.com/scheduler/[version_number]/...`
+
+`[version_number]`는 패키지의 `major.minor` 버전을 지정합니다. 예: **7.0**, **6.0**, **5.3** 등. CDN은 각 major/minor 릴리스에 대해 항상 최신 패치 버전을 제공합니다.
+
+### 핵심 파일
+
+- JS: https://cdn.dhtmlx.com/scheduler/7.0/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/7.0/dhtmlxscheduler.css
+
+### 스킨(오직 v6.0 이하 버전용)
+
+v6.0 이하 버전에서는 별도의 스킨 파일을 제공합니다.
+v7.0부터는 모든 스킨이 `dhtmlxscheduler.css`에 포함되며, `scheduler.skin`/`scheduler.setSkin()`으로 선택됩니다. 자세한 내용은 [Migration guide](migration.md)를 확인하십시오.
+
+- Terrace: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_terrace.css
+- Flat: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_flat.css
+- Contrast Black: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_contrast_black.css
+- Contrast White: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_contrast_white.css
+- Material: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_material.css
+
+## 특정 Scheduler 버전, 비압축
+
+다음 형식으로 사용하십시오:
+
+`https://cdn.dhtmlx.com/scheduler/[version_number]/sources/...`
+
+`[version_number]`는 패키지의 `major.minor` 버전을 지정합니다. 예: **7.0**, **6.0**, **5.3** 등. CDN은 각 major/minor 릴리스에 대해 항상 최신 패치 버전을 제공합니다.
+
+### 핵심 파일
-코어 파일: [JS](https://cdn.dhtmlx.com/scheduler/4.3/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/4.3/dhtmlxscheduler.css)
+- JS: https://cdn.dhtmlx.com/scheduler/7.0/sources/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/7.0/sources/dhtmlxscheduler.css
-스킨: [Terrace](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_contrast_white.css).
-## 특정 Scheduler 버전, 압축 해제됨
+### 스킨(오직 v6.0 이하 버전용)
-특정 버전의 압축 해제된 소스를 사용하려면, 경로를 **https://cdn.dhtmlx.com/scheduler/[version_number]/sources/...** 로 설정하세요.
+v6.0 이하 버전에서는 별도의 스킨 파일이 제공됩니다.
+v7.0부터는 모든 스킨이 `dhtmlxscheduler.css`에 포함되며, `scheduler.skin`/`scheduler.setSkin()`으로 선택됩니다. 자세한 내용은 [Migration guide](migration.md)를 확인하십시오.
-코어 파일: [JS](https://cdn.dhtmlx.com/scheduler/4.3/sources/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/4.3/sources/skins/dhtmlxscheduler.css)
+비압축 스킨 파일:
-스킨: [Terrace](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_contrast_white.css).
+- Terrace: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_terrace.css
+- Flat: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_flat.css
+- Contrast Black: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_contrast_black.css
+- Contrast White: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_contrast_white.css
+- Material: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_material.css
\ No newline at end of file
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/guides/configuration.md b/i18n/ko/docusaurus-plugin-content-docs/current/guides/configuration.md
index 8b89e288..7d46a6c2 100644
--- a/i18n/ko/docusaurus-plugin-content-docs/current/guides/configuration.md
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/guides/configuration.md
@@ -7,8 +7,8 @@ sidebar_label: "일반 설정 안내"
스케줄러의 외관을 사용자 정의하려면, 라이브러리는 세 가지 주요 객체를 제공합니다:
-- scheduler.config - 날짜, 스케일, 컨트롤 등 다양한 옵션을 설정할 수 있습니다.
-- scheduler.templates - 날짜, 제목, 툴팁의 포맷 및 스타일링을 위한 템플릿을 제공합니다.
+- [scheduler.config](api/api_overview.md#scheduler-properties) - 날짜, 스케일, 컨트롤 등 다양한 옵션을 설정할 수 있습니다.
+- [scheduler.templates](api/api_overview.md#scheduler-templates) - 날짜, 제목, 툴팁의 포맷 및 스타일링을 위한 템플릿을 제공합니다.
- [scheduler.xy](api/other/xy.md) - 다양한 스케줄러 요소의 크기를 정의하는 설정입니다.
또한, dhtmlxScheduler는 컴포넌트의 기능을 확장하는 [여러 확장 기능](#extensions)을 포함하고 있습니다.
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/guides/multiuser-live-updates.md b/i18n/ko/docusaurus-plugin-content-docs/current/guides/multiuser-live-updates.md
index 9b0ed311..155d2310 100644
--- a/i18n/ko/docusaurus-plugin-content-docs/current/guides/multiuser-live-updates.md
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/guides/multiuser-live-updates.md
@@ -365,4 +365,4 @@ remoteEvents.on({
"value":{"type":"custom-action","value":value}}}
~~~
-이 가이드는 DHTMLX Scheduler에서 실시간 업데이트를 구현하고 사용자 정의하는 기초를 제공합니다. 전체 예제는 [GitHub 저장소](https://github.com/DHTMLX/scheduler-multiuser-backend-demo/.를 참고하십시오.
\ No newline at end of file
+이 가이드는 DHTMLX Scheduler에서 실시간 업데이트를 구현하고 사용자 정의하는 기초를 제공합니다. 전체 예제는 [GitHub 저장소](https://github.com/DHTMLX/scheduler-multiuser-backend-demo/).를 참고하십시오.
\ No newline at end of file
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md b/i18n/ko/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
index 7064fdbe..a57c112c 100644
--- a/i18n/ko/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
@@ -35,7 +35,7 @@ description: "OAuth 2.0 및 Google Calendar API v3를 사용하는 Node.js + Exp
## 데모 저장소
이 가이드와 일치하는 완전한 작동 프로젝트는 GitHub에서 확인할 수 있습니다:
-- https://github.com/dhtmlx/scheduler-google-auth-demo
+- https://github.com/dhtmlx/scheduler-google-calendar-demo
가이드는 핵심 단계와 중요한 통합 코드를 설명합니다. 저장소는 “실행 가능한 전체 참조”입니다.
@@ -50,8 +50,8 @@ description: "OAuth 2.0 및 Google Calendar API v3를 사용하는 Node.js + Exp
- 저장소를 클론합니다:
~~~bash title="Terminal"
-git clone https://github.com/dhtmlx/scheduler-google-auth-demo.git
-cd scheduler-google-auth-demo
+git clone https://github.com/dhtmlx/scheduler-google-calendar-demo.git
+cd scheduler-google-calendar-demo
~~~
프로젝트가 private 레지스트리에서 `@dhx/*` 패키지를 설치한다면 npm을 구성하십시오:
@@ -164,7 +164,7 @@ http://localhost:3000
일반적인 구조:
~~~text title="Project structure"
-scheduler-google-auth-demo/
+scheduler-google-calendar-demo/
client/
index.ejs
main.ts
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md b/i18n/ko/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md
new file mode 100644
index 00000000..8c3013dd
--- /dev/null
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md
@@ -0,0 +1,462 @@
+---
+title: 리액트 스케줄러와 Starhive 통합
+sidebar_label: Starhive 빠른 시작
+description: "Next.js API 경로를 통해 DHTMLX React Scheduler를 Starhive NoSQL 백엔드에 연결합니다."
+---
+
+# 리액트 스케줄러와 Starhive 통합
+
+이 자습서는 **React Scheduler**를 **Starhive** NoSQL 백엔드에 Next.js Route Handlers를 통해 연결합니다. Starhive는 타입이 지정된 스키마와 생성된 TypeScript 클라이언트를 제공하므로 API 계층은 최소화됩니다: 이벤트와 리소스를 로드하는 하나의 엔드포인트와 생성/수정/삭제를 처리하는 또 다른 엔드포인트가 있습니다.
+
+다음과 같은 구성을 구축합니다:
+
+- 클라이언트 컴포넌트에 Scheduler를 호스팅하는 Next.js 페이지
+- `/api/load` - 첫 렌더링 시 Starhive에서 이벤트와 리소스를 가져옵니다
+- `/api/event` (POST) 및 `/api/event/[id]` (PUT, DELETE) - Scheduler의 `dataBridge`가 사용하는 쓰기 경로
+
+:::note
+전체 소스 코드는 [GitHub에서 이용 가능](https://github.com/DHTMLX/react-scheduler-starhive-demo)합니다.
+:::
+
+## 전제 조건
+
+- Next.js + React + TypeScript 기초 지식
+- Node.js 18+
+- Starhive 계정(30일 체험으로 충분)
+
+## 1단계. 프로젝트 생성
+
+```bash
+npx create-next-app@latest react-scheduler-starhive-demo
+cd react-scheduler-starhive-demo
+```
+
+React Scheduler를 [React Scheduler 설치 가이드](integrations/react/installation.md)에 따라 설치합니다. 평가용으로:
+
+```bash
+npm install @dhtmlx/trial-react-scheduler
+```
+
+이미 Professional 패키지를 사용 중이라면 명령 및 가져오기에 있는 `@dhtmlx/trial-react-scheduler`를 `@dhx/react-scheduler`로 바꿉니다.
+
+생성된 Starhive TypeScript 클라이언트의 피어 의존성이 필요한 경우도 있으므로 `axios`도 필요합니다.
+
+```bash
+npm install axios
+```
+
+## 2단계. Starhive 공간 설정
+
+로그인 후 우측 상단 모서리에 있는 **+ Create**를 클릭하고 공간 이름을 `Scheduler`로 설정합니다.
+
+공간 내부에서 두 가지 타입을 만듭니다: `Resources`와 `Events`. Resources는 타임라인의 행을 보유하고(팀, 사람, 방 등), Events는 하나의 Resources를 참조합니다.
+
+다음 속성을 **+ Attribute** 버튼을 통해 추가합니다. Starhive는 각 항목의 `id`를 자동으로 생성하므로 직접 선언할 필요가 없습니다.
+
+**Resources type**
+
+| Field | Type |
+| ------- | ---- |
+| `label` | Text |
+
+**Events type**
+
+| Field | Type |
+| ------------- | -------------------------- |
+| `text` | Text |
+| `start_date` | Date & Time |
+| `end_date` | Date & Time |
+| `resource_id` | Reference → Resources |
+
+## 3단계. 샘플 데이터 가져오기
+
+`scheduler_resources.csv`를 생성합니다:
+
+```csv
+label
+"Frontend Team"
+"Backend Team"
+"QA Team"
+"DevOps"
+"Security Team"
+```
+
+그리고 `scheduler_events.csv`를 생성합니다:
+
+```csv
+text,start_date,end_date,resource_id
+"Development","2026-04-01T08:00:00","2026-04-01T10:30:00","Frontend Team"
+"Code Review","2026-04-01T09:00:00","2026-04-01T11:30:00","Backend Team"
+"QA Testing","2026-04-01T10:00:00","2026-04-01T13:00:00","QA Team"
+"Deployment","2026-04-01T11:00:00","2026-04-01T13:30:00","DevOps"
+"Incident Response","2026-04-01T12:00:00","2026-04-01T15:00:00","DevOps"
+"Maintenance Window","2026-04-01T08:30:00","2026-04-01T11:00:00","Backend Team"
+"Security Scan","2026-04-01T13:00:00","2026-04-01T15:30:00","Security Team"
+```
+
+Starhive UI에서 각 파일의 타입을 열고 **CSV import**를 클릭합니다.
+
+## 4단계. 스키마 생성 및 복사
+
+**Settings → API Connectors**로 이동합니다. `Scheduler` 공간을 선택하고 언어를 TypeScript로 설정한 다음 **Generate**, 그리고 **Download**를 클릭합니다.
+
+압축을 풀고 `project/src/io/` 아래의 `starhive` 폴더를 찾은 뒤, Next.js 프로젝트의 `lib/starhive/`로 복사합니다. 생성된 파일은 작업공간별 UUID를 포함하고 있어 스키마가 변경되거나 워크스페이스를 전환할 때마다 이 단계를 반복해야 합니다.
+
+:::note
+작성 시점의 Starhive TypeScript 생성기는 엄격한 TypeScript를 통과하지 않는 출력(`Sla.ts` 참조 누락, 인라인 `AttributeVisitor` 리터럴의 구현 누락, `client.request` 호출이 `any`로 타입된 필드에 대해 발생하는 TS2347 등)을 만들 수 있습니다. 보조 데모 저장소에는 이러한 문제를 해결하기 위한 세 가지 최소 패치가 포함되어 있습니다; [`lib/starhive/PATCHES.md`](https://github.com/DHTMLX/react-scheduler-starhive-demo/blob/main/lib/starhive/)에서 차이점을 확인하고 스키마를 재생성할 때마다 동일한 패치를 다시 적용하십시오. Starhive가 수정 사항을 공개할 때까지 계속 적용합니다.
+:::
+
+## 5단계. Starhive 클라이언트 구성
+
+`lib/starhiveClient.ts`를 만듭니다:
+
+```ts title="lib/starhiveClient.ts"
+import { StarhiveClient } from "./starhive/client/StarhiveClient";
+import { JSON_DECODERS } from "./starhive/schema/JsonDecoders";
+
+let starhiveClient: StarhiveClient | null = null;
+
+export function getStarhiveClient() {
+ if (starhiveClient) return starhiveClient;
+
+ const workspaceId = process.env.STARHIVE_WORKSPACE_ID;
+ const apiKey = process.env.STARHIVE_API_TOKEN;
+
+ if (!workspaceId || !apiKey) {
+ throw new Error("Missing Starhive configuration (workspaceId or API token)");
+ }
+
+ starhiveClient = new StarhiveClient(apiKey, workspaceId, JSON_DECODERS);
+ return starhiveClient;
+}
+```
+
+함수는 모듈 범위에서 클라이언트를 캐시하므로 라우트 핸들러가 하나의 인스턴스를 공유합니다.
+
+루트 프로젝트에 `.env.local`(또는 `.env`)를 추가합니다:
+
+```env title=".env.local"
+STARHIVE_API_TOKEN=your-api-token
+STARHIVE_WORKSPACE_ID=your-workspace-id
+```
+
+API 토큰은 설정 → 개인 액세스 토큰에서 생성합니다. 워크스페이스 ID는 `https://app.starhive.com/workspace//home` 경로의 일부입니다.
+
+## 6단계. 이벤트와 리소스 불러오기
+
+`app/api/load/route.ts`를 생성합니다:
+
+```ts title="app/api/load/route.ts"
+import { NextResponse } from 'next/server';
+import { getStarhiveClient } from '@/lib/starhiveClient';
+import { Events } from '@/lib/starhive/schema/Events';
+import { Resources } from '@/lib/starhive/schema/Resources';
+
+function normalizeEvents(events: Events[]) {
+ return events.map(ev => ({
+ id: ev.getId() || '',
+ text: ev.getText(),
+ start_date: ev.getStartDate(),
+ end_date: ev.getEndDate(),
+ resource_id: ev.getResourceId()?.[0] || null,
+ }));
+}
+
+export async function GET() {
+ try {
+ const client = getStarhiveClient();
+ const [events, resources] = await Promise.all([
+ client.search(Events.TYPE_ID, ""),
+ client.search(Resources.TYPE_ID, "")
+ ]);
+
+ return NextResponse.json({
+ events: normalizeEvents(events.result),
+ resources: resources.result.map((r) => ({
+ key: r.getId(),
+ label: r.getLabel(),
+ })),
+ });
+ } catch (error) {
+ return NextResponse.json({ error: 'Failed to load data' }, { status: 500 });
+ }
+}
+```
+
+`normalizeEvents`는 각 Starhive 객체를 React Scheduler가 기대하는 형태로 평면화합니다: `{ id, text, start_date, end_date, resource_id }`. Resources는 `{ key, label }`로 축약되며 이는 타임라인 뷰의 `y_unit`에서 소비됩니다.
+
+개발 서버를 시작한 후 `http://localhost:3000/api/load`를 방문해 JSON 형태를 확인합니다.
+
+## 7단계. Scheduler 렌더링 및 이벤트 불러오기
+
+`app/page.tsx`를 생성합니다:
+
+```tsx title="app/page.tsx"
+'use client';
+
+import { useEffect, useMemo, useState } from 'react';
+import ReactScheduler, {
+ type Event,
+ type SchedulerViewsProp,
+} from '@dhtmlx/trial-react-scheduler';
+import '@dhtmlx/trial-react-scheduler/dist/react-scheduler.css';
+
+type Resource = { key: string; label: string };
+
+export default function Scheduler() {
+ const [resources, setResources] = useState([]);
+ const [events, setEvents] = useState([]);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ fetch('/api/load')
+ .then((response) => response.json())
+ .then((data) => {
+ setResources(data.resources);
+ setEvents(data.events);
+ })
+ .catch((error) => {
+ console.error('Failed to load resources data:', error);
+ })
+ .finally(() => {
+ setLoading(false);
+ });
+ }, []);
+
+ const views: SchedulerViewsProp = useMemo(
+ () => ({
+ timeline: [
+ {
+ name: "timeline",
+ x_unit: "hour",
+ x_date: "%H:%i",
+ x_step: 1,
+ x_start: 8,
+ x_size: 13,
+ x_length: 13,
+ event_dy: 50,
+ event_min_dy: 50,
+ y_property: "resource_id",
+ render: "bar",
+ y_unit: resources,
+ },
+ ],
+ }),
+ [resources]
+ );
+
+ if (loading) {
+ return Loading...
;
+ }
+
+ return (
+
+
+
+ );
+}
+```
+
+로딩 플래그는 이벤트 수를 확인하는 것보다 Scheduler가 비어 있어도 로딩 화면에 머물지 않도록 하는 것이 좋습니다.
+
+`npm run dev`를 실행하면 imported 이벤트가 리소스별로 그룹화된 타임라인이 표시됩니다.
+
+## 8단계. CRUD 엔드포인트 구현
+
+Scheduler의 `dataBridge`는 생성은 POST, 업데이트는 PUT, 삭제는 DELETE의 세 엔드포인트를 호출하며 다음과 같은 응답 형태를 기대합니다:
+
+| HTTP 메서드 | 엔드포인트 | 응답 |
+| ----------- | ------------------------- | ------------------------------ |
+| `GET` | `/api/load` | `{ events, resources }` |
+| `POST` | `/api/event` | `{ action: "inserted", tid: id }` |
+| `PUT` | `/api/event/{event_id}` | `{ action: "updated" }` |
+| `DELETE` | `/api/event/{event_id}` | `{ action: "deleted" }` |
+
+POST 핸들러를 `app/api/event/route.ts`에 만듭니다:
+
+```ts title="app/api/event/route.ts"
+import { NextRequest, NextResponse } from 'next/server';
+import { getStarhiveClient } from '@/lib/starhiveClient';
+import { Events } from '@/lib/starhive/schema/Events';
+
+export async function POST(req: NextRequest) {
+ try {
+ const { text, start_date, end_date, resource_id } = await req.json();
+ const client = getStarhiveClient();
+
+ const event = Events.builder()
+ .text(text)
+ .startDate(new Date(start_date))
+ .endDate(new Date(end_date))
+ .resourceId([resource_id])
+ .build();
+
+ const result = await client.createObject(event);
+ return NextResponse.json({ action: 'inserted', tid: result.getId() });
+ } catch (error) {
+ return NextResponse.json({ error: 'Create failed' }, { status: 500 });
+ }
+}
+```
+
+그리고 동적 PUT/DELETE 핸들러를 `app/api/event/[id]/route.ts`에 추가합니다:
+
+```ts title="app/api/event/[id]/route.ts"
+import { NextRequest, NextResponse } from 'next/server';
+import { Events } from "@/lib/starhive/schema/Events";
+import { getStarhiveClient } from "@/lib/starhiveClient";
+
+export async function PUT(
+ request: NextRequest,
+ { params }: { params: Promise<{ id: string }> },
+) {
+ try {
+ const { id } = await params;
+ const body = await request.json();
+ const client = getStarhiveClient();
+
+ const existingEvent = await client.getObject(id, Events.TYPE_ID);
+ if (!existingEvent) {
+ return NextResponse.json({ error: 'Event not found' }, { status: 404 });
+ }
+
+ const updatedEvent = Events.builder()
+ .id(id)
+ .text(body.text)
+ .startDate(new Date(body.start_date))
+ .endDate(new Date(body.end_date))
+ .resourceId([body.resource_id])
+ .build();
+
+ await client.updateObject(updatedEvent);
+ return NextResponse.json({ action: 'updated' });
+ } catch (error: any) {
+ console.error('Update error:', error);
+ return NextResponse.json(
+ { error: 'Update failed', details: error.message },
+ { status: 500 }
+ );
+ }
+}
+
+export async function DELETE(
+ request: NextRequest,
+ { params }: { params: Promise<{ id: string }> },
+) {
+ try {
+ const { id } = await params;
+ const client = getStarhiveClient();
+ await client.deleteObjectsInBulk([id]);
+
+ return NextResponse.json({ action: 'deleted' });
+ } catch (error: any) {
+ console.error('Delete error:', error);
+ return NextResponse.json(
+ { error: 'Delete failed', details: error.message },
+ { status: 500 }
+ );
+ }
+}
+```
+
+:::note
+Next.js 15+에서 동적 경로 핸들러의 `params` 인수는 `Promise`입니다. 값을 읽기 전에 반드시 `Promise<{...}>`로 타입을 지정하고 `await`하십시오. 일부 설정에서 `Promise<>` 래퍼를 생략하면 컴파일되지만 엄격 모드에서 실패합니다.
+:::
+
+## 9단계. dataBridge 연결
+
+클라이언트 측의 작은 헬퍼를 `services/scheduler.ts`에 생성합니다:
+
+```ts title="services/scheduler.ts"
+import type { Event } from '@dhtmlx/trial-react-scheduler';
+
+async function request(url: string, options: RequestInit): Promise {
+ const res = await fetch(url, options);
+ if (!res.ok) throw new Error(`Request failed: ${res.status}`);
+ return res.json();
+}
+
+export function createEvent(event: Event) {
+ return request('/api/event', {
+ method: 'POST',
+ body: JSON.stringify(event),
+ headers: { 'Content-Type': 'application/json' },
+ });
+}
+
+export function updateEvent(event: Event) {
+ return request(`/api/event/${event.id}`, {
+ method: 'PUT',
+ body: JSON.stringify(event),
+ headers: { 'Content-Type': 'application/json' },
+ });
+}
+
+export function deleteEvent(id: string | number) {
+ return request(`/api/event/${id}`, {
+ method: 'DELETE',
+ });
+}
+```
+
+그다음 페이지에 dataBridge를 연결합니다. imports를 추가하고 ``에 `data` 속성을 추가합니다:
+
+```tsx title="app/page.tsx"
+import { createEvent, deleteEvent, updateEvent } from '@/services/scheduler';
+
+// Scheduler 컴포넌트 내부:
+const dataBridge = useMemo(() => ({
+ save: (entity: string, action: string, payload: Event, id: string | number) => {
+ if (entity !== "event") return;
+
+ switch (action) {
+ case "update":
+ return updateEvent(payload);
+ case "create":
+ return createEvent(payload);
+ case "delete":
+ return deleteEvent(id);
+ default:
+ console.warn(`Unknown action: ${action}`);
+ return;
+ }
+ },
+}), []);
+
+// 컴포넌트에 데이터 브리지 전달:
+
+```
+
+테스트 방법
+
+```bash
+npm run dev
+```
+
+브라우저에서 http://localhost:3000 를 열고 이벤트를 드래그로 새 시간으로 옮기고, 텍스트를 편집하고 하나를 삭제해 보십시오. 각 변경 사항은 Starhive UI의 `Events` 타입 아래 즉시 반영됩니다.
+
+## Starhive 통합에 대한 참고사항
+
+- 서버 측 자격 증명만 사용합니다. `STARHIVE_API_TOKEN`과 `STARHIVE_WORKSPACE_ID`는 Route Handler 내부에서 읽히며 브라우저 번들에 노출되지 않습니다. 토큰을 Client Component로 올리거나 `NEXT_PUBLIC_*` 변수로 노출하지 마십시오.
+- 스키마 재생성. Starhive의 속성을 추가하거나 이름을 바꿀 때는 TypeScript 스키마를 재생성하고 `lib/starhive/`를 교체합니다. 문제가 발생하면 [`lib/starhive/PATCHES.md`](https://github.com/DHTMLX/react-scheduler-starhive-demo/blob/main/lib/starhive/) 경로의 패치를 재적용하십시오.
+- 실시간 동기화 없음. Firebase 통합과 달리 Starhive는 연결된 클라이언트에 변경 내용을 푸시하지 않습니다. 여러 사용자가 동일한 Scheduler를 편집하면 서로의 변경 사항이 덮어씌워질 수 있습니다. 다중 사용자 시나리오의 경우 클라이언트 측 폴링을 추가하거나 Starhive 웹훅을 사용해 SSE/웹소켓으로 무효화 이벤트를 보내고 원격 변경 시 `events` 상태를 새로고침하십시오.
+- 대용량 데이터 세트의 동적 로딩. `/api/load` 경로는 워크스페이스의 모든 이벤트를 로드합니다. 프로덕션에서는 GET 핸들러에서 `from` / `to` 쿼리 매개변수를 받아 `start_date` / `end_date`를 필터링하고 클라이언트에서 `scheduler.setLoadMode("day")`를 호출하여 보이는 범위의 데이터만 가져오도록 하십시오.
+- 참조 속성은 배열을 담습니다. `Events.getResourceId()`는 `string[] | undefined`를 반환합니다. Starhive의 참조 속성은 다-valued이기 때문입니다. 데모는 `?.[0] || null`로 평탄화합니다. 이벤트가 여러 리소스에 속하도록 허용하는 경우 타임라인 뷰의 `y_property` 해상도와 평탄화/빌더 호출을 이에 맞게 조정하십시오.
+
+## 관련 페이지
+
+- [데이터 바인딩 및 상태 관리 기초](integrations/react/state/state-management-basics.md)
+- [React Scheduler 개요](integrations/react/overview.md#bindingdata)
+- [서버 통합](guides/server-integration.md)
+- [React Scheduler와 Firebase 통합](integrations/react/firebase-integration.md) - 실시간 동기화의 형제 패턴
\ No newline at end of file
diff --git a/i18n/ko/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md b/i18n/ko/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
index a659b1d9..4d8a4ca8 100644
--- a/i18n/ko/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
+++ b/i18n/ko/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
@@ -15,7 +15,7 @@ description: Valtio 프록시 저장소로 React Scheduler의 상태를 관리
- 스냅샷 기반 undo/redo(이벤트 + 구성)
:::note
-전체 소스 코드는 [GitHub에서 확인 가능](https://github.com/nicetip/react-scheduler-valtio-starter).
+전체 소스 코드는 [GitHub에서 확인 가능](https://github.com/DHTMLX/react-scheduler-valtio-starter).
:::
## Prerequisites
diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md b/i18n/ru/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md
index 9d4241a4..6cf979ce 100644
--- a/i18n/ru/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md
+++ b/i18n/ru/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md
@@ -1,63 +1,89 @@
---
title: "Полный список CDN-ссылок"
-sidebar_label: "Полный список CDN-ссылок"
+sidebar_label: "CDN-ссылки"
---
# Полный список CDN-ссылок
-В этой статье представлен полный набор ссылок для подключения функционала Scheduler через CDN. Каждый раздел посвящён определённой версии Scheduler:
+В этой статье перечислены CDN-ссылки для подключения **dhtmlxScheduler** к вашему приложению.
-- Основные файлы - *dhtmlxscheduler.js* и *dhtmlxscheduler.css*, содержащие основные возможности
-- Скины - ссылки на все доступные [скины](guides/skins.md)
+Scheduler состоит из двух основных файлов:
-:::note
-Начиная с версии v6.0, все [расширения](guides/extensions-list.md) включены в файл *dhtmlxscheduler.js*. Если вы используете dhtmlxScheduler 5.3 или более раннюю версию, ознакомьтесь со статьёй по [миграции](migration.md#53---60).
-:::
+- **JavaScript:** `dhtmlxscheduler.js`
+- **Стили:** `dhtmlxscheduler.css`
-## Последняя версия Scheduler
-Чтобы использовать последнюю версию библиотеки, укажите путь **https://cdn.dhtmlx.com/scheduler/edge/...**
+## Последняя версия Scheduler (edge)
-Основные файлы: [JS](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.css)
+Используйте:
-Скины: [Terrace](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_contrast_white.css).
+`https://cdn.dhtmlx.com/scheduler/edge/...`
-## Последняя версия Scheduler, не сжатая
+### Основные файлы
-Для получения не сжатых исходников последней версии используйте путь **https://cdn.dhtmlx.com/scheduler/edge/sources/...**
+- JS: https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.css
-Основные файлы: [JS](https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.css)
-Скины: [Terrace](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_contrast_white.css).
+## Последняя версия Scheduler (edge), Несжатая
-## Конкретная версия Scheduler
+Используйте:
-Чтобы подключить определённую версию библиотеки, укажите путь **https://cdn.dhtmlx.com/scheduler/[version_number]/...**
+`https://cdn.dhtmlx.com/scheduler/edge/sources/...`
-Основные файлы: [JS](https://cdn.dhtmlx.com/scheduler/4.3/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/4.3/dhtmlxscheduler.css)
+### Основные файлы
-Скины: [Terrace](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_contrast_white.css).
+- JS: https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.css
-## Конкретная версия Scheduler, не сжатая
-Чтобы использовать не сжатые исходники выбранной версии, укажите путь **https://cdn.dhtmlx.com/scheduler/[version_number]/sources/...**
+## Определённая версия Scheduler
-Основные файлы: [JS](https://cdn.dhtmlx.com/scheduler/4.3/sources/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/4.3/sources/skins/dhtmlxscheduler.css)
+Используйте:
-Скины: [Terrace](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_contrast_white.css).
+`https://cdn.dhtmlx.com/scheduler/[version_number]/...`
+
+Значение `[version_number]` задаёт версию пакета в формате `major.minor`, например **7.0**, **6.0**, **5.3** и т. д. Наш CDN всегда предоставляет последнюю патч-версию для каждого выпуска major/minor.
+
+### Основные файлы
+
+- JS: https://cdn.dhtmlx.com/scheduler/7.0/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/7.0/dhtmlxscheduler.css
+
+### Скины (только для v6.0 и более ранних)
+
+Отдельные файлы скинов доступны в версиях v6.0 и ранее.
+Начиная с v7.0, все скины входят в `dhtmlxscheduler.css` и выбираются через `scheduler.skin`/`scheduler.setSkin()`, пожалуйста, ознакомьтесь с [Руководство по миграции](migration.md) для получения более подробной информации.
+
+- Terrace: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_terrace.css
+- Flat: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_flat.css
+- Contrast Black: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_contrast_black.css
+- Contrast White: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_contrast_white.css
+- Material: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_material.css
+
+## Определённая версия Scheduler, Несжатая
+
+Используйте:
+
+`https://cdn.dhtmlx.com/scheduler/[version_number]/sources/...`
+
+Значение `[version_number]` задаёт версию пакета в формате `major.minor`, например **7.0**, **6.0**, **5.3** и т. д. Наш CDN всегда предоставляет последнюю патч-версию для каждого выпуска major/minor.
+
+### Основные файлы
+
+- JS: https://cdn.dhtmlx.com/scheduler/7.0/sources/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/7.0/sources/dhtmlxscheduler.css
+
+
+### Скины (только для v6.0 и более ранних)
+
+Отдельные файлы скинов доступны в версиях v6.0 и ранее.
+Начиная с v7.0, все скины входят в `dhtmlxscheduler.css` и выбираются через `scheduler.skin`/`scheduler.setSkin()`, пожалуйста, ознакомьтесь с [Руководство по миграции](migration.md) для получения более подробной информации.
+
+Несжатые файлы скинов:
+
+- Terrace: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_terrace.css
+- Flat: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_flat.css
+- Contrast Black: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_contrast_black.css
+- Contrast White: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_contrast_white.css
+- Material: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_material.css
\ No newline at end of file
diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md b/i18n/ru/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
index af471caa..4cba6ec1 100644
--- a/i18n/ru/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
+++ b/i18n/ru/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
@@ -35,7 +35,7 @@ description: "Реализуйте интеграцию Node.js + Express, ко
## Демонстрационный репозиторий
Полный рабочий проект, соответствующий данному руководству, доступен на GitHub:
-- https://github.com/dhtmlx/scheduler-google-auth-demo
+- https://github.com/dhtmlx/scheduler-google-calendar-demo
Руководство объясняет ключевые шаги и демонстрирует важный код интеграции. Репозиторий является «полной рабочей ссылкой».
@@ -50,8 +50,8 @@ description: "Реализуйте интеграцию Node.js + Express, ко
- Клонировать репозиторий:
~~~bash title="Terminal"
-git clone https://github.com/dhtmlx/scheduler-google-auth-demo.git
-cd scheduler-google-auth-demo
+git clone https://github.com/dhtmlx/scheduler-google-calendar-demo.git
+cd scheduler-google-calendar-demo
~~~
Если ваш проект устанавливает пакеты `@dhx/*` из частного реестра, настройте npm:
@@ -164,7 +164,7 @@ http://localhost:3000
Типичная структура:
~~~text title="Project structure"
-scheduler-google-auth-demo/
+scheduler-google-calendar-demo/
client/
index.ejs
main.ts
diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md b/i18n/ru/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md
new file mode 100644
index 00000000..3ab5e46f
--- /dev/null
+++ b/i18n/ru/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md
@@ -0,0 +1,462 @@
+---
+title: Интеграция React Scheduler и Starhive
+sidebar_label: Быстрый старт Starhive
+description: "Подключение DHTMLX React Scheduler к NoSQL-бэкенду Starhive через маршруты API Next.js."
+---
+
+# Интеграция React Scheduler и Starhive
+
+Этот учебник подключает **React Scheduler** к NoSQL-бэкенду **Starhive** через обработчики маршрутов Next.js. Starhive предоставляет типизированную схему и сгенерированный клиент TypeScript, поэтому уровень API остаётся минимальным: один конечный пункт загружает события и ресурсы, другой обрабатывает создание / обновление / удаление.
+
+Вы создадите:
+
+- страницу Next.js, которая размещает Scheduler в клиентском компоненте
+- `/api/load` - получает события и ресурсы из Starhive при первом рендере
+- `/api/event` (POST) и `/api/event/[id]` (PUT, DELETE) - пути записи, используемые Scheduler `dataBridge`
+
+:::note
+Полный исходный код доступен на GitHub (ссылка в оригинальном источнике).
+:::
+
+## Требования
+
+- основы Next.js + React + TypeScript
+- Node.js 18+
+- учетная запись [Starhive](https://starhive.com/) (30-дневная пробная версия подходит)
+
+## Шаг 1. Создайте проект
+
+```bash
+npx create-next-app@latest react-scheduler-starhive-demo
+cd react-scheduler-starhive-demo
+```
+
+Установите React Scheduler согласно руководству по установке [React Scheduler](integrations/react/installation.md). Для оценки:
+
+```bash
+npm install @dhtmlx/trial-react-scheduler
+```
+
+Если вы уже используете пакет Professional, замените `@dhtmlx/trial-react-scheduler` на `@dhx/react-scheduler` в командах и импортируемых элементах.
+
+Также потребуется `axios` — это зависимость-партнёр сгенерированного клиентского Starhive TypeScript.
+
+```bash
+npm install axios
+```
+
+## Шаг 2. Настройте пространство Starhive
+
+После входа в систему нажмите **+ Create** в правом верхнем углу и назовите пространство как `Scheduler`.
+
+Внутри пространства создайте два типа: `Resources` и `Events`. Resources хранят строки временной шкалы (команды, люди, комнаты и т. п.). Events ссылаются на один Resource.
+
+Добавьте следующие атрибуты через кнопку **+ Attribute**. Starhive автоматически создаёт `id` для каждого элемента, поэтому объявлять его не нужно.
+
+**Resources type**
+
+| Поле | Тип |
+| ------- | ---- |
+| `label` | Text |
+
+**Events type**
+
+| Поле | Тип |
+| ------------- | -------------------------- |
+| `text` | Text |
+| `start_date` | Date & Time |
+| `end_date` | Date & Time |
+| `resource_id` | Reference → Resources |
+
+## Шаг 3. Импорт данных образца
+
+Создайте `scheduler_resources.csv`:
+
+```csv
+label
+"Frontend Team"
+"Backend Team"
+"QA Team"
+"DevOps"
+"Security Team"
+```
+
+И `scheduler_events.csv`:
+
+```csv
+text,start_date,end_date,resource_id
+"Development","2026-04-01T08:00:00","2026-04-01T10:30:00","Frontend Team"
+"Code Review","2026-04-01T09:00:00","2026-04-01T11:30:00","Backend Team"
+"QA Testing","2026-04-01T10:00:00","2026-04-01T13:00:00","QA Team"
+"Deployment","2026-04-01T11:00:00","2026-04-01T13:30:00","DevOps"
+"Incident Response","2026-04-01T12:00:00","2026-04-01T15:00:00","DevOps"
+"Maintenance Window","2026-04-01T08:30:00","2026-04-01T11:00:00","Backend Team"
+"Security Scan","2026-04-01T13:00:00","2026-04-01T15:30:00","Security Team"
+```
+
+В интерфейсе Starhive откройте тип и нажмите CSV импорт для каждого файла.
+
+## Шаг 4. Сгенерируйте и скопируйте схему
+
+Перейдите в **Settings → API Connectors**. Выберите пространство `Scheduler`, укажите язык TypeScript, нажмите **Generate**, затем **Download**.
+
+Распакуйте архив, найдите папку `starhive` в `project/src/io/` и скопируйте её в `lib/starhive/` в вашем проекте Next.js. Сгенерированные файлы содержат рабочие UUID, поэтому повторяйте этот шаг каждый раз, когда схема меняется или вы переключаетесь между рабочими пространствами.
+
+:::note
+На момент написания генератор TypeScript Starhive выводит код, который не проходит строгий TypeScript: отсутствует ссылка на `Sla.ts`, реализация `visitSlaAttribute` в литерале `AttributeVisitor`, и вызов `client.request` против поля типа `any` (TS2347). Со стороны демонстрационного репозитория есть три минимальных патча, которые решают эти проблемы; смотрите [`lib/starhive/PATCHES.md`](https://github.com/DHTMLX/react-scheduler-starhive-demo/blob/main/lib/starhive/) для диффов. Повторно применяйте те же патчи при повторной генерации схемы, пока Starhive не выпустит исправление.
+:::
+
+## Шаг 5. Настройте клиента Starhive
+
+Создайте `lib/starhiveClient.ts`:
+
+```ts title="lib/starhiveClient.ts"
+import { StarhiveClient } from "./starhive/client/StarhiveClient";
+import { JSON_DECODERS } from "./starhive/schema/JsonDecoders";
+
+let starhiveClient: StarhiveClient | null = null;
+
+export function getStarhiveClient() {
+ if (starhiveClient) return starhiveClient;
+
+ const workspaceId = process.env.STARHIVE_WORKSPACE_ID;
+ const apiKey = process.env.STARHIVE_API_TOKEN;
+
+ if (!workspaceId || !apiKey) {
+ throw new Error("Missing Starhive configuration (workspaceId or API token)");
+ }
+
+ starhiveClient = new StarhiveClient(apiKey, workspaceId, JSON_DECODERS);
+ return starhiveClient;
+}
+```
+
+Функция кэширует клиент на уровне модуля, чтобы обработчики маршрутов использовали один экземпляр.
+
+Добавьте `.env.local` (или `.env`) в корень проекта:
+
+```env title=".env.local"
+STARHIVE_API_TOKEN=ваш-api-токен
+STARHIVE_WORKSPACE_ID=ваш-id-рабочего-пространства
+```
+
+Сгенерируйте токен API в разделе **Settings → Personal access tokens**. ID рабочего пространства — это фрагмент пути в `https://app.starhive.com/workspace//home`.
+
+## Шаг 6. Загружайте события и ресурсы
+
+Создайте `app/api/load/route.ts`:
+
+```ts title="app/api/load/route.ts"
+import { NextResponse } from 'next/server';
+import { getStarhiveClient } from '@/lib/starhiveClient';
+import { Events } from '@/lib/starhive/schema/Events';
+import { Resources } from '@/lib/starhive/schema/Resources';
+
+function normalizeEvents(events: Events[]) {
+ return events.map(ev => ({
+ id: ev.getId() || '',
+ text: ev.getText(),
+ start_date: ev.getStartDate(),
+ end_date: ev.getEndDate(),
+ resource_id: ev.getResourceId()?.[0] || null,
+ }));
+}
+
+export async function GET() {
+ try {
+ const client = getStarhiveClient();
+ const [events, resources] = await Promise.all([
+ client.search(Events.TYPE_ID, ""),
+ client.search(Resources.TYPE_ID, "")
+ ]);
+
+ return NextResponse.json({
+ events: normalizeEvents(events.result),
+ resources: resources.result.map((r) => ({
+ key: r.getId(),
+ label: r.getLabel(),
+ })),
+ });
+ } catch (error) {
+ return NextResponse.json({ error: 'Не удалось загрузить данные' }, { status: 500 });
+ }
+}
+```
+
+Функция `normalizeEvents` превращает каждый объект Starhive в форму, которую ожидает React Scheduler: `{ id, text, start_date, end_date, resource_id }`. Ресурсы сводятся к `{ key, label }`, что и требуется для `y_unit` у представления временной шкалы.
+
+После запуска dev-сервера перейдите по адресу `http://localhost:3000/api/load`, чтобы проверить форму JSON.
+
+## Шаг 7. Рендеринг Scheduler и загрузка событий
+
+Создайте `app/page.tsx`:
+
+```tsx title="app/page.tsx"
+'use client';
+
+import { useEffect, useMemo, useState } from 'react';
+import ReactScheduler, {
+ type Event,
+ type SchedulerViewsProp,
+} from '@dhtmlx/trial-react-scheduler';
+import '@dhtmlx/trial-react-scheduler/dist/react-scheduler.css';
+
+type Resource = { key: string; label: string };
+
+export default function Scheduler() {
+ const [resources, setResources] = useState([]);
+ const [events, setEvents] = useState([]);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ fetch('/api/load')
+ .then((response) => response.json())
+ .then((data) => {
+ setResources(data.resources);
+ setEvents(data.events);
+ })
+ .catch((error) => {
+ console.error('Не удалось загрузить данные ресурсов:', error);
+ })
+ .finally(() => {
+ setLoading(false);
+ });
+ }, []);
+
+ const views: SchedulerViewsProp = useMemo(
+ () => ({
+ timeline: [
+ {
+ name: "timeline",
+ x_unit: "hour",
+ x_date: "%H:%i",
+ x_step: 1,
+ x_start: 8,
+ x_size: 13,
+ x_length: 13,
+ event_dy: 50,
+ event_min_dy: 50,
+ y_property: "resource_id",
+ render: "bar",
+ y_unit: resources,
+ },
+ ],
+ }),
+ [resources]
+ );
+
+ if (loading) {
+ return Loading...
;
+ }
+
+ return (
+
+
+
+ );
+}
+```
+
+Флаг `loading` предпочтительнее проверки `events.length` или `resources.length`: рабочее пространство может действительно не содержать событий и тем не менее нужно отрисовать пустой Scheduler, а не показывать загрузчик.
+
+Запустите `npm run dev` — временная шкала появится вместе с импортированными событиями, сгруппированными по ресурсам.
+
+## Шаг 8. Реализуйте Endpoints CRUD
+
+Scheduler `dataBridge` вызывает три endpoint’а — POST для создания, PUT для обновления, DELETE для удаления — и ожидает определённые формы ответов:
+
+| HTTP-метод | Endpoint | Ответ |
+| ----------- | ------------------------- | --------------------------------- |
+| `GET` | `/api/load` | `{ events, resources }` |
+| `POST` | `/api/event` | `{ action: "inserted", tid: id }` |
+| `PUT` | `/api/event/{event_id}` | `{ action: "updated" }` |
+| `DELETE` | `/api/event/{event_id}` | `{ action: "deleted" }` |
+
+Создайте обработчик POST по адресу `app/api/event/route.ts`:
+
+```ts title="app/api/event/route.ts"
+import { NextRequest, NextResponse } from 'next/server';
+import { getStarhiveClient } from '@/lib/starhiveClient';
+import { Events } from '@/lib/starhive/schema/Events';
+
+export async function POST(req: NextRequest) {
+ try {
+ const { text, start_date, end_date, resource_id } = await req.json();
+ const client = getStarhiveClient();
+
+ const event = Events.builder()
+ .text(text)
+ .startDate(new Date(start_date))
+ .endDate(new Date(end_date))
+ .resourceId([resource_id])
+ .build();
+
+ const result = await client.createObject(event);
+ return NextResponse.json({ action: 'inserted', tid: result.getId() });
+ } catch (error) {
+ return NextResponse.json({ error: 'Create failed' }, { status: 500 });
+ }
+}
+```
+
+И динамические обработчики PUT/DELETE по адресу `app/api/event/[id]/route.ts`:
+
+```ts title="app/api/event/[id]/route.ts"
+import { NextRequest, NextResponse } from 'next/server';
+import { Events } from "@/lib/starhive/schema/Events";
+import { getStarhiveClient } from "@/lib/starhiveClient";
+
+export async function PUT(
+ request: NextRequest,
+ { params }: { params: Promise<{ id: string }> },
+) {
+ try {
+ const { id } = await params;
+ const body = await request.json();
+ const client = getStarhiveClient();
+
+ const existingEvent = await client.getObject(id, Events.TYPE_ID);
+ if (!existingEvent) {
+ return NextResponse.json({ error: 'Event not found' }, { status: 404 });
+ }
+
+ const updatedEvent = Events.builder()
+ .id(id)
+ .text(body.text)
+ .startDate(new Date(body.start_date))
+ .endDate(new Date(body.end_date))
+ .resourceId([body.resource_id])
+ .build();
+
+ await client.updateObject(updatedEvent);
+ return NextResponse.json({ action: 'updated' });
+ } catch (error: any) {
+ console.error('Update error:', error);
+ return NextResponse.json(
+ { error: 'Update failed', details: error.message },
+ { status: 500 }
+ );
+ }
+}
+
+export async function DELETE(
+ request: NextRequest,
+ { params }: { params: Promise<{ id: string }> },
+) {
+ try {
+ const { id } = await params;
+ const client = getStarhiveClient();
+ await client.deleteObjectsInBulk([id]);
+
+ return NextResponse.json({ action: 'deleted' });
+ } catch (error: any) {
+ console.error('Delete error:', error);
+ return NextResponse.json(
+ { error: 'Delete failed', details: error.message },
+ { status: 500 }
+ );
+ }
+}
+```
+
+:::note
+В Next.js 15+ аргумент `params` у динамических обработчиков маршрутов является `Promise`. Всегда указывайте тип как `Promise<{...}>` и `await` его перед чтением сегментов — пропуск обёртки `Promise<>` в некоторых сборках может компилироваться, но не проходить строгий режим.
+:::
+
+## Шаг 9. Подключите dataBridge
+
+Создайте небольшой клиентский помощник на стороне клиента в `services/scheduler.ts`:
+
+```ts title="services/scheduler.ts"
+import type { Event } from '@dhtmlx/trial-react-scheduler';
+
+async function request(url: string, options: RequestInit): Promise {
+ const res = await fetch(url, options);
+ if (!res.ok) throw new Error(`Request failed: ${res.status}`);
+ return res.json();
+}
+
+export function createEvent(event: Event) {
+ return request('/api/event', {
+ method: 'POST',
+ body: JSON.stringify(event),
+ headers: { 'Content-Type': 'application/json' },
+ });
+}
+
+export function updateEvent(event: Event) {
+ return request(`/api/event/${event.id}`, {
+ method: 'PUT',
+ body: JSON.stringify(event),
+ headers: { 'Content-Type': 'application/json' },
+ });
+}
+
+export function deleteEvent(id: string | number) {
+ return request(`/api/event/${id}`, {
+ method: 'DELETE',
+ });
+}
+```
+
+Затем подключите `dataBridge` к странице. Обновите `app/page.tsx`, добавив импорты и свойство `data` у ``:
+
+```tsx title="app/page.tsx"
+import { createEvent, deleteEvent, updateEvent } from '@/services/scheduler';
+
+// внутри компонента Scheduler:
+const dataBridge = useMemo(() => ({
+ save: (entity: string, action: string, payload: Event, id: string | number) => {
+ if (entity !== "event") return;
+
+ switch (action) {
+ case "update":
+ return updateEvent(payload);
+ case "create":
+ return createEvent(payload);
+ case "delete":
+ return deleteEvent(id);
+ default:
+ console.warn(`Unknown action: ${action}`);
+ return;
+ }
+ },
+}), []);
+
+// передайте его компоненту:
+
+```
+
+## Протестируйте
+
+```bash
+npm run dev
+```
+
+Откройте `http://localhost:3000`, перетащите событие в новое время, отредактируйте его текст и удалите одно. Каждое изменение должно немедленно отражаться в интерфейсе Starhive под типом `Events`.
+
+## Заметки по интеграции Starhive
+
+- **Серверные креденшлы только на сервере.** `STARHIVE_API_TOKEN` и `STARHIVE_WORKSPACE_ID` читаются внутри обработчиков маршрутов (`getStarhiveClient`); они не попадают в браузерный бандл. Не переносите клиент Starhive в Клиентский компонент и не публикуйте токен через переменные `NEXT_PUBLIC_*`.
+- **Регенерация схемы.** Всякий раз, когда вы добавляете или переименовываете атрибуты в Starhive, регенерируйте TypeScript-схему и заменяйте `lib/starhive/`. Повторно применяйте патчи в [`lib/starhive/PATCHES.md`](https://github.com/DHTMLX/react-scheduler-starhive-demo/blob/main/lib/starhive/), если сборка `next build` жалуется на аналогичные upstream-проблемы.
+- **Нет привязки к реальному времени.** В отличие от интеграции с Firebase, Starhive не отправляет изменения подключённым клиентам. Несколько пользователей, редактирующих один Scheduler, могут перезаписывать изменения друг друга. Для много-пользовательских сценариев добавляйте опрос на стороне клиента — или подключайте вебхуки Starhive для отправки уведомлений об инвалидации через SSE / WebSockets и обновляйте состояние `events` при удалённых изменениях.
+- **Динамическая загрузка больших наборов данных.** Маршрут `/api/load` загружает каждое событие в рабочем пространстве. В продакшне можно принимать параметры запроса `from` / `to` в обработчике GET, фильтровать по `start_date` / `end_date` и вызывать `scheduler.setLoadMode("day")` на клиенте, чтобы подгружался только видимый диапазон.
+- **Справочные атрибуты возвращают массивы.** `Events.getResourceId()` возвращает `string[] | undefined`, потому что ссылочные атрибуты Starhive могут быть мультивалентными. Демка разворачивает через `?.[0] || null`. Если вы разрешаете событиям принадлежать нескольким ресурсам, измените разрешение `y_property` у представления timeline и соответствующим образом обновите вызовы `normalize` / `builder`.
+
+## Связанные страницы
+
+- [Основы связывания данных и управления состоянием](integrations/react/state/state-management-basics.md)
+- [Обзор React Scheduler](integrations/react/overview.md#bindingdata)
+- [Серверная интеграция](guides/server-integration.md)
+- [React Scheduler и интеграция с Firebase](integrations/react/firebase-integration.md) — соседняя схема с синхронизацией в реальном времени
\ No newline at end of file
diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md b/i18n/ru/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
index d100dfcf..b3a23323 100644
--- a/i18n/ru/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
+++ b/i18n/ru/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
@@ -15,7 +15,7 @@ description: Управляйте состоянием React Scheduler с пом
- откат/повтор на основе снимков (события + конфигурация)
:::note
-Полный исходный код доступен [на GitHub](https://github.com/nicetip/react-scheduler-valtio-starter).
+Полный исходный код доступен [на GitHub](https://github.com/DHTMLX/react-scheduler-valtio-starter).
:::
## Требования
diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md b/i18n/zh/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md
index 585f7c4b..0eb6e5d7 100644
--- a/i18n/zh/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md
+++ b/i18n/zh/docusaurus-plugin-content-docs/current/guides/cdn-links-list.md
@@ -5,61 +5,85 @@ sidebar_label: "CDN 链接完整列表"
# CDN 链接完整列表
-本文为您提供了通过 CDN 引入 Scheduler 功能的完整链接集合。每个部分对应特定的 Scheduler 版本:
+本文列出在应用中引入 **dhtmlxScheduler** 的 CDN 链接。
-- 核心文件 - 包含主要功能的 *dhtmlxscheduler.js* 和 *dhtmlxscheduler.css* 文件
-- 皮肤 - 所有可用 [皮肤](guides/skins.md) 的链接
+Scheduler 由两个核心文件组成:
-:::note
-从 v6.0 开始,所有 [扩展](/guides/extensions-list/) 都已集成进 *dhtmlxscheduler.js* 文件。如果您使用的是 dhtmlxScheduler 5.3 或更早版本,请参考 [迁移指南](migration.md#53---60)。
-:::
+- **JavaScript:** `dhtmlxscheduler.js`
+- **Styles:** `dhtmlxscheduler.css`
-## 最新 Scheduler 版本
-如需使用最新版库,请将资源路径设置为 **https://cdn.dhtmlx.com/scheduler/edge/...**
+## 最新 Scheduler 版本(edge)
-核心文件: [JS](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.css)
+使用:
-皮肤: [Terrace](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler_contrast_white.css)。
+`https://cdn.dhtmlx.com/scheduler/edge/...`
-## 最新 Scheduler 版本,未压缩
+### 核心文件
-如需获取最新版未压缩源码,请使用路径 **https://cdn.dhtmlx.com/scheduler/edge/sources/...**
+- JS: https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.css
-核心文件: [JS](https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.css)
-皮肤: [Terrace](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/edge/sources/skins/dhtmlxscheduler_contrast_white.css)。
+## 最新 Scheduler 版本(edge),未压缩
+
+使用:
+
+`https://cdn.dhtmlx.com/scheduler/edge/sources/...`
+
+### 核心文件
+
+- JS: https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/edge/sources/dhtmlxscheduler.css
+
## 指定 Scheduler 版本
-如需引用特定版本库,请将资源路径设置为 **https://cdn.dhtmlx.com/scheduler/[version_number]/...**
+使用:
+
+`https://cdn.dhtmlx.com/scheduler/[version_number]/...`
+
+其中 `[version_number]` 指定软件包的 `major.minor` 版本,例如 **7.0**、**6.0**、**5.3** 等。我们的 CDN 总是为每个 major/minor 版本提供最新的补丁版本。
+
+### 核心文件
+
+- JS: https://cdn.dhtmlx.com/scheduler/7.0/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/7.0/dhtmlxscheduler.css
+
+### 皮肤(仅限 v6.0 及更早版本)
+
+在 v6.0 及更早版本中,提供了单独的皮肤文件。自 v7.0 起,所有皮肤都包含在 `dhtmlxscheduler.css` 中,并通过 `scheduler.skin`/`scheduler.setSkin()` 进行选择,更多细节请查阅 [Migration guide](migration.md)。
+
+- Terrace: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_terrace.css
+- Flat: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_flat.css
+- Contrast Black: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_contrast_black.css
+- Contrast White: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_contrast_white.css
+- Material: https://cdn.dhtmlx.com/scheduler/6.0/dhtmlxscheduler_material.css
+
+
+## 指定 Scheduler 版本,未压缩
+
+使用:
+
+`https://cdn.dhtmlx.com/scheduler/[version_number]/sources/...`
+
+其中 `[version_number]` 指定软件包的 `major.minor` 版本,例如 **7.0**、**6.0**、**5.3** 等。我们的 CDN 总是为每个 major/minor 版本提供最新的补丁版本。
-核心文件: [JS](https://cdn.dhtmlx.com/scheduler/4.3/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/4.3/dhtmlxscheduler.css)
+### 核心文件
-皮肤: [Terrace](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/5.0/dhtmlxscheduler_contrast_white.css)。
+- JS: https://cdn.dhtmlx.com/scheduler/7.0/sources/dhtmlxscheduler.js
+- CSS: https://cdn.dhtmlx.com/scheduler/7.0/sources/dhtmlxscheduler.css
-## 指定 Scheduler 版本,未压缩
-如需使用特定版本的未压缩源码,请将路径设置为 **https://cdn.dhtmlx.com/scheduler/[version_number]/sources/...**
+### 皮肤(仅限 v6.0 及更早版本)
-核心文件: [JS](https://cdn.dhtmlx.com/scheduler/4.3/sources/dhtmlxscheduler.js), [CSS](https://cdn.dhtmlx.com/scheduler/4.3/sources/skins/dhtmlxscheduler.css)
+在 v6.0 及更早版本中,提供了单独的皮肤文件。自 v7.0 起,所有皮肤都包含在 `dhtmlxscheduler.css` 中,并通过 `scheduler.skin`/`scheduler.setSkin()` 进行选择,更多细节请查阅 [Migration guide](migration.md)。
-皮肤: [Terrace](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_terrace.css),
-[Material](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_material.css),
-[Flat](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_flat.css),
-[Contrast Black](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_contrast_black.css),
-[Contrast White](https://cdn.dhtmlx.com/scheduler/5.0/sources/skins/dhtmlxscheduler_contrast_white.css)。
+未压缩的皮肤文件:
+- Terrace: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_terrace.css
+- Flat: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_flat.css
+- Contrast Black: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_contrast_black.css
+- Contrast White: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_contrast_white.css
+- Material: https://cdn.dhtmlx.com/scheduler/6.0/sources/skins/dhtmlxscheduler_material.css
\ No newline at end of file
diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/guides/configuration.md b/i18n/zh/docusaurus-plugin-content-docs/current/guides/configuration.md
index f02772a0..b665f420 100644
--- a/i18n/zh/docusaurus-plugin-content-docs/current/guides/configuration.md
+++ b/i18n/zh/docusaurus-plugin-content-docs/current/guides/configuration.md
@@ -7,8 +7,8 @@ sidebar_label: "通用配置说明"
为了自定义调度器的外观,库提供了三个主要对象:
-- scheduler.config - 用于设置日期、视图、控件等选项。
-- scheduler.templates - 用于格式化日期、标题、提示信息和样式的模板。
+- [scheduler.config](api/overview/properties_overview.md) - 用于设置日期、视图、控件等选项。
+- [scheduler.templates](api/api_overview.md#scheduler-templates) - 用于格式化日期、标题、提示信息和样式的模板。
- [scheduler.xy](api/other/xy.md) - 定义调度器各元素尺寸的设置。
此外,dhtmlxScheduler 还包含了[若干扩展](#extensions),以增强组件功能。
diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md b/i18n/zh/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
index cf7774d0..233facd7 100644
--- a/i18n/zh/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
+++ b/i18n/zh/docusaurus-plugin-content-docs/current/integrations/google-calendar/google-calendar-sync.md
@@ -35,7 +35,7 @@ description: "实现一个 Node.js + Express 集成,将 DHTMLX Scheduler 事
## 演示仓库
与本指南匹配的完整可运行项目可在 GitHub 上获取:
-- https://github.com/dhtmlx/scheduler-google-auth-demo
+- https://github.com/dhtmlx/scheduler-google-calendar-demo
该指南解释了关键步骤并展示了重要的集成代码。仓库是“完整可运行的参考实现”。
@@ -49,8 +49,8 @@ description: "实现一个 Node.js + Express 集成,将 DHTMLX Scheduler 事
- 克隆仓库:
~~~bash title="Terminal"
-git clone https://github.com/dhtmlx/scheduler-google-auth-demo.git
-cd scheduler-google-auth-demo
+git clone https://github.com/dhtmlx/scheduler-google-calendar-demo.git
+cd scheduler-google-calendar-demo
~~~
如果你的项目需要从私有注册表安装 `@dhx/*` 包,请配置 npm:
@@ -160,7 +160,7 @@ http://localhost:3000
一个典型的结构是:
~~~text title="Project structure"
-scheduler-google-auth-demo/
+scheduler-google-calendar-demo/
client/
index.ejs
main.ts
diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md b/i18n/zh/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md
new file mode 100644
index 00000000..3fd8278a
--- /dev/null
+++ b/i18n/zh/docusaurus-plugin-content-docs/current/integrations/react/starhive-integration.md
@@ -0,0 +1,462 @@
+---
+title: React Scheduler 与 Starhive 集成
+sidebar_label: Starhive 快速入门
+description: "通过 Next.js API 路由,将 DHTMLX React Scheduler 连接到 Starhive NoSQL 后端。"
+---
+
+# React Scheduler 与 Starhive 集成
+
+本教程通过 Next.js Route Handlers 将 **React Scheduler** 连接到一个 **Starhive** NoSQL 后端。Starhive 提供带类型的架构和一个生成的 TypeScript 客户端,因此 API 层保持尽量简洁:一个端点用于加载事件和资源,另一个用于创建 / 更新 / 删除。
+
+你将构建:
+
+- 一个在客户端组件中托管 Scheduler 的 Next.js 页面
+- `/api/load` - 首次渲染时从 Starhive 获取事件与资源
+- `/api/event`(POST)和 `/api/event/[id]`(PUT、DELETE) - Scheduler `dataBridge` 使用的写入路径
+
+:::note
+完整的源代码可在 [GitHub 上获取](https://github.com/DHTMLX/react-scheduler-starhive-demo)。
+:::
+
+## 前提条件
+
+- Next.js + React + TypeScript 的基础知识
+- Node.js 18+
+- 一个 [Starhive](https://starhive.com/) 帐户(30 天试用即可)
+
+## 步骤 1. 创建项目
+
+```bash
+npx create-next-app@latest react-scheduler-starhive-demo
+cd react-scheduler-starhive-demo
+```
+
+按照 [React Scheduler 安装指南](integrations/react/installation.md) 的指引安装 React Scheduler。为了评估:
+
+```bash
+npm install @dhtmlx/trial-react-scheduler
+```
+
+如果你已使用 Professional 版本,请将命令及导入中的 `@dhtmlx/trial-react-scheduler` 替换为 `@dhx/react-scheduler`。
+
+你还需要 `axios` —— 它是生成的 Starhive TypeScript 客户端的对等依赖项。
+
+```bash
+npm install axios
+```
+
+## 步骤 2. 设置 Starhive 空间
+
+登录后,在右上角点击 **+ Create**,将空间命名为 `Scheduler`。
+
+在空间内创建两个类型:`Resources` 与 `Events`。Resources 负责时间线的行(团队、人员、房间等)。Events 参考每一个 Resource。
+
+通过 **+ Attribute** 按钮添加以下属性。Starhive 会为每个项自动生成 `id`,因此你不需要显式声明它。
+
+**Resources 类型**
+
+| 字段 | 类型 |
+| ---- | ---- |
+| `label` | Text |
+
+**Events 类型**
+
+| 字段 | 类型 |
+| ---- | ---- |
+| `text` | Text |
+| `start_date` | Date & Time |
+| `end_date` | Date & Time |
+| `resource_id` | Reference → Resources |
+
+## 步骤 3. 导入示例数据
+
+创建 `scheduler_resources.csv`:
+
+```csv
+label
+"Frontend Team"
+"Backend Team"
+"QA Team"
+"DevOps"
+"Security Team"
+```
+
+以及 `scheduler_events.csv`:
+
+```csv
+text,start_date,end_date,resource_id
+"Development","2026-04-01T08:00:00","2026-04-01T10:30:00","Frontend Team"
+"Code Review","2026-04-01T09:00:00","2026-04-01T11:30:00","Backend Team"
+"QA Testing","2026-04-01T10:00:00","2026-04-01T13:00:00","QA Team"
+"Deployment","2026-04-01T11:00:00","2026-04-01T13:30:00","DevOps"
+"Incident Response","2026-04-01T12:00:00","2026-04-01T15:00:00","DevOps"
+"Maintenance Window","2026-04-01T08:30:00","2026-04-01T11:00:00","Backend Team"
+"Security Scan","2026-04-01T13:00:00","2026-04-01T15:30:00","Security Team"
+```
+
+在 Starhive UI 中打开各类型并为每个文件点击 CSV 导入。
+
+## 步骤 4. 生成并复制模式
+
+前往 Settings → API Connectors。选择 `Scheduler` 空间,将语言设为 TypeScript,点击 Generate,然后 Download。
+
+解压缩 ZIP,在 `project/src/io/` 下找到 `starhive` 文件夹,并将其拷贝到你 Next.js 项目的 `lib/starhive/` 目录中。生成的文件包含工作区特定的 UUID,因此每当模式变化或切换工作区时你都需要重复此步骤。
+
+:::note
+撰写时,Starhive TypeScript 生成器输出的内容尚未通过严格的 TypeScript:存在缺失的 `Sla.ts` 引用、内联 `AttributeVisitor` 字面量中缺失的 `visitSlaAttribute` 实现,以及对一个 **any** 类型字段的 `client.request` 调用(TS2347)。配套的演示仓库提供了三处最小化补丁,能够解决这些问题;请参阅 [`lib/starhive/PATCHES.md`](https://github.com/DHTMLX/react-scheduler-starhive-demo/blob/main/lib/starhive/) 的 diff。在重新生成模式时请再次应用相同补丁,直到 Starhive 提供修复为止。
+ :::
+
+## 步骤 5. 配置 Starhive 客户端
+
+创建 `lib/starhiveClient.ts`:
+
+```ts title="lib/starhiveClient.ts"
+import { StarhiveClient } from "./starhive/client/StarhiveClient";
+import { JSON_DECODERS } from "./starhive/schema/JsonDecoders";
+
+let starhiveClient: StarhiveClient | null = null;
+
+export function getStarhiveClient() {
+ if (starhiveClient) return starhiveClient;
+
+ const workspaceId = process.env.STARHIVE_WORKSPACE_ID;
+ const apiKey = process.env.STARHIVE_API_TOKEN;
+
+ if (!workspaceId || !apiKey) {
+ throw new Error("Missing Starhive configuration (workspaceId or API token)");
+ }
+
+ starhiveClient = new StarhiveClient(apiKey, workspaceId, JSON_DECODERS);
+ return starhiveClient;
+}
+```
+
+该函数在模块作用域缓存客户端,因此路由处理程序共享同一个实例。
+
+在项目根目录添加 `.env.local`(或 `.env`):
+
+```env title=".env.local"
+STARHIVE_API_TOKEN=your-api-token
+STARHIVE_WORKSPACE_ID=your-workspace-id
+```
+
+在 Settings → Personal access tokens 下生成 API 令牌。工作区 ID 是在 `https://app.starhive.com/workspace//home` 的路径段。
+
+## 步骤 6. 加载事件与资源
+
+创建 `app/api/load/route.ts`:
+
+```ts title="app/api/load/route.ts"
+import { NextResponse } from 'next/server';
+import { getStarhiveClient } from '@/lib/starhiveClient';
+import { Events } from '@/lib/starhive/schema/Events';
+import { Resources } from '@/lib/starhive/schema/Resources';
+
+function normalizeEvents(events: Events[]) {
+ return events.map(ev => ({
+ id: ev.getId() || '',
+ text: ev.getText(),
+ start_date: ev.getStartDate(),
+ end_date: ev.getEndDate(),
+ resource_id: ev.getResourceId()?.[0] || null,
+ }));
+}
+
+export async function GET() {
+ try {
+ const client = getStarhiveClient();
+ const [events, resources] = await Promise.all([
+ client.search(Events.TYPE_ID, ""),
+ client.search(Resources.TYPE_ID, "")
+ ]);
+
+ return NextResponse.json({
+ events: normalizeEvents(events.result),
+ resources: resources.result.map((r) => ({
+ key: r.getId(),
+ label: r.getLabel(),
+ })),
+ });
+ } catch (error) {
+ return NextResponse.json({ error: 'Failed to load data' }, { status: 500 });
+ }
+}
+```
+
+`normalizeEvents` 将每个 Starhive 对象扁平化为 React Scheduler 期望的形状:`{ id, text, start_date, end_date, resource_id }`。Resources 将扁平化为 `{ key, label }`,这是时间线视图中的 `y_unit` 所消耗的格式。
+
+在启动开发服务器后访问 `http://localhost:3000/api/load` 以确认 JSON 结构。
+
+## 步骤 7. 渲染 Scheduler 并加载事件
+
+创建 `app/page.tsx`:
+
+```tsx title="app/page.tsx"
+'use client';
+
+import { useEffect, useMemo, useState } from 'react';
+import ReactScheduler, {
+ type Event,
+ type SchedulerViewsProp,
+} from '@dhtmlx/trial-react-scheduler';
+import '@dhtmlx/trial-react-scheduler/dist/react-scheduler.css';
+
+type Resource = { key: string; label: string };
+
+export default function Scheduler() {
+ const [resources, setResources] = useState([]);
+ const [events, setEvents] = useState([]);
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ fetch('/api/load')
+ .then((response) => response.json())
+ .then((data) => {
+ setResources(data.resources);
+ setEvents(data.events);
+ })
+ .catch((error) => {
+ console.error('Failed to load resources data:', error);
+ })
+ .finally(() => {
+ setLoading(false);
+ });
+ }, []);
+
+ const views: SchedulerViewsProp = useMemo(
+ () => ({
+ timeline: [
+ {
+ name: "timeline",
+ x_unit: "hour",
+ x_date: "%H:%i",
+ x_step: 1,
+ x_start: 8,
+ x_size: 13,
+ x_length: 13,
+ event_dy: 50,
+ event_min_dy: 50,
+ y_property: "resource_id",
+ render: "bar",
+ y_unit: resources,
+ },
+ ],
+ }),
+ [resources]
+ );
+
+ if (loading) {
+ return Loading...
;
+ }
+
+ return (
+
+
+
+ );
+}
+```
+
+使用 `loading` 标志比直接检查 `events.length` 或 `resources.length` 更可靠:一个工作区如果确实没有事件,也应渲染空的 Scheduler 而不是一直处于加载状态。
+
+运行 `npm run dev`,时间线将显示并按资源分组导入的事件。
+
+## 步骤 8. 实现 CRUD 端点
+
+Scheduler 的 `dataBridge` 会调用三个端点 - 创建使用 POST、更新使用 PUT、删除使用 DELETE - 并期望特定的响应结构:
+
+| HTTP 方法 | Endpoint | Response |
+| --------- | ------------------------- | --------------------------------- |
+| `GET` | `/api/load` | `{ events, resources }` |
+| `POST` | `/api/event` | `{ action: "inserted", tid: id }` |
+| `PUT` | `/api/event/{event_id}` | `{ action: "updated" }` |
+| `DELETE` | `/api/event/{event_id}` | `{ action: "deleted" }` |
+
+在 `app/api/event/route.ts` 上创建 POST 处理程序:
+
+```ts title="app/api/event/route.ts"
+import { NextRequest, NextResponse } from 'next/server';
+import { getStarhiveClient } from '@/lib/starhiveClient';
+import { Events } from '@/lib/starhive/schema/Events';
+
+export async function POST(req: NextRequest) {
+ try {
+ const { text, start_date, end_date, resource_id } = await req.json();
+ const client = getStarhiveClient();
+
+ const event = Events.builder()
+ .text(text)
+ .startDate(new Date(start_date))
+ .endDate(new Date(end_date))
+ .resourceId([resource_id])
+ .build();
+
+ const result = await client.createObject(event);
+ return NextResponse.json({ action: 'inserted', tid: result.getId() });
+ } catch (error) {
+ return NextResponse.json({ error: 'Create failed' }, { status: 500 });
+ }
+}
+```
+
+以及动态 PUT/DELETE 处理程序在 `app/api/event/[id]/route.ts`:
+
+```ts title="app/api/event/[id]/route.ts"
+import { NextRequest, NextResponse } from 'next/server';
+import { Events } from "@/lib/starhive/schema/Events";
+import { getStarhiveClient } from "@/lib/starhiveClient";
+
+export async function PUT(
+ request: NextRequest,
+ { params }: { params: Promise<{ id: string }> },
+) {
+ try {
+ const { id } = await params;
+ const body = await request.json();
+ const client = getStarhiveClient();
+
+ const existingEvent = await client.getObject(id, Events.TYPE_ID);
+ if (!existingEvent) {
+ return NextResponse.json({ error: 'Event not found' }, { status: 404 });
+ }
+
+ const updatedEvent = Events.builder()
+ .id(id)
+ .text(body.text)
+ .startDate(new Date(body.start_date))
+ .endDate(new Date(body.end_date))
+ .resourceId([body.resource_id])
+ .build();
+
+ await client.updateObject(updatedEvent);
+ return NextResponse.json({ action: 'updated' });
+ } catch (error: any) {
+ console.error('Update error:', error);
+ return NextResponse.json(
+ { error: 'Update failed', details: error.message },
+ { status: 500 }
+ );
+ }
+}
+
+export async function DELETE(
+ request: NextRequest,
+ { params }: { params: Promise<{ id: string }> },
+) {
+ try {
+ const { id } = await params;
+ const client = getStarhiveClient();
+ await client.deleteObjectsInBulk([id]);
+
+ return NextResponse.json({ action: 'deleted' });
+ } catch (error: any) {
+ console.error('Delete error:', error);
+ return NextResponse.json(
+ { error: 'Delete failed', details: error.message },
+ { status: 500 }
+ );
+ }
+}
+```
+
+:::note
+在 Next.js 15+ 中,动态路由处理程序的 `params` 参数是一个 `Promise`。请始终将其类型标注为 `Promise<{...}>`,并在读取段值之前 `await` 它——在某些环境中省略 `Promise<>` 包装会在严格模式下编译失败。
+:::
+
+## 步骤 9. 将 dataBridge 与前端连接起来
+
+在 `services/scheduler.ts` 中创建一个小型客户端辅助工具:
+
+```ts title="services/scheduler.ts"
+import type { Event } from '@dhtmlx/trial-react-scheduler';
+
+async function request(url: string, options: RequestInit): Promise {
+ const res = await fetch(url, options);
+ if (!res.ok) throw new Error(`Request failed: ${res.status}`);
+ return res.json();
+}
+
+export function createEvent(event: Event) {
+ return request('/api/event', {
+ method: 'POST',
+ body: JSON.stringify(event),
+ headers: { 'Content-Type': 'application/json' },
+ });
+}
+
+export function updateEvent(event: Event) {
+ return request(`/api/event/${event.id}`, {
+ method: 'PUT',
+ body: JSON.stringify(event),
+ headers: { 'Content-Type': 'application/json' },
+ });
+}
+
+export function deleteEvent(id: string | number) {
+ return request(`/api/event/${id}`, {
+ method: 'DELETE',
+ });
+}
+```
+
+接着将 `dataBridge` 连接到页面中。更新 `app/page.tsx`,添加导入并在 `` 上使用 `data` 属性:
+
+```tsx title="app/page.tsx"
+import { createEvent, deleteEvent, updateEvent } from '@/services/scheduler';
+
+// Scheduler 组件内部:
+const dataBridge = useMemo(() => ({
+ save: (entity: string, action: string, payload: Event, id: string | number) => {
+ if (entity !== "event") return;
+
+ switch (action) {
+ case "update":
+ return updateEvent(payload);
+ case "create":
+ return createEvent(payload);
+ case "delete":
+ return deleteEvent(id);
+ default:
+ console.warn(`Unknown action: ${action}`);
+ return;
+ }
+ },
+}), []);
+
+// 将其传给组件:
+
+```
+
+## 测试
+
+```bash
+npm run dev
+```
+
+打开 `http://localhost:3000`,拖动某个事件到新的时间段、编辑文本、删除一个事件。每次修改都会在 Starhive UI 的 `Events` 类型下即时体现。
+
+## 关于 Starhive 集成的说明
+
+- **服务器端凭据独立。** `STARHIVE_API_TOKEN` 和 `STARHIVE_WORKSPACE_ID` 仅在路由处理程序中读取;它们永远不会进入浏览器打包中。不要将 Starhive 客户端放入客户端组件,或通过 `NEXT_PUBLIC_*` 变量暴露令牌。
+- **模式再生成。** 当你在 Starhive 中添加或重命名属性时,重新生成 TypeScript 模式并替换 `lib/starhive/`。如果在执行 `next build` 时收到相同的上游问题,请按照 [`lib/starhive/PATCHES.md`](https://github.com/DHTMLX/react-scheduler-starhive-demo/blob/main/lib/starhive/) 的 diff 重新应用补丁,直到 Starhive 提供修复。
+- **没有实时同步。** 与 Firebase 集成不同,Starhive 不会将变更推送给已连接的客户端。多用户编辑同一 Scheduler 时会覆盖彼此的改动。若需要支持多用户场景,可以在客户端添加轮询,或将 Starhive 的 Webhooks 连接到 SSE / WebSockets 以在远程变更时刷新 `events` 状态。
+- **大数据集的动态加载。** `/api/load` 路由会加载工作空间中的所有事件。生产环境中,可以在 GET 处理程序中接受 `from` / `to` 查询参数,按 `start_date` / `end_date` 进行筛选,并在客户端调用 `scheduler.setLoadMode("day")`,以便仅获取可见范围的数据。
+- **引用属性携带数组。** `Events.getResourceId()` 返回 `string[] | undefined`,因为 Starhive 的引用属性是多值的。演示中通过 `?.[0] || null` 进行扁平化处理。如果允许事件属于多个资源,请相应地调整时间线视图的 `y_property` 分辨方案以及 normalize / builder 调用。
+
+## 相关页面
+
+- [数据绑定与状态管理基础](integrations/react/state/state-management-basics.md)
+- [React Scheduler 概览](integrations/react/overview.md#bindingdata)
+- [服务端集成](guides/server-integration.md)
+- [React Scheduler 与 Firebase 集成](integrations/react/firebase-integration.md) - 实时同步的对等模式
\ No newline at end of file
diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md b/i18n/zh/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
index 3e3d002f..e3014fb4 100644
--- a/i18n/zh/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
+++ b/i18n/zh/docusaurus-plugin-content-docs/current/integrations/react/state/valtio.md
@@ -15,7 +15,7 @@ description: 使用 Valtio 代理存储管理 React Scheduler 的状态,通过
- 基于快照的撤销/重做(事件 + 配置)
:::note
-完整的源代码可在 GitHub 上查看:[GitHub 演示仓库](https://github.com/nicetip/react-scheduler-valtio-starter)。
+完整的源代码可在 GitHub 上查看:[GitHub 演示仓库](https://github.com/DHTMLX/react-scheduler-valtio-starter)。
:::
## 前提条件
diff --git a/i18n/zh/docusaurus-plugin-content-docs/current/migration.md b/i18n/zh/docusaurus-plugin-content-docs/current/migration.md
index 85ab0e70..6e229898 100644
--- a/i18n/zh/docusaurus-plugin-content-docs/current/migration.md
+++ b/i18n/zh/docusaurus-plugin-content-docs/current/migration.md
@@ -275,7 +275,7 @@ scheduler.config.day_column_padding = 0;
自 v7.0 起,导入/导出功能已集成至 Scheduler 库中。
-如果之前为在线导出功能引入了 **https://export.dhtmlx.com/scheduler/api.js**,例如:
+如果之前为在线导出功能引入了 `https://export.dhtmlx.com/scheduler/api.js`,例如:
~~~js
diff --git a/src/css/custom.css b/src/css/custom.css
index f5cceccb..3cbcd702 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -122,6 +122,9 @@ html[data-theme='dark'] .docusaurus-highlight-code-line {
/* end imgs */
+.markdown a {
+ font-weight: 600;
+}
/* Change the appearance of mobile navigation */
diff --git a/src/css/framework_icons.css b/src/css/framework_icons.css
index 37a8276e..a5d2c46f 100644
--- a/src/css/framework_icons.css
+++ b/src/css/framework_icons.css
@@ -1,6 +1,6 @@
.framework-grid {
display: grid;
- grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
+ grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
gap: 1.25rem;
margin: 1.5rem 0 2rem;
}
diff --git a/static/img/scheduler_overview.png b/static/img/scheduler_overview.png
new file mode 100644
index 00000000..cb0bd10e
Binary files /dev/null and b/static/img/scheduler_overview.png differ