Skip to content
Open
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
16 changes: 16 additions & 0 deletions server/api/app/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
SPDX-License-Identifier: MIT
*/

package app

import (
"context"

"stackChan/api/app/v1"
)

type IAppV1 interface {
GetAppList(ctx context.Context, req *v1.GetAppListReq) (res *v1.GetAppListRes, err error)
}
23 changes: 23 additions & 0 deletions server/api/app/v1/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
SPDX-License-Identifier: MIT
*/

package v1

import (
"github.com/gogf/gf/v2/frame/g"
)

type GetAppListReq struct {
g.Meta `path:"/apps" method:"get" tags:"App" summary:"List installable apps offered by the App Center"`
}

type AppInfo struct {
AppName string `json:"appName" dc:"App display name"`
IconUrl string `json:"iconUrl" dc:"Icon URL"`
Description string `json:"description" dc:"Short description"`
FirmwareUrl string `json:"firmwareUrl" dc:"OTA firmware URL for installation"`
}

type GetAppListRes []AppInfo
2 changes: 2 additions & 0 deletions server/api/device/device.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 15 additions & 1 deletion server/api/device/v1/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type GetRandomDeviceRes []entity.Device

type GetDeviceInfoReq struct {
g.Meta `path:"/device/info" method:"get" tags:"Device" summary:"Device Info Get request"`
Mac string `json:"mac" v:"required" description:"Mac address"`
Mac string `json:"mac" description:"Mac address. Optional: when empty, returns an empty device info placeholder so authenticated firmware calls that do not carry a mac still receive a well-formed response."`
}

type GetDeviceInfoRes model.DeviceInfo
Expand All @@ -51,3 +51,17 @@ type UpdateDeviceInfoReq struct {
}

type UpdateDeviceInfoRes string

type GetUserAccountInfoReq struct {
g.Meta `path:"/device/user" method:"get" tags:"Device" summary:"Get the user account bound to the authenticated device"`
}

type GetUserAccountInfoRes struct {
Username string `json:"username" dc:"Username bound to the device"`
}

type UnbindAccountReq struct {
g.Meta `path:"/device/unbind" method:"post" tags:"Device" summary:"Unbind the authenticated device from its user account"`
}

type UnbindAccountRes struct{}
3 changes: 2 additions & 1 deletion server/internal/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net"
"net/http"
"path/filepath"
"stackChan/internal/controller/app"
"stackChan/internal/controller/dance"
"stackChan/internal/controller/device"
"stackChan/internal/controller/file"
Expand Down Expand Up @@ -67,7 +68,7 @@ var (

s.Group("/stackChan", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Bind(device.NewV1(), friend.NewV1(), dance.NewV1(), file.NewV1(), post.NewV1())
group.Bind(device.NewV1(), friend.NewV1(), dance.NewV1(), file.NewV1(), post.NewV1(), app.NewV1())
})
s.Run()
return nil
Expand Down
10 changes: 10 additions & 0 deletions server/internal/controller/app/app.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
SPDX-License-Identifier: MIT
*/

// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================

package app
20 changes: 20 additions & 0 deletions server/internal/controller/app/app_new.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
SPDX-License-Identifier: MIT
*/

// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================

package app

import (
"stackChan/api/app"
)

type ControllerV1 struct{}

func NewV1() app.IAppV1 {
return &ControllerV1{}
}
24 changes: 24 additions & 0 deletions server/internal/controller/app/app_v1_get_app_list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
SPDX-License-Identifier: MIT
*/

package app

import (
"context"

"stackChan/api/app/v1"
)

// GetAppList returns the list of apps offered by the App Center. The
// firmware consumes this list in firmware/main/hal/hal_app_center.cpp to
// populate the Mooncake AppCenter UI and to trigger OTA downloads.
//
// This minimal implementation returns an empty list so self-hosted
// deployments start with a clean slate. Production deployments are
// expected to replace the body with a DB-backed catalogue.
func (c *ControllerV1) GetAppList(ctx context.Context, req *v1.GetAppListReq) (res *v1.GetAppListRes, err error) {
empty := v1.GetAppListRes{}
return &empty, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import (
)

func (c *ControllerV1) GetDeviceInfo(ctx context.Context, req *v1.GetDeviceInfoReq) (res *v1.GetDeviceInfoRes, err error) {
if req.Mac == "" {
return (*v1.GetDeviceInfoRes)(&model.DeviceInfo{}), nil
}
var info model.DeviceInfo
err = dao.Device.Ctx(ctx).WherePri(req.Mac).Scan(&info)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
SPDX-License-Identifier: MIT
*/

package device

import (
"context"

"stackChan/api/device/v1"
)

// GetUserAccountInfo returns the username bound to the authenticated device.
// The firmware calls this endpoint right after boot to sync the account
// label displayed in the setup app (see firmware/main/hal/hal_account.cpp).
//
// This minimal implementation returns a default placeholder so that
// self-hosted deployments work out of the box. Production deployments are
// expected to extend this handler with a real account lookup based on the
// Authorization header token.
func (c *ControllerV1) GetUserAccountInfo(ctx context.Context, req *v1.GetUserAccountInfoReq) (res *v1.GetUserAccountInfoRes, err error) {
return &v1.GetUserAccountInfoRes{Username: "Self-hosted User"}, nil
}
23 changes: 23 additions & 0 deletions server/internal/controller/device/device_v1_unbind_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
SPDX-License-Identifier: MIT
*/

package device

import (
"context"

"stackChan/api/device/v1"
)

// UnbindAccount removes the binding between the authenticated device and
// its user account. The firmware calls this endpoint when the user triggers
// "Unbind" from the setup app (see firmware/main/hal/hal_account.cpp).
//
// This minimal implementation is a no-op so the firmware flow completes
// successfully. Production deployments are expected to delete the real
// account binding identified by the Authorization header token.
func (c *ControllerV1) UnbindAccount(ctx context.Context, req *v1.UnbindAccountReq) (res *v1.UnbindAccountRes, err error) {
return &v1.UnbindAccountRes{}, nil
}