fix(backend): JWT config mapstructure tag 修复 + 模型从 hotel 重构为 shop

- 修复 JWTConfig 缺少 mapstructure tag 导致 access_expire_min 解析为 0,
  token 签发即过期,所有 API 请求返回 401
- 全部 config struct 补齐 mapstructure tag(secret/dsn/hmac_secret 等)
- 模型层从 hotel/HotelID 统一重命名为 shop/ShopID
- 删除旧 migrations(001-004),新增 001_init 综合迁移文件
- 更新 schema.sql、testutil、handler/service/model 相关引用

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-04-07 22:20:12 +08:00
parent 37112d6599
commit 31ea370cea
50 changed files with 2675 additions and 951 deletions
+21 -21
View File
@@ -13,12 +13,12 @@ import (
func TestLicenseService_Activate_Success(t *testing.T) {
db := testutil.SetupTestDB()
hotel := testutil.CreateTestHotel(db, "LIC001")
shop := testutil.CreateTestShop(db, "LIC001")
// 创建许可证
expiry := time.Now().Add(30 * 24 * time.Hour)
lic := &model.License{
HotelID: hotel.ID,
ShopID: shop.ID,
LicenseKey: "AAAAA-BBBBB-CCCCC-DDDDD",
IsActive: true,
ExpiresAt: &expiry,
@@ -36,10 +36,10 @@ func TestLicenseService_Activate_Success(t *testing.T) {
func TestLicenseService_Activate_AlreadyBoundToDifferentDevice(t *testing.T) {
db := testutil.SetupTestDB()
hotel := testutil.CreateTestHotel(db, "LIC002")
shop := testutil.CreateTestShop(db, "LIC002")
lic := &model.License{
HotelID: hotel.ID,
ShopID: shop.ID,
LicenseKey: "EEEEE-FFFFF-GGGGG-HHHHH",
DeviceID: "existing-device",
IsActive: true,
@@ -56,10 +56,10 @@ func TestLicenseService_Activate_AlreadyBoundToDifferentDevice(t *testing.T) {
func TestLicenseService_Activate_SameDevice(t *testing.T) {
db := testutil.SetupTestDB()
hotel := testutil.CreateTestHotel(db, "LIC003")
shop := testutil.CreateTestShop(db, "LIC003")
lic := &model.License{
HotelID: hotel.ID,
ShopID: shop.ID,
LicenseKey: "IIIII-JJJJJ-KKKKK-LLLLL",
DeviceID: "same-device",
IsActive: true,
@@ -88,11 +88,11 @@ func TestLicenseService_Activate_NotFound(t *testing.T) {
func TestLicenseService_Activate_Inactive(t *testing.T) {
db := testutil.SetupTestDB()
hotel := testutil.CreateTestHotel(db, "LIC004")
shop := testutil.CreateTestShop(db, "LIC004")
// 先创建激活的许可证,再禁用(避免 GORM 零值跳过问题)
lic := &model.License{
HotelID: hotel.ID,
ShopID: shop.ID,
LicenseKey: "MMMMM-NNNNN-OOOOO-PPPPP",
IsActive: true,
}
@@ -110,12 +110,12 @@ func TestLicenseService_Activate_Inactive(t *testing.T) {
func TestLicenseService_Activate_Expired(t *testing.T) {
db := testutil.SetupTestDB()
hotel := testutil.CreateTestHotel(db, "LIC005")
shop := testutil.CreateTestShop(db, "LIC005")
// 已过期
expiry := time.Now().Add(-24 * time.Hour)
lic := &model.License{
HotelID: hotel.ID,
ShopID: shop.ID,
LicenseKey: "QQQQQ-RRRRR-SSSSS-TTTTT",
IsActive: true,
ExpiresAt: &expiry,
@@ -132,11 +132,11 @@ func TestLicenseService_Activate_Expired(t *testing.T) {
func TestLicenseService_Verify_Success(t *testing.T) {
db := testutil.SetupTestDB()
hotel := testutil.CreateTestHotel(db, "LIC006")
shop := testutil.CreateTestShop(db, "LIC006")
expiry := time.Now().Add(30 * 24 * time.Hour)
lic := &model.License{
HotelID: hotel.ID,
ShopID: shop.ID,
LicenseKey: "UUUUU-VVVVV-WWWWW-XXXXX",
DeviceID: "my-device",
IsActive: true,
@@ -145,7 +145,7 @@ func TestLicenseService_Verify_Success(t *testing.T) {
require.NoError(t, db.Create(lic).Error)
svc := NewLicenseService(db)
result, err := svc.Verify(hotel.ID, "my-device")
result, err := svc.Verify(shop.ID, "my-device")
require.NoError(t, err)
require.NotNil(t, result)
@@ -154,12 +154,12 @@ func TestLicenseService_Verify_Success(t *testing.T) {
func TestLicenseService_Verify_Expired(t *testing.T) {
db := testutil.SetupTestDB()
hotel := testutil.CreateTestHotel(db, "LIC007")
shop := testutil.CreateTestShop(db, "LIC007")
// 已过期
expiry := time.Now().Add(-1 * time.Hour)
lic := &model.License{
HotelID: hotel.ID,
ShopID: shop.ID,
LicenseKey: "YYYYY-ZZZZZ-AAAAA-BBBBB",
DeviceID: "expired-device",
IsActive: true,
@@ -168,7 +168,7 @@ func TestLicenseService_Verify_Expired(t *testing.T) {
require.NoError(t, db.Create(lic).Error)
svc := NewLicenseService(db)
result, err := svc.Verify(hotel.ID, "expired-device")
result, err := svc.Verify(shop.ID, "expired-device")
assert.Error(t, err)
assert.Equal(t, ErrLicenseExpired, err)
@@ -177,10 +177,10 @@ func TestLicenseService_Verify_Expired(t *testing.T) {
func TestLicenseService_Verify_NotFound(t *testing.T) {
db := testutil.SetupTestDB()
hotel := testutil.CreateTestHotel(db, "LIC008")
shop := testutil.CreateTestShop(db, "LIC008")
svc := NewLicenseService(db)
result, err := svc.Verify(hotel.ID, "nonexistent-device")
result, err := svc.Verify(shop.ID, "nonexistent-device")
assert.Error(t, err)
assert.Equal(t, ErrLicenseNotFound, err)
@@ -189,11 +189,11 @@ func TestLicenseService_Verify_NotFound(t *testing.T) {
func TestLicenseService_Verify_NoExpiry(t *testing.T) {
db := testutil.SetupTestDB()
hotel := testutil.CreateTestHotel(db, "LIC009")
shop := testutil.CreateTestShop(db, "LIC009")
// 永久许可证(无过期时间)
lic := &model.License{
HotelID: hotel.ID,
ShopID: shop.ID,
LicenseKey: "CCCCC-DDDDD-EEEEE-FFFFF",
DeviceID: "lifetime-device",
IsActive: true,
@@ -202,7 +202,7 @@ func TestLicenseService_Verify_NoExpiry(t *testing.T) {
require.NoError(t, db.Create(lic).Error)
svc := NewLicenseService(db)
result, err := svc.Verify(hotel.ID, "lifetime-device")
result, err := svc.Verify(shop.ID, "lifetime-device")
require.NoError(t, err)
require.NotNil(t, result)