@squadbase/vantage-template 0.1.1-dev1.2be5c44 → 0.1.1-dev1.57af5cd

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -302,6 +302,34 @@ const res = await fetch(`${baseUrl}/queries/${QUERY_ID}?since=2026-01-01`, {
302
302
  })
303
303
  ```
304
304
 
305
+ ### 生の応答から行を取り出す(`noUncheckedIndexedAccess`)
306
+
307
+ テンプレートの `tsconfig.json` は `noUncheckedIndexedAccess: true`。**配列の添字はすべて
308
+ `T | undefined`** なので、HTTP Query が通す上流の生の応答(GA4 の `rows[].metricValues[]` など)を
309
+ `row.metricValues[0].value` と書くと `Object is possibly 'undefined'.` で落ちる。書く前に添字
310
+ アクセスを頭の中で型検査し、応答の型と行の変換関数を先に決めて `?.` と `??` で取り出す:
311
+
312
+ ```ts
313
+ type Ga4Row = {
314
+ dimensionValues?: { value?: string }[]
315
+ metricValues?: { value?: string }[]
316
+ }
317
+ type SessionsDaily = { date: string; sessions: number; pageViews: number }
318
+
319
+ const toSessionsDaily = (row: Ga4Row): SessionsDaily => ({
320
+ date: row.dimensionValues?.[0]?.value ?? "",
321
+ sessions: Number(row.metricValues?.[0]?.value ?? "0"),
322
+ pageViews: Number(row.metricValues?.[1]?.value ?? "0"),
323
+ })
324
+
325
+ const report = (await res.json()) as { rows?: Ga4Row[] }
326
+ return Response.json((report.rows ?? []).map(toSessionsDaily))
327
+ ```
328
+
329
+ - 値が欠けた行を落としたいときは `if (!date) throw new HttpError(502, …)` ではなく、変換後に
330
+ `.filter((r) => r.date !== "")` で除く。`date!` のような非 null 断言で黙らせない。
331
+ - SQL Query の `rows` も同じ。`rows[0]` を使うなら `const first = rows[0]; if (!first) …` で先に絞る。
332
+
305
333
  ## 構築中の一時的なエラーを「進行中」に見せる(`components/build-recovery.tsx`)
306
334
 
307
335
  ページを書いている途中は、ファイルが書き終わる順番の都合で一瞬だけページが throw する
@@ -349,3 +377,26 @@ lockfile は `bun.lock`)。Squadbase のサンドボックスは bun と依存
349
377
  `bun install` を一度走らせて `bun.lock` を追従させ、両方を同じコミットに入れる。
350
378
  - スクリプトは `bun run <script>`(`bun run dev` / `bun run build` / `bun run check` /
351
379
  `bun run routes`)。`npm run <script>` でも動くが、install に npm を使わないこと。
380
+
381
+ ## このアプリで作れるもの
382
+
383
+ ユーザーの目的に合わせて、どの形にするかを選ぶ。ここに書かれていない形は約束しない。
384
+
385
+ - **ダッシュボード** — 数字を繰り返し見に来て、変化に気づきたいとき。指標と推移・内訳を 1 画面に
386
+ 置き、`server/api/` で実データを取る。
387
+ - 書き込む場所: `src/<slug>.tsx`, `server/api/<slug>/**`
388
+ - ページ: あり
389
+ - 作り方: `src/` にページ(`.tsx`)を置く。書く前に `agents/page.md`(API は `agents/api.md`)を読む。
390
+ - **スライド** — 分析の示唆をまとめて誰かに伝えるとき(調査結果の報告、会議資料、施策の提案)。
391
+ 結論 → 根拠 → 次の一手の順にまとめる。
392
+ - 書き込む場所: `src/<slug>.slide.tsx`, `vantage-slide/**`
393
+ - ページ: あり
394
+ - 作り方: `src/<slug>.slide.tsx` に `<SlideDeck>` を返すページを置く(`@squadbase/vantage/slide`)。
395
+ 書く前に `agents/slide.md` を読み、`vantage-slide` Skill が未配置なら
396
+ `vantage add skill vantage-slide` で置いてから読む。
397
+ - **オートメーション** — 決まった時刻に集計・通知・定期レポートを回したいとき、しきい値で
398
+ アラートしたいとき。
399
+ - 書き込む場所: `automations/<slug>/**`, `pipelines/**`
400
+ - ページ: なし
401
+ - 作り方: `automations/<名前>/automation.yml` に定義し、処理のコードは `pipelines/` に置く。
402
+ 書く前に Automation のガイド(`readAutomationGuide`)を読む。
@@ -11,6 +11,13 @@
11
11
  `src/monthly-report.slide.tsx` → `/monthly-report`。中身は `<SlideDeck>` を返す普通の React
12
12
  コンポーネントで、`definePage` もナビも通常のページと同じように効きます。
13
13
 
14
+ **ファイル名の決め方:**
15
+
16
+ - **ルート `/` がすでに他のページ(`index.tsx`など)で使われている場合は、スライドのタイトルから slug を作ってファイル名にする。** `index.slide.tsx` は `index.tsx` と同じ `/` に解決するので `ROUTE_CONFLICT` になる。
17
+ - 例: "Label check" というスライド → `src/label-check.slide.tsx` → `/label-check`
18
+ - 例: "Monthly Report" というスライド → `src/monthly-report.slide.tsx` → `/monthly-report`
19
+ - 新規プロジェクトでまだ `/` が空いている場合のみ、`index.slide.tsx` を使ってよい。
20
+
14
21
  ```tsx
15
22
  import { Slide, SlideDeck } from "@squadbase/vantage/slide"
16
23
 
@@ -6,7 +6,7 @@
6
6
  "name": "vibe-app",
7
7
  "dependencies": {
8
8
  "@squadbase/react": "^0.1.0",
9
- "@squadbase/vantage": "0.6.2-dev1.3e69e88",
9
+ "@squadbase/vantage": "0.6.2-dev1.9612525",
10
10
  "@squadbase/vantage-sdk": "0.1.1-dev1.25f1dd3",
11
11
  "date-fns": "^4.1.0",
12
12
  "lucide-react": "^0.468.0",
@@ -204,7 +204,7 @@
204
204
 
205
205
  "@squadbase/react": ["@squadbase/react@0.1.0", "", { "dependencies": { "zod": "^4.3.6" }, "peerDependencies": { "@types/react": "17.x || 18.x || 19.x", "react": "17.x || 18.x || 19.x" }, "optionalPeers": ["@types/react"] }, "sha512-k+Dpyj7eH+Yjydw54iEluCjYDae086d12hWgBjNMpw4wLbQGz3CrJ6Yipodg8n1cKUt7zvwddlcTHd79bgKsXg=="],
206
206
 
207
- "@squadbase/vantage": ["@squadbase/vantage@0.6.2-dev1.3e69e88", "", { "dependencies": { "@base-ui/react": "^1.6.0", "@hono/node-server": "^2.0.8", "@streamdown/code": "^1.1.1", "@tailwindcss/vite": "^4.3.2", "@tanstack/react-query": "^5.101.2", "@tanstack/react-router": "^1.170.17", "@tanstack/react-table": "^8.21.3", "@vitejs/plugin-react": "^6.0.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", "date-fns": "^4.1.0", "echarts": "^6.0.0", "esbuild": "^0.28.1", "fflate": "^0.8.3", "hono": "^4.13.5", "html-to-image": "^1.11.13", "lucide-react": "^0.468.0", "papaparse": "^5.7.0", "picocolors": "^1.1.1", "react-day-picker": "^10.0.1", "read-excel-file": "^9.3.10", "streamdown": "^2.5.0", "tailwind-merge": "^3.0.0", "tailwindcss": "^4.3.2", "tw-animate-css": "^1.0.0", "vite": "^8.1.4" }, "peerDependencies": { "react": ">=18.2.0", "react-dom": ">=18.2.0" }, "bin": { "vantage": "dist/cli.js" } }, "sha512-3bcyZD247noScN0OncBaFbpA0zhAFfKVwHjnRjffrJhyx9IxHfUg59+D1FjoJRMLaehE3J0YbXcisPL7RzlWrQ=="],
207
+ "@squadbase/vantage": ["@squadbase/vantage@0.6.2-dev1.9612525", "", { "dependencies": { "@base-ui/react": "^1.6.0", "@hono/node-server": "^2.0.8", "@streamdown/code": "^1.1.1", "@tailwindcss/vite": "^4.3.2", "@tanstack/react-query": "^5.101.2", "@tanstack/react-router": "^1.170.17", "@tanstack/react-table": "^8.21.3", "@vitejs/plugin-react": "^6.0.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", "date-fns": "^4.1.0", "echarts": "^6.0.0", "esbuild": "^0.28.1", "fflate": "^0.8.3", "hono": "^4.13.5", "html-to-image": "^1.11.13", "lucide-react": "^0.468.0", "papaparse": "^5.7.0", "picocolors": "^1.1.1", "react-day-picker": "^10.0.1", "read-excel-file": "^9.3.10", "streamdown": "^2.5.0", "tailwind-merge": "^3.0.0", "tailwindcss": "^4.3.2", "tw-animate-css": "^1.0.0", "vite": "^8.1.4" }, "peerDependencies": { "react": ">=18.2.0", "react-dom": ">=18.2.0" }, "bin": { "vantage": "dist/cli.js" } }, "sha512-OB5BgzpG4TF2MYCCbmn6R4EWsmofFpiuRdhbI/GvWlg+7MFqA8C/WjLBrADZ24KXojWX4QRNnsTJUDbK4zQVcw=="],
208
208
 
209
209
  "@squadbase/vantage-sdk": ["@squadbase/vantage-sdk@0.1.1-dev1.25f1dd3", "", {}, "sha512-78C16NNmnhbn3JhiaXIlAzz7I15n6+lbOzbADCqCNAA2t/FD7Bkst6MuekuixtAj6i/J3m5gIrSp7GpwZbLQdg=="],
210
210
 
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@squadbase/react": "^0.1.0",
15
- "@squadbase/vantage": "0.6.2-dev1.3e69e88",
15
+ "@squadbase/vantage": "0.6.2-dev1.9612525",
16
16
  "@squadbase/vantage-sdk": "0.1.1-dev1.25f1dd3",
17
17
  "date-fns": "^4.1.0",
18
18
  "lucide-react": "^0.468.0",
@@ -17,6 +17,7 @@ export const page = definePage({
17
17
  title: "Dashboard",
18
18
  description: "Sample data — replace with your own to get started.",
19
19
  navLabel: "Home",
20
+ placeholder: true,
20
21
  })
21
22
 
22
23
  const METRICS = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squadbase/vantage-template",
3
- "version": "0.1.1-dev1.2be5c44",
3
+ "version": "0.1.1-dev1.57af5cd",
4
4
  "description": "CLI tool for initializing and customizing Squadbase Vantage projects.",
5
5
  "keywords": [
6
6
  "squadbase",