Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 43 additions & 68 deletions backend/gen_microservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ import (
// Generated layout:
//
// <name>/
// ├── cmd/<name>/main.go
// ├── cmd/<name>/main.go # framework-specific entrypoint
// ├── internal/
// │ ├── handler/handler.go
// │ └── service/service.go
// │ ├── handler/handler.go # framework-specific handler
// │ ├── router/router.go # framework-specific router
// │ ├── service/service.go # stub service interface + impl
// │ ├── cache/cache.go # if cache addon selected
// │ ├── database/database.go # if database addon selected
// │ └── logger/logger.go # if zap/logrus addon selected
// ├── go.mod
// ├── .gitignore
// ├── Makefile
// ├── README.md
// └── Dockerfile (optional)
// └── Dockerfile # if dockerSupport is true
type MicroserviceGenerator struct{}

func (g *MicroserviceGenerator) Generate(request CreateProjectRequest) (*bytes.Buffer, error) {
Expand Down Expand Up @@ -48,29 +54,54 @@ func (g *MicroserviceGenerator) Generate(request CreateProjectRequest) (*bytes.B
return nil, err
}

// cmd/<name>/main.go
mainContent := generateMicroserviceMain(request.ModuleName)
// cmd/<name>/main.go — framework-aware
mainContent, err := GenerateMainContent(request.Framework)
if err != nil {
log.Printf("[ERROR] Failed to generate main.go: %v", err)
return nil, fmt.Errorf("failed to generate main.go: %w", err)
}
if err := addToZip(zipWriter, fmt.Sprintf("%s/cmd/%s/main.go", folderName, folderName), mainContent); err != nil {
log.Printf("[ERROR] %v", err)
return nil, err
}

// internal/handler/handler.go
if err := addToZip(zipWriter, fmt.Sprintf("%s/internal/handler/handler.go", folderName), microserviceHandlerStub()); err != nil {
// internal/handler/handler.go — framework-specific handler
if err := addToZip(zipWriter, fmt.Sprintf("%s/internal/handler/handler.go", folderName), GenerateHandlerContent(request.Framework)); err != nil {
log.Printf("[ERROR] %v", err)
return nil, err
}

// internal/service/service.go
if err := addToZip(zipWriter, fmt.Sprintf("%s/internal/service/service.go", folderName), microserviceServiceStub()); err != nil {
// internal/router/router.go — framework-specific router
if err := addToZip(zipWriter, fmt.Sprintf("%s/internal/router/router.go", folderName), GenerateRouterContent(request.Framework)); err != nil {
log.Printf("[ERROR] %v", err)
return nil, err
}

// Addons
// internal/service/service.go — named service stub
if err := addToZip(zipWriter, fmt.Sprintf("%s/internal/service/service.go", folderName), GenerateServiceContent(folderName)); err != nil {
log.Printf("[ERROR] %v", err)
return nil, err
}

// Addons — cache/database via registry; "other" (logging) handled inline
for addonType, addons := range request.Addons {
if len(addons) == 0 {
continue
}
if addonType == "other" {
loggerContent, err := GenerateLoggingAddon(addons)
if err != nil {
log.Printf("[WARN] Skipping logging addon: %v", err)
continue
}
if err := addToZip(zipWriter, fmt.Sprintf("%s/internal/logger/logger.go", folderName), loggerContent); err != nil {
log.Printf("[ERROR] %v", err)
return nil, err
}
continue
}
gen, ok := addonRegistry[addonType]
if !ok || len(addons) == 0 {
if !ok {
continue
}
if err := gen.Generate(folderName, addons, zipWriter); err != nil {
Expand Down Expand Up @@ -105,59 +136,3 @@ func (g *MicroserviceGenerator) Generate(request CreateProjectRequest) (*bytes.B
}
return buf, nil
}

func generateMicroserviceMain(moduleName string) []byte {
return []byte(fmt.Sprintf(`// Code generated by go-initializer. DO NOT EDIT.
package main

import (
"log"
"net/http"

"%s/internal/handler"
)

func main() {
h := handler.New()
http.HandleFunc("/healthz", h.Healthz)
log.Println("Starting server on :8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
`, moduleName))
}

func microserviceHandlerStub() []byte {
return []byte(`// Code generated by go-initializer. DO NOT EDIT.
package handler

import "net/http"

// Handler holds application dependencies.
type Handler struct{}

// New creates a new Handler.
func New() *Handler {
return &Handler{}
}

// Healthz handles health check requests.
func (h *Handler) Healthz(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
}
`)
}

func microserviceServiceStub() []byte {
return []byte(`// Code generated by go-initializer. DO NOT EDIT.
package service

// Service holds business logic.
type Service struct{}

// New creates a new Service.
func New() *Service {
return &Service{}
}
`)
}
Binary file modified backend/go-initializer
Binary file not shown.
4 changes: 2 additions & 2 deletions tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Project layout to generate:
└── Dockerfile # if dockerSupport is true
```

- [ ] **T14 — [Backend] Complete `GenerateMicroservice`** — the generator structure exists; wire Phase 2 helpers to make `cmd/main.go` framework-aware; add `internal/router.go` from `GenerateRouterContent`; replace the current hardcoded `internal/handler/handler.go` with `GenerateHandlerContent`; replace the current `internal/service/service.go` stub with `GenerateServiceContent`; handle "other" logging addons; emit `.gitignore` and `Makefile`
- [x] **T14 — [Backend] Complete `GenerateMicroservice`** — the generator structure exists; wire Phase 2 helpers to make `cmd/main.go` framework-aware; add `internal/router.go` from `GenerateRouterContent`; replace the current hardcoded `internal/handler/handler.go` with `GenerateHandlerContent`; replace the current `internal/service/service.go` stub with `GenerateServiceContent`; handle "other" logging addons; emit `.gitignore` and `Makefile`

---

Expand Down Expand Up @@ -183,7 +183,7 @@ Supported frameworks: `cobra`, `urfave`, `kingpin`
| 1 — Bug Fixes & Static Files | T1–T6 | Low | None | All done |
| 2 — Framework-Aware Engine | T7–T11 | Medium | Phase 1 | All done |
| 3 — Complete `simple-project` | T12–T13 | Medium | Phase 2 | All done |
| 4 — Complete `microservice` | T14 | Medium-High | Phase 2 | Partial (structure exists, not framework-aware) |
| 4 — Complete `microservice` | T14 | Medium-High | Phase 2 | All done |
| 5 — `api-server` Generator | T15–T16 | Medium-High | Phase 2 | Open |
| 6 — `cli-app` Generator | T17–T20 | High | Phase 2 | Open |
| 7 — Frontend Dynamic UI | T21–T23 | Low-Medium | Phase 1 | Open |
Expand Down
Loading