Files
root 44406b72db 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>
2026-07-07 23:15:37 +08:00

101 lines
2.7 KiB
Go

package logic
import (
authmodule "img_infinite_canvas/internal/modules/auth"
"img_infinite_canvas/internal/types"
)
func toAPIAuthOptions(options authmodule.Options) *types.AuthOptionsResponse {
methods := make([]types.AuthMethod, 0, len(options.Methods))
for _, method := range options.Methods {
methods = append(methods, types.AuthMethod{
Id: method.ID,
Label: method.Label,
Provider: method.Provider,
})
}
return &types.AuthOptionsResponse{
Region: options.Region,
Methods: methods,
Turnstile: types.AuthTurnstileOptions{
Enabled: options.Turnstile.Enabled,
SiteKey: options.Turnstile.SiteKey,
},
}
}
func toAPIAuthCode(result authmodule.CodeResult) *types.AuthCodeResponse {
var email *types.AuthEmailMessage
if result.Email != nil {
email = &types.AuthEmailMessage{
FromName: result.Email.FromName,
FromEmail: result.Email.FromEmail,
ToEmail: result.Email.ToEmail,
Subject: result.Email.Subject,
Code: result.Email.Code,
Text: result.Email.Text,
Html: result.Email.HTML,
}
}
return &types.AuthCodeResponse{
Target: result.Target,
ExpiresIn: result.ExpiresIn,
DevCode: result.DevCode,
Email: email,
}
}
func toAPIAuthSession(session authmodule.Session) *types.AuthSessionResponse {
status := session.Status
if status == "" {
status = authmodule.SessionStatusAuthenticated
}
return &types.AuthSessionResponse{
Status: status,
User: types.AuthUser{
Id: session.User.ID,
Region: session.User.Region,
Phone: session.User.Phone,
CountryCode: session.User.CountryCode,
Email: session.User.Email,
Name: session.User.Name,
AvatarUrl: session.User.AvatarURL,
},
AccessToken: session.AccessToken,
ExpiresIn: session.ExpiresIn,
RefreshToken: session.RefreshToken,
RefreshExpiresIn: session.RefreshExpiresIn,
BindingToken: session.BindingToken,
BindingExpiresIn: session.BindingExpiresIn,
}
}
func toAPIAuthUser(user authmodule.User) types.AuthUser {
return types.AuthUser{
Id: user.ID,
Region: user.Region,
Phone: user.Phone,
CountryCode: user.CountryCode,
Email: user.Email,
Name: user.Name,
AvatarUrl: user.AvatarURL,
}
}
func toAPIAccountDevices(devices []authmodule.Device) []types.AccountDevice {
items := make([]types.AccountDevice, 0, len(devices))
for _, device := range devices {
items = append(items, types.AccountDevice{
Id: device.ID,
Online: device.Online,
Current: device.Current,
DeviceType: device.DeviceType,
System: device.System,
Browser: device.Browser,
Client: device.Client,
LastSeenAt: device.LastSeenAt.UTC().Format("2006-01-02 15:04(UTC)"),
})
}
return items
}