Initial commit: img-infinite-canvas AI design workbench MVP
Moteva-style AI design workbench replica. Home prompt creates a project; the project page provides an infinite canvas with node drag, zoom/pan, a design chat panel, history replay, image asset upload, and project save/regenerate. - Backend: go-zero, DDD layering, sqlc/pgx, optional PostgreSQL; memory or Redis cache; asynq job queue; MinIO/S3/R2/OSS object storage; sky-valley/pi agent runtime adapter. - Frontend: Next.js App Router + Vite artifact build, TypeScript, i18n, shadcn/ui components, auth (OTP/Turnstile/Google/WeChat). - Deploy: Docker Compose and k3s manifests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.10.1
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"img_infinite_canvas/internal/config"
|
||||
"img_infinite_canvas/internal/errorx"
|
||||
"img_infinite_canvas/internal/handler"
|
||||
"img_infinite_canvas/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/conf"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
var (
|
||||
configFile = flag.String("f", "etc/config.yaml", "the config file")
|
||||
runMode = flag.String("mode", "all", "process mode: api, worker, or all")
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
httpx.SetErrorHandlerCtx(errorx.Handle)
|
||||
|
||||
ctx := svc.NewServiceContext(c)
|
||||
defer ctx.Close()
|
||||
|
||||
mode := normalizeRunMode(*runMode)
|
||||
if mode == "worker" {
|
||||
if !ctx.HasJobWorker() {
|
||||
logx.Must(fmt.Errorf("job worker is disabled by JobQueue.Driver"))
|
||||
}
|
||||
fmt.Println("Starting job worker...")
|
||||
if err := ctx.RunJobWorker(); err != nil {
|
||||
logx.Must(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if mode == "all" {
|
||||
if err := ctx.StartJobWorker(); err != nil {
|
||||
logx.Must(err)
|
||||
}
|
||||
defer ctx.ShutdownJobWorker()
|
||||
}
|
||||
if err := ctx.StartOutboxPublisher(); err != nil {
|
||||
logx.Must(err)
|
||||
}
|
||||
defer ctx.ShutdownOutboxPublisher()
|
||||
|
||||
server := rest.MustNewServer(c.RestConf)
|
||||
defer server.Stop()
|
||||
server.Use(handler.UserContextMiddleware(ctx.AuthService))
|
||||
handler.RegisterHandlers(server, ctx)
|
||||
handler.RegisterV1Handlers(server, ctx)
|
||||
|
||||
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||
server.Start()
|
||||
}
|
||||
|
||||
func normalizeRunMode(mode string) string {
|
||||
switch strings.ToLower(strings.TrimSpace(mode)) {
|
||||
case "", "all":
|
||||
return "all"
|
||||
case "api":
|
||||
return "api"
|
||||
case "worker":
|
||||
return "worker"
|
||||
default:
|
||||
logx.Must(fmt.Errorf("unsupported process mode %q", mode))
|
||||
return "all"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user