Skip to content

feat: expand item types and improve API response handling #25

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
May 18, 2025
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
eb738b2
feat: expand item types and improve API response handling
cubxxw May 15, 2025
945e9d3
refactor: clean up exports and improve type definitions in client files
cubxxw May 15, 2025
24ec5dd
refactor: improve API response handling and type assertions in ItemsT…
cubxxw May 15, 2025
8597763
fix: enhance error handling and localization in dashboard and login c…
cubxxw May 15, 2025
db7a5f4
chore: update pnpm version and enhance error handling in components
cubxxw May 15, 2025
5b6d0ae
fix: update item description handling in DashboardPage component
cubxxw May 16, 2025
d1b77aa
chore: update environment configurations and enhance Google OAuth han…
cubxxw May 16, 2025
b19bebc
fix: enhance authentication flow and improve error handling in middle…
cubxxw May 16, 2025
30581cf
chore: add extension testing capabilities and update Makefile
cubxxw May 16, 2025
fcca09d
chore: update client generation workflow and enhance admin dependencies
cubxxw May 16, 2025
8632aa7
chore: remove deprecated files and update project structure
cubxxw May 16, 2025
c235c6d
chore: remove SECURITY.md and update popup components for better acce…
cubxxw May 16, 2025
292e23a
chore: update Jest configuration and enhance testing utilities
cubxxw May 16, 2025
8ed343e
chore: update Makefile and improve code formatting across components
cubxxw May 16, 2025
3e934dd
feat: enhance sidebar functionality and improve API interactions
cubxxw May 17, 2025
0aa50fa
feat: add diagnose functionality and enhance sidebar resources
cubxxw May 17, 2025
37d3779
feat: add resource links for independent developers in README_zh-CN
cubxxw May 17, 2025
e057865
fix: update favicon file types and replace icon assets
cubxxw May 17, 2025
15803ba
chore: update Makefile and enhance extension functionality
cubxxw May 17, 2025
904b9db
refactor: enhance extension build process and update documentation
cubxxw May 18, 2025
8184607
chore: update test setup and enhance database management
cubxxw May 18, 2025
326d986
feat: add social media integration and improve options page layout
cubxxw May 18, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Any operations involving issues and pulls on GitHub
globs:
alwaysApply: false
---
**Repository Resolution Logic:**
**Github Repository Resolution Logic:**

- If owner and repo are explicitly provided, use them.
- Otherwise, default to:
Expand All @@ -17,3 +17,7 @@ alwaysApply: false
- The language chosen for raising an issue: Chinese-
- Be careful not to be too AI in your tone.
- Pay attention to choosing the appropriate labels and types. And select the latest Milestone

**Postgres db operation Logic:**

- db name is `app`
4 changes: 1 addition & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ DOMAIN=localhost.nip.io
# Used by the backend to generate links (e.g., in emails).
# Example for local development: http://localhost:8000
# Example for production: https://dashboard.yourdomain.com
FRONTEND_HOST=http://localhost:8000
FRONTEND_HOST=http://localhost:3000

# -- Backend Settings --

Expand Down Expand Up @@ -220,5 +220,3 @@ OR_API_KEY="sk-or-api03-1234567890"
# Google OAuth client ID and secret for authentication
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_OAUTH_REDIRECT_URI=http://localhost:8000/api/v1/login/google/callback
FRONTEND_URL=http://localhost:3000
10 changes: 8 additions & 2 deletions .github/workflows/generate-client.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: 8
version: 9.9.0

- name: Setup Node.js
uses: actions/setup-node@v4
Expand All @@ -56,6 +56,10 @@ jobs:
- name: Install Frontend Dependencies
run: pnpm install
working-directory: frontend

- name: Install Admin Dependencies
run: pnpm install
working-directory: admin

# 安装所有后端依赖项
- name: Install Backend Dependencies
Expand Down Expand Up @@ -94,7 +98,9 @@ jobs:

# 6. Stage Generated Files
- name: Stage Generated Client Files
run: git add frontend/src/client # Adjust path if needed
run: |
git add frontend/app/openapi-client
git add admin/src/client

