|
|
@ -4,8 +4,9 @@ Guidelines for agentic coding agents working on this repository. |
|
|
|
|
|
|
|
|
## Project Overview |
|
|
## Project Overview |
|
|
|
|
|
|
|
|
- **Backend**: ASP.NET Core 8.0 Web API (C#) |
|
|
- **Backend**: ASP.NET Core 8.0 Web API (C#) with PostgreSQL and SqlSugar ORM |
|
|
- **Frontend**: Vue 3 + TypeScript + Vite + Element Plus |
|
|
- **Admin Frontend**: Vue 3 + TypeScript + Vite + Element Plus (port 5173) |
|
|
|
|
|
- **Game Frontend**: Vue 3 + TypeScript + Vite + Element Plus + TailwindCSS + Three.js (port 5174) |
|
|
|
|
|
|
|
|
--- |
|
|
--- |
|
|
|
|
|
|
|
|
@ -14,16 +15,19 @@ Guidelines for agentic coding agents working on this repository. |
|
|
### Backend (.NET API) |
|
|
### Backend (.NET API) |
|
|
|
|
|
|
|
|
```bash |
|
|
```bash |
|
|
# Build the solution (from Build_God_Api directory) |
|
|
# Build the solution |
|
|
dotnet build Build_God_Api/Build_God_Api.csproj |
|
|
dotnet build Build_God_Api/Build_God_Api/Build_God_Api.csproj |
|
|
|
|
|
|
|
|
# Run the API |
|
|
# Run the API (launches on https://localhost:59447, http://localhost:59448) |
|
|
dotnet run --project Build_God_Api/Build_God_Api.csproj |
|
|
dotnet run --project Build_God_Api/Build_God_Api/Build_God_Api.csproj |
|
|
|
|
|
|
|
|
|
|
|
# Run with specific URL |
|
|
|
|
|
dotnet run --urls "http://localhost:5091" |
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
**Note**: No test framework or linting is currently configured for the backend. |
|
|
**Note**: No test framework or linting is currently configured for the backend. |
|
|
|
|
|
|
|
|
### Frontend (Vue 3) |
|
|
### Admin Frontend (Build_God_Admin_Frontend/Frontend) |
|
|
|
|
|
|
|
|
```bash |
|
|
```bash |
|
|
# Install dependencies |
|
|
# Install dependencies |
|
|
@ -42,7 +46,23 @@ npm run type-check |
|
|
npm run preview |
|
|
npm run preview |
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
**Note**: No test framework or ESLint is currently configured for the frontend. |
|
|
### Game Frontend (Build_God_Game) |
|
|
|
|
|
|
|
|
|
|
|
```bash |
|
|
|
|
|
# Install dependencies |
|
|
|
|
|
npm install |
|
|
|
|
|
|
|
|
|
|
|
# Start development server (http://localhost:5174) |
|
|
|
|
|
npm run dev |
|
|
|
|
|
|
|
|
|
|
|
# Build for production |
|
|
|
|
|
npm run build |
|
|
|
|
|
|
|
|
|
|
|
# Type-check only |
|
|
|
|
|
vue-tsc --build |
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
**Note**: No test framework or ESLint is configured for either frontend. |
|
|
|
|
|
|
|
|
--- |
|
|
--- |
|
|
|
|
|
|
|
|
@ -52,36 +72,43 @@ npm run preview |
|
|
|
|
|
|
|
|
#### Conventions |
|
|
#### Conventions |
|
|
- Use **file-scoped namespaces** (`namespace Build_God_Api.Controllers;`) |
|
|
- Use **file-scoped namespaces** (`namespace Build_God_Api.Controllers;`) |
|
|
- Enable **nullable reference types** |
|
|
- Enable **nullable reference types** (`<Nullable>enable</Nullable>`) |
|
|
- Use **primary constructors** for dependency injection |
|
|
- Use **primary constructors** for dependency injection |
|
|
- Use **async/await** for all I/O operations |
|
|
- Use **async/await** for all I/O operations |
|
|
|
|
|
- Use **region** sparingly - prefer natural code organization |
|
|
|
|
|
|
|
|
#### Naming |
|
|
#### Naming |
|
|
- **Classes/Types**: PascalCase (`AccountController`, `AccountService`) |
|
|
- **Classes/Types**: PascalCase (`AccountController`, `AccountService`) |
|
|
- **Methods/Properties**: PascalCase (`GetAccount`, `UserName`) |
|
|
- **Methods/Properties**: PascalCase (`GetAccount`, `UserName`) |
|
|
- **Local variables/Parameters**: camelCase (`accountId`, `emailAddress`) |
|
|
- **Local variables/Parameters**: camelCase (`accountId`, `emailAddress`) |
|
|
- **Interfaces**: Prefix with `I` (`IAccountService`) |
|
|
- **Interfaces**: Prefix with `I` (`IAccountService`) |
|
|
|
|
|
- **DTOs**: Postfix with `Cmd` for commands, `Dto` for responses |
|
|
|
|
|
|
|
|
#### Project Structure |
|
|
#### Project Structure |
|
|
``` |
|
|
``` |
|
|
Build_God_Api/ |
|
|
Build_God_Api/Build_God_Api/ |
|
|
Controllers/ # API endpoints |
|
|
Controllers/ # API endpoints |
|
|
Services/ # Business logic (interface + implementation) |
|
|
Services/ # Business logic interfaces |
|
|
Services/Game/ # Game-specific services |
|
|
Services/Game/ # Game-specific services |
|
|
DB/ # Database entities (extend BaseEntity) |
|
|
DB/ # Database entities (extend BaseEntity) |
|
|
Dto/ # Data transfer objects |
|
|
Dto/ # Data transfer objects |
|
|
Common/ # Utilities |
|
|
Common/ # Utilities and helpers |
|
|
Hubs/ # SignalR hubs |
|
|
Hubs/ # SignalR hubs |
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
#### Error Handling |
|
|
#### Error Handling |
|
|
- Return `BadRequest("error message")` for validation errors |
|
|
- Return `BadRequest("error message")` for validation errors |
|
|
- Return `Ok(result)` for successful operations |
|
|
- Return `Ok(result)` for successful operations |
|
|
- Use try-catch with `ILogger<T>` for error logging |
|
|
- Use try-catch with `Console.WriteLine` for error logging |
|
|
|
|
|
- Validate inputs at controller level using DataAnnotations |
|
|
|
|
|
|
|
|
#### Route Conventions |
|
|
#### Route Conventions |
|
|
- Use `[Route("api/god/[controller]")]` |
|
|
- Use `[Route("api/god/[controller]")]` |
|
|
- Use `[ApiController]` and HTTP method attributes |
|
|
- Use `[ApiController]` and HTTP method attributes (`[HttpGet]`, `[HttpPost]`) |
|
|
|
|
|
|
|
|
|
|
|
#### Database Entities (SqlSugar) |
|
|
|
|
|
- All entities extend `BaseEntity` which provides `Id`, `CreatedOn`, `UpdatedOn`, `CreatedBy`, `UpdatedBy` |
|
|
|
|
|
- Use `[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]` for auto-increment primary keys |
|
|
|
|
|
|
|
|
--- |
|
|
--- |
|
|
|
|
|
|
|
|
@ -90,35 +117,57 @@ Build_God_Api/ |
|
|
#### Conventions |
|
|
#### Conventions |
|
|
- Use **Composition API** with `<script setup lang="ts">` |
|
|
- Use **Composition API** with `<script setup lang="ts">` |
|
|
- Use **path aliases**: `@/` maps to `src/` |
|
|
- Use **path aliases**: `@/` maps to `src/` |
|
|
|
|
|
- Admin: Plain CSS (`<style scoped lang="css">`) |
|
|
|
|
|
- Game: Tailwind CSS utility classes |
|
|
|
|
|
|
|
|
#### Naming |
|
|
#### Naming |
|
|
- **Components**: PascalCase (`LoginView.vue`, `Sidebar.vue`) |
|
|
- **Components**: PascalCase (`LoginView.vue`, `Sidebar.vue`) |
|
|
- **Variables/functions**: camelCase (`handleLogin`, `userName`) |
|
|
- **Variables/functions**: camelCase (`handleLogin`, `userName`) |
|
|
- **Types/Interfaces**: PascalCase (`LoginRequest`, `User`) |
|
|
- **Types/Interfaces**: PascalCase (`LoginRequest`, `User`) |
|
|
|
|
|
- **Store names**: kebab-case in defineStore (`defineStore('auth', ...)`) |
|
|
|
|
|
|
|
|
#### Project Structure |
|
|
#### Project Structure |
|
|
``` |
|
|
``` |
|
|
src/ |
|
|
Admin Frontend (src/): |
|
|
api/ # API calls |
|
|
api/ # API modules |
|
|
|
|
|
components/ # Reusable components |
|
|
|
|
|
views/ # Page components (subdir: admin/) |
|
|
|
|
|
stores/ # Pinia stores |
|
|
|
|
|
router/ # Vue Router config |
|
|
|
|
|
assets/ # Static assets |
|
|
|
|
|
|
|
|
|
|
|
Game Frontend (src/): |
|
|
|
|
|
api/ # API modules |
|
|
components/ # Reusable components |
|
|
components/ # Reusable components |
|
|
|
|
|
composables/ # Vue composables |
|
|
views/ # Page components |
|
|
views/ # Page components |
|
|
stores/ # Pinia stores |
|
|
stores/ # Pinia stores |
|
|
router/ # Vue Router configuration |
|
|
router/ # Vue Router config |
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
#### Imports |
|
|
#### Imports |
|
|
- Use `@/` alias: `import { useAuthStore } from '@/stores/auth'` |
|
|
- Use `@/` alias: `import { useAuthStore } from '@/stores/auth'` |
|
|
- Group: external libs → internal imports → types |
|
|
- Order: external libs → internal imports → types/interfaces |
|
|
|
|
|
|
|
|
|
|
|
#### TypeScript Settings (tsconfig.app.json) |
|
|
|
|
|
```json |
|
|
|
|
|
{ |
|
|
|
|
|
"strict": false, |
|
|
|
|
|
"strictNullChecks": false, |
|
|
|
|
|
"noUnusedLocals": false, |
|
|
|
|
|
"noUnusedParameters": false |
|
|
|
|
|
} |
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
#### TypeScript |
|
|
#### TypeScript Patterns |
|
|
- Define types/interfaces for all API payloads |
|
|
- Define types/interfaces for all API payloads |
|
|
- Use `ref<T>` and `computed<T>` for reactive state |
|
|
- Use `ref<T>` and `computed<T>` for reactive state |
|
|
- Avoid `any` - use `unknown` or proper types |
|
|
- Use `unknown` or proper types instead of `any` |
|
|
|
|
|
|
|
|
#### Vue Component Pattern |
|
|
#### Vue Component Pattern |
|
|
```vue |
|
|
```vue |
|
|
<script setup lang="ts"> |
|
|
<script setup lang="ts"> |
|
|
import { ref } from 'vue' |
|
|
import { ref, computed } from 'vue' |
|
|
import { useRouter } from 'vue-router' |
|
|
import { useRouter } from 'vue-router' |
|
|
import { ElMessage } from 'element-plus' |
|
|
import { ElMessage } from 'element-plus' |
|
|
|
|
|
|
|
|
@ -143,8 +192,59 @@ import { ref, computed } from 'vue' |
|
|
export const useAuthStore = defineStore('auth', () => { |
|
|
export const useAuthStore = defineStore('auth', () => { |
|
|
const token = ref('') |
|
|
const token = ref('') |
|
|
const isAuthenticated = computed(() => !!token.value) |
|
|
const isAuthenticated = computed(() => !!token.value) |
|
|
return { token, isAuthenticated } |
|
|
|
|
|
|
|
|
const login = async (credentials: LoginRequest): Promise<boolean> => { |
|
|
|
|
|
// implementation |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return { token, isAuthenticated, login } |
|
|
|
|
|
}) |
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
#### API Module Pattern |
|
|
|
|
|
All API modules share a centralized axios instance from `api/index.ts`. |
|
|
|
|
|
|
|
|
|
|
|
**`src/api/index.ts`** - Shared axios instance (one per frontend): |
|
|
|
|
|
```typescript |
|
|
|
|
|
import axios from 'axios' |
|
|
|
|
|
|
|
|
|
|
|
const instance = axios.create({ |
|
|
|
|
|
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:5091/api/god/', |
|
|
|
|
|
timeout: 10000, |
|
|
|
|
|
headers: { 'Content-Type': 'application/json' } |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
instance.interceptors.request.use((config) => { |
|
|
|
|
|
const token = localStorage.getItem('auth_token') // or sessionStorage for Admin |
|
|
|
|
|
if (token) config.headers.Authorization = `Bearer ${token}` |
|
|
|
|
|
return config |
|
|
}) |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
instance.interceptors.response.use( |
|
|
|
|
|
(response) => response.data, |
|
|
|
|
|
(error) => { |
|
|
|
|
|
if (error.response?.status === 401) { |
|
|
|
|
|
localStorage.removeItem('auth_token') |
|
|
|
|
|
window.location.href = '/login' |
|
|
|
|
|
} |
|
|
|
|
|
return Promise.reject(error.response?.data || error.message) |
|
|
|
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
export default instance |
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
**`src/api/{entity}.ts`** - Individual API modules (import from index): |
|
|
|
|
|
```typescript |
|
|
|
|
|
import http from './index' |
|
|
|
|
|
|
|
|
|
|
|
export interface CharacterDto { ... } |
|
|
|
|
|
|
|
|
|
|
|
export const characterApi = { |
|
|
|
|
|
getList: (): Promise<CharacterDto[]> => { |
|
|
|
|
|
return http.get('/character/list') |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
``` |
|
|
``` |
|
|
|
|
|
|
|
|
--- |
|
|
--- |
|
|
@ -157,7 +257,7 @@ export const useAuthStore = defineStore('auth', () => { |
|
|
|
|
|
|
|
|
### Authentication |
|
|
### Authentication |
|
|
- JWT Bearer tokens |
|
|
- JWT Bearer tokens |
|
|
- Store in `localStorage` as `auth_token` |
|
|
- Store in `localStorage` as `auth_token` (Game) or `sessionStorage` (Admin) |
|
|
- Header: `Authorization: Bearer {token}` |
|
|
- Header: `Authorization: Bearer {token}` |
|
|
|
|
|
|
|
|
### Key Endpoints |
|
|
### Key Endpoints |
|
|
@ -169,9 +269,9 @@ export const useAuthStore = defineStore('auth', () => { |
|
|
|
|
|
|
|
|
## 4. Development Workflow |
|
|
## 4. Development Workflow |
|
|
|
|
|
|
|
|
1. **Start Backend**: `dotnet run --project Build_God_Api/Build_God_Api.csproj` |
|
|
1. **Start Backend**: `dotnet run --project Build_God_Api/Build_God_Api/Build_God_Api.csproj` |
|
|
2. **Start Frontend**: `npm run dev` (in `Build_God_Admin_Frontend/Frontend/`) |
|
|
2. **Start Admin Frontend**: `npm run dev` (in `Build_God_Admin_Frontend/Frontend/`) |
|
|
3. **Access**: Frontend at `http://localhost:5173` |
|
|
3. **Start Game Frontend**: `npm run dev` (in `Build_God_Game/`) |
|
|
|
|
|
|
|
|
--- |
|
|
--- |
|
|
|
|
|
|
|
|
@ -185,7 +285,7 @@ export const useAuthStore = defineStore('auth', () => { |
|
|
5. Register service in `Program.cs` |
|
|
5. Register service in `Program.cs` |
|
|
|
|
|
|
|
|
### Frontend |
|
|
### Frontend |
|
|
1. Create API module in `src/api/` |
|
|
1. Add API function in `src/api/{entity}.ts` (import `http` from `./index`) |
|
|
2. Add Pinia store in `src/stores/` if needed |
|
|
2. Add Pinia store in `src/stores/` if needed |
|
|
3. Create view component in `src/views/` |
|
|
3. Create view component in `src/views/` |
|
|
4. Add route in `src/router/index.ts` |
|
|
4. Add route in `src/router/index.ts` |
|
|
@ -194,9 +294,9 @@ export const useAuthStore = defineStore('auth', () => { |
|
|
|
|
|
|
|
|
## 6. Important Notes |
|
|
## 6. Important Notes |
|
|
|
|
|
|
|
|
- **Admin login**: `admin` / `love_god.123` |
|
|
- **Admin credentials**: `admin` / `love_god.123` |
|
|
- **Test account**: `Tom` / `123456` (email: 976802198@qq.com) |
|
|
- **Test account**: `Tom` / `123456` (email: 976802198@qq.com) |
|
|
- Backend runs on port **5091** |
|
|
- Backend runs on ports **59447** (HTTPS) and **59448** (HTTP) |
|
|
- Frontend uses Vite proxy for API calls |
|
|
- Admin Frontend uses sessionStorage; Game Frontend uses localStorage |
|
|
- Always use `await` with async operations |
|
|
- Always use `await` with async operations |
|
|
- Run `npm run type-check` before committing |
|
|
- Run type-check before committing |
|
|
|