package main import ( "fmt" "os" ) var structure = []string{ // Main Entry Point "cmd/server/main.go", // Configuration "internal/config/config.go", "internal/config/database.go", "internal/config/jwt.go", // Models "internal/models/user.go", "internal/models/role.go", "internal/models/item.go", "internal/models/lost_item.go", "internal/models/claim.go", "internal/models/category.go", "internal/models/archive.go", "internal/models/audit_log.go", "internal/models/claim_verification.go", // BARU: tracking verifikasi klaim "internal/models/match_result.go", // BARU: hasil matching barang "internal/models/revision_log.go", // BARU: audit trail edit barang "internal/models/notification.go", // BARU: notifikasi (opsional) // Repositories "internal/repositories/user_repo.go", "internal/repositories/role_repo.go", "internal/repositories/item_repo.go", "internal/repositories/lost_item_repo.go", "internal/repositories/claim_repo.go", "internal/repositories/category_repo.go", "internal/repositories/archive_repo.go", "internal/repositories/audit_log_repo.go", "internal/repositories/claim_verification_repo.go", // BARU "internal/repositories/match_result_repo.go", // BARU "internal/repositories/revision_log_repo.go", // BARU "internal/repositories/notification_repo.go", // BARU (opsional) // Services "internal/services/auth_service.go", "internal/services/user_service.go", "internal/services/item_service.go", "internal/services/lost_item_service.go", "internal/services/claim_service.go", "internal/services/match_service.go", "internal/services/category_service.go", "internal/services/archive_service.go", "internal/services/audit_service.go", "internal/services/export_service.go", "internal/services/verification_service.go", // BARU: logic verifikasi terpisah "internal/services/notification_service.go", // BARU: handle notifikasi // Controllers "internal/controllers/auth_controller.go", "internal/controllers/user_controller.go", "internal/controllers/item_controller.go", "internal/controllers/lost_item_controller.go", "internal/controllers/claim_controller.go", "internal/controllers/match_controller.go", "internal/controllers/category_controller.go", "internal/controllers/archive_controller.go", "internal/controllers/admin_controller.go", "internal/controllers/report_controller.go", // BARU: export laporan terpisah // Middleware "internal/middleware/jwt_middleware.go", "internal/middleware/role_middleware.go", "internal/middleware/logger.go", "internal/middleware/cors.go", "internal/middleware/rate_limiter.go", // BARU: rate limiting (recommended) // Workers (Concurrency) "internal/workers/expire_worker.go", "internal/workers/audit_worker.go", "internal/workers/matching_worker.go", // BARU: auto-matching background "internal/workers/notification_worker.go", // BARU: kirim notifikasi // Utils "internal/utils/hash.go", "internal/utils/response.go", "internal/utils/error.go", "internal/utils/validator.go", "internal/utils/matching.go", "internal/utils/similarity.go", "internal/utils/pdf_export.go", "internal/utils/excel_export.go", "internal/utils/image_handler.go", // BARU: handle upload/resize foto // Routes "internal/routes/routes.go", // Upload directories "uploads/items/.gitkeep", "uploads/lost_items/.gitkeep", "uploads/claims/.gitkeep", // Web Frontend "web/index.html", "web/login.html", "web/admin.html", "web/manager.html", "web/user.html", "web/css/style.css", "web/js/main.js", "web/js/admin.js", "web/js/manager.js", "web/js/user.js", // Database (Manual migration via HeidiSQL) "database/schema.sql", "database/seed.sql", // Root Files ".env.example", "README.md", "Makefile", // BARU: untuk command shortcuts "go.mod", "go.sum", } func main() { fmt.Println("🚀 Memulai pembuatan struktur project Lost & Found...") fmt.Println("📦 Total file yang akan dibuat:", len(structure)) fmt.Println() successCount := 0 failCount := 0 for _, path := range structure { dir := getDir(path) if dir != "" { err := os.MkdirAll(dir, os.ModePerm) if err != nil { fmt.Printf("❌ Gagal buat folder: %s - %v\n", dir, err) failCount++ continue } } file, err := os.Create(path) if err != nil { fmt.Printf("❌ Gagal buat file: %s - %v\n", path, err) failCount++ continue } file.Close() fmt.Printf("✅ Dibuat: %s\n", path) successCount++ } fmt.Println() fmt.Println("════════════════════════════════════════════════════") fmt.Printf("🎉 Proses selesai!\n") fmt.Printf("✅ Berhasil: %d file\n", successCount) if failCount > 0 { fmt.Printf("❌ Gagal: %d file\n", failCount) } fmt.Println("════════════════════════════════════════════════════") fmt.Println() printStructureInfo() printNextSteps() printNewFeatures() } func getDir(path string) string { i := len(path) - 1 for i >= 0 && path[i] != '/' && path[i] != '\\' { i-- } if i > 0 { return path[:i] } return "" } func printStructureInfo() { fmt.Println("📁 Struktur Project:") fmt.Println(" - cmd/server : Entry point aplikasi") fmt.Println(" - internal/config : Konfigurasi (DB, JWT)") fmt.Println(" - internal/models : Entity models (12 models)") fmt.Println(" - internal/repos : Database operations") fmt.Println(" - internal/services : Business logic") fmt.Println(" - internal/controllers: HTTP handlers") fmt.Println(" - internal/middleware : Auth, RBAC & logging") fmt.Println(" - internal/workers : Background jobs (4 workers)") fmt.Println(" - internal/utils : Helper functions") fmt.Println(" - internal/routes : API routing") fmt.Println(" - uploads : Storage untuk foto upload") fmt.Println(" - web : Frontend files (HTML, CSS, JS)") fmt.Println(" - database : Schema & seed (manual via HeidiSQL)") fmt.Println() } func printNextSteps() { fmt.Println("🔧 Next Steps:") fmt.Println(" 1. Copy .env.example ke .env") fmt.Println(" 2. Edit .env dengan konfigurasi database Anda") fmt.Println(" 3. Run: go mod init lost-and-found") fmt.Println(" 4. Run: go mod tidy") fmt.Println(" 5. Install dependencies:") fmt.Println(" - go get github.com/gin-gonic/gin") fmt.Println(" - go get github.com/golang-jwt/jwt/v5") fmt.Println(" - go get gorm.io/gorm") fmt.Println(" - go get gorm.io/driver/postgres") fmt.Println(" 6. Buka HeidiSQL dan jalankan database/schema.sql") fmt.Println(" 7. (Opsional) Jalankan database/seed.sql untuk data dummy") fmt.Println(" 8. Mulai coding dari cmd/server/main.go") fmt.Println() } func printNewFeatures() { fmt.Println("✨ File Baru yang Ditambahkan:") fmt.Println() fmt.Println("📌 MODELS (4 baru):") fmt.Println(" • claim_verification.go → Tracking verifikasi & % matching") fmt.Println(" • match_result.go → Hasil auto-matching barang") fmt.Println(" • revision_log.go → Audit trail edit barang") fmt.Println(" • notification.go → Notifikasi ke user") fmt.Println() fmt.Println("📌 SERVICES (2 baru):") fmt.Println(" • verification_service.go → Logic verifikasi klaim terpisah") fmt.Println(" • notification_service.go → Handle notifikasi") fmt.Println() fmt.Println("📌 WORKERS (2 baru):") fmt.Println(" • matching_worker.go → Auto-matching background") fmt.Println(" • notification_worker.go → Kirim notifikasi async") fmt.Println() fmt.Println("📌 UTILS (1 baru):") fmt.Println(" • image_handler.go → Handle upload & resize foto") fmt.Println() fmt.Println("📌 MIDDLEWARE (1 baru):") fmt.Println(" • rate_limiter.go → Rate limiting untuk security") fmt.Println() fmt.Println("📌 UPLOADS:") fmt.Println(" • uploads/items/ → Foto barang ditemukan") fmt.Println(" • uploads/lost_items/ → Foto barang hilang") fmt.Println(" • uploads/claims/ → Foto bukti klaim") fmt.Println() fmt.Println("════════════════════════════════════════════════════") fmt.Println("💡 Tips:") fmt.Println(" - Foto disimpan di folder uploads/") fmt.Println(" - Database hanya simpan path foto (bukan file)") fmt.Println(" - Gunakan Makefile untuk shortcuts command") fmt.Println(" - Database dikelola manual via HeidiSQL") fmt.Println("════════════════════════════════════════════════════") }