Files
atahango/belgeler/USER_CREATE_UPDATE_WITH_AVATAR.md
Beyhan Oğur bbbf76b184 first commit
2026-04-26 21:35:24 +03:00

14 KiB
Raw Permalink Blame History

🎉 User Create & Update - Avatar Upload Desteği

Yeni Özellik

Artık yeni kullanıcı oluştururken ve mevcut kullanıcıyı güncellerken aynı request'te avatar da yükleyebilirsiniz!


📋 Güncellenen Endpoint'ler

1. POST /v1/admin/users (Create User)

Artık Multipart/Form-Data Destekliyor!

Önceden:

# Sadece JSON
curl -X POST http://localhost:8080/v1/admin/users \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","password":"Pass123!","user_name":"john"}'

Şimdi:

# Multipart ile avatar da ekleyebilirsiniz!
curl -X POST http://localhost:8080/v1/admin/users \
  -H "Authorization: Bearer ADMIN_TOKEN" \
  -F "email=user@example.com" \
  -F "password=Pass123!" \
  -F "user_name=john" \
  -F "email_verified=true" \
  -F "roles=admin,user" \
  -F "avatar=@/path/to/photo.jpg"

Response:

{
  "id": "new-user-uuid",
  "username": "john",
  "email": "user@example.com",
  "avatar": "/uploads/avatars/new-user-uuid_1707012345.jpg",
  "email_verified": true,
  "roles": [
    {"name": "admin"},
    {"name": "user"}
  ],
  "created_at": "2026-02-04T..."
}

2. PUT /v1/admin/users/:id (Update User)

Hem JSON hem Multipart Destekliyor!

JSON ile (avatar URL):

curl -X PUT http://localhost:8080/v1/admin/users/USER_ID \
  -H "Authorization: Bearer ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "new@example.com",
    "user_name": "newname",
    "roles": ["admin"]
  }'

Multipart ile (avatar dosya):

curl -X PUT http://localhost:8080/v1/admin/users/USER_ID \
  -H "Authorization: Bearer ADMIN_TOKEN" \
  -F "email=new@example.com" \
  -F "user_name=newname" \
  -F "roles=admin,user" \
  -F "avatar=@/path/to/new-photo.jpg"

Response:

{
  "message": "User updated successfully",
  "user": {
    "id": "user-uuid",
    "username": "newname",
    "email": "new@example.com",
    "avatar": "/uploads/avatars/user-uuid_1707012346.jpg",
    "roles": [
      {"name": "admin"},
      {"name": "user"}
    ],
    "updated_at": "2026-02-04T..."
  }
}

🎯 Form Fields

Create User (POST)

Field Type Required ıklama
email string Email adresi
password string Şifre (min 6 karakter)
user_name string Kullanıcı adı
email_verified boolean Email doğrulanmış mı? (true/false)
roles string Roller (comma separated: "admin,user")
avatar file Avatar dosyası (max 5MB, jpg/png/gif/webp)

Update User (PUT)

Field Type Required ıklama
email string Yeni email
password string Yeni şifre
user_name string Yeni kullanıcı adı
email_verified boolean Email doğrulama durumu
roles string Yeni roller (comma separated)
avatar file Yeni avatar dosyası

Not: Tüm alanlar optional, sadece güncellemek istediklerinizi gönderin.


💻 Frontend Kullanımı

HTML Form - Yeni Kullanıcı Oluştur

<form id="createUserForm">
  <input type="email" name="email" required placeholder="Email">
  <input type="password" name="password" required placeholder="Password">
  <input type="text" name="user_name" required placeholder="Username">
  
  <label>
    <input type="checkbox" name="email_verified" value="true">
    Email Verified
  </label>
  
  <select name="roles" multiple>
    <option value="admin">Admin</option>
    <option value="user">User</option>
  </select>
  
  <input type="file" name="avatar" accept="image/*">
  
  <button type="submit">Create User</button>
</form>

