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

574 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🎉 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:**
```bash
# 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:**
```bash
# 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:**
```json
{
"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):**
```bash
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):**
```bash
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:**
```json
{
"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 | Açı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 | Açı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
```html
<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
```jsx
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
```vue
<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
```bash
# 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
```bash
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
```bash
# 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
```bash
# 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 request**te 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:**
```json
{
"roles": ["admin", "user"]
}
```
### 2. Boolean Fields
**Multipart:**
```
email_verified=true
```
**JSON:**
```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
```go
// 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
```bash
✅ go build -o main .
✅ Build successful
✅ CreateUser multipart destekliyor
✅ UpdateUser multipart + JSON destekliyor
```
### Test Edin
```bash
# 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! 🎉**