# Proje Yapısı ``` goaresv3/ ├── main.go ├── .env ├── app/ │ ├── accounts/ │ │ ├── handlers/user.go │ │ └── models/accounts.go │ ├── settings/ │ │ ├── handlers/settings.go │ │ └── models/{setting,hero,cors}.go │ ├── shop/ │ │ ├── handlers/shop.go │ │ └── models/{product,cart}.go │ └── blog/ │ ├── handlers/blog.go │ └── models/blog.go ├-------── config/ | ├── db.go │ └── redis.go ├── pkg/ │ ├── jwt/jwt.go │ ├── mailer/mailer.go │ ├── middleware/{auth,cors_dynamic,rate_limit_dynamic}.go │ └── swaggerui/initializer.go ├── router/router.go ├── docs/{docs.go,swagger.json,swagger.yaml} └── belgeler/ ``` ## Uygulama Akışı 1. `.env` yüklenir (`godotenv`). 2. `config.ConnectDB()` ile MySQL bağlantısı açılır. 3. `config.RunAutoMigrate()` tüm modüllerin şemalarını uygular. 4. `config.SeedSecurityDefaults()` CORS/RateLimit başlangıç kayıtlarını (yoksa) ekler. 5. Gin başlatılır, global middlewareler çalışır: - `DynamicCORS()` - `DynamicRateLimit()` 6. `router.Setup(r)` ile endpointler yüklenir. ## Yetki Modeli - `AuthRequired()`: - Sadece standart JWT (`HS256`) access token doğrular - `iss`, `aud`, `nbf` claim kontrolleri zorunludur - Context'e `user_id`, `email`, `username` yazar - `AdminRequired()`: - `users.is_admin` alanını kontrol eder - `POST/PUT/DELETE/PATCH` gibi mutating endpointlerde kullanılır ## Route Grupları - Public: `/api/v1/auth/*` - Auth zorunlu (read + user işlemleri): `/api/v1/*` - Admin zorunlu (mutating yönetim işlemleri): `/api/v1/*` altında admin grubu - Swagger UI: `/swagger/*any` ## Swagger Uretimi 1. Swagger dokumanini olustur/guncelle: - `swag init -g main.go -o docs` 2. Uygulamayi calistir ve Swagger UI ac: - `http://localhost:8080/swagger/index.html` Not: - Legacy access token formatlari desteklenmez. - `JWT_SECRET` bos ise uygulama fail-fast ile acilmaz. - `Authorization` header formati zorunludur: `Bearer `. { "access": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwidXNlcl9pZCI6IjEiLCJlbWFpbCI6ImJleWhhbkBiZXloYW4uZGV2IiwidXNlcm5hbWUiOiJiZXloYW5vIiwiZXhwIjoxNzc2MjkxNjQzLCJpYXQiOjE3NzYyOTA3NDMsImp0aSI6Ijg1NzkzZWE5ODQ5NjI4MzE0MjNlMWIyZWJmNDU1YjA0In0.2trNlY6FxrNAIEyIu_VZEEwDdKAm9OMQYm8ab2Npiz0", "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsInVzZXJfaWQiOiIxIiwiZXhwIjoxNzc2ODk1NTQzLCJpYXQiOjE3NzYyOTA3NDMsImp0aSI6ImNiMTM4MWZjNTgwMjRjMzJiMDFlMDMwNjU4MjlkNDQzIn0.zpIaABAy0vZJa94_OTZNj4Mn1YISZonDgztrAoqiQg4" } { "access": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwidXNlcl9pZCI6IjEiLCJlbWFpbCI6ImJleWhhbkBiZXloYW4uZGV2IiwidXNlcm5hbWUiOiJiZXloYW5vIiwiZXhwIjoxNzc2MjkyMjc0LCJpYXQiOjE3NzYyOTEzNzQsImp0aSI6ImJlNTQxMGNkYzljYjRkODBmM2EyYzgwNDJkMWE4MzFmIn0.sNbrxgNkLzama5m52zIunQOOu2K4a08xZz9CUwdRNg4", "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsInVzZXJfaWQiOiIxIiwiZXhwIjoxNzc2ODk2MTc0LCJpYXQiOjE3NzYyOTEzNzQsImp0aSI6IjI3NTlhMGI1YzFjZjFhYjBlN2EyMWVlZjE3NmM4YzdjIn0.5YdO_jVJzIzJHWGf52o46RZqgcC-DmVQv1BUx1lPUMc" } { "access": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwidXNlcl9pZCI6IjEiLCJlbWFpbCI6ImJleWhhbkBiZXloYW4uZGV2IiwidXNlcm5hbWUiOiJCZXloYW4gT8SfdXIiLCJleHAiOjE3NzYyOTgwNzAsImlhdCI6MTc3NjI5NzE3MCwianRpIjoiZGUyZWNiZGY5ZjU4MGJhOTA4ODI1MGUyMWE0MTNjYTcifQ.NiT5spcCm9sd7S9DttuFHA__KzFq3pQIJ8xkJKtntnc", "refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsInVzZXJfaWQiOiIxIiwiZXhwIjoxNzc2OTAxOTcwLCJpYXQiOjE3NzYyOTcxNzAsImp0aSI6ImQ5MTgyZGUyNTE4ZjkwMmUwMGQwMjA2MWZmMTZhYjg5In0.lW7CNuSqEq1aY7XIWVm6v9diGOWmlm_BqIMnM9CtZ8Y" }