<script>
document.getElementById('createUserForm').onsubmit = async (e) => {
  e.preventDefault();
  
  const formData = new FormData(e.target);
  
  // Roles'ü comma separated yap
  const rolesSelect = e.target.roles;
  const selectedRoles = Array.from(rolesSelect.selectedOptions).map(opt => opt.value);
  formData.set('roles', selectedRoles.join(','));
  
  const token = localStorage.getItem('admin_token');
  
  const response = await fetch('http://localhost:8080/v1/admin/users', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`
    },
    body: formData
  });
  
  const data = await response.json();
  
  if (response.ok) {
    console.log('User created:', data);
    alert('User created successfully!');
    if (data.avatar) {
      console.log('Avatar URL:', data.avatar);
    }
  } else {
    alert('Error: ' + data.error);
  }
};
</script>

React - Kullanıcı Güncelle

import { useState } from 'react';

function UpdateUserForm({ userId }) {
  const [formData, setFormData] = useState({
    email: '',
    user_name: '',
    password: '',
    email_verified: false,
    roles: [],
    avatar: null
  });
  
  const handleSubmit = async (e) => {
    e.preventDefault();
    
    const data = new FormData();
    
    if (formData.email) data.append('email', formData.email);
    if (formData.user_name) data.append('user_name', formData.user_name);
    if (formData.password) data.append('password', formData.password);
    if (formData.email_verified) data.append('email_verified', 'true');
    if (formData.roles.length > 0) data.append('roles', formData.roles.join(','));
    if (formData.avatar) data.append('avatar', formData.avatar);
    
    const token = localStorage.getItem('admin_token');
    
    try {
      const response = await fetch(`http://localhost:8080/v1/admin/users/${userId}`, {
        method: 'PUT',
        headers: {
          'Authorization': `Bearer ${token}`
        },
        body: data
      });
      
      const result = await response.json();
      
      if (response.ok) {
        console.log('User updated:', result.user);
        alert('User updated successfully!');
      } else {
        alert('Error: ' + result.error);
      }
    } catch (error) {
      console.error('Update failed:', error);
    }
  };
  
  return (
    <form onSubmit={handleSubmit}>
      <input 
        type="email" 
        placeholder="Email"
        value={formData.email}
        onChange={(e) => setFormData({...formData, email: e.target.value})}
      />
      
      <input 
        type="text" 
        placeholder="Username"
        value={formData.user_name}
        onChange={(e) => setFormData({...formData, user_name: e.target.value})}
      />
      
      <input 
        type="password" 
        placeholder="New Password"
        value={formData.password}
        onChange={(e) => setFormData({...formData, password: e.target.value})}
      />
      
      <label>
        <input 
          type="checkbox"
          checked={formData.email_verified}
          onChange={(e) => setFormData({...formData, email_verified: e.target.checked})}
        />
        Email Verified
      </label>
      
      <select 
        multiple
        value={formData.roles}
        onChange={(e) => setFormData({
          ...formData, 
          roles: Array.from(e.target.selectedOptions).map(opt => opt.value)
        })}
      >
        <option value="admin">Admin</option>
        <option value="user">User</option>
      </select>
      
      <input 
        type="file" 
        accept="image/*"
        onChange={(e) => setFormData({...formData, avatar: e.target.files[0]})}
      />
      
      <button type="submit">Update User</button>
    </form>
  );
}

Vue.js - Yeni Kullanıcı Oluştur

<template>
  <form @submit.prevent="createUser">
    <input v-model="formData.email" type="email" required placeholder="Email">
    <input v-model="formData.password" type="password" required placeholder="Password">
    <input v-model="formData.user_name" type="text" required placeholder="Username">
    
    <label>
      <input v-model="formData.email_verified" type="checkbox">
      Email Verified
    </label>
    
    <select v-model="formData.roles" multiple>
      <option value="admin">Admin</option>
      <option value="user">User</option>
    </select>
    
    <input type="file" @change="handleFileChange" accept="image/*">
    
    <button type="submit">Create User</button>
  </form>
</template>

