ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证小学校向け週案作成Webアプリ
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗週案エディタ(School Plan Note) は、小学校(および小中学校)の教員向けに開発された、週案(週間指導計画)および校務支援のWebアプリケーションです。
Google Apps Script (GAS) と Google スプレッドシートをバックエンドとして利用し、最新の生成AI(Gemini API)を組み込むことで、教員の日常的な事務作業の負担を大幅に軽減することを目的としています。
アプリはシングルページ構成で、画面上部の8つのタブを切り替えて使います。以下の機能説明は、このタブ名で参照しています。
| タブ | 何をする画面か |
|---|---|
| 週案 | 週単位のグリッドに授業予定を入力する。起動時に開く画面 |
| 行事予定 | 学校の年間行事予定PDFを登録・閲覧する |
| タスク | 準備物・連絡事項などのタスクを管理する(未処理件数がタブにバッジ表示) |
| 単元 | 「単元マスタ」シートを表形式で編集する(画面見出しは「単元マスタ編集」) |
| 学級通信 | 学級通信をブロックエディタで作り、PDF出力・Classroom投稿する |
| 時数 | 教科別の実施時数集計と、年度末の過不足シミュレーション |
| PDF読み込み | 指導計画PDF・行事予定PDFをAIで解析して取り込む |
| 設定 | 使用中のデータベース、システム設定、固定時間割、標準時数、データ保全・復元など |
タブの右端には表示テーマの切替ボタンがあり、押すたびに「自動(OSの設定に追従)→ ライト → ダーク」を巡回します。
ブラウザ上の直感的なグリッドUIで、1週間分の予定を入力・管理できます。行は上から 行事/登校前/朝学習/1校時/2校時/中休み/3校時/4校時/昼休み/5校時/6校時/放課後/宿題/持ち物 の14行で、各校時は「教科」「単元」「学習活動」の3つに分かれています。土曜・日曜の列は表示/非表示を切り替えられます。
セルはダブルクリック(ダブルタップ)で編集でき、**ドラッグ&ドロップでのコマ移動・Undo(元に戻す)**にも対応しています。朝学習・中休み・昼休み・放課後の欄には、「タスク」タブに登録したタスクをボタンから転記できます。
閲覧モードは完全に読み取り専用、書き換えは編集モードだけ: 週案タブには「閲覧モード」と「編集モード」があり、内容を書き換える操作(入力、コマのコピー&ペースト、クリア、ドラッグ&ドロップでの入れ替え、元に戻す、タスクの書き込み)はすべて編集モードでのみ行えます。閲覧モードでは右クリックや長押しのセル操作メニューも出ません。閲覧中に書き換えようとしたときは、編集モードへの入り方を案内します。
E キー、セルのダブルクリック(ダブルタップ)、選択中セルで Enter。Ctrl+C / Ctrl+V: 編集モードで、文字を選択していない時の Ctrl+C がコマ全体のコピーになり、コピーしたコマを Ctrl+V するとセルごと貼り付きます。文字を選択してのコピーや、他アプリからコピーした文字の貼り付けは今までどおり文字として扱われるため、入力の邪魔になりません。閲覧モードでは横取りしないので、選んだ文字がブラウザ標準の動きでそのままコピーできます。登校前タスク列: 「行事」列と「朝学習」列の間に、出勤後・児童登校前に済ませておくタスクを記入できる「登校前」列を用意しています。アプリが作成するデータベースには最初から含まれています(11_Tenant.gs の DB_CANONICAL_HEADERS)。この列が導入される前に作ったシートや、手作りのシートで欄が出ない場合は、スプレッドシートを直接開いて「行事」列の隣に列を挿入し、見出しに 登校前 と入力してください。列は見出し名で解決するため(00_config.gs の scanDbHeaderForSheet_())、並び順は問いません。印刷時は印刷オプションのチェックボックスで表示するかどうかを選べます(初期状態は非表示)。
祝日の自動表示: 内閣府が公開する祝日データ(syukujitsu.csv)を自動取得し、週案グリッドの該当日を赤色で強調して祝日名(例:「海の日」)をバッジ表示します。印刷時も標準・コンパクト両レイアウトで祝日の列を赤系で色分けし、祝日名を表示するため、休みの日が一目で分かります。祝日データは未取得なら週案の生成時に自動取得されます。更新はアプリを開いたとき(doGet)に行われ、前回取得から25日以上経っていれば自動で取り直します(07_WebApp.gs の HOLIDAY_REFRESH_INTERVAL_DAYS)。手動更新の操作はありません。
入力支援メニュー: ツールバーの「入力支援」に、固定時間割反映/単元自動入力/以降を一括自動入力/単元をずらすをまとめています。グリッドの右側には開閉できるサイドパネルがあり、今週のタスクと行事予定PDFをタブで切り替えられます。タスクのカードは週案のセルへドラッグして、そのまま記入できます(ドラッグできない端末では、セルを選んでカードの書き込みボタンを押します)。ツールバーのキーボードアイコンからショートカット一覧を確認できます。
AI自動入力: 「単元マスタ」の進捗と過去の履歴を照らし合わせ、次の時間の学習内容を自動で割り当てます。その週だけの自動入力と、その週以降をまとめて埋める一括自動入力を選べます。
進捗つき単元選択: 週案の単元選択モーダルに、単元ごとの指導状況(未指導/○時間目まで実施済み/指導済み)を表示します。指導が終わった単元は既定で折りたたまれて下に送られ、次に指導する単元が先頭に強調表示されるため、毎回一覧から目で探す必要がありません。単元名での検索もでき、単元を選んだあとの「何時間目」も自動で次の時間目が初期選択されます。この進捗には、まだ保存していないその週の入力も含まれます。月曜のコマに1時間目を入れたら、保存しなくても火曜のコマでは2時間目が初期選択になります(手入力・ドラッグ&ドロップ・自動入力の結果も同じように反映されます)。この反映は画面内で完結するため、サーバーへの問い合わせは増えません。
週をまたいだ全文検索: 週ナビゲーションの「検索」ボタンから、すべての週の入力内容(行事・朝学習・各校時の教科/単元/学習内容・宿題・持ち物・振り返りなど)をキーワードで横断検索できます。「あの実験いつやったっけ」も一発で見つかり、検索結果をクリックするとその週の週案へジャンプします。
印刷: 「印刷」ボタンで印刷オプションが開きます。レイアウトは標準(A4・2ページ)/コンパクト(A4・1ページ)の2種類。行事・登校前・朝学習・中休み・昼休み・放課後・教科時数表・週のまとめ・Todoリストの9項目を個別にON/OFFでき、フォントサイズは既定で用紙に合わせて自動調整され、その週の分量に対してA4に収まる範囲でいちばん大きいサイズが選ばれます(自動調整をOFFにすると8〜14pxで手動指定できます)。選択内容はブラウザに記憶されます。Todoリストと教科時数表は標準レイアウトの2ページ目にのみ印刷されます。なお、アプリの「印刷」ボタンを使わずブラウザの印刷(Ctrl+P など)を直接呼んだ場合は、週案の紙面ではなくいま開いている画面が刷られます。この場合も画面の途中で切れないよう、紙では画面の高さの縛りと内側のスクロールを外して全体を流し込みます。
固定時間割の反映: 「設定」タブの「固定時間割エディタ」で基本の時間割を登録しておくと、週案画面の「入力支援」からその週へ一括反映できます。「年間一括転記」を使えば、長期休業期間を除いた今後のすべての週へまとめて転記できます(既存の入力は上書きされます)。
PDF自動読み取り: 学校配布のPDF(年間指導計画・行事予定)をAIが解析し、スプレッドシートに転記します。「PDF読み込み」タブにドラッグ&ドロップするか、クリックしてファイルを選ぶ方式で(複数可・1ファイル15MBまで)、ファイルごとの処理状況が画面に表示されます。抽出結果は書き込み前にプレビュー(行事予定は月ごと、指導計画は教科ごと)で確認・修正・除外してから反映できます。指導計画の反映時は、同じ教科の既存データが置き換えられます。
学級通信のAI生成: 「学級通信」タブでは、その週の週案(持ち物・行事・単元)をもとに、保護者向けの**「お知らせ」記事(「1.見出し」+本文)をAIがまとめて下書きできます(1〜3本・文体も選択可)。記事1本ずつの生成や、テキストブロック単位での本文生成・リライト**も行えます。
いつもの学級通信(A4 1枚): 題字と発行日・学校名・担任名、週予定の表(日付と曜日を1行・あさの行・祝日や休みの日は列ごと灰色・空欄は「−」)、表の下の持ち物・当番の3行、「お知らせ」を、紙の学級通信の形でひと押しで組みます。文字の大きさは Google ドキュメントと同じ pt で 0.5 刻みに選べます。
タスク自動抽出: 週案の予定(実験、特別な行事など)から、事前に準備すべきタスク(準備物、連絡事項など)をAIが自動で洗い出し、優先度付きでリストアップします。
タスク進行管理: タスクは「未着手→進行中→完了」の3段階で進行を管理でき、優先度(高・中・低)やメモも設定できます。期限切れ・今日が期日のタスクはナビゲーションのバッジや進行状況サマリーで一目で把握できます。メールリマインダーを有効にすると、指定した時刻(0〜23時・既定は7時)に「期限切れ/今日が期日/1週間以内」の未完了タスクが毎日メールで届きます(対象が0件の日は送信されません)。
単元の時数再構成: 「単元」タブの表で、各行の魔法のステッキのアイコン(auto_fix_high)から、「この単元を◯時間に組み直したい」をAIに任せられます。実際の進度に合わせて時数を増減させると、学習活動が新しい時間数に合わせて統合・分割されます。週案に入力済みの時間は変更されません(AIには渡されません)。結果は必ずプレビューで確認・修正してから反映され、単元マスタ上の並び順(=年間指導計画の順)も保たれます。反映前の状態は復元ポイントとして保存されます。
年間時数の再配分: 「時数」タブの年度末シミュレーションで過不足のある教科に「調整案」ボタンが表示されます。標準時数に届くよう、未指導の単元へ時数を配分し直す案を作成します。まず機械的に比例配分した案を作り、AIはその調整だけを行うため、AIが使えない場合でも必ず案が出ます。
「単元マスタ」シートは 1行 = 単元の1時間分 という持ち方で、総時間数を同じ単元の全行に重複して持ちます。そのため使い込むうちに「総時間数と実際の行数が合わない」「何時間目が重複・欠番になっている」といったズレが溜まりがちです。
「単元」タブでは、教科名・単元名・総時数・時数・学習活動の5列を表形式で直接編集できます。教科での絞り込みと単元名での検索、行の追加・削除にも対応しています。
「単元」タブの「整合性チェック」ボタンで、こうしたズレを一覧表示し、ワンクリックで修復できます(AIは使いません)。修復は学習活動の内容を消しません。並べ替え・連番の振り直し・総時数の再設定と、不足分の空行追加だけを行い、週案で既に指導済みの時数を下回らないように調整します。実行前の状態は復元ポイントとして保存されます。
「総時数より行が多い」状態は不整合として扱いません。 週案の「◯時間で終了」や、単元マスタで総時数を手で減らしたときにこの形になります(余った時間の指導案を残したまま、単元を短く閉じた状態)。整合性チェックがこれを行数へ戻してしまうと単元を終わりにできないため、不整合として拾うのは「総時数のぶんだけ行が足りない」ときだけです。なお単元が何時間かは総時数の列が正で、行数や週案のセルに書かれた分母(単元名 2/5 の 5)ではありません。
総時数の 0 は「今年は指導しない」という印です(空欄=まだ決めていない、とは別物)。週案の「指導しない」「まとめて終了にする」を押すとこの 0 が入り、その単元は指導し終えた単元と同じように扱われて自動入力も戻らなくなります。0 の単元は教科の単元時数の合計にも数えません。整合性チェックの修復は 0 を消さず、行数も減らしません。「単元」タブで総時数を書き戻せば、いつでも指導する状態に戻せます。
あわせて、教科ごとの「単元時数の合計」と「年間標準時数」の比較も表示されます。両者が一致している必要はありませんが、年間指導計画を見直す目安になります。
放課後の自動振り返りモード: 放課後(15時以降)にアプリを開くと、その日の振り返りモードに自動で遷移。質問(予定との変更点・成果・課題・特記事項)に答えていくだけで、日報形式の振り返りが自動で完成し、データベースの「振り返り」列に記録されます。
音声入力対応: 振り返りの各入力欄には「音声入力」ボタンが付いており、話すだけで回答を記入できます(Chrome/Edge等の対応ブラウザ)。教室の片付けをしながらでも、その日の振り返りをさっと記録できます。
あとで書く(保留): その場で対応できない場合は「あとで書く」を選択でき、保留された振り返りには「振り返り」ボタンの一覧から任意のタイミングで取り組めます。
週報の自動生成: その週の授業がある全ての日の振り返りが完了すると、AIが管理職報告用の「週のまとめ」を自動生成し、同一週の日曜日の振り返りセルに保存します。週案の印刷時には、フリースペース(時数表と検印欄の間)に掲載されます。
各教科の実施時数を自動集計。学年ごとの標準時数に対する消化割合や進捗をグラフで可視化します。
年度末シミュレーション(過不足予測): 「今日までに実施済みの時数」と「明日以降に入力済みの予定時数」から年度末の着地見込みを教科別に計算し、標準時数に対する過不足を予測します。不足が見込まれる教科は警告表示され、「残り必要ペース(時間/週)」も表示されるため、年度途中での指導計画の調整に役立ちます。
単元時数の再配分: シミュレーションの表から、過不足のある教科の未指導単元へ時数を配分し直す案を作成できます(詳細は「生成AIによる業務アシスト」を参照)。
ブラウザ上で完結するブロックエディタを搭載。見出し/テキスト/画像/段組み/ギャラリー/時間割/区切り線/QRコード/ワードアートの9種類のブロックを挿入し、ドラッグ&ドロップで並べ替えられます。
時間割ブロック: 週案から読み込んだその週の予定を表にします。行は週案と同じ時程の並び(行事/1校時/2校時/中休み/3校時/4校時/昼休み/5校時/6校時/放課後/宿題/持ち物)で、休み時間は校時のあいだに入ります。ブロックの下の操作パネルで、出す行と土曜日の列を1つずつ切り替えられます。日付は「9/14」の形(頭の0を落とした形)で入り、大きさは小・中・大・特大から選べます。見出しの曜日と日付の上下は「日付を上に」で入れ替えられ、見出し帯の色も自由に選べます(文字色は帯の明るさから自動で決まるので、薄い色を選んでも読めなくなりません。紙にも同じ色で出ます)。選んだ内容は通信と一緒に保存されます。
宿題と持ち物は1件1行の箇条書きで、左詰めに出ます。週案で改行して入力したぶんだけ行が分かれます(すでに「・」や「-」を付けている行は中黒が二重になりません)。通信の中で書き替えるときも複数行で入力できます。
1年生の学級ではひらがなで出ます(「設定」タブの担当学年が1年のとき)。教科名(国語→こくご、中体育→なかたいいく、外体育→そとたいいく など)だけでなく、表の左端の見出しもひらがなになります(行事→ぎょうじ、1校時→1じかんめ、中休み→なかやすみ、昼休み→ひるやすみ、放課後→ほうかご、宿題→しゅくだい、持ち物→もちもの)。字数が増えるぶん、左端の列は自動で広くなります。
QRコードは端末の中だけで生成します。 入力したURLを外部のQR生成サービスへ送ることはありません(同梱した qrcode-generator を使用)。学校のフィルタリングで外部通信が塞がれていても表示されます。
作成した通信はPDF化して保存できるほか、名前を付けて保存・読み込み・削除ができます。Google Classroom への投稿にも対応しています。
AIによる一括生成・本文生成・リライトが使えます(詳細は「2. 生成AI (Gemini) による業務アシスト」を参照)。
明日の予定の自動投稿: 「設定」タブで投稿時刻(0〜23時)を指定すると、毎日その時刻に翌日の時間割・宿題・持ち物をClassroomのストリームへ自動投稿します。時刻を空欄にすると自動投稿は解除されます。自動投稿に含まれるのは予定だけで、AIが書いた文章は含まれません。
「今日の様子」をつけて投稿: 「設定」タブの「今日の様子をつけて投稿」ボタンを押すと、その日の学習予定をもとにAIが保護者向けの短い文章の下書きを作り、確認画面に表示します。先生が読んで直してから投稿する仕組みで、確認をとばして投稿することはできません。下書きが作れないとき(AI未設定など)は、自分で入力するか「今日の様子なしで投稿」を選べます。
「設定」タブの「明日の予定を投稿」ボタンから、手動投稿もできます。学級通信の投稿は「学級通信」タブの「Classroom投稿」から行います。
設定タブでONにすると、学級ごとに専用のデータベースシートを持ち、画面左上の切替メニューで学級を切り替えて週案を管理できます。専科教員や複数学級を受け持つ場合に便利です。
学級ごとに独立するのは、データベースシート(週案・振り返り)・時数集計・担当学年・教科別標準時数です。全学級で共通なのは、タスク・単元マスタ・学級通信・固定時間割・長期休業設定・Classroom連携設定です。
学級を追加すると、既定の「データベース」シートをコピーした専用シート(年間カレンダー付き・入力内容は空)が自動作成されます。モードをOFFに戻しても学級シートとデータは削除されず、既定のシートを使う従来どおりの動作に戻ります。使わない人の画面には一切表示されないオプトイン方式です。
学校ごとに作成された年間行事予定のPDFファイルを、アプリ内の「行事予定」タブでそのまま表示・閲覧できます。表示は先生自身のブラウザセッションでDriveプレビューを埋め込む形で行われます。
「PDFを追加」ボタンで Google ピッカーが開き、Drive上のPDFを複数選べます。選んだあとに任意で**学校名(グループ名)**を入力でき、一覧はその学校名ごとにグループ表示されます(学校名なしは「共通・学校未指定」として先頭に並びます)。ファイル名・学校名での絞り込み検索もできます。
Driveにコピーもフォルダも作りません。 drive.file スコープで動かすため、保存されるのは選んだファイルの参照(ファイルID・ファイル名・学校名)だけです。したがって「一覧から外す」を実行しても、Drive上のPDF本体は削除されません。
「設定」タブの「データ保全・復元」から、記録を失わないための仕組みをまとめて利用できます。追加のOAuthスコープは要求せず、drive.file の範囲だけで動作します。既存シートの列順も変更しません。
完全バックアップ: スプレッドシート全体を別ファイルとして複製します。1日1回の自動バックアップが既定で有効(設定でOFFにできます)で、「今すぐ完全バックアップ」から手動作成もできます。保持は30日/最大4世代で、超えた分は作成・一覧表示のたびにドライブのごみ箱へ移動します。データベースの全消去や学級削除の直前には、自動バックアップの設定に関わらずバックアップが作られます。
復元ポイント(スナップショット): 週案の保存前や、単元マスタの整合性チェック・時数再構成・年間再配分の反映前に自動で作られます。「今週の復元ポイント」から手動作成もでき、一覧から現在の内容との差分を確認したうえで書き戻せます。保持は90日/最大300件(自動作成は対象ごとに直近10件)です。
ごみ箱(30日): タスク・週案の行・学級通信の削除は、いきなり消さずにごみ箱へ移動します。30日以内なら設定画面から元に戻せます。
監査ログ: いつ・誰が・どの操作をしたかを記録し、画面から一覧できます。APIキーなどの機密情報はログにもバックアップ設定にも保存しません。記録するのは操作の事実までで、変更前後の中身そのものは持ちません(週案の保存なら、変更した日付と復元ポイントIDが残ります)。中身を戻すのは復元ポイント・ごみ箱・完全バックアップの役目です。
これらの管理用データは、スプレッドシート内の _週案_メタ / _週案_監査ログ / _週案_復元ポイント / _週案_ごみ箱 シートに保存されます。
Backend: Google Apps Script (GAS)
Database: Google Spreadsheet
Frontend: HTML5, CSS3, JavaScript (Vanilla JS / SPA Architecture)
AI Integration: Google Gemini API (gemini-2.5-flash 等)
External API: Google Classroom API(拡張サービス Classroom v1)/Google Drive REST API v3(drive.file スコープ。組み込みの DriveApp は drive.file で動かないため使いません。詳細は 17_DriveApi.gs)/Google Picker API(apis.google.com を読み込む唯一の外部スクリプト)/内閣府の祝日CSV
OAuthスコープ: drive.file / script.scriptapp / script.external_request / script.send_mail / userinfo.email / classroom.courses.readonly / classroom.announcements(appsscript.json)
スプレッドシートも Drive も REST API を直接呼ぶことで drive.file だけで扱っています(18_SheetsApi.gs / 17_DriveApi.gs。理由は docs/B5)
同梱ライブラリ: Bootstrap 5.3.3 / Bootstrap Icons 1.11.3 / SweetAlert2 11.14.5 / Material Symbols(使用アイコンのみのサブセット)を CDNではなくリポジトリに焼き込んで配信
学校のネットワークは cdn.jsdelivr.net や fonts.googleapis.com を塞いでいることがある。
塞がれると、レイアウトが崩れ、確認ダイアログが ReferenceError で止まり、
アイコンが calendar_month のような英単語で表示される(実測)。
原因がアプリの外にあるため、先生が調べても分からない。
そのため、無いと動かない/見た目が壊れるものは、すべてリポジトリに焼き込んでいる。
| ファイル | 編集してよいか |
|---|---|
tools/build-vendor.mjs / tools/ms-ligatures.py / package.json | ここを直す(原本) |
Vendor_Bootstrap.html / Vendor_Icons.html / Vendor_Sweetalert.html | 手で編集しない(生成物) |
原本を直したら、必ず次を走らせてから push すること。
npm install
npm run build:vendor # Vendor_*.html を作り直す
npm run verify:icons # アイコンが絵として描かれるか実ブラウザで確認
npm run quality # 静的検査 + テスト(CI と同じ)
npm run build:vendor には Python の fonttools が要る(pip install fonttools brotli)。
本文用の Web フォント(Zen Maru Gothic ほか)だけは Google Fonts のまま。
これは届かなくても字の形が変わるだけで、端末側フォントを --font-ui の後ろに並べてある。
.
├── 00_config.gs # 定数、設定情報、DBシート解決(複数学級対応)の定義
├── 02_Database.gs # データベース操作、カレンダー生成
├── 03_PdfProcessing.gs # PDFファイルの取得とAI解析キューイング
├── 04_AutoFill.gs # 週案の自動入力ロジック
├── 05_Classroom.gs # Google Classroom API連携処理
├── 06_Settings.gs # スクリプトプロパティによる設定管理
├── 07_WebApp.gs # Webアプリのエントリーポイント(doGet)と各種API
├── 08_Gemini.gs # Gemini API呼び出しとプロンプト管理
├── 09_Reflection.gs # 日次振り返り(日報)とAI週報(週まとめ)
├── 10_MultiClass.gs # 複数学級モード(学級の追加・削除・切替)の管理API
├── 11_Tenant.gs # マルチテナント基盤(ユーザーごとのDB紐付け/新規作成・設定のユーザー別保存)
├── 12_Performance.gs # 体感速度・通信効率の改善API(週の一括読み書き・保存の競合検出)
├── 13_DataProtection.gs # データ保全の共通基盤(内部シート・監査ログ・スキーマ版・機密のマスキング)
├── 13_DataProtection_Backups.gs # 完全バックアップの作成・世代管理
├── 13_DataProtection_Snapshots.gs # 復元ポイントの作成・分割保存・復元
├── 13_DataProtection_Trash.gs # ごみ箱(30日)への移動と復元
├── 13_DataProtection_Operations.gs # 保護付きの破壊的操作(全消去など)と保全状況サマリー
├── 14_UnitProgress.gs # 単元の進捗インデックス(単元ピッカー用)とキャッシュ
├── 15_UnitMasterOps.gs # 単元単位の書き込みと単元マスタの整合性チェック・修復
├── 16_UnitRecompose.gs # 単元の時数再構成(AI)と年間時数の再配分
├── 17_DriveApi.gs # Drive REST API v3 ラッパー(drive.file で動かすため DriveApp は使わない)
├── 18_SheetsApi.gs # Sheets REST API v4 ファサード(spreadsheets スコープを避けるため SpreadsheetApp は使わない/範囲読み・追記で通信量を抑える)
├── 99_Utils.gs # 日付計算等の共通ユーティリティ関数
├── appsscript.json # GASマニフェスト(OAuthスコープ・Classroom拡張サービス)
├── App.html # フロントエンドSPAのメインHTML
├── App_Css.html # UIスタイルシート (CSS)
├── App_Css_02_UnitPlanning.html # UIスタイルシート: 単元ピッカー・整合性チェック・再配分
├── App_Css_03_A11y.html # UIスタイルシート: 見やすさ・押しやすさの補正
├── App_Css_04_CellOps.html # UIスタイルシート: セル操作メニュー(最後に読み込む)
├── Vendor_Bootstrap.html # [生成物] Bootstrap 5 の CSS
├── Vendor_Icons.html # [生成物] Material Symbols / Bootstrap Icons のサブセット
├── Vendor_Sweetalert.html # [生成物] SweetAlert2
├── Vendor_Qrcode.html # [生成物] qrcode-generator(QRコードを端末内で作る)
├── tools/build-vendor.mjs # 上記 Vendor_*.html の生成スクリプト
├── tools/ms-ligatures.py # アイコン名から残すグリフを引く(合字表を読む)
├── tools/verify-icons.mjs # アイコンが絵として描かれるかを実ブラウザで確認
├── scripts/check-project.mjs # 静的検査の入口(npm run check)
├── scripts/gas-deploy.mjs # GASへの反映とデプロイ更新(npm run deploy / docs/D5)
├── scripts/lib/ # 静的検査の本体(project-quality / giga-v5-checks)
├── .claspignore # GASへ送るのはリポジトリ直下の .gs / .html / appsscript.json だけ
├── tests/ # 静的検査・回帰テスト(node --test / npm test)
│ ├── round-trip-budget.test.mjs # 週案の読み書きが Sheets API を何往復・何KB使うかの上限
│ └── gas-deploy.test.mjs # 反映の前に控えを取る・URLを変えない・品質ゲートを先に通す
├── quality.config.json # 静的検査の設定(必須ファイル・禁止スコープ・例外リスト)
├── package.json # 品質ゲートとVendor生成用のnpmスクリプト・開発依存
├── .github/workflows/quality.yml # CI: Node 20 / 22 で npm run check と npm test を実行
├── .github/workflows/deploy.yml # CI: main へのマージでGASへ反映しデプロイを更新(docs/D5)
├── docs/ # GitHub Pages の PWA シェルと設計・運用ドキュメント
│ ├── index.html / sw.js / offline.html / install-hook.js / manifest.webmanifest / config.js / icons/
│ ├── privacy-policy.html / terms.html # OAuth審査用のプライバシーポリシー・利用規約
│ ├── DATABASE_SCHEMA.md # スプレッドシートのシート構成
│ ├── QUALITY_ASSURANCE.md # 品質ゲートの方針
│ ├── B*/C*/D*.md # Driveスコープ・OAuth審査・配布・移行の各手順
│ │ # (C5 は審査提出用デモ動画の撮影台本)
│ └── note/ # 紹介記事とスクリーンショット
├── AUDIT.md # GIGA Standard v5 の監査結果(実測値と、測っていないものの明示)
├── MANUAL.md # 先生向けの使い方(「うまくいかないとき」つき)
├── ROLLOUT.md # 改修の記録と、他リポジトリにも効く知見
├── OPTIMIZATION_PROGRESS.md # 最適化・改修の進捗記録
├── CONTRIBUTING.md # 開発への参加方法
├── SECURITY.md # 脆弱性の報告手順
├── LICENSE # MIT License
├── THIRD_PARTY_NOTICES.md # 同梱した第三者OSSの著作権・許諾表示
├── App_Js_01_Core.html # フロントエンドJS: 状態管理・初期化・ビュー切替・全文検索
├── App_Js_02_Plan.html # フロントエンドJS: 週案グリッド・編集・セル操作(D&D/Undo等)
├── App_Js_03_Print.html # フロントエンドJS: 週案印刷(標準/コンパクト)
├── App_Js_04_Reflection.html # フロントエンドJS: 日次振り返り・週まとめ・音声入力
├── App_Js_05_Hours.html # フロントエンドJS: 年間時数・時数シミュレーション
├── App_Js_06_Newsletter.html # フロントエンドJS: 学級通信ブロックエディタ
├── App_Js_07_PdfImport.html # フロントエンドJS: PDF読み込み(アップロード・プレビュー)
├── App_Js_08_Events.html # フロントエンドJS: 行事予定PDFビュー
├── App_Js_09_Utils.html # フロントエンドJS: 共通ユーティリティ・トースト
├── App_Js_10_Settings.html # フロントエンドJS: 固定時間割・標準時数・システム設定
├── App_Js_11_Task.html # フロントエンドJS: タスク管理(AI抽出・リマインダー)
├── App_Js_12_UnitMaster.html # フロントエンドJS: 単元マスタ管理
├── App_Js_13_SystemTools.html # フロントエンドJS: テーマ・メンテナンス・初期設定ウィザード
├── App_Js_14_MultiClass.html # フロントエンドJS: 複数学級モード(学級切替・管理)
├── App_Js_15_DataProtection_Core.html # フロントエンドJS: データ保全パネル・バックアップ・復元ポイント
├── App_Js_15_DataProtection_Manage.html # フロントエンドJS: ごみ箱・監査ログの一覧
├── App_Js_15_DataProtection_Overrides.html # フロントエンドJS: 削除操作を「ごみ箱へ移動」に置き換える差分
├── App_Js_16_UnitProgress.html # フロントエンドJS: 進捗つき単元ピッカー
├── App_Js_17_UnitMasterAI.html # フロントエンドJS: 単元の時数再構成・年間再配分
└── App_Js_18_UnitMasterCheck.html # フロントエンドJS: 単元マスタの整合性チェック
このアプリケーションを使用するには、GoogleアカウントとGemini APIキーが必要です。
⚠️ Gemini API キーは「課金を有効にした(有料ティアの)」ものを使ってください。 無料ティアでは、送信した週案や PDF の内容が Google のモデル改善(機械学習)に使われる場合があります。 本アプリは Google ユーザーデータを AI の学習に使わせない方針(Limited Use)で運用しているため、 有料ティアのキーを前提としています。詳細は プライバシーポリシー §4 を参照してください。
プロジェクトのクローン 本リポジトリをクローンまたはダウンロードします。
Google スプレッドシートの準備 新規でGoogleスプレッドシートを作成し、「拡張機能」>「Apps Script」を開きます。
ソースコードの配置 GASのエディタ(または clasp を使用)に、本リポジトリの .gs および .html ファイルをすべてコピーして保存します。
💡 手でコピーする作業は自動にできます。 D5: GASへの反映を自動にする の 準備(1度だけ)を済ませると、
mainにマージした時点で品質ゲート → 控え → 反映 → デプロイ更新まで走ります。 手元からnpm run deployの一発でも反映できます。既存のURLは変わりません。
⚠️ 更新するときは、増えたファイル・消えたファイルにも合わせてください。 既存ファイルだけ貼り替えると、新しく増えたファイル(例:
18_SheetsApi.gs)が無いまま動き、 「sheetsOpenById_ is not defined」のような原因の分かりにくいエラーになります。 起動時に不足・残存を検出して名指しで知らせますが、clasp pushを使うのがいちばん確実です。claspを使う場合は、必要なOAuthスコープ(メール送信script.send_mailなどを含む)を宣言したappsscript.jsonも一緒に反映してください。GASエディタで直接編集する場合は「プロジェクトの設定」で「appsscript.jsonマニフェスト ファイルをエディタで表示する」を有効にし、本リポジトリのappsscript.jsonのoauthScopesとdependenciesを反映します。
Google サービスの有効化 GASエディタの「サービス」から Google Classroom API(Classroom / v1)を追加します。前の手順で appsscript.json の dependencies を反映していれば、この追加はすでに済んでいます。
メール送信は組み込みサービス(MailApp)、スプレッドシートは Sheets REST API v4(18_SheetsApi.gs)、Drive は REST API v3(17_DriveApi.gs)の直接呼び出しで扱うため、Apps Script の「サービス」への追加は不要です。
組み込みの SpreadsheetApp / DriveApp は使いません。使うと spreadsheets / drive という広いスコープを要求してしまうためです。
⚠️ ただし Cloud Console 側では、REST で呼ぶ API を有効にする必要があります。 Google Sheets API と Google Drive API、および Google Picker API をオンにしてください(C1 ステップ2)。 オンにし忘れると「
Sheets API (403): ... has not been used in project ... or it is disabled」で止まります。
Webアプリとしてデプロイ 「デプロイ」>「新しいデプロイ」を選択し、種類を「ウェブアプリ」にしてデプロイします。発行されたURLにアクセスしてアプリを起動します。
Note スプレッドシートにバインドして使う場合、
SPREADSHEET_IDスクリプトプロパティはonOpen/doGetの実行時に自動保存されるため、手動設定は不要です。配布元がスクリプトプロパティに手で設定するのは、マルチテナント配布時のsp_dbTemplateId(DBテンプレートID)だけです。
⚠️ タスクリマインダー(メール通知)を使う場合の再承認について メール送信機能(
MailApp)を後から追加・更新した場合、既存の承認にはメール送信権限が含まれず、時間ベースのトリガーが「権限不足」で失敗します。上記のappsscript.json(script.send_mail/userinfo.emailスコープを含む)を反映したうえで、アプリを一度開き直して表示される権限リクエストを承認してください。承認後にWebアプリの「タスク」画面からリマインダーを設定し直すと、正しい権限でトリガーが再作成されます。
⚠️ Drive スコープを
drive.fileに最小化しました(再承認が必要) アクセス権を Drive フル(auth/drive)からauth/drive.file(アプリが作成・ユーザーが選択したファイルのみ)へ縮小しました。マニフェスト反映後は再認可(同意し直し)が必要です。これに伴う運用変更:
- 「PDF読み込み」タブ(指導計画PDF・行事予定PDF)は、Driveフォルダの一覧取得をやめ、端末からの直接アップロード(ドラッグ&ドロップ/クリックして選択)に統一しました。
- 「行事予定」タブのPDF一覧は、Driveフォルダを読むのではなく、Googleピッカーで選んだファイルの参照(ID・ファイル名・学校名)だけを保存する方式です。アプリはフォルダを作らず、PDFのコピーも作りません。学校名はグループ名として使われるだけで、Drive上のフォルダ構成とは無関係です。
- 「設定」タブから**「PDF格納フォルダID」の入力欄は削除済み**です(
drive.fileでは任意フォルダにアクセスできません)。- 週案・学級通信のPDF出力/Classroom 投稿/バックアップは、アプリが作成するファイルのみを扱うため引き続き動作します。
- 移行前にフル
driveスコープで扱っていた既存ファイルは、drive.file移行後に再認識されない場合があります(行事予定PDFは「PDFを追加」から選び直してください)。詳細はdocs/B1_DRIVE_SCOPE_AUDIT.md。
(※ 詳細なスプレッドシートのシート構成(データベース、単元マスタ、タスク等)は docs/DATABASE_SCHEMA.md を参照してください。新規作成機能(createMyDatabase)はテンプレートが無くても必要シートを自動構築します。)
1つのWebアプリを共通URLで配布し、利用者がGoogleログインすると各自のスプレッドシート(DB)に紐付く/新規作成できる構成に対応しています(11_Tenant.gs)。学校をまたいで「誰でも共通URLからすぐ使い始める」運用を想定した仕組みです。
スタンドアロンのWebアプリとしてデプロイ(スプレッドシートにバインドせず、単体のGASプロジェクトとして)。「デプロイ」>「新しいデプロイ」で以下を選びます。
DBテンプレートを用意(任意)。テンプレートを設定しなくても、利用者の「新規作成」はアプリが必要シート(データベース・単元マスタ・タスク)を自動構築するため動作します(initializeNewDatabase_)。独自の書式・数式・サンプル単元などを含む「検証済みテンプレート」を配りたい場合のみ、完成済みスプレッドシートを**「リンクを知っている全員が閲覧可(=複製可)」**に共有し、そのIDをGASの「プロジェクトの設定」>「スクリプト プロパティ」に登録します(設定時はテンプレート複製が優先されます)。詳細は docs/DATABASE_SCHEMA.md。
sp_dbTemplateId: テンプレートのスプレッドシートIDsp_sharedDeployment を true に設定(1つのURLを多数の先生へ配る場合は必須)。スクリプトプロパティはスクリプト全体で1つしかないため、設定しないと、まだ自分のDBを作っていない利用者が配布元のDBへ合流したり、配布元のGemini APIキーで送信したりする経路が残ります。true にすると、利用者ごとの設定はユーザープロパティだけを見るようになります。
利用者は共通URLを開くだけです。初回ログイン時にオンボーディング画面が表示され、
sp_dbTemplateId が設定されていればそれを複製し、未設定なら必要シートをプログラムで構築します。テンプレート未設定でも常に選べます)のいずれかを選ぶと、以降はその利用者専用のDBが自動で使われます(紐付け先は利用者ごとの UserProperties に保存)。
後方互換: 従来どおりスプレッドシートにバインドして使う場合、この画面は表示されず動作は変わりません(バインド先が自動で紐付け済みとして扱われます)。
マルチテナントで正しく分離できるよう、個人ごとに変わる設定はユーザー別(UserProperties)に保存します(Gemini APIキー・モデル、担当学年、教科別標準時数、固定時間割、Classroom連携、タスクリマインダー、複数学級設定、行事予定PDFの参照リスト、初期設定ウィザード完了フラグ 等)。読み取りは「ユーザー別 → 従来のスクリプトプロパティ」の順にフォールバックするため、既存のバインド環境から移行しても設定は失われず、保存し直すと自動的にユーザー別へ移ります(11_Tenant.gs の tGetProp_/tSetProp_)。
sp_dbTemplateId)など。sp_dbTemplateId など共有設定のみ)。全ユーザーへ既定値として見えてしまうためです。UserProperties)**に保存されるため、複数ユーザーが同時にPDF読み込みを実行しても競合しません。バッチ処理はアクセスユーザーとして実行される時間主導トリガーで進むため、状態も同じユーザーの UserProperties で整合します。本アプリはPWA(Progressive Web App)としてインストールできます。ChromeやEdgeのアドレスバーから「アプリをインストール」を選ぶと、独立したウィンドウで動作するデスクトップアプリのように使えます。
仕組み: GASのWebアプリURL(
script.google.com)はGoogleのラッパーページ経由で配信されるため、そのままではPWAの条件(manifest等)を満たせません。そこでdocs/フォルダのPWAシェル(manifest + Service Worker)をGitHub Pagesで公開し、その中にGASアプリを全画面のiframeとして埋め込む構成になっています。
GitHub Pages を有効化する
本リポジトリ(またはフォーク)の「Settings」>「Pages」を開き、Source を「Deploy from a branch」、Branch を main / フォルダを /docs に設定して保存します。数分後に https://<ユーザー名>.github.io/SchoolPlan_Editor/ が公開されます。
本家は独自ドメイン https://schoolplan-editor.giga-school.com/ で配信しています(docs/CNAME がその設定です)。docs/manifest.webmanifest の start_url / scope / id は相対パス ./ にしてあるので、サブディレクトリ配信(…github.io/SchoolPlan_Editor/)とサブドメイン直下配信(schoolplan-editor.giga-school.com/)のどちらでもそのまま動きます。絶対パスに書き換えないでください — 配信場所が変わった瞬間に scope がページの URL を含まなくなり、PWA としてインストールできなくなります。フォークして使う場合は docs/CNAME を削除するか、自分のドメインに書き換えてください。
GASアプリのURLを設定する(どちらか一方でOK)
https://script.google.com/macros/s/~/exec)を貼り付けます。URLはそのブラウザのローカルストレージに保存されます。docs/config.js の appUrl にWebアプリURLを記載してコミットすると、全ユーザー共通の接続先として固定されます(学校内で配布する場合はこちらが便利です)。Chromeでインストールする 公開ページをChromeで開き、アドレスバー右端のインストールアイコン(画面のような形のアイコン)をクリックするか、メニュー「キャスト、保存、共有」>「ページをアプリとしてインストール」を選択します。画面左下の⚙メニューにも「アプリとしてインストール」ボタンが表示されます。
docs/offline.html(外部資産にもJSにも頼らない画面)が表示されます。beforeinstallprompt が発火しないため、⚙メニューのボタンは「ホーム画面に追加(インストール)」として常時表示されます)。script.google.com の /exec ページを追加すると、アイコンが付かず(タイトルの一文字だけ)、アドレスバーとGASの「Googleではなく他のユーザーが作成した」表示が残ったまま開きます。これはGAS側では直せません — /exec の外枠はGoogleが出しているページで、apple-touch-icon も manifest も差し込めない(HtmlService で触れるのは title・viewport・favicon のみ)ためです。そこでアプリ側は、シェルの外で開かれたことを検知したら(シェルからの schoolPlanNote:shellAck が届かない)、iOSに限り画面上部に入口ページへ戻る案内を出します。戻り先は 00_config.gs の PWA_SHELL_URL で、フォーク時はここを自分のGitHub PagesのURLに書き換えてください(空文字にすると案内を出しません)。ログイン用に「新しいタブで開く」を押した先生がそのタブのまま追加してしまうのが、実際に起きた経路です。docs/about.html にも manifest とインストール導線を置いてあります。 ポータルやOAuth同意画面の「アプリのホームページ」からの入口は紹介ページなので、ここに manifest が無いと、iOS Safariの「ホーム画面に追加」がアプリではなく紹介ページのブックマーク(アイコンはページの縮小画像)を作ってしまいます。紹介ページの「ホーム画面に追加」は、いったんアプリの入口(./?install=1)へ渡し、そこで手順を出します — iOS Safariはいま開いているページを登録するため、追加の操作は manifest と apple-touch-icon を持つ入口ページで行う必要があるからです。逆に紹介ページに apple-mobile-web-app-capable は書きません(manifestを読まない古いiOSで、紹介ページ自体が枠なしで開く行き止まりになります)。品質ゲートの GIGA_LANDING_* がこれらを見ています。docs/ の中身を変更する。
npm run build:sw を実行してからコミットする。
docs/sw.js の APP_VERSION が SHELL_ASSETS の中身から作り直される。
この行は手で触らない。
以前は
CACHE_NAMEの版を手で上げる決まりだったが、上げるのは人の仕事で、 2026-08-21 に12リポジトリで同時に上げ忘れる事故が起きた。上げ忘れると 古いシェルのキャッシュが掃除されず、直した内容が先生の端末に届かない。 いまはnpm run qualityが--checkでずれを見るので、刻み忘れたまま コミットしても CI が捕まえる。
更新は先生が「最新にする」を押すまで切り替わらない設計にしてある。 入力中に画面が入れ替わると、打ちかけの週案が消えるため。
キャッシュの接頭辞
schoolplan-editor-shell-はこのリポジトリ専用である。 独自ドメイン移行前はgigayama.github.ioに複数アプリが同居していたため、 接頭辞を他リポジトリ(school-plan-note-shell-)と共有すると、 片方が有効になるたびにもう片方のキャッシュを消してしまっていた。 現在はアプリごとに専用サブドメイン(schoolplan-editor.giga-school.com)を持つが、 移行前の端末に残った旧オリジンの Service Worker のために接頭辞は残してある。
デプロイで発行されたWebアプリのURL(https://script.google.com/macros/s/~/exec)を開きます。PWAとしてインストールしている場合はそのアイコンから起動します。
初回起動時は、設定が不十分な場合に初期設定ウィザードが自動で開き、担当学年 → Gemini APIキー → Google Classroom連携(任意)→ 年間カレンダーの4ステップを案内します。最後にまとめて保存され、すべて後から「設定」タブで変更できます(「設定」タブの「初期設定ウィザード」ボタンからいつでも再実行できます)。
「週案」タブで日々の授業予定を入力します。「AI自動入力」ボタンで単元を自動割り当て可能です。
「タスク」タブを開くと、入力された週案を元にAIが準備物をサジェストします。
放課後(15時以降)に開くと、その日の振り返りが自動で立ち上がります。
⚠️ スプレッドシートのカスタムメニュー「週案ツール」は廃止しました。 配布形態は D1 のスタンドアロン(共通URL)に一本化されており、
onOpen()を持っていた01_Main.gsは Sheets REST API への移行時に削除されています (B5)。メニューにあった操作 — Classroomへの手動投稿・ シート保護・キャッシュのクリア・PDF処理の強制停止 — は、すべて Web アプリの「設定」タブにあります。 祝日データの更新も、アプリを開いたときに自動で行われます。
静的検査と回帰テストを npm スクリプトにまとめてあり、CI(.github/workflows/quality.yml)が Pull Request と main への push で Node 20 / 22 の両方で同じものを実行します。
npm ci # 依存の取得(CI は --ignore-scripts 付き)
npm run check # 静的検査(quality.config.json の設定で実行)
npm test # 回帰テスト(node --test / tests/)
npm run quality # 上の2つをまとめて実行
GASへの反映も npm スクリプトにまとめてあります(手順は D5)。
npm run gas:install # clasp を入れる(リポジトリの依存には含めていません)
npm run gas:login # 1度だけ。GASプロジェクトの持ち主のアカウントで許可する
npm run gas:status # 送られるファイルを一覧する(送りません)
npm run deploy # 品質ゲート → 控え → 反映 → 既存デプロイの更新(URLは変わりません)
npm run check は、必須ファイルの存在、App.html から参照される include() の解決、禁止OAuthスコープ(auth/drive 全体・https://mail.google.com/)の混入、postMessage のワイルドカード送信先などを検査します。例外として許可する箇所は quality.config.json の securityExceptions に明示されています。
バグ報告、機能追加の要望、プルリクエストを歓迎します! 大きく機能を変更する場合は、事前にIssueで議論させていただけますと幸いです。開発の進め方は CONTRIBUTING.md、脆弱性の報告は SECURITY.md を参照してください。
このプロジェクトは MIT License の下で公開されています。 詳細は LICENSE ファイルをご確認ください。
同梱している第三者ソフトウェア(Bootstrap/Bootstrap Icons/Material Symbols/SweetAlert2/qrcode-generator)の著作権表示と許諾表示は THIRD_PARTY_NOTICES.md にまとめています。同じ内容は各 Vendor_*.html の先頭にも焼き込まれており、アプリを配信したときにも一緒に届きます。
アプリ内で初期設定 初回起動時に初期設定ウィザードが開くので、案内に沿って設定します。Gemini APIキーもここで入力します。
スクリプトプロパティにAPIキーを登録する必要はありません。 個人ごとの設定(Gemini APIキー・モデル、担当学年、教科別標準時数、固定時間割、Classroom連携、タスクリマインダー、複数学級設定など)は、アプリが UserProperties にユーザー別で保存します(キーは sp_geminiApiKey など。詳細は後述の「設定の保存先」)。