# 7. Handle Changes for Same-Repo Events (Push/PR from same repo)
- name: Commit and Push Changes (Same Repo)
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v3
with:
version: 8
version: 9.9.0
- uses: actions/setup-node@v4
with:
node-version: lts/*
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,5 @@ jobs:
run: |
echo "## 🚀 Release Summary" >> $GITHUB_STEP_SUMMARY
echo "Release draft created for version ${{ github.event.inputs.version }}." >> $GITHUB_STEP_SUMMARY
echo "Visit the [Releases section](https://github.com/vintasoftware/nextjs-fastapi-template/releases) to review and publish the release." >> $GITHUB_STEP_SUMMARY
echo "Visit the [Releases section](https://github.com/https://github.com/telepace/releases) to review and publish the release." >> $GITHUB_STEP_SUMMARY
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix the malformed GitHub URL in the release summary.

The GitHub URL contains a duplication of "https://github.com/" which will result in a broken link.

-          echo "Visit the [Releases section](https://github.com/https://github.com/telepace/releases) to review and publish the release." >> $GITHUB_STEP_SUMMARY
+          echo "Visit the [Releases section](https://github.com/telepace/releases) to review and publish the release." >> $GITHUB_STEP_SUMMARY
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo "Visit the [Releases section](https://github.com/https://github.com/telepace/releases) to review and publish the release." >> $GITHUB_STEP_SUMMARY
echo "Visit the [Releases section](https://github.com/telepace/releases) to review and publish the release." >> $GITHUB_STEP_SUMMARY
🤖 Prompt for AI Agents
In .github/workflows/release.yml at line 60, the GitHub URL in the release
summary is malformed due to a duplicated "https://github.com/". Remove the extra
"https://github.com/" so the URL correctly points to
"https://github.com/telepace/releases" to fix the broken link.

echo "Once the draft is published, another action will automatically be triggered to publish the packages." >> $GITHUB_STEP_SUMMARY
22 changes: 20 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ lint: backend-lint frontend-lint admin-lint

## test: Run tests for all components
.PHONY: test
test: backend-test frontend-test website-test admin-test
test: backend-test frontend-test website-test admin-test extension-test-unit
@echo "===========> All tests completed successfully"

## format: Format code in all components
.PHONY: format
Expand Down Expand Up @@ -397,7 +398,7 @@ website-test: website-install

## extension-all: Run all extension related tasks without starting services
.PHONY: extension-all
extension-all: extension-build extension-package
extension-all: extension-build extension-package extension-test
@echo "===========> Extension all checks completed successfully"

## extension: Start extension development
Expand All @@ -418,6 +419,23 @@ extension-package: check-pnpm
@echo "===========> Packaging browser extension for distribution"
@cd $(EXTENSION_DIR) && $(PNPM) run package

## extension-test: Run all extension tests
.PHONY: extension-test
extension-test: extension-test-unit extension-test-e2e
@echo "===========> All extension tests completed"

## extension-test-unit: Run extension unit tests with Jest
.PHONY: extension-test-unit
extension-test-unit: check-pnpm
@echo "===========> Running extension unit tests"
@cd $(EXTENSION_DIR) && $(PNPM) test

## extension-test-e2e: Run extension E2E tests with Playwright
.PHONY: extension-test-e2e
extension-test-e2e: check-pnpm
@echo "===========> Running extension E2E tests"
@cd $(EXTENSION_DIR) && $(PNPM) exec playwright test

# ==============================================================================
# DOCKER TARGETS
# ==============================================================================
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ This project provides optimized scripts and Makefile targets for common developm
### Frontend Development

- `make frontend-install` - Install frontend dependencies
- `make frontend-dev` - Run frontend development server
- `make frontend` - Run frontend development server
- `make frontend-build` - Build frontend for production
- `make frontend-test` - Run frontend tests
- `make frontend-lint` - Run linters on frontend code
Expand Down
2 changes: 0 additions & 2 deletions admin/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,3 @@ export { CancelablePromise, CancelError } from "./core/CancelablePromise"
export { OpenAPI, type OpenAPIConfig } from "./core/OpenAPI"
export * from "./sdk.gen"
export * from "./types.gen"
export { isApiResponse, extractApiResponseError } from "./utils"
export { type ItemPublic } from "./types"
19 changes: 4 additions & 15 deletions admin/src/client/sdk.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import type { CancelablePromise } from './core/CancelablePromise';
import { OpenAPI } from './core/OpenAPI';
import { request as __request } from './core/request';
import type { GoogleOauthGoogleCallbackApiData, GoogleOauthGoogleCallbackApiResponse, GoogleOauthGoogleLoginResponse, GoogleOauthGoogleCallbackData, GoogleOauthGoogleCallbackResponse, HealthGetHealthRootResponse, HealthGetHealthApiResponse, ItemsReadItemsData, ItemsReadItemsResponse, ItemsCreateItemData, ItemsCreateItemResponse, ItemsReadItemData, ItemsReadItemResponse, ItemsUpdateItemData, ItemsUpdateItemResponse, ItemsDeleteItemData, ItemsDeleteItemResponse, LoginLoginAccessTokenData, LoginLoginAccessTokenResponse, LoginTestTokenResponse, LoginLogoutResponse, LoginRecoverPasswordData, LoginRecoverPasswordResponse, LoginResetPasswordData, LoginResetPasswordResponse, LoginRecoverPasswordHtmlContentData, LoginRecoverPasswordHtmlContentResponse, PrivateCreateUserData, PrivateCreateUserResponse, UsersReadUsersData, UsersReadUsersResponse, UsersCreateUserData, UsersCreateUserResponse, UsersReadUserMeResponse, UsersDeleteUserMeResponse, UsersUpdateUserMeData, UsersUpdateUserMeResponse, UsersUpdatePasswordMeData, UsersUpdatePasswordMeResponse, UsersRegisterUserData, UsersRegisterUserResponse, UsersReadUserByIdData, UsersReadUserByIdResponse, UsersUpdateUserData, UsersUpdateUserResponse, UsersDeleteUserData, UsersDeleteUserResponse, UtilsTestEmailData, UtilsTestEmailResponse, UtilsHealthCheckResponse } from './types.gen';
import type { GoogleOauthGoogleCallbackApiData, GoogleOauthGoogleCallbackApiResponse, GoogleOauthGoogleLoginResponse, GoogleOauthGoogleCallbackData, GoogleOauthGoogleCallbackResponse, HealthGetHealthApiResponse, ItemsReadItemsData, ItemsReadItemsResponse, ItemsCreateItemData, ItemsCreateItemResponse, ItemsReadItemData, ItemsReadItemResponse, ItemsUpdateItemData, ItemsUpdateItemResponse, ItemsDeleteItemData, ItemsDeleteItemResponse, LoginLoginAccessTokenData, LoginLoginAccessTokenResponse, LoginTestTokenResponse, LoginLogoutResponse, LoginRecoverPasswordData, LoginRecoverPasswordResponse, LoginResetPasswordData, LoginResetPasswordResponse, LoginRecoverPasswordHtmlContentData, LoginRecoverPasswordHtmlContentResponse, PrivateCreateUserData, PrivateCreateUserResponse, UsersReadUsersData, UsersReadUsersResponse, UsersCreateUserData, UsersCreateUserResponse, UsersReadUserMeResponse, UsersDeleteUserMeResponse, UsersUpdateUserMeData, UsersUpdateUserMeResponse, UsersUpdatePasswordMeData, UsersUpdatePasswordMeResponse, UsersRegisterUserData, UsersRegisterUserResponse, UsersReadUserByIdData, UsersReadUserByIdResponse, UsersUpdateUserData, UsersUpdateUserResponse, UsersDeleteUserData, UsersDeleteUserResponse, UtilsTestEmailData, UtilsTestEmailResponse, UtilsHealthCheckResponse } from './types.gen';

export class GoogleOauthService {
/**
* Google Callback Api
* Handle Google OAuth callback from frontend
* This is maintained for backward compatibility but not used in the new flow
* @param data The data for the request.
* @param data.requestBody
* @returns unknown Successful Response
Expand All @@ -29,6 +30,7 @@ export class GoogleOauthService {
/**
* Google Login
* Initiate Google OAuth2 authentication flow
* This endpoint redirects to Google's login page
* @returns unknown Successful Response
* @throws ApiError
*/
Expand All @@ -42,6 +44,7 @@ export class GoogleOauthService {
/**
* Google Callback
* Handle the callback from Google OAuth
* This endpoint is called by Google after the user has logged in
* @param data The data for the request.
* @param data.code
* @param data.state
Expand All @@ -67,22 +70,8 @@ export class GoogleOauthService {
}

export class HealthService {
/**
* Get Health Root
* 兼容前端的根级别健康检查路由
* @returns unknown Successful Response
* @throws ApiError
*/
public static getHealthRoot(): CancelablePromise<HealthGetHealthRootResponse> {
return __request(OpenAPI, {
method: 'GET',
url: '/health'
});
}

/**
* Get Health Api
* 兼容前端的API级别健康检查路由
* @returns unknown Successful Response
* @throws ApiError
*/
Expand Down
2 changes: 0 additions & 2 deletions admin/src/client/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ export type GoogleOauthGoogleCallbackData = {

export type GoogleOauthGoogleCallbackResponse = (unknown);

export type HealthGetHealthRootResponse = (unknown);

export type HealthGetHealthApiResponse = (unknown);

export type ItemsReadItemsData = {
Expand Down
34 changes: 30 additions & 4 deletions admin/src/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,33 @@
* 项目的公共接口定义
*/
export interface ItemPublic {
id: string;
title: string;
description?: string | null;
}
id: string
title: string
description?: string | null
}

/**
* 项目集合的公共接口定义
*/
export interface ItemsPublic {
data: Array<ItemPublic>
count: number
}

/**
* 从API响应中提取Item数据的类型
*/
export type ItemResponse = {
data: ItemPublic
meta?: Record<string, unknown> | null
error?: string | null
}

/**
* 从API响应中提取Items集合数据的类型
*/
export type ItemsResponse = {
data: ItemsPublic
meta?: Record<string, unknown> | null
error?: string | null
}
32 changes: 16 additions & 16 deletions admin/src/client/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
* 检查一个值是否为API响应格式
*/
export const isApiResponse = (value: unknown): boolean => {
if (!value || typeof value !== 'object') {
if (!value || typeof value !== "object") {
return false
}

const obj = value as Record<string, unknown>
// 检查是否包含API响应格式的关键字段
return ('data' in obj || 'meta' in obj || 'error' in obj)
return "data" in obj || "meta" in obj || "error" in obj
}

/**
Expand All @@ -22,41 +22,41 @@ export const extractApiResponseError = (response: unknown): string | null => {
if (!isApiResponse(response)) {
return null
}

const apiResponse = response as Record<string, unknown>

// 直接返回error字段
if (typeof apiResponse.error === 'string') {
if (typeof apiResponse.error === "string") {
return apiResponse.error
}

// 尝试从meta中提取详细错误信息
if (apiResponse.meta && typeof apiResponse.meta === 'object') {
if (apiResponse.meta && typeof apiResponse.meta === "object") {
const meta = apiResponse.meta as Record<string, unknown>

// 检查meta中是否有details字段
if (meta.details) {
if (Array.isArray(meta.details) && meta.details.length > 0) {
const firstDetail = meta.details[0]
if (typeof firstDetail === 'object' && firstDetail !== null) {
if (typeof firstDetail === "object" && firstDetail !== null) {
// 尝试获取msg或message字段
const detailObj = firstDetail as Record<string, unknown>
if (typeof detailObj.msg === 'string') {
if (typeof detailObj.msg === "string") {
return detailObj.msg
}
if (typeof detailObj.message === 'string') {
if (typeof detailObj.message === "string") {
return detailObj.message
}
}
// 如果是字符串,直接返回
if (typeof firstDetail === 'string') {
if (typeof firstDetail === "string") {
return firstDetail
}
} else if (typeof meta.details === 'string') {
} else if (typeof meta.details === "string") {
return meta.details
}
}
}

return null
}
}
16 changes: 7 additions & 9 deletions admin/src/routes/_layout/items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,15 @@ function ItemsTable() {
})

// 安全地处理API响应
const apiData = apiResponse?.data || ({} as any)

const responseData = apiResponse?.data || {} as any
// 使用类型断言处理响应数据
const items: ItemPublic[] = Array.isArray(apiData.data)
? apiData.data
: Array.isArray(apiData)
? apiData
: []

const items: ItemPublic[] = Array.isArray(responseData.data)
? responseData.data
: []

// 使用类型断言处理计数
const count = typeof apiData.count === "number" ? apiData.count : items.length
const count = typeof responseData.count === "number" ? responseData.count : items.length

if (isLoading) {
return <PendingItems />
Expand Down
Loading
Loading