User dogfood found many bugs. This wave addresses: - nginx.conf: proxy_next_upstream + retries on 502/503/504, explicit proxy_ssl_name, 8s connect timeout. The DNS-resolver race that caused the Studio 'apply_patch 502' is now eaten by nginx retry. - src/lib/wizardApi.ts: applyBatch retries 3x on 502/503/504 with exponential backoff. Even if nginx misses the retry the client takes a second shot. - src/lib/chatApi.ts: listThreads now THROWS when ensureInbox fails instead of silently returning []. Chat scene shows the error + retry button instead of an empty 'No conversations' state that hides the real failure. - src/scenes/Chat.tsx: explicit error banner with 'Try again' button. - src/lib/llmClient.ts: rewritten to call /api/v1/llm/generate (real demo gateway, same as dev.flow-master.ai uses). Removed the local /internal/canvas-llm/chat sidecar entirely. - src/scenes/Agent.tsx: removed the LLM-state probe + 'off by default' OFF pill. LLM is now part of the assistant unconditionally. - src/lib/flowCuration.ts: dropped the STARTABLE_FLOW_KEYS allowlist gate in curatedPublishedFlows so list_processes now returns every published business process, not just pr_to_po_def. - src/state/store.ts + tests: DataMode is now 'live' only. Removed the SNAPSHOT branch; live is the only mode. Renamed the failure toast accordingly. Initial scene is 'mission' not 'landing'. - src/scenes/Login.tsx + test: post-login navigates to 'mission' instead of the empty landing splash. - src/scenes/Settings.tsx + src/components/CommandBar.tsx: removed every snapshot/setMode reference. Settings shows 'EA2 · live always'. Command palette no longer offers a snapshot switch. - src/App.tsx: topbar redesign. Removed Settings + Home tabs (now in user menu), removed standalone Light/Dark + Console buttons (collapsed into user menu), removed the SNAPSHOT/LIVE mode pill + topbar refresh. New UserMenu component shows a 2-char avatar circle; clicking opens a dropdown with Home / Settings / Refresh data / theme toggle / API console toggle. Topbar now has: brand · tabs · cmd-k · notification bell · avatar. - src/index.css: user-menu styles + chat-err styles + dark variants. 30/30 vitest pass. tsc + vite build green.
46 lines
1.7 KiB
JavaScript
46 lines
1.7 KiB
JavaScript
// Real human dogfood — persona chip click should sign in directly.
|
|
import { chromium } from "playwright";
|
|
|
|
const URL = "https://canvas.flow-master.ai/";
|
|
|
|
const b = await chromium.launch({ headless: true });
|
|
const ctx = await b.newContext({ viewport: { width: 1440, height: 900 } });
|
|
const p = await ctx.newPage();
|
|
|
|
const calls = [];
|
|
p.on("response", (r) => {
|
|
const u = r.url();
|
|
if (u.includes("/api/")) calls.push({ status: r.status(), url: u.replace("https://canvas.flow-master.ai", "") });
|
|
});
|
|
|
|
console.log("[1] Visit canvas.flow-master.ai");
|
|
await p.goto(URL, { waitUntil: "domcontentloaded" });
|
|
await p.waitForTimeout(2000);
|
|
|
|
console.log("[2] Click CEO persona chip");
|
|
await p.locator(".persona-chip", { hasText: /Mariana/ }).click();
|
|
await p.waitForTimeout(4000);
|
|
|
|
console.log("[3] Check scene + url");
|
|
const onLogin = (await p.locator(".login-page").count()) > 0;
|
|
const onLanding = (await p.locator(".hero-eyebrow").count()) > 0;
|
|
const sceneClass = await p.evaluate(() => document.querySelector("[class*='shell-']")?.className);
|
|
console.log(` onLogin=${onLogin} onLanding=${onLanding} shell=${sceneClass}`);
|
|
|
|
console.log("[4] Try Mission");
|
|
await p.locator(".tab", { hasText: /Mission/ }).click().catch(() => {});
|
|
await p.waitForTimeout(3000);
|
|
const onMission = (await p.locator(".bp-node-body, .empty").count()) > 0;
|
|
console.log(` onMission=${onMission}`);
|
|
|
|
await p.screenshot({ path: "/tmp/canvas-evidence/05-LIVE-after-fix.png", fullPage: false });
|
|
|
|
console.log("\n=== API CALLS ===");
|
|
const status = {};
|
|
for (const c of calls) status[c.status] = (status[c.status] || 0) + 1;
|
|
console.log("status counts:", JSON.stringify(status));
|
|
console.log("first 10:");
|
|
for (const c of calls.slice(0, 10)) console.log(` ${c.status} ${c.url.slice(0, 80)}`);
|
|
|
|
await b.close();
|