fix(terminal): simplify REST endpoints to use instance_id only
The frontend router navigates to /instances/:instanceId/terminal without
project_id or repo_id. The backend terminal REST endpoints were requiring
these path params, causing 404s.
- Simplify _get_terminal_instance to validate by instance_id only
- Update all REST routes from /projects/{pid}/repositories/{rid}/instances/{iid}/terminal/*
to /instances/{instance_id}/terminal/*
- Update frontend API client to match new paths
- Update useTerminalSessions hook to take instanceId only
- Update TerminalPage to use simplified hook
- Update tests to match new paths
Fixes: 404 on GET /projects/repositories/instances/{id}/terminal/sessions
This commit is contained in:
@@ -25,62 +25,52 @@ export interface TerminalSessionCreateResponse {
|
||||
}
|
||||
|
||||
export async function listTerminalSessions(
|
||||
projectId: string,
|
||||
repoId: string,
|
||||
instanceId: string,
|
||||
): Promise<TerminalSession[]> {
|
||||
const response = await apiClient.get(
|
||||
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/terminal/sessions`,
|
||||
`/instances/${instanceId}/terminal/sessions`,
|
||||
);
|
||||
return response.data.sessions;
|
||||
}
|
||||
|
||||
export async function createTerminalSession(
|
||||
projectId: string,
|
||||
repoId: string,
|
||||
instanceId: string,
|
||||
name?: string,
|
||||
): Promise<TerminalSessionCreateResponse> {
|
||||
const response = await apiClient.post(
|
||||
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/terminal/sessions`,
|
||||
`/instances/${instanceId}/terminal/sessions`,
|
||||
{ name },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function closeTerminalSession(
|
||||
projectId: string,
|
||||
repoId: string,
|
||||
instanceId: string,
|
||||
sessionId: string,
|
||||
): Promise<{ status: string; session_id: string }> {
|
||||
const response = await apiClient.delete(
|
||||
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/terminal/sessions/${sessionId}`,
|
||||
`/instances/${instanceId}/terminal/sessions/${sessionId}`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function resetTerminalSession(
|
||||
projectId: string,
|
||||
repoId: string,
|
||||
instanceId: string,
|
||||
sessionId: string,
|
||||
): Promise<{ id: string; name: string; status: string }> {
|
||||
const response = await apiClient.post(
|
||||
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/terminal/sessions/${sessionId}/reset`,
|
||||
`/instances/${instanceId}/terminal/sessions/${sessionId}/reset`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export async function renameTerminalSession(
|
||||
projectId: string,
|
||||
repoId: string,
|
||||
instanceId: string,
|
||||
sessionId: string,
|
||||
name: string,
|
||||
): Promise<{ id: string; name: string }> {
|
||||
const response = await apiClient.post(
|
||||
`/projects/${projectId}/repositories/${repoId}/instances/${instanceId}/terminal/sessions/${sessionId}/rename`,
|
||||
`/instances/${instanceId}/terminal/sessions/${sessionId}/rename`,
|
||||
{ name },
|
||||
);
|
||||
return response.data;
|
||||
|
||||
@@ -21,8 +21,6 @@ export interface UseTerminalSessionsResult {
|
||||
}
|
||||
|
||||
export function useTerminalSessions(
|
||||
projectId: string,
|
||||
repoId: string,
|
||||
instanceId: string,
|
||||
): UseTerminalSessionsResult {
|
||||
const [sessions, setSessions] = useState<TerminalSession[]>([]);
|
||||
@@ -34,7 +32,7 @@ export function useTerminalSessions(
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const sess = await listTerminalSessions(projectId, repoId, instanceId);
|
||||
const sess = await listTerminalSessions(instanceId);
|
||||
setSessions(sess);
|
||||
if (sess.length > 0 && !activeSessionId) {
|
||||
setActiveSessionId(sess[0].id);
|
||||
@@ -44,18 +42,13 @@ export function useTerminalSessions(
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [projectId, repoId, instanceId, activeSessionId]);
|
||||
}, [instanceId, activeSessionId]);
|
||||
|
||||
const createSession = useCallback(
|
||||
async (name?: string) => {
|
||||
setError(null);
|
||||
try {
|
||||
const newSession = await createTerminalSession(
|
||||
projectId,
|
||||
repoId,
|
||||
instanceId,
|
||||
name,
|
||||
);
|
||||
const newSession = await createTerminalSession(instanceId, name);
|
||||
const session: TerminalSession = {
|
||||
id: newSession.id,
|
||||
name: newSession.name,
|
||||
@@ -74,14 +67,14 @@ export function useTerminalSessions(
|
||||
return null;
|
||||
}
|
||||
},
|
||||
[projectId, repoId, instanceId],
|
||||
[instanceId],
|
||||
);
|
||||
|
||||
const closeSession = useCallback(
|
||||
async (sessionId: string) => {
|
||||
setError(null);
|
||||
try {
|
||||
await closeTerminalSession(projectId, repoId, instanceId, sessionId);
|
||||
await closeTerminalSession(instanceId, sessionId);
|
||||
setSessions((prev) => {
|
||||
const filtered = prev.filter((s) => s.id !== sessionId);
|
||||
if (activeSessionId === sessionId && filtered.length > 0) {
|
||||
@@ -97,20 +90,14 @@ export function useTerminalSessions(
|
||||
);
|
||||
}
|
||||
},
|
||||
[projectId, repoId, instanceId, activeSessionId],
|
||||
[instanceId, activeSessionId],
|
||||
);
|
||||
|
||||
const renameSession = useCallback(
|
||||
async (sessionId: string, name: string) => {
|
||||
setError(null);
|
||||
try {
|
||||
await renameTerminalSession(
|
||||
projectId,
|
||||
repoId,
|
||||
instanceId,
|
||||
sessionId,
|
||||
name,
|
||||
);
|
||||
await renameTerminalSession(instanceId, sessionId, name);
|
||||
setSessions((prev) =>
|
||||
prev.map((s) => (s.id === sessionId ? { ...s, name } : s)),
|
||||
);
|
||||
@@ -120,14 +107,14 @@ export function useTerminalSessions(
|
||||
);
|
||||
}
|
||||
},
|
||||
[projectId, repoId, instanceId],
|
||||
[instanceId],
|
||||
);
|
||||
|
||||
const resetSession = useCallback(
|
||||
async (sessionId: string) => {
|
||||
setError(null);
|
||||
try {
|
||||
await resetTerminalSession(projectId, repoId, instanceId, sessionId);
|
||||
await resetTerminalSession(instanceId, sessionId);
|
||||
// Refetch to get updated session info
|
||||
await loadSessions();
|
||||
} catch (err) {
|
||||
@@ -136,7 +123,7 @@ export function useTerminalSessions(
|
||||
);
|
||||
}
|
||||
},
|
||||
[projectId, repoId, instanceId, loadSessions],
|
||||
[instanceId, loadSessions],
|
||||
);
|
||||
|
||||
// Initial load
|
||||
|
||||
@@ -18,9 +18,7 @@ const SESSIONS_TO_INFO = (sessions: TerminalSession[]): TerminalSessionInfo[] =>
|
||||
}));
|
||||
|
||||
export const TerminalPage: React.FC = () => {
|
||||
const { projectId, repoId, instanceId } = useParams<{
|
||||
projectId: string;
|
||||
repoId: string;
|
||||
const { instanceId } = useParams<{
|
||||
instanceId: string;
|
||||
}>();
|
||||
const navigate = useNavigate();
|
||||
@@ -39,7 +37,7 @@ export const TerminalPage: React.FC = () => {
|
||||
resetSession,
|
||||
loading,
|
||||
error,
|
||||
} = useTerminalSessions(projectId ?? "", repoId ?? "", instanceId ?? "");
|
||||
} = useTerminalSessions(instanceId ?? "");
|
||||
|
||||
// Auto-create default session if none exist
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user