feat: mentor workspace files end-to-end with secure presign
Adds generateMentorObjectKey helper producing <projectName>/mentorship/<timestamp>-<file>. Replaces the client-supplied bucket/objectKey on workspaceUploadFile with an HMAC-signed upload token that binds bucket, objectKey, uploader, and a 1h expiry — paths can no longer be forged from the client. Adds workspaceGetUploadUrl, workspaceGetFiles, workspaceGetFileDownloadUrl, workspaceDeleteFile procedures with mentor-or-team-member auth. Builds <WorkspaceFilesPanel> and wires it into the mentor workspace Files tab and the applicant /applicant/mentor page. Replaces the file-promotion-panel mock array with a real workspaceGetFiles query. Tests cover token sign/verify (5), key construction (5), and end-to-end procedure flow including auth + tampered tokens (7). Spec: docs/superpowers/specs/2026-04-28-mentor-round-readiness-design.md §F.1 Plan: docs/superpowers/plans/2026-04-28-pr2-mentor-workspace-files.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -149,3 +149,18 @@ export function generateObjectKey(
|
||||
return `${sanitizedProject}/${sanitizedRound}/${timestamp}-${sanitizedFile}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a unique object key for a mentor-workspace file.
|
||||
*
|
||||
* Structure: {ProjectName}/mentorship/{timestamp}-{fileName}
|
||||
*
|
||||
* Mirrors generateObjectKey but pins the round-name slot to "mentorship"
|
||||
* so all mentor workspace files for a project live under one folder.
|
||||
*/
|
||||
export function generateMentorObjectKey(
|
||||
projectTitle: string,
|
||||
fileName: string,
|
||||
): string {
|
||||
return generateObjectKey(projectTitle, fileName, 'mentorship')
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user