fix: Browser mode 404 error for meeting-detail page
- Preserve query parameters (e.g., ?id=123) when opening in browser - Add packaged mode detection for CLIENT_DIR path resolution - Include client files in extraResources for backend to serve - Add debug logging for client directory detection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -11,10 +11,23 @@ from .routers import auth, meetings, ai, export, sidecar
|
|||||||
from .sidecar_manager import get_sidecar_manager
|
from .sidecar_manager import get_sidecar_manager
|
||||||
|
|
||||||
# Determine client directory path
|
# Determine client directory path
|
||||||
|
# In development: backend/../client/src
|
||||||
|
# In packaged mode: backend/backend/_internal/../../client (relative to backend executable)
|
||||||
BACKEND_DIR = Path(__file__).parent.parent
|
BACKEND_DIR = Path(__file__).parent.parent
|
||||||
PROJECT_DIR = BACKEND_DIR.parent
|
PROJECT_DIR = BACKEND_DIR.parent
|
||||||
CLIENT_DIR = PROJECT_DIR / "client" / "src"
|
CLIENT_DIR = PROJECT_DIR / "client" / "src"
|
||||||
|
|
||||||
|
# Check for packaged mode (PyInstaller sets _MEIPASS)
|
||||||
|
import sys
|
||||||
|
if getattr(sys, 'frozen', False):
|
||||||
|
# Packaged mode: look for client folder relative to executable
|
||||||
|
# Backend runs from resources/backend/, client files at resources/backend/client/
|
||||||
|
EXEC_DIR = Path(sys.executable).parent.parent # up from backend/backend.exe
|
||||||
|
CLIENT_DIR = EXEC_DIR / "client"
|
||||||
|
print(f"[Backend] Packaged mode: CLIENT_DIR={CLIENT_DIR}")
|
||||||
|
else:
|
||||||
|
print(f"[Backend] Development mode: CLIENT_DIR={CLIENT_DIR}")
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def lifespan(app: FastAPI):
|
async def lifespan(app: FastAPI):
|
||||||
@@ -77,6 +90,7 @@ async def health_check():
|
|||||||
# ========================================
|
# ========================================
|
||||||
|
|
||||||
# Check if client directory exists for browser mode
|
# Check if client directory exists for browser mode
|
||||||
|
print(f"[Backend] CLIENT_DIR exists: {CLIENT_DIR.exists()}")
|
||||||
if CLIENT_DIR.exists():
|
if CLIENT_DIR.exists():
|
||||||
# Serve static assets (CSS, JS, etc.)
|
# Serve static assets (CSS, JS, etc.)
|
||||||
app.mount("/styles", StaticFiles(directory=CLIENT_DIR / "styles"), name="styles")
|
app.mount("/styles", StaticFiles(directory=CLIENT_DIR / "styles"), name="styles")
|
||||||
|
|||||||
@@ -41,6 +41,26 @@
|
|||||||
{
|
{
|
||||||
"from": "config.json",
|
"from": "config.json",
|
||||||
"to": "config.json"
|
"to": "config.json"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": "src/pages",
|
||||||
|
"to": "backend/client/pages",
|
||||||
|
"filter": ["**/*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": "src/styles",
|
||||||
|
"to": "backend/client/styles",
|
||||||
|
"filter": ["**/*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": "src/services",
|
||||||
|
"to": "backend/client/services",
|
||||||
|
"filter": ["**/*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"from": "src/config",
|
||||||
|
"to": "backend/client/config",
|
||||||
|
"filter": ["**/*"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"win": {
|
"win": {
|
||||||
|
|||||||
@@ -734,10 +734,19 @@ ipcMain.handle("open-in-browser", async () => {
|
|||||||
const host = backendConfig.host || "127.0.0.1";
|
const host = backendConfig.host || "127.0.0.1";
|
||||||
const port = backendConfig.port || 8000;
|
const port = backendConfig.port || 8000;
|
||||||
|
|
||||||
// Determine the current page URL
|
// Determine the current page URL and preserve query parameters
|
||||||
let currentPage = "login";
|
let currentPage = "login";
|
||||||
|
let queryString = "";
|
||||||
|
|
||||||
if (mainWindow) {
|
if (mainWindow) {
|
||||||
const currentUrl = mainWindow.webContents.getURL();
|
const currentUrl = mainWindow.webContents.getURL();
|
||||||
|
|
||||||
|
// Parse query string from current URL (e.g., ?id=123)
|
||||||
|
const urlMatch = currentUrl.match(/\?(.+)$/);
|
||||||
|
if (urlMatch) {
|
||||||
|
queryString = "?" + urlMatch[1];
|
||||||
|
}
|
||||||
|
|
||||||
if (currentUrl.includes("meetings.html")) {
|
if (currentUrl.includes("meetings.html")) {
|
||||||
currentPage = "meetings";
|
currentPage = "meetings";
|
||||||
} else if (currentUrl.includes("meeting-detail.html")) {
|
} else if (currentUrl.includes("meeting-detail.html")) {
|
||||||
@@ -745,7 +754,7 @@ ipcMain.handle("open-in-browser", async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const browserUrl = `http://${host}:${port}/${currentPage}`;
|
const browserUrl = `http://${host}:${port}/${currentPage}${queryString}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await shell.openExternal(browserUrl);
|
await shell.openExternal(browserUrl);
|
||||||
|
|||||||
Reference in New Issue
Block a user