--- name: s3_upload kind: function lang: go domain: infra version: "1.0.0" purity: impure signature: "func S3Upload(cfg S3Config, key string, data io.Reader, contentType string) error" description: "STUB. Sube data a un bucket S3-compatible (AWS S3, MinIO, etc) bajo la key indicada con el Content-Type dado. La implementacion real requiere github.com/aws/aws-sdk-go-v2." tags: [s3, upload, storage, cloud, stub, infra] uses_functions: [] uses_types: [S3Config_go_infra] returns: [] returns_optional: false error_type: "error_go_core" imports: [fmt, io, time] params: - name: cfg desc: "S3Config con endpoint, bucket, credenciales y region" - name: key desc: "key del objeto en el bucket (ej: \"images/foto.png\")" - name: data desc: "reader con el contenido binario a subir" - name: contentType desc: "MIME type del objeto (ej: \"image/png\")" output: "nil si la subida fue exitosa, error si fallo. STUB actual retorna siempre error \"not implemented\"" tested: false tests: [] test_file_path: "" file_path: "functions/infra/s3_upload.go" --- ## Estado **Stub**. Para activar la implementacion real: 1. Anadir dependencias: ```bash go get github.com/aws/aws-sdk-go-v2/aws go get github.com/aws/aws-sdk-go-v2/config go get github.com/aws/aws-sdk-go-v2/credentials go get github.com/aws/aws-sdk-go-v2/service/s3 ``` 2. Reemplazar el cuerpo del stub por: ```go import ( "context" "github.com/aws/aws-sdk-go-v2/aws" awscfg "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" ) func S3Upload(cfg S3Config, key string, data io.Reader, contentType string) error { ctx := context.Background() awsCfg, err := awscfg.LoadDefaultConfig(ctx, awscfg.WithRegion(cfg.Region), awscfg.WithCredentialsProvider(credentials.NewStaticCredentialsProvider( cfg.AccessKey, cfg.SecretKey, "")), ) if err != nil { return fmt.Errorf("s3_upload: aws config: %w", err) } client := s3.NewFromConfig(awsCfg, func(o *s3.Options) { o.UsePathStyle = true if cfg.Endpoint != "" { scheme := "http" if cfg.UseSSL { scheme = "https" } o.BaseEndpoint = aws.String(fmt.Sprintf("%s://%s", scheme, cfg.Endpoint)) } }) _, err = client.PutObject(ctx, &s3.PutObjectInput{ Bucket: aws.String(cfg.Bucket), Key: aws.String(key), Body: data, ContentType: aws.String(contentType), }) return err } ``` ## Ejemplo (con implementacion real) ```go cfg := S3Config{ Endpoint: "s3.amazonaws.com", Bucket: "mi-bucket", AccessKey: os.Getenv("S3_ACCESS_KEY"), SecretKey: os.Getenv("S3_SECRET_KEY"), Region: "us-east-1", UseSSL: true, } f, _ := os.Open("./uploads/photo.png") defer f.Close() err := S3Upload(cfg, "images/photo.png", f, "image/png") ``` ## Notas Compatible con AWS S3, MinIO, Wasabi y otros S3-compatible. El campo `UsePathStyle = true` es necesario para MinIO y para algunos endpoints custom; AWS S3 nativo soporta tanto path-style como virtual-hosted-style.