package main import ( "fmt" "log" "verification-platform-backend/internal/database" "verification-platform-backend/internal/model" "gorm.io/gorm/clause" ) func main() { database.Init() db := database.DB docTranslations := map[string]struct { TitleEn string ContentEn string SummaryEn string }{ "api-heartbeat": { TitleEn: "Heartbeat Verification", ContentEn: "# Heartbeat Verification\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/heartbeat\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| device_id | string | Yes | Device ID |\n\n### Request Example\n```json\n{\n \"device_id\": \"device_001\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"success\"\n}\n```\n\n### Notes\n- Keeps user online status\n- Recommended to call every 30 seconds\n- User will be considered offline if heartbeat is not called for a certain period\n- JWT token must be included in the request header", SummaryEn: "Heartbeat verification instructions", }, "api-recharge": { TitleEn: "Card Key Recharge", ContentEn: "# Card Key Recharge\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/recharge\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| username | string | Yes | User account |\n| card_key | string | Yes | Card key |\n\n### Request Example\n```json\n{\n \"username\": \"user123\",\n \"card_key\": \"VIP123456\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Recharge successful\",\n \"data\": {\n \"value\": 30\n }\n}\n```\n\n### Response Fields\n| Field | Type | Description |\n|--------|------|------|\n| value | number | Recharge value (meaning varies by card type) |\n\n### Error Response\n```json\n{\n \"code\": 400,\n \"message\": \"Invalid or expired card key\"\n}\n```", SummaryEn: "Card key recharge instructions", }, "api-devices": { TitleEn: "Get Bound Device List", ContentEn: "# Get Bound Device List\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/devices\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"devices\": [\n {\n \"device_id\": \"device_001\",\n \"device_name\": \"My Computer\",\n \"bind_time\": \"2024-03-04T12:00:00Z\",\n \"last_active\": \"2024-03-04T13:00:00Z\"\n }\n ]\n }\n}\n```\n\n### Response Fields\n| Field | Type | Description |\n|--------|------|------|\n| device_id | string | Device ID |\n| device_name | string | Device name |\n| bind_time | string | Bind time |\n| last_active | string | Last active time |", SummaryEn: "Get bound device list instructions", }, "api-unbind-device": { TitleEn: "Unbind Device", ContentEn: "# Unbind Device\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/unbind-device\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| device_id | string | Yes | Device ID |\n\n### Request Example\n```json\n{\n \"device_id\": \"device_001\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Unbind successful\"\n}\n```\n\n### Error Response\n```json\n{\n \"code\": 400,\n \"message\": \"Device not found or not bound\"\n}\n```", SummaryEn: "Unbind device instructions", }, "api-unbind-device-with-auth": { TitleEn: "Unbind Device with Authentication", ContentEn: "# Unbind Device with Authentication\n\nWhen users cannot login due to device limit, they can use this endpoint to unbind a device with username and password.\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/unbind-device-with-auth\n```\n\n### Note\nThis endpoint does not require Authorization header, uses username and password for authentication.\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| username | string | Yes | Username |\n| password | string | Yes | Password |\n| device_id | string | Yes | Device ID to unbind |\n\n### Request Example\n```json\n{\n \"username\": \"user123\",\n \"password\": \"password123\",\n \"device_id\": \"device_001\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"message\": \"Unbind successful\"\n }\n}\n```", SummaryEn: "Unbind device with authentication instructions", }, "api-reset-password": { TitleEn: "Reset Password (Email Verification)", ContentEn: "# Reset Password (Email Verification)\n\nWhen users forget their password, they can reset it via email verification code.\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/reset-password\n```\n\n### Note\nThis endpoint does not require Authorization header, must call send email verification code endpoint first.\n\n### Prerequisites\n- Application has password reset enabled\n- User's package supports password reset\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| email | string | Yes | Email address |\n| code | string | Yes | Email verification code |\n| password | string | Yes | New password (at least 6 characters) |\n\n### Request Example\n```json\n{\n \"email\": \"user@example.com\",\n \"code\": \"123456\",\n \"password\": \"newpassword123\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"message\": \"Password reset successful\"\n }\n}\n```", SummaryEn: "Reset password via email verification code", }, "api-change-password": { TitleEn: "Change Password", ContentEn: "# Change Password\n\nChange password by verifying username and original password.\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/change-password\n```\n\n### Note\nThis endpoint does not require Authorization header, uses username and original password for authentication.\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| username | string | Yes | Username |\n| old_password | string | Yes | Original password |\n| new_password | string | Yes | New password (at least 6 characters) |\n\n### Request Example\n```json\n{\n \"username\": \"user123\",\n \"old_password\": \"oldpassword123\",\n \"new_password\": \"newpassword123\"\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"message\": \"Password changed successfully\"\n }\n}\n```", SummaryEn: "Change password", }, "api-device-count": { TitleEn: "Get Device Count", ContentEn: "# Get Device Count\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/device-count\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"count\": 3,\n \"max_devices\": 5\n }\n}\n```\n\n### Response Fields\n| Field | Type | Description |\n|--------|------|------|\n| count | number | Current bound device count |\n| max_devices | number | Maximum allowed devices |", SummaryEn: "Get device count instructions", }, "api-app-info": { TitleEn: "Get Application Info", ContentEn: "# Get Application Info\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/info\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"app_id\": 1,\n \"name\": \"My App\",\n \"description\": \"Game verification app\",\n \"status\": \"active\"\n }\n}\n```\n\n### Response Fields\n| Field | Type | Description |\n|--------|------|------|\n| app_id | number | Application ID |\n| name | string | Application name |\n| description | string | Application description |\n| status | string | Application status |", SummaryEn: "Get application info instructions", }, "api-account": { TitleEn: "Get User Account Info", ContentEn: "# Get User Account Info\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/account\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"user_id\": 123,\n \"username\": \"user123\",\n \"expire_time\": \"2024-04-04T00:00:00Z\",\n \"remaining_days\": 30\n }\n}\n```\n\n### Response Fields\n| Field | Type | Description |\n|--------|------|------|\n| user_id | number | User ID |\n| username | string | Username |\n| expire_time | string | Expiration time |\n| remaining_days | number | Remaining days |", SummaryEn: "Get user account info instructions", }, "api-constants": { TitleEn: "Get Application Constants", ContentEn: "# Get Application Constants\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/constants\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Constant Name\",\n \"key\": \"CONSTANT_KEY\",\n \"value\": \"Constant Value\",\n \"var_type\": \"string\",\n \"description\": \"Constant description\"\n }\n ]\n}\n```", SummaryEn: "Get application constants instructions", }, "api-constant": { TitleEn: "Get Specific Constant", ContentEn: "# Get Specific Constant\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/constants/:key\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Path Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| key | string | Yes | Constant key |\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"id\": 1,\n \"name\": \"Constant Name\",\n \"key\": \"CONSTANT_KEY\",\n \"value\": \"Constant Value\",\n \"var_type\": \"string\",\n \"description\": \"Constant description\"\n }\n}\n```", SummaryEn: "Get specific constant instructions", }, "api-variables": { TitleEn: "Get Application Variables", ContentEn: "# Get Application Variables\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/variables\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": [\n {\n \"id\": 1,\n \"name\": \"Variable Name\",\n \"key\": \"VARIABLE_KEY\",\n \"default_value\": \"Default Value\",\n \"var_type\": \"string\",\n \"scope\": \"user\",\n \"description\": \"Variable description\"\n }\n ]\n}\n```", SummaryEn: "Get application variables instructions", }, "api-variable": { TitleEn: "Get Specific Variable", ContentEn: "# Get Specific Variable\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/variables/:key\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Path Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| key | string | Yes | Variable key |\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"id\": 1,\n \"name\": \"Variable Name\",\n \"key\": \"VARIABLE_KEY\",\n \"default_value\": \"Default Value\",\n \"var_type\": \"string\",\n \"scope\": \"user\",\n \"description\": \"Variable description\"\n }\n}\n```", SummaryEn: "Get specific variable instructions", }, "api-update-variables": { TitleEn: "Update User Variables", ContentEn: "# Update User Variables\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/variables\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| variables | object | Yes | Variable key-value pairs |\n\n### Request Example\n```json\n{\n \"variables\": {\n \"nickname\": \"New Nickname\",\n \"level\": 10\n }\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Update successful\"\n}\n```\n\n### Notes\n- Only user-scoped variables can be updated\n- Variable value types must match the defined types", SummaryEn: "Update user variables instructions", }, "api-call-function": { TitleEn: "Call Cloud Function", ContentEn: "# Call Cloud Function\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/call-function\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| function_name | string | Yes | Cloud function name |\n| params | object | No | Parameters to pass to the function |\n\n### Request Example\n```json\n{\n \"function_name\": \"calculatePrice\",\n \"params\": {\n \"x\": 10,\n \"y\": 20\n }\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Success\",\n \"data\": {\n \"result\": 30,\n \"execution_time\": 0.001234\n }\n}\n```", SummaryEn: "Call cloud function instructions", }, "api-check-update": { TitleEn: "Check for Updates", ContentEn: "# Check for Updates\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/check-update\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| version | string | No | Current client version |\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": {\n \"has_update\": true,\n \"latest_version\": \"2.0.0\",\n \"download_url\": \"https://example.com/download/v2.0.0\",\n \"update_notes\": \"Fixed several bugs\",\n \"update_strategy\": \"optional\",\n \"update_method\": \"manual\"\n }\n}\n```", SummaryEn: "Check for updates instructions", }, "api-announcements": { TitleEn: "Get Announcements", ContentEn: "# Get Announcements\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/announcements\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": [\n {\n \"id\": 1,\n \"title\": \"System Maintenance Notice\",\n \"content\": \"System will be under maintenance tonight...\",\n \"created_at\": \"2024-03-04T10:00:00Z\"\n }\n ]\n}\n```", SummaryEn: "Get announcements instructions", }, "api-instances": { TitleEn: "Get Online Instance List", ContentEn: "# Get Online Instance List\n\n### Endpoint\n```\nGET /api/v1/app/:appKey/instances\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| user_id | number | Yes | User ID |\n\n### Request Example\n```json\n{\n \"user_id\": 123\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"data\": [\n {\n \"id\": 1,\n \"instance_id\": \"instance_001\",\n \"device_id\": \"device_001\",\n \"device_name\": \"My Computer\",\n \"is_online\": true,\n \"last_heartbeat\": \"2024-03-04T13:00:00Z\",\n \"created_at\": \"2024-03-04T12:00:00Z\"\n }\n ]\n}\n```", SummaryEn: "Get online instance list instructions", }, "api-force-offline": { TitleEn: "Force Instance Offline", ContentEn: "# Force Instance Offline\n\n### Endpoint\n```\nPOST /api/v1/app/:appKey/instances/:instance_id/offline\n```\n\n### Request Header\n```\nAuthorization: Bearer {token}\n```\n\n### Path Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| instance_id | string | Yes | Instance identifier |\n\n### Request Parameters\n| Parameter | Type | Required | Description |\n|--------|------|------|------|\n| user_id | number | Yes | User ID |\n\n### Request Example\n```json\n{\n \"user_id\": 123\n}\n```\n\n### Response Example\n```json\n{\n \"code\": 200,\n \"message\": \"Forced offline successfully\"\n}\n```", SummaryEn: "Force instance offline instructions", }, "example-software": { TitleEn: "Software Verification Example", ContentEn: "# Software Verification Example\n\n## Complete Verification Flow\n\n### 1. User Input Username and Password\n\n```javascript\nconst username = document.getElementById('username').value;\nconst password = document.getElementById('password').value;\n```\n\n### 2. Get Device ID\n\n```javascript\nfunction getDeviceId() {\n let deviceId = localStorage.getItem('device_id');\n if (!deviceId) {\n deviceId = 'device_' + Math.random().toString(36).substr(2, 9);\n localStorage.setItem('device_id', deviceId);\n }\n return deviceId;\n}\n\nconst deviceId = getDeviceId();\n```\n\n### 3. Call Login API\n\n```javascript\nconst response = await fetch(`/api/v1/app/${appKey}/login`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n username,\n password,\n device_id: deviceId\n })\n});\n\nconst result = await response.json();\n\nif (result.code !== 200) {\n alert('Login failed: ' + result.message);\n return;\n}\n```\n\n### 4. Save Token\n\n```javascript\nlocalStorage.setItem('token', result.data.token);\nlocalStorage.setItem('expire_time', result.data.expire_time);\n```\n\n### 5. Start Heartbeat\n\n```javascript\nsetInterval(async () => {\n await fetch(`/api/v1/app/${appKey}/heartbeat`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${localStorage.getItem('token')}`\n },\n body: JSON.stringify({\n device_id: deviceId\n })\n });\n}, 30000);\n```\n\n### 6. Enter Main Program\n\n```javascript\nstartApplication();\n```", SummaryEn: "Complete software login verification example", }, "example-game": { TitleEn: "Game Verification Example", ContentEn: "# Game Verification Example\n\n## Unity Integration\n\n### 1. Call Login API\n\n```csharp\nusing UnityEngine;\nusing UnityEngine.Networking;\n\npublic class AuthManager : MonoBehaviour {\n private string appKey = \"your_app_key\";\n private string token;\n private string deviceId;\n \n void Start() {\n deviceId = SystemInfo.deviceUniqueIdentifier;\n }\n \n public async void Login(string username, string password) {\n string url = $\"https://api.example.com/api/v1/app/{appKey}/login\";\n \n string jsonData = $\"{{\\\"username\\\": \\\"{username}\\\", \\\"password\\\": \\\"{password}\\\", \\\"device_id\\\": \\\"{deviceId}\\\"}}\";\n \n using (UnityWebRequest request = UnityWebRequest.Post(url, jsonData)) {\n request.SetRequestHeader(\"Content-Type\", \"application/json\");\n \n yield return request.SendWebRequest();\n \n if (request.result == UnityWebRequest.Result.Success) {\n string response = request.downloadHandler.text;\n var result = JsonUtility.FromJson(response);\n \n if (result.code == 200) {\n token = result.data.token;\n PlayerPrefs.SetString(\"token\", token);\n \n // Start heartbeat\n StartCoroutine(HeartbeatCoroutine());\n \n // Enter game\n LoadMainScene();\n } else {\n Debug.LogError(\"Login failed: \" + result.message);\n }\n } else {\n Debug.LogError(\"Request failed: \" + request.error);\n }\n }\n }\n}\n```", SummaryEn: "Unity game integration example", }, "faq-api-key": { TitleEn: "How to Get API Key?", ContentEn: "# How to Get API Key?\n\n## Steps\n\n1. Login to admin dashboard\n2. Go to \"Application Management\" page\n3. Create new application or select existing one\n4. In application details page you can see:\n - **AppID**: Application unique identifier\n - **AppKey**: Application key\n - **SecretKey**: Encryption key\n\n## Notes\n\n- AppKey is only shown once when created, please save it in time\n- Click \"Reset Key\" button to reset AppKey if needed\n- Old key becomes invalid immediately after reset\n- SecretKey is for server-side response verification, do not use it on client side", SummaryEn: "Detailed steps to get API key", }, "faq-card-fail": { TitleEn: "What to Do if Card Key Verification Fails?", ContentEn: "# What to Do if Card Key Verification Fails?\n\n## Common Reasons\n\n1. **Card Key Expired**\n - Check the validity period of the card key\n - Expired card keys cannot be used\n\n2. **Card Key Already Used**\n - Single-use card keys can only be verified once\n - Used card keys cannot be verified again\n\n3. **Device Binding Error**\n - Check if device ID is correct\n - Confirm if application has device binding enabled\n\n4. **Application Configuration Error**\n - Check if AppID and AppKey are correct\n - Confirm if application status is normal\n\n## Solutions\n\n1. Contact application customer service\n2. Get a new card key\n3. Check device network connection\n4. View application logs for detailed error information", SummaryEn: "Common reasons and solutions for card key verification failure", }, "faq-agent": { TitleEn: "How to Implement Agent Authorization?", ContentEn: "# How to Implement Agent Authorization?\n\n## What is Agent Authorization?\n\nAgent authorization allows admins to authorize their applications to other admins, who can then generate card keys and sell them.\n\n## Authorization Process\n\n1. **Apply for Authorization**\n - Authorized party submits application to authorizer\n - Enter application ID\n - Wait for authorizer approval\n\n2. **Approve Authorization**\n - Authorizer views application\n - Set card key type permissions after approval\n - Set agent discount\n\n3. **Generate Card Keys**\n - Authorized party selects authorized application\n - Select card key types with permission\n - Generate and sell card keys\n\n4. **Settle Revenue**\n - Sales revenue is settled proportionally\n - Authorized party receives income\n\n## Permission Management\n\n- Authorizer can modify card key type permissions at any time\n- Can pause or terminate authorization\n- Can view agent's sales data", SummaryEn: "Implementation process and permission management for agent authorization", }, } var categories []model.DocCategory if err := db.Find(&categories).Error; err != nil { log.Fatal("Failed to get categories:", err) } for i := range categories { translation, ok := docTranslations[categories[i].Slug] if ok { categories[i].NameEn = translation.TitleEn categories[i].DescriptionEn = translation.ContentEn db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "id"}}, DoUpdates: clause.AssignmentColumns([]string{"name_en", "description_en"}), }).Create(&categories[i]) fmt.Printf("Updated category: %s -> %s\n", categories[i].Name, categories[i].NameEn) } } var docs []model.Doc if err := db.Find(&docs).Error; err != nil { log.Fatal("Failed to get docs:", err) } for i := range docs { translation, ok := docTranslations[docs[i].Slug] if ok { docs[i].TitleEn = translation.TitleEn docs[i].ContentEn = translation.ContentEn docs[i].SummaryEn = translation.SummaryEn db.Clauses(clause.OnConflict{ Columns: []clause.Column{{Name: "id"}}, DoUpdates: clause.AssignmentColumns([]string{"title_en", "content_en", "summary_en"}), }).Create(&docs[i]) fmt.Printf("Updated doc: %s -> %s\n", docs[i].Title, docs[i].TitleEn) } } fmt.Println("\nDocument translations updated successfully!") }