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:
2026-07-07 23:15:37 +08:00
commit 44406b72db
349 changed files with 73265 additions and 0 deletions
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func agentChatHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.AgentChatRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewAgentChatLogic(r.Context(), svcCtx)
resp, err := l.AgentChat(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,29 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func agentWebsocketHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ProjectIdRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewAgentWebsocketLogic(r.Context(), svcCtx)
err := l.Stream(w, r, &req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func createAssetUploadHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.CreateAssetUploadRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewCreateAssetUploadLogic(r.Context(), svcCtx)
resp, err := l.CreateAssetUpload(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func createProjectAsyncHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.CreateProjectRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewCreateProjectAsyncLogic(r.Context(), svcCtx)
resp, err := l.CreateProjectAsync(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func createProjectHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.CreateProjectRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewCreateProjectLogic(r.Context(), svcCtx)
resp, err := l.CreateProject(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,24 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
)
func dashboardHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := logic.NewDashboardLogic(r.Context(), svcCtx)
resp, err := l.Dashboard()
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func deleteAssetHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.DeleteAssetRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewDeleteAssetLogic(r.Context(), svcCtx)
resp, err := l.DeleteAsset(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func deleteProjectHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ProjectIdRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewDeleteProjectLogic(r.Context(), svcCtx)
resp, err := l.DeleteProject(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func deleteProjectsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.DeleteProjectsRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewDeleteProjectsLogic(r.Context(), svcCtx)
resp, err := l.DeleteProjects(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func extractNodeTextAsyncHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ExtractNodeTextAsyncRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewExtractNodeTextAsyncLogic(r.Context(), svcCtx)
resp, err := l.ExtractNodeTextAsync(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,32 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
"github.com/zeromicro/go-zero/rest/httpx"
)
func extractNodeTextHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ExtractNodeTextRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewExtractNodeTextLogic(r.Context(), svcCtx)
resp, err := l.ExtractNodeText(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func generateMockupModelHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GenerateMockupModelRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewGenerateMockupModelLogic(r.Context(), svcCtx)
resp, err := l.GenerateMockupModel(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func generateProjectAsyncHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GenerateRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewGenerateProjectAsyncLogic(r.Context(), svcCtx)
resp, err := l.GenerateProjectAsync(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func generateProjectHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GenerateRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewGenerateProjectLogic(r.Context(), svcCtx)
resp, err := l.GenerateProject(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,24 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
)
func getAccountProfileHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := logic.NewGetAccountProfileLogic(r.Context(), svcCtx)
resp, err := l.GetAccountProfile()
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func getAgentThreadStatusHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ProjectIdRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewGetAgentThreadStatusLogic(r.Context(), svcCtx)
resp, err := l.GetAgentThreadStatus(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,24 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
)
func getAuthOptionsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := logic.NewGetAuthOptionsLogic(r.Context(), svcCtx)
resp, err := l.GetAuthOptions()
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func getGeneratorTaskHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GeneratorTaskRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewGetGeneratorTaskLogic(r.Context(), svcCtx)
resp, err := l.GetGeneratorTask(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,33 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func getMockupBlobHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MockupBlobRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewGetMockupBlobLogic(r.Context(), svcCtx)
data, err := l.GetMockupBlob(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Cache-Control", "public, max-age=14400")
_, _ = w.Write(data)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func getProjectHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ProjectIdRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewGetProjectLogic(r.Context(), svcCtx)
resp, err := l.GetProject(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func getProjectHistoryHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ProjectIdRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewGetProjectHistoryLogic(r.Context(), svcCtx)
resp, err := l.GetProjectHistory(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,24 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
)
func getWechatAuthUrlHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := logic.NewGetWechatAuthUrlLogic(r.Context(), svcCtx)
resp, err := l.GetWechatAuthUrl()
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
+24
View File
@@ -0,0 +1,24 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
)
func healthHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := logic.NewHealthLogic(r.Context(), svcCtx)
resp, err := l.Health()
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,24 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
)
func listAccountDevicesHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := logic.NewListAccountDevicesLogic(r.Context(), svcCtx)
resp, err := l.ListAccountDevices()
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func listAgentThreadsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ProjectIdRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewListAgentThreadsLogic(r.Context(), svcCtx)
resp, err := l.ListAgentThreads(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func listProjectsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ProjectListRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewListProjectsLogic(r.Context(), svcCtx)
resp, err := l.ListProjects(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func loginChinaPasswordHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ChinaPasswordLoginRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewLoginChinaPasswordLogic(r.Context(), svcCtx)
resp, err := l.LoginChinaPassword(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func loginChinaSmsCodeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ChinaSmsLoginRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewLoginChinaSmsCodeLogic(r.Context(), svcCtx)
resp, err := l.LoginChinaSmsCode(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func loginChinaWechatHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ChinaWechatLoginRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewLoginChinaWechatLogic(r.Context(), svcCtx)
resp, err := l.LoginChinaWechat(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func loginGlobalEmailCodeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GlobalEmailLoginRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewLoginGlobalEmailCodeLogic(r.Context(), svcCtx)
resp, err := l.LoginGlobalEmailCode(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func loginGlobalGoogleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GoogleLoginRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewLoginGlobalGoogleLogic(r.Context(), svcCtx)
resp, err := l.LoginGlobalGoogle(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,24 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
)
func logoutAccountHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := logic.NewLogoutAccountLogic(r.Context(), svcCtx)
resp, err := l.LogoutAccount()
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func mergeLayersHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.MergeLayersRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewMergeLayersLogic(r.Context(), svcCtx)
resp, err := l.MergeLayers(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func prepareMockupSurfaceHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.PrepareMockupSurfaceRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewPrepareMockupSurfaceLogic(r.Context(), svcCtx)
resp, err := l.PrepareMockupSurface(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,58 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"encoding/json"
"fmt"
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func projectEventsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ProjectIdRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
flusher, ok := w.(http.Flusher)
if !ok {
httpx.ErrorCtx(r.Context(), w, fmt.Errorf("streaming is not supported"))
return
}
header := w.Header()
header.Set("Content-Type", "text/event-stream")
header.Set("Cache-Control", "no-cache")
header.Set("Connection", "keep-alive")
header.Set("X-Accel-Buffering", "no")
l := logic.NewProjectEventsLogic(r.Context(), svcCtx)
threadID := r.URL.Query().Get("threadId")
if threadID == "" {
threadID = r.URL.Query().Get("thread_id")
}
err := l.Stream(&req, threadID, func(event string, payload any) error {
data, err := json.Marshal(payload)
if err != nil {
return err
}
if _, err := fmt.Fprintf(w, "event: %s\ndata: %s\n\n", event, data); err != nil {
return err
}
flusher.Flush()
return nil
})
if err != nil && r.Context().Err() == nil {
data, _ := json.Marshal(map[string]string{"error": err.Error()})
_, _ = fmt.Fprintf(w, "event: stream_error\ndata: %s\n\n", data)
flusher.Flush()
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func recognizeObjectHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.RecognizeObjectRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewRecognizeObjectLogic(r.Context(), svcCtx)
resp, err := l.RecognizeObject(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,24 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
)
func removeAccountDevicesHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
l := logic.NewRemoveAccountDevicesLogic(r.Context(), svcCtx)
resp, err := l.RemoveAccountDevices()
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func requestChinaSmsCodeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.AuthCodeRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewRequestChinaSmsCodeLogic(r.Context(), svcCtx)
resp, err := l.RequestChinaSmsCode(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func requestGlobalEmailCodeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.AuthCodeRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewRequestGlobalEmailCodeLogic(r.Context(), svcCtx)
resp, err := l.RequestGlobalEmailCode(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
+245
View File
@@ -0,0 +1,245 @@
// Code generated by goctl. DO NOT EDIT.
// goctl 1.10.1
package handler
import (
"net/http"
"img_infinite_canvas/internal/svc"
"github.com/zeromicro/go-zero/rest"
)
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
[]rest.Route{
{
Method: http.MethodGet,
Path: "/account/devices",
Handler: listAccountDevicesHandler(serverCtx),
},
{
Method: http.MethodDelete,
Path: "/account/devices",
Handler: removeAccountDevicesHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/account/logout",
Handler: logoutAccountHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/account/profile",
Handler: getAccountProfileHandler(serverCtx),
},
{
Method: http.MethodPatch,
Path: "/account/profile",
Handler: updateAccountProfileHandler(serverCtx),
},
{
Method: http.MethodDelete,
Path: "/assets",
Handler: deleteAssetHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/assets/upload-url",
Handler: createAssetUploadHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/auth/china/password-login",
Handler: loginChinaPasswordHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/auth/china/sms-code",
Handler: requestChinaSmsCodeHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/auth/china/sms-login",
Handler: loginChinaSmsCodeHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/auth/china/wechat-login",
Handler: loginChinaWechatHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/auth/china/wechat/auth-url",
Handler: getWechatAuthUrlHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/auth/global/email-code",
Handler: requestGlobalEmailCodeHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/auth/global/email-login",
Handler: loginGlobalEmailCodeHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/auth/global/google-login",
Handler: loginGlobalGoogleHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/auth/options",
Handler: getAuthOptionsHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/context/vision/recognize_object",
Handler: recognizeObjectHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/dashboard",
Handler: dashboardHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/generator/tasks",
Handler: getGeneratorTaskHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/generator/tasks",
Handler: submitGeneratorTaskHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/health",
Handler: healthHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/mockup/blob/:dataId",
Handler: getMockupBlobHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/projects",
Handler: listProjectsHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects",
Handler: createProjectHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/projects/:id",
Handler: getProjectHandler(serverCtx),
},
{
Method: http.MethodDelete,
Path: "/projects/:id",
Handler: deleteProjectHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects/:id/agent/chat",
Handler: agentChatHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/projects/:id/agent/status",
Handler: getAgentThreadStatusHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects/:id/agent/stop",
Handler: stopAgentTaskHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/projects/:id/agent/threads",
Handler: listAgentThreadsHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/projects/:id/agent/ws",
Handler: agentWebsocketHandler(serverCtx),
},
{
Method: http.MethodPatch,
Path: "/projects/:id/canvas",
Handler: saveCanvasHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/projects/:id/events",
Handler: projectEventsHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects/:id/generate",
Handler: generateProjectHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects/:id/generate/async",
Handler: generateProjectAsyncHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/projects/:id/history",
Handler: getProjectHistoryHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects/:id/layers/merge",
Handler: mergeLayersHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects/:id/nodes/:nodeId/actions/async",
Handler: runNodeActionAsyncHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects/:id/nodes/:nodeId/mockup-model",
Handler: generateMockupModelHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects/:id/nodes/:nodeId/mockup-surface",
Handler: prepareMockupSurfaceHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects/:id/nodes/:nodeId/text-extraction",
Handler: extractNodeTextHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects/:id/nodes/:nodeId/text-extraction/async",
Handler: extractNodeTextAsyncHandler(serverCtx),
},
{
Method: http.MethodPatch,
Path: "/projects/:id/title",
Handler: updateProjectTitleHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/projects/async",
Handler: createProjectAsyncHandler(serverCtx),
},
{
Method: http.MethodDelete,
Path: "/projects/batch-delete",
Handler: deleteProjectsHandler(serverCtx),
},
},
rest.WithPrefix("/api"),
)
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func runNodeActionAsyncHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.NodeActionRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewRunNodeActionAsyncLogic(r.Context(), svcCtx)
resp, err := l.RunNodeActionAsync(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func saveCanvasHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.SaveCanvasRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewSaveCanvasLogic(r.Context(), svcCtx)
resp, err := l.SaveCanvas(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func stopAgentTaskHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.StopAgentTaskRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewStopAgentTaskLogic(r.Context(), svcCtx)
resp, err := l.StopAgentTask(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func submitGeneratorTaskHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GeneratorTaskSubmitRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewSubmitGeneratorTaskLogic(r.Context(), svcCtx)
resp, err := l.SubmitGeneratorTask(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func updateAccountProfileHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.UpdateAccountProfileRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewUpdateAccountProfileLogic(r.Context(), svcCtx)
resp, err := l.UpdateAccountProfile(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,31 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"github.com/zeromicro/go-zero/rest/httpx"
"img_infinite_canvas/internal/logic"
"img_infinite_canvas/internal/svc"
"img_infinite_canvas/internal/types"
)
func updateProjectTitleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.UpdateProjectTitleRequest
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := logic.NewUpdateProjectTitleLogic(r.Context(), svcCtx)
resp, err := l.UpdateProjectTitle(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp)
}
}
}
@@ -0,0 +1,79 @@
package handler
import (
"context"
"net/http"
"strings"
"img_infinite_canvas/internal/domain/design"
)
type bearerAuthenticator interface {
UserIDFromBearer(ctx context.Context, authorization string) (string, bool)
}
func UserContextMiddleware(authenticator bearerAuthenticator) func(http.HandlerFunc) http.HandlerFunc {
return func(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
userID := r.Header.Get("X-User-Id")
authenticated := false
if authenticator != nil {
if tokenUserID, ok := userIDFromRequestAuth(r.Context(), r, authenticator); ok {
userID = tokenUserID
authenticated = true
}
}
if requiresAuthenticatedUser(r) && !authenticated {
writeAuthRequired(w)
return
}
ctx := design.ContextWithUserID(r.Context(), userID)
next(w, r.WithContext(ctx))
}
}
}
func userIDFromRequestAuth(ctx context.Context, r *http.Request, authenticator bearerAuthenticator) (string, bool) {
if tokenUserID, ok := authenticator.UserIDFromBearer(ctx, r.Header.Get("Authorization")); ok {
return tokenUserID, true
}
if token := strings.TrimSpace(r.Header.Get("token")); token != "" {
if tokenUserID, ok := authenticator.UserIDFromBearer(ctx, "Bearer "+token); ok {
return tokenUserID, true
}
}
if cookie, err := r.Cookie("usertoken"); err == nil && strings.TrimSpace(cookie.Value) != "" {
if tokenUserID, ok := authenticator.UserIDFromBearer(ctx, "Bearer "+cookie.Value); ok {
return tokenUserID, true
}
}
return "", false
}
func requiresAuthenticatedUser(r *http.Request) bool {
path := r.URL.Path
if !strings.HasPrefix(path, "/api/") {
return false
}
if strings.HasPrefix(path, "/api/auth/") || path == "/api/auth/options" || path == "/api/health" || path == "/api/dashboard" {
return false
}
return strings.HasPrefix(path, "/api/projects") ||
strings.HasPrefix(path, "/api/account") ||
strings.HasPrefix(path, "/api/assets") ||
strings.HasPrefix(path, "/api/generator/")
}
func writeAuthRequired(w http.ResponseWriter) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusUnauthorized)
_, _ = w.Write([]byte(`{"error":"login required","errorCode":"auth.login_required","code":401}`))
}
func LegacyUserContextMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
userID := r.Header.Get("X-User-Id")
ctx := design.ContextWithUserID(r.Context(), userID)
next(w, r.WithContext(ctx))
}
}
+35
View File
@@ -0,0 +1,35 @@
// Code scaffolded by goctl. Safe to edit.
// goctl 1.10.1
package handler
import (
"net/http"
"img_infinite_canvas/internal/svc"
"github.com/zeromicro/go-zero/rest"
)
func RegisterV1Handlers(server *rest.Server, serverCtx *svc.ServiceContext) {
server.AddRoutes(
[]rest.Route{
{
Method: http.MethodPost,
Path: "/context/vision/recognize_object",
Handler: recognizeObjectHandler(serverCtx),
},
{
Method: http.MethodGet,
Path: "/generator/tasks",
Handler: getGeneratorTaskHandler(serverCtx),
},
{
Method: http.MethodPost,
Path: "/generator/tasks",
Handler: submitGeneratorTaskHandler(serverCtx),
},
},
rest.WithPrefix("/v1"),
)
}