<script>
export default {
  data() {
    return {
      formData: {
        email: '',
        password: '',
        user_name: '',
        email_verified: false,
        roles: [],
        avatar: null
      }
    }
  },
  methods: {
    handleFileChange(e) {
      this.formData.avatar = e.target.files[0];
    },
    
    async createUser() {
      const data = new FormData();
      
      data.append('email', this.formData.email);
      data.append('password', this.formData.password);
      data.append('user_name', this.formData.user_name);
      data.append('email_verified', this.formData.email_verified ? 'true' : 'false');
      
      if (this.formData.roles.length > 0) {
        data.append('roles', this.formData.roles.join(','));
      }
      
      if (this.formData.avatar) {
        data.append('avatar', this.formData.avatar);
      }
      
      const token = localStorage.getItem('admin_token');
      
      try {
        const response = await fetch('http://localhost:8080/v1/admin/users', {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${token}`
          },
          body: data
        });
        
        const result = await response.json();
        
        if (response.ok) {
          console.log('User created:', result);
          alert('User created successfully!');
          this.$emit('userCreated', result);
        } else {
          alert('Error: ' + result.error);
        }
      } catch (error) {
        console.error('Error:', error);
      }
    }
  }
}
</script>

🧪 Test Örnekleri

Test 1: Yeni Kullanıcı + Avatar Oluştur

# Admin token al
curl -X POST http://localhost:8080/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@gauth.local","password":"Admin@123"}'

# Token'ı kaydet
TOKEN="eyJhbGci..."

# Yeni kullanıcı oluştur (avatar ile)
curl -X POST http://localhost:8080/v1/admin/users \
  -H "Authorization: Bearer $TOKEN" \
  -F "email=newuser@example.com" \
  -F "password=NewUser123!" \
  -F "user_name=newuser" \
  -F "email_verified=true" \
  -F "roles=user" \
  -F "avatar=@./user-photo.jpg"

# Response'da avatar URL göreceksiniz!

Test 2: Kullanıcı Güncelle + Yeni Avatar

USER_ID="user-uuid-here"

curl -X PUT http://localhost:8080/v1/admin/users/$USER_ID \
  -H "Authorization: Bearer $TOKEN" \
  -F "email=updated@example.com" \
  -F "user_name=updatedname" \
  -F "roles=admin,user" \
  -F "avatar=@./new-avatar.jpg"

Test 3: Sadece Avatar Değiştir

# Diğer alanları göndermeden sadece avatar
curl -X PUT http://localhost:8080/v1/admin/users/$USER_ID \
  -H "Authorization: Bearer $TOKEN" \
  -F "avatar=@./profile-pic.jpg"

Test 4: Avatar Olmadan Güncelle

# Avatar olmadan da güncelleme yapabilirsiniz
curl -X PUT http://localhost:8080/v1/admin/users/$USER_ID \
  -H "Authorization: Bearer $TOKEN" \
  -F "email=another@example.com" \
  -F "user_name=anothername"

📊 Özellikler

Create User

  • Multipart/form-data ile avatar yükleme
  • Email, password, username required
  • Roles optional (comma separated: "admin,user")
  • Email verified optional (true/false)
  • Avatar optional (max 5MB)
  • Tek requestte hem kullanıcı hem avatar oluşturulur

Update User

  • Hem JSON hem multipart destekliyor
  • Tüm alanlar optional
  • Avatar dosya ile veya URL ile güncellenebilir
  • Eski avatar otomatik silinir (local ise)
  • OAuth avatar'ları korunur

Avatar Validasyonu

  • Format: JPG, JPEG, PNG, GIF, WebP
  • Maksimum boyut: 5MB
  • Otomatik dosya ismi: {user_id}_{timestamp}.{ext}

🔄 Content-Type Desteği

Create User

Content-Type: multipart/form-data

Update User

Content-Type: application/json  (JSON için)
Content-Type: multipart/form-data  (Avatar upload için)

Handler otomatik olarak Content-Type'a göre parse eder!


⚠️ Önemli Notlar

1. Roles Format

Multipart:

roles=admin,user

JSON:

{
  "roles": ["admin", "user"]
}

2. Boolean Fields

Multipart:

email_verified=true

JSON:

{
  "email_verified": true
}

3. Avatar Önceliği

  1. Dosya upload (multipart) → En yüksek öncelik
  2. Avatar URL (JSON) → Dosya yoksa
  3. Mevcut avatar → Değişiklik yoksa

4. Eski Avatar Temizleme

// Otomatik temizlik
if user.Avatar != "" && strings.HasPrefix(user.Avatar, "/uploads/") {
    os.Remove("." + user.Avatar)  // Eski local dosya silinir
}

// OAuth avatar'lar korunur
// https://... ile başlayanlar silinmez

Özet

Artık Yapabilirsiniz

  1. Yeni kullanıcı oluştururken avatar yükleyin
  2. Kullanıcı güncellerken avatar değiştirin
  3. Hem JSON hem multipart desteği
  4. Tek request'te tüm işlemler
  5. Otomatik dosya temizleme
  6. Validation ve error handling

Build Durumu

✅ go build -o main .
✅ Build successful
✅ CreateUser multipart destekliyor
✅ UpdateUser multipart + JSON destekliyor

Test Edin

# Uygulamayı başlat
./main

# Yeni kullanıcı + avatar
curl -X POST http://localhost:8080/v1/admin/users \
  -H "Authorization: Bearer TOKEN" \
  -F "email=test@example.com" \
  -F "password=Test123!" \
  -F "user_name=testuser" \
  -F "avatar=@photo.jpg"

Artık user create ve update'te avatar yükleyebilirsiniz! 🎉