@@ -206,6 +206,8 @@ type ValidationError struct {
206206}
207207
208208// Error returns the validation message.
209+ // @intent expose the caller-fixable validation message without wrapping it in transport-specific formatting.
210+ // @return returns the original validation message stored on the error.
209211func (e * ValidationError ) Error () string { return e .msg }
210212
211213// IsValidationError reports whether err is a ValidationError.
@@ -215,6 +217,8 @@ func IsValidationError(err error) bool {
215217 return errors .As (err , & v )
216218}
217219
220+ // newValidationError constructs a ValidationError for caller-fixable workspace input issues.
221+ // @intent centralize creation of typed validation failures so handlers can recognize them consistently.
218222func newValidationError (msg string ) * ValidationError { return & ValidationError {msg : msg } }
219223
220224// UploadFile validates, decodes, and atomically writes a single workspace file.
@@ -232,12 +236,19 @@ func (s *Service) UploadFile(req UploadRequest) (*UploadResult, error) {
232236 return & UploadResult {Namespace : req .Namespace , FilePath : req .FilePath , Size : len (prepared .decoded )}, nil
233237}
234238
239+ // preparedUpload holds validated upload data before it is written to disk.
240+ // @intent split validation/decoding from filesystem mutation so bulk uploads can validate before committing files.
235241type preparedUpload struct {
236242 req UploadRequest
237243 decoded []byte
238244 target string
239245}
240246
247+ // prepareUpload validates one upload request, decodes its content, and resolves its destination path.
248+ // @intent prepare a single upload for later commit while enforcing per-file and aggregate decoded-size limits.
249+ // @param alreadyDecoded tracks the total decoded bytes accepted earlier in the same bulk request.
250+ // @return returns a preparedUpload ready for commit when validation succeeds.
251+ // @domainRule rejects missing fields, invalid paths, invalid base64, oversized files, and oversized aggregate payloads.
241252func (s * Service ) prepareUpload (req UploadRequest , alreadyDecoded int ) (* preparedUpload , error ) {
242253 limits := s .limitsOrDefault ()
243254 if req .Namespace == "" || req .FilePath == "" || req .ContentBase64 == "" {
@@ -263,6 +274,9 @@ func (s *Service) prepareUpload(req UploadRequest, alreadyDecoded int) (*prepare
263274 return & preparedUpload {req : req , decoded : decoded , target : target }, nil
264275}
265276
277+ // commitPrepared creates parent directories, revalidates the path, and atomically writes one prepared upload.
278+ // @intent separate filesystem mutation from validation so bulk uploads can fail fast before writing any file.
279+ // @sideEffect creates directories and writes the target file atomically.
266280func (s * Service ) commitPrepared (p * preparedUpload ) error {
267281 if err := os .MkdirAll (filepath .Dir (p .target ), 0o755 ); err != nil {
268282 return fmt .Errorf ("create directory: %w" , err )
@@ -276,6 +290,9 @@ func (s *Service) commitPrepared(p *preparedUpload) error {
276290 return nil
277291}
278292
293+ // limitsOrDefault returns the configured limits with zero values replaced by workspace defaults.
294+ // @intent ensure upload validation always runs with concrete byte ceilings even when callers omit custom limits.
295+ // @return returns a Limits value whose file, request, and aggregate byte caps are all populated.
279296func (s * Service ) limitsOrDefault () Limits {
280297 l := s .Limits
281298 if l .MaxFileBytes == 0 {
@@ -306,7 +323,14 @@ type BulkEntryError struct {
306323 Err error
307324}
308325
326+ // Error formats the failing bulk entry index with the underlying error text.
327+ // @intent preserve a user-facing error string that points callers to the exact bad entry.
328+ // @return returns an error string prefixed with the failing entry index.
309329func (e * BulkEntryError ) Error () string { return fmt .Sprintf ("entry %d: %v" , e .Index , e .Err ) }
330+
331+ // Unwrap returns the underlying entry error.
332+ // @intent allow callers to inspect the original validation or filesystem failure that broke a bulk upload.
333+ // @return returns the underlying entry error for errors.Is and errors.As checks.
310334func (e * BulkEntryError ) Unwrap () error { return e .Err }
311335
312336// UploadFiles parses a bulk upload JSON payload, validates every entry, and writes them sequentially.
0 commit comments