feat: vercel deploy status in ecosystem bar, deploy rule in CLAUDE.md

This commit is contained in:
posimai 2026-04-02 20:04:39 +09:00
parent 90ac87db41
commit f5817eb156
3 changed files with 52 additions and 0 deletions

View File

@ -33,6 +33,15 @@ npm run deploy # = git push gitea main && git push github main
**VPS バックエンドserver.jsのデプロイ:**
`bash deploy-server.sh` を実行する(完全無人。手動で `scp` しない)。
**posimai-devUbuntu PC サービス)のデプロイ:**
`posimai-dev/` 以下のファイルを変更したら、必ず以下を実行すること。
```bash
npm run deploy:dev # = git push + scp転送 + systemctl restart posimai-dev
```
`git push` だけでは Ubuntu PC に反映されないSyncthing の同期遅延があるため)。
## 3. アプリ追加・更新時の必須タスク(ダッシュボード追記)
エコシステムからの孤立を防ぐため、新規アプリ作成や既存アプリ修正の際は**必ずユーザーに言われる前に**ダッシュボードのリポジトリを更新しデプロイすること。

View File

@ -180,6 +180,28 @@ app.get('/api/gitea-commit', async (req, res) => {
} catch (e) { res.json({ error: e.message }); }
});
// ── Vercel 最新デプロイ (/api/vercel-deploys) ──────────────────
app.get('/api/vercel-deploys', async (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
const token = process.env.VERCEL_TOKEN || '';
if (!token) return res.status(503).json({ error: 'no token' });
try {
const r = await fetch('https://api.vercel.com/v6/deployments?limit=1', {
headers: { Authorization: `Bearer ${token}` },
signal: AbortSignal.timeout(6000),
});
const data = await r.json();
const d = data.deployments?.[0];
if (!d) return res.json({ error: 'no deployments' });
res.json({
name: d.name,
state: d.state,
url: d.url,
created: d.createdAt,
});
} catch (e) { res.status(502).json({ error: e.message }); }
});
// ── VPS health プロキシ (/api/vps-health) ──────────────────────
// ブラウザから直接叩くと自己署名証明書環境でCORSエラーになるためサーバー経由でプロキシ
app.get('/api/vps-health', async (req, res) => {

View File

@ -325,6 +325,8 @@
<div id="ecosystem-bar">
<div class="eco-item"><div class="eco-dot" id="eco-gitea-dot"></div><span id="eco-commit">commit: —</span></div>
<div class="eco-item" style="color:var(--border);font-size:8px">|</div>
<div class="eco-item"><div class="eco-dot" id="eco-vercel-dot"></div><span id="eco-vercel">deploy: —</span></div>
<div class="eco-item" style="color:var(--border);font-size:8px">|</div>
<div class="eco-item" id="eco-temp-item" style="display:none"><span id="eco-temp-label">temp: —</span></div>
</div>
<div id="bottom-row">
@ -705,6 +707,25 @@ function timeAgo(iso){
fetchGiteaCommit();
setInterval(fetchGiteaCommit, 120000);
// ── Vercel 最新デプロイ ─────────────────────────────────────────
async function fetchVercelDeploy(){
try{
const r=await fetch('/api/vercel-deploys',{signal:AbortSignal.timeout(8000)});
const d=await r.json();
if(d.error) return;
const dot=document.getElementById('eco-vercel-dot');
const el=document.getElementById('eco-vercel');
const stateMap={READY:'var(--ok)',ERROR:'var(--crit)',BUILDING:'var(--warn)',CANCELED:'var(--text3)'};
const color=stateMap[d.state]||'var(--text3)';
if(dot) dot.style.background=color;
const ago=timeAgo(d.created);
const label=(d.name||'').replace(/^posimai-/,'');
if(el) el.textContent=`deploy: ${label} ${d.state?.toLowerCase()} ${ago}`;
}catch(_){}
}
fetchVercelDeploy();
setInterval(fetchVercelDeploy, 300000);
// ── VPS メトリクス ─────────────────────────────────────────────
async function fetchVpsHealth(){
try{