posimai-root/docs/synology/SYNOLOGY_PHASE1_DEPLOY.md

250 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 1: Brain 本文全文保存 — Synology 側 実施手順(コピペ用)
**目的**: Reader から送られた本文を Brain API が受け取り DB に保存し、AI 分析で本文を使うようにする。
**前提**: Synology NAS に SSH で接続できること。Brain API と PostgreSQL がすでに動いていること。
**補足**: Synology の「Container Manager」は従来の「Docker」パッケージの後継です。中身は同じなので、SSH では `docker` コマンドが使えます。
---
## あなたの環境docker ps の結果)について
| コンテナ名 | イメージ | 用途の目安 |
|---------------|-----------------|--------------------|
| **posimai_api** | node:20-slim (8090) | **Brain API** の可能性が高い |
| **gitea_db** | postgres:15 | **Gitea 用** PostgreSQLBrain 用ではない) |
| その他 | gitea, mcp_server, uptime-kuma 等 | - |
**Brain 専用の PostgreSQL コンテナは一覧にありません。**
- **posimai_api** が Brain API で、その中で **SQLite****別の DB** を使っている場合は、手順 1 の「PostgreSQL に接続」は**そのままでは使えません**。
- まず **posimai_apiBrain APIのコードや設定**を確認し、「どの DB に接続しているか」を把握する必要があります。
**進め方の目安**
1. **Brain 用に PostgreSQL を別コンテナで用意している場合**
→ そのコンテナ名で手順 1 の「1-3. PostgreSQL に接続」を実行し、手順 1 → 2 の順で実施。
2. **Brain が SQLite など PostgreSQL 以外を使っている場合**
→ **手順 1 はいったん飛ばし、手順 2API のコード修正)だけ先に実施**してください。
保存処理で `full_text` を扱うようにし、使っている DB のスキーマに `full_text` カラム(または相当の項目)を後から追加する形になります。
SQLite なら、posimai_api のプロジェクト内のマイグレーションや、DB ファイルを開いて `ALTER TABLE` する方法などがあります。)
3. **どこに DB があるか分からない場合**
posimai_api の設定ファイル(例: `.env` / `config.js` / 環境変数)や、ソース内の `pool` / `createPool` / `sqlite` などの記述を確認すると、接続先が分かります。
---
## 手順 1: データベースにカラムを追加するBrain が PostgreSQL を使っている場合のみ)
### 1-1. Synology に SSH 接続
```bash
ssh admin@posimai-lab.tail72e846.ts.net
```
(パスワードを聞かれたら入力。ユーザー名が `mai` の場合は `ssh mai@posimai-lab.tail72e846.ts.net`
### 1-2. コンテナ名を確認する(重要)
手順書の `posimai-brain-postgres` は**例**です。お使いの環境ではコンテナ名が違う場合があります。
**方法A: コマンドで一覧を表示**
```bash
docker ps
```
表示された一覧の「NAMES」列で、PostgreSQL のコンテナ名を確認してください(例: `postgres` / `brain-postgres` / `synology-postgres` など)。
**方法B: DSM の Container Manager で確認**
1. DSM にログイン → **Container Manager** を開く
2. 「コンテナ」一覧で、PostgreSQL または Brain 用 DB のコンテナを探す
3. コンテナ名(名前の列)をメモする
**次の 1-3 で使うコマンドの `コンテナ名` を、上で確認した名前に置き換えてください。**
### 1-3. PostgreSQL に接続
**Container ManagerDockerで PostgreSQL を動かしている場合:**
```bash
docker exec -it コンテナ名 psql -U brain_user -d brain_db
```
- `コンテナ名` を 1-2 で確認した名前に置き換えます。
- 例: コンテナ名が `postgres` なら
`docker exec -it postgres psql -U brain_user -d brain_db`
- ユーザー名・DB 名(`brain_user` / `brain_db`)が違う場合は、実際の設定に合わせて変更してください。
**PostgreSQL を Docker 以外で動かしている場合NAS に直接インストール等):**
```bash
psql -U brain_user -d brain_db
```
### 1-4. 以下の SQL をそのままコピーして貼り付け、Enter で実行
```sql
-- full_text カラムを追加(本文全文)
ALTER TABLE articles ADD COLUMN IF NOT EXISTS full_text TEXT;
-- オプション: 画像用(将来用)
ALTER TABLE articles ADD COLUMN IF NOT EXISTS images TEXT[];
-- 更新日時用
ALTER TABLE articles ADD COLUMN IF NOT EXISTS updated_at TIMESTAMP DEFAULT NOW();
-- 確認articles の構造が表示されればOK
\d articles
```
`\d articles` の結果に `full_text` が含まれていれば成功です。
### 1-5. PostgreSQL を終了
```bash
\q
```
---
## 手順 2: Brain API のコードを修正する
**posimai_api** が Brain API の場合、そのコンテナで動いているコードNAS 上でマウントしているフォルダ内の `server.js` など)を編集します。
Brain API の `server.js`(またはルーターを定義しているファイル)を編集します。
**編集する場所の目安:**
- `POST /save` または `POST /brain/api/save` を処理しているブロック
- `GET /articles` または `GET /brain/api/articles` を処理しているブロック
### 2-1. POST /save の置き換え
**いまの `post('/save', ...)` そのブロックの終わりまで** を、以下で**まるごと置き換え**してください。
```javascript
// POST /save — Reader から url, title, content, source を受け取り本文を保存
app.post('/save', authMiddleware, async (req, res) => {
const { url, title, content, source } = req.body || {};
if (!url || !title) {
return res.status(400).json({ error: 'Missing required fields: url and title' });
}
try {
let fullText = content || null;
let meta = {};
if (!fullText || fullText.trim().length === 0) {
meta = await fetchOGP(url); // 既存の OGP 取得関数
fullText = meta.desc || '';
} else {
meta = await fetchOGP(url);
}
const ai = await analyzeWithGemini(title, fullText, url); // 第2引数を fullText に変更
const result = await pool.query(`
INSERT INTO articles (user_id, url, title, full_text, summary, topics, source, reading_time, favicon, og_image, status, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, 'inbox', NOW(), NOW())
ON CONFLICT (user_id, url) DO UPDATE SET
title = EXCLUDED.title,
full_text = EXCLUDED.full_text,
summary = EXCLUDED.summary,
topics = EXCLUDED.topics,
reading_time = EXCLUDED.reading_time,
favicon = EXCLUDED.favicon,
og_image = EXCLUDED.og_image,
updated_at = NOW()
RETURNING id
`, [req.userId, url, title, fullText, ai.summary, ai.topics, source || 'reader', ai.readingTime, meta.favicon || null, meta.ogImage || null]);
const articleId = result.rows[0].id;
return res.json({ success: true, articleId, fullTextSaved: !!fullText, textLength: fullText?.length || 0 });
} catch (error) {
console.error('[Brain API] Save failed:', error);
return res.status(500).json({ error: 'Failed to save article', message: error.message });
}
});
```
**あわせて確認すること:**
- `analyzeWithGemini` の**第2引数**を、これまでの「短い説明」ではなく **本文全文fullText** に変更する。
- `fetchOGP` はそのまま利用して問題ありません。
### 2-2. GET /articles の置き換え
**いまの `get('/articles', ...)` そのブロックの終わりまで** を、以下で**まるごと置き換え**してください。
```javascript
// GET /articles — 一覧取得時に full_text も返すBrain UI で本文表示するため)
app.get('/articles', authMiddleware, async (req, res) => {
try {
const { rows } = await pool.query(`
SELECT id, url, title, full_text, summary, topics, source, reading_time, favicon, og_image, status, created_at, updated_at
FROM articles
WHERE user_id = $1
ORDER BY created_at DESC
`, [req.userId]);
return res.json({
articles: rows.map(row => ({
id: row.id,
url: row.url,
title: row.title,
fullText: row.full_text,
summary: row.summary,
topics: row.topics,
source: row.source,
readingTime: row.reading_time,
favicon: row.favicon,
ogImage: row.og_image,
status: row.status,
createdAt: row.created_at,
updatedAt: row.updated_at
}))
});
} catch (error) {
console.error('[Brain API] Failed to fetch articles:', error);
return res.status(500).json({ error: 'Failed to fetch articles', message: error.message });
}
});
```
**注意:** お使いのコードが `app` ではなく `router` の場合は、上記の `app.post` / `app.get``router.post` / `router.get` に読み替えてください。
---
## 手順 3: API サーバーを再起動する
**Docker で Brain API を動かしている場合:**
```bash
docker restart posimai-brain-api
docker logs -f posimai-brain-api
```
ログにエラーが出ていなければ成功です。`Ctrl+C` でログ表示を終了できます。
**Docker を使っていない場合:**
Brain API を起動している方法systemd や手動実行など)に合わせて再起動してください。
---
## 手順 4: 動作確認
1. **Reader** で記事を開き、「Brainに保存」を押す。
2. ブラウザの開発者ツールF12の「ネットワーク」で、`/save` へのレスポンスを確認する。
- `fullTextSaved: true` かつ `textLength` が数百以上なら、本文が送れて保存されています。
3. **Brain** の一覧を開き、該当記事の「本文を読む」が出ていれば、API と DB の対応は問題ありません。
---
## うまくいかないとき
- **「column full_text does not exist」**
→ 手順 1 の SQL が実行されていないか、別の DB を見ている可能性があります。もう一度 1-21-4 を実行してください。
- **「analyzeWithGemini is not a function」**
`analyzeWithGemini` の定義で、第2引数が「本文」になるように変更してください従来の短い説明用引数を fullText に変更)。
- **Reader から保存しても Brain に反映されない**
→ Synology の Brain API のログ(`docker logs posimai-brain-api`)でエラーが出ていないか確認してください。
---
**次のステップ:** Brain のフロントVercel などは、すでに「本文を読む」で保存済み本文を表示できるように修正済みです。Synology 側の上記対応が完了すれば Phase 1 は完了です。