The path of one project — from the client's initial document upload to an authorization-checked download of the finished files — exactly as implemented in the controllers.
Up to 20 files at once (PDF, DOC/DOCX, XLS/XLSX, PNG/JPG, ZIP), 25 MB max each. The project starts with status "submitted".
ProjectController@storeEach file gets a randomly generated UUID name and lives outside any publicly reachable folder — there is no URL that just opens the file.
ProjectFileUploadService::storeOne()A staff dashboard lists every project, filterable by status.
If the status is "needs info", the client uploads additional documents and the project automatically moves back to "submitted".
ProjectController@storeFilesFinal deliverables are tagged separately as "deliverables" — distinct from the client's original input files.
Admin\ProjectController@storeDeliverablesEvery download goes through a check — does the requester own this project (or are they staff) — before the file is even read from disk.
ProjectFileController@downloadProject::scopeForClient) — requesting someone else's project returns 403, not 404, so it's clearly a permissions block, not a missing resource.