feat: auto-assign new sessions to selected project

Modified session creation endpoint to accept and store projectId:
- Accept optional projectId parameter in POST /claude/api/claude/sessions
- Validate projectId exists and is not deleted before assignment
- Store projectId in both session metadata and database
- Update project's lastActivity timestamp when session is created
- Also updated duplicate endpoint to preserve projectId from source session

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
uroma
2026-01-19 17:16:29 +00:00
Unverified
parent 3aa4af93ff
commit 5e1b18a05a

View File

@@ -431,8 +431,49 @@ app.get('/claude/api/claude/sessions', requireAuth, (req, res) => {
app.post('/claude/api/claude/sessions', requireAuth, (req, res) => { app.post('/claude/api/claude/sessions', requireAuth, (req, res) => {
try { try {
const { workingDir, metadata } = req.body; const { workingDir, metadata, projectId } = req.body;
const session = claudeService.createSession({ workingDir, metadata });
// Validate projectId if provided
let validatedProjectId = null;
if (projectId !== null && projectId !== undefined) {
validatedProjectId = validateProjectId(projectId);
if (!validatedProjectId) {
return res.status(400).json({ error: 'Invalid project ID' });
}
// Verify project exists and is not deleted
const project = db.prepare(`
SELECT id FROM projects
WHERE id = ? AND deletedAt IS NULL
`).get(validatedProjectId);
if (!project) {
return res.status(404).json({ error: 'Project not found' });
}
}
// Create session with projectId in metadata
const sessionMetadata = {
...metadata,
...(validatedProjectId ? { projectId: validatedProjectId } : {})
};
const session = claudeService.createSession({ workingDir, metadata: sessionMetadata });
// Store session in database with projectId
db.prepare(`
INSERT INTO sessions (id, projectId, deletedAt)
VALUES (?, ?, NULL)
`).run(session.id, validatedProjectId);
// Update project's lastActivity if session was assigned to a project
if (validatedProjectId) {
const now = new Date().toISOString();
db.prepare(`
UPDATE projects
SET lastActivity = ?
WHERE id = ?
`).run(now, validatedProjectId);
}
res.json({ res.json({
success: true, success: true,
@@ -441,7 +482,8 @@ app.post('/claude/api/claude/sessions', requireAuth, (req, res) => {
pid: session.pid, pid: session.pid,
workingDir: session.workingDir, workingDir: session.workingDir,
status: session.status, status: session.status,
createdAt: session.createdAt createdAt: session.createdAt,
projectId: validatedProjectId
} }
}); });
} catch (error) { } catch (error) {
@@ -578,6 +620,9 @@ app.post('/claude/api/claude/sessions/:id/duplicate', requireAuth, (req, res) =>
return res.status(400).json({ error: 'Invalid working directory' }); return res.status(400).json({ error: 'Invalid working directory' });
} }
// Get projectId from source session (if exists)
const sourceProjectId = sourceSession.metadata.projectId || null;
// Create new session with same settings // Create new session with same settings
const newSession = claudeService.createSession({ const newSession = claudeService.createSession({
workingDir: sourceSession.workingDir, workingDir: sourceSession.workingDir,
@@ -588,6 +633,22 @@ app.post('/claude/api/claude/sessions/:id/duplicate', requireAuth, (req, res) =>
} }
}); });
// Store duplicated session in database with same projectId as source
db.prepare(`
INSERT INTO sessions (id, projectId, deletedAt)
VALUES (?, ?, NULL)
`).run(newSession.id, sourceProjectId);
// Update project's lastActivity if session was assigned to a project
if (sourceProjectId) {
const now = new Date().toISOString();
db.prepare(`
UPDATE projects
SET lastActivity = ?
WHERE id = ?
`).run(now, sourceProjectId);
}
res.json({ res.json({
success: true, success: true,
session: { session: {
@@ -596,7 +657,8 @@ app.post('/claude/api/claude/sessions/:id/duplicate', requireAuth, (req, res) =>
workingDir: newSession.workingDir, workingDir: newSession.workingDir,
status: newSession.status, status: newSession.status,
createdAt: newSession.createdAt, createdAt: newSession.createdAt,
metadata: newSession.metadata metadata: newSession.metadata,
projectId: sourceProjectId
} }
}); });
} catch (error) { } catch (error) {