App Architecture

Private upload and account boundary

Recommended first secure application slice for Circuit Genome: authenticated users, account-scoped uploads, private storage, and per-request authorization on every file read, analysis, download, and delete action.

Status

AudienceApp implementers planning the first authenticated upload workflow.
First MilestoneA logged-in user can upload a file and only that user can see it.
Current Repo RealityStatic marketing/docs site plus a small serverless contact endpoint.
Storage RuleUser uploads must not live in a public web folder or in the public site repo.

Non-Negotiable Rules

Recommended System Boundary

Area What Lives There What Does Not
Public siteMarketing pages, docs, exporter downloads, examples.User uploads, session data, private reports.
Private appAccounts, sessions, uploads, analyzer jobs, per-user reports.Anonymous public file access.
DatabaseUsers, sessions, upload metadata, processing state, audit events.Large raw file payloads.
Private object storageUploaded source files and derived private artifacts.Public web assets and docs.

First-Version Pages

Page Purpose Access
/signupCreate an account.Public
/loginAuthenticate and create a session.Public
/dashboardList only the current user's uploads.Authenticated
/uploads/newUpload a new source file.Authenticated
/uploads/:idShow metadata, validation, and future analysis outputs for one owned file.Authenticated + owner-only

Core API Surface

Route Purpose Security Requirement
POST /api/auth/signupCreate user + password hash.Rate limit and validate email/password policy.
POST /api/auth/loginCreate authenticated session cookie.HTTP-only, secure, same-site cookie.
POST /api/auth/logoutInvalidate the current session.Must clear session server-side and client-side.
GET /api/uploadsReturn uploads owned by the current user.Never return cross-account rows.
POST /api/uploadsStore file metadata and private file bytes.Authenticated only; validate size, type, and filename.
GET /api/uploads/:idReturn one upload's metadata.Deny by default unless upload.user_id === session.user_id.
GET /api/uploads/:id/downloadStream the owned file from private storage.Owner check on every request.
DELETE /api/uploads/:idDelete one owned upload.Owner check plus audit event.

Minimal Data Model

Table Key Fields Notes
usersid, email, password_hash, created_atEmail should be unique and normalized.
sessionsid, user_id, expires_at, created_atStore only opaque session IDs server-side.
uploadsid, user_id, original_filename, storage_key, mime_type, size_bytes, uploaded_at, processing_statusThis is the ownership boundary for private files.
upload_eventsid, upload_id, event_type, created_at, metadata_jsonUseful for audit trail and troubleshooting.

Implementation Notes

Suggested Build Sequence

Phase Deliverable Outcome
1Signup, login, logout, protected dashboard.Users can authenticate and see only their own workspace shell.
2Private upload endpoint + owned file list + file detail page.The account boundary exists for stored source files.
3Validation and analysis job status.Uploads become usable artifacts rather than stored files only.
4Delete, rename, derived artifacts, and audit trail.The private workflow becomes operationally manageable.
5Organizations, shared projects, quotas, and billing.Collaboration and commercial controls can be added on top of a correct ownership model.
Practical stack note: if this site stays on a Vercel-style serverless deployment, keep file bytes in private object storage and keep metadata in a relational database. Do not treat the function filesystem or the site repo as durable private user storage.