Skip to content

Commit d59a856

Browse files
committed
Merge branch 'main' into runtime-workspace
2 parents b3ba0d0 + c5d4be6 commit d59a856

25 files changed

+5730
-229
lines changed

.github/workflows/node.js.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,17 @@ jobs:
3232
cache: 'npm'
3333
- run: npm ci
3434
- run: npm run tsc
35+
36+
check-docs:
37+
runs-on: ubuntu-latest
38+
strategy:
39+
matrix:
40+
node-version: [22.x]
41+
steps:
42+
- uses: actions/checkout@v4
43+
- uses: actions/setup-node@v4
44+
with:
45+
node-version: ${{ matrix.node-version }}
46+
cache: 'npm'
47+
- run: npm ci
48+
- run: npm run checkDocs

.github/workflows/update-docs.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Update Docs Revision And Database
2+
on:
3+
push:
4+
branches: [ "main" ]
5+
permissions:
6+
contents: write
7+
jobs:
8+
check-docs:
9+
runs-on: ubuntu-latest
10+
strategy:
11+
matrix:
12+
node-version: [22.x]
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: actions/setup-node@v4
16+
with:
17+
node-version: ${{ matrix.node-version }}
18+
cache: 'npm'
19+
- run: npm ci
20+
- run: npx drizzle-kit migrate
21+
env:
22+
DATABASE_URL: ${{ secrets.DATABASE_URL }}
23+
- run: npx tsx ./scripts/checkDocs.ts --write
24+
env:
25+
DATABASE_URL: ${{ secrets.DATABASE_URL }}
26+
- name: Configure git for push
27+
run: |
28+
git remote set-url origin "https://github-actions:${GITHUB_TOKEN}@github.com/${{ github.repository }}"
29+
git config user.name "github-actions[bot]"
30+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
31+
env:
32+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33+
- name: Commit build output
34+
run: |
35+
git add .
36+
git diff --staged --exit-code || (git commit -m "[ci] update revisions.yml" && git push origin main)
37+
# The `||` ensures the commit and push only happen if there are changes (git diff exits with non-zero)

.gitignore

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
/.open-next
44
/cloudflare-env.d.ts
55

6-
# generated docs section file lists (regenerated by npm run generateSections)
7-
/public/docs/**/sections.yml
8-
9-
# generated languages list (regenerated by npm run generateLanguages)
10-
/public/docs/languages.yml
6+
# generated docs section file lists (regenerated by npm run generateDocsMeta)
7+
/public/docs/**/sections.json
8+
/public/docs/languages.json
119

1210
# dependencies
1311
/node_modules

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ COPY --from=dependencies /app/node_modules ./node_modules
2222
# Copy application source code
2323
COPY . .
2424

25-
ENV NODE_ENV=production
25+
# Stop if documentation has any change that is not reflected to revisions.yml and database.
26+
RUN npx tsx ./scripts/checkDocs.ts --check-diff
2627

2728
# Next.js collects completely anonymous telemetry data about general usage.
2829
# Learn more here: https://nextjs.org/telemetry

README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ npm run lint
5454
```
5555
でコードをチェックします。出てくるwarningやerrorはできるだけ直しましょう。
5656

57+
### データベースのスキーマ
58+
5759
* データベースのスキーマ(./app/schema/hoge.ts)を編集した場合、 `npx drizzle-kit generate` でmigrationファイルを作成し、 `npx drizzle-kit migrate` でデータベースに反映します。
58-
* また、mainにマージする際に本番環境のデータベースにもmigrateをする必要があります
60+
* 本番環境のデータベースのmigrateはmainにpushされた際にGitHub Actionで実行されます
5961
* スキーマのファイルを追加した場合は app/lib/drizzle.ts でimportを追加する必要があります(たぶん)
6062
* `npx prisma dev` で立ち上げたデータベースは `npx prisma dev ls` でデータベース名の確認・ `npx prisma dev rm default` で削除ができるらしい
6163

@@ -72,6 +74,11 @@ Cloudflare Worker のビルドログとステータス表示が見れますが
7274

7375
## ドキュメント
7476

77+
```bash
78+
npm run checkDocs
79+
```
80+
でドキュメントの読み込み時にエラーにならないか確認できます (index.ymlの間違いなど)
81+
7582
* ドキュメントはセクション(見出し)ごとにわけ、 public/docs/言語id/ページid/並び替え用連番-セクション名.md に置く。
7683
* ページはディレクトリの名前によらず 言語id/index.yml に書かれている順で表示される。
7784
* セクションはセクションIDによらずファイル名順で表示される。
@@ -111,6 +118,8 @@ Cloudflare Worker のビルドログとステータス表示が見れますが
111118
* REPLのコード例は1セクションに最大1つまで。
112119
* コードエディターとコード実行ブロックはいくつでも置けます。
113120
* ページ0以外の各ページの最後はレベル2見出し「この章のまとめ」と、レベル3見出し「練習問題n」を置く
121+
* 編集したドキュメントにローカルの開発環境でアクセスする際は `npx tsx ./scripts/checkDocs.ts --write` でrevisions.ymlを更新してください。チャットを正しく動作させるために必要です。基本的には手動でこのファイルを編集する必要はありません。
122+
* 本番環境ではドキュメントの変更がmainブランチにpushされた際に自動で更新されます。gitのコミットidを参照して更新するため、ローカルで更新したrevisions.ymlはpushしないでください。
114123

115124
### ベースとなるドキュメントの作り方
116125

@@ -141,18 +150,17 @@ Cloudflare Worker のビルドログとステータス表示が見れますが
141150
- Canvasを使われた場合はやり直す。(Canvasはファイル名付きコードブロックで壊れる)
142151
- 太字がなぜか `**キーワード**` の代わりに `\*\*キーワード\*\*` となっている場合がある。 `\*\*` → `**` の置き換えで対応
143152
- 見出しの前に `-----` (水平線)が入る場合がある。my.code();は水平線の表示に対応しているが、消す方向で統一
144-
- `言語名-repl` にはページ内で一意なIDを追加する (例: `言語名-repl:1`)
145153
- REPLの出力部分に書かれたコメントは消えるので修正する
146154
- ダメな例
147155
````
148-
```js-repl:1
156+
```js-repl
149157
> console.log("Hello")
150158
Hello // 文字列を表示する
151159
```
152160
````
153161
- 以下のようにすればok
154162
````
155-
```js-repl:1
163+
```js-repl
156164
> console.log("Hello") // 文字列を表示する
157165
Hello
158166
@@ -162,7 +170,6 @@ Cloudflare Worker のビルドログとステータス表示が見れますが
162170
```
163171
````
164172
- 練習問題のファイル名は不都合がなければ `practice(章番号)_(問題番号).拡張子` で統一。空でもよいのでファイルコードブロックとexecコードブロックを置く
165-
- 1章にはたぶん練習問題要らない。
166173

167174
## markdown仕様
168175

app/[lang]/[pageId]/chatForm.tsx

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,15 @@ import { DynamicMarkdownSection } from "./pageContent";
1111
import { useEmbedContext } from "@/terminal/embedContext";
1212
import { useChatHistoryContext } from "./chatHistory";
1313
import { askAI } from "@/actions/chatActions";
14+
import { PagePath } from "@/lib/docs";
1415

1516
interface ChatFormProps {
16-
docs_id: string;
17-
documentContent: string;
17+
path: PagePath;
1818
sectionContent: DynamicMarkdownSection[];
1919
close: () => void;
2020
}
2121

22-
export function ChatForm({
23-
docs_id,
24-
documentContent,
25-
sectionContent,
26-
close,
27-
}: ChatFormProps) {
22+
export function ChatForm({ path, sectionContent, close }: ChatFormProps) {
2823
// const [messages, updateChatHistory] = useChatHistory(sectionId);
2924
const [inputValue, setInputValue] = useState("");
3025
const [isLoading, setIsLoading] = useState(false);
@@ -80,9 +75,8 @@ export function ChatForm({
8075
// }
8176

8277
const result = await askAI({
78+
path,
8379
userQuestion,
84-
docsId: docs_id,
85-
documentContent,
8680
sectionContent,
8781
replOutputs,
8882
files,
@@ -94,7 +88,9 @@ export function ChatForm({
9488
console.log(result.error);
9589
} else {
9690
addChat(result.chat);
97-
// TODO: chatIdが指す対象の回答にフォーカス
91+
document.getElementById(result.chat.sectionId)?.scrollIntoView({
92+
behavior: "smooth",
93+
});
9894
setInputValue("");
9995
close();
10096
}

app/[lang]/[pageId]/chatHistory.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"use client";
22

33
import { ChatWithMessages, getChat } from "@/lib/chatHistory";
4+
import { PagePath } from "@/lib/docs";
45
import {
56
createContext,
67
ReactNode,
@@ -28,11 +29,11 @@ export function useChatHistoryContext() {
2829

2930
export function ChatHistoryProvider({
3031
children,
31-
docs_id,
32+
path,
3233
initialChatHistories,
3334
}: {
3435
children: ReactNode;
35-
docs_id: string;
36+
path: PagePath;
3637
initialChatHistories: ChatWithMessages[];
3738
}) {
3839
const [chatHistories, setChatHistories] =
@@ -43,7 +44,7 @@ export function ChatHistoryProvider({
4344
}, [initialChatHistories]);
4445
// その後、クライアント側で最新のchatHistoriesを改めて取得して更新する
4546
const { data: fetchedChatHistories } = useSWR<ChatWithMessages[]>(
46-
docs_id,
47+
path,
4748
getChat,
4849
{
4950
// リクエストは古くても構わないので1回でいい

app/[lang]/[pageId]/page.tsx

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ import { notFound } from "next/navigation";
33
import { PageContent } from "./pageContent";
44
import { ChatHistoryProvider } from "./chatHistory";
55
import { getChatFromCache, initContext } from "@/lib/chatHistory";
6-
import { getMarkdownSections, getPagesList } from "@/lib/docs";
6+
import {
7+
getMarkdownSections,
8+
getPagesList,
9+
LangId,
10+
PageSlug,
11+
} from "@/lib/docs";
712

813
export async function generateMetadata({
914
params,
1015
}: {
11-
params: Promise<{ lang: string; pageId: string }>;
16+
params: Promise<{ lang: LangId; pageId: PageSlug }>;
1217
}): Promise<Metadata> {
1318
const { lang, pageId } = await params;
1419
const pagesList = await getPagesList();
@@ -28,35 +33,31 @@ export async function generateMetadata({
2833
export default async function Page({
2934
params,
3035
}: {
31-
params: Promise<{ lang: string; pageId: string }>;
36+
params: Promise<{ lang: LangId; pageId: PageSlug }>;
3237
}) {
3338
const { lang, pageId } = await params;
3439
const pagesList = await getPagesList();
3540
const langEntry = pagesList.find((l) => l.id === lang);
3641
const pageEntry = langEntry?.pages.find((p) => p.slug === pageId);
3742
if (!langEntry || !pageEntry) notFound();
3843

39-
const docsId = `${lang}/${pageId}`;
44+
// server componentなのでuseMemoいらない
45+
const path = { lang: lang, page: pageId };
4046
const sections = await getMarkdownSections(lang, pageId);
4147

42-
// AI用のドキュメント全文(rawContentを結合)
43-
const documentContent = sections.map((s) => s.rawContent).join("\n");
44-
4548
const context = await initContext();
46-
const initialChatHistories = await getChatFromCache(docsId, context);
49+
const initialChatHistories = await getChatFromCache(path, context);
4750

4851
return (
4952
<ChatHistoryProvider
5053
initialChatHistories={initialChatHistories}
51-
docs_id={docsId}
54+
path={path}
5255
>
5356
<PageContent
54-
documentContent={documentContent}
5557
splitMdContent={sections}
58+
langEntry={langEntry}
5659
pageEntry={pageEntry}
57-
docs_id={docsId}
58-
lang={lang}
59-
pageId={pageId}
60+
path={path}
6061
/>
6162
</ChatHistoryProvider>
6263
);

0 commit comments

Comments
 (0)