Files
EmailBill/AGENTS.md
SunCheng 4aa7e82429
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Failing after 1m57s
Docker Build & Deploy / Deploy to Production (push) Has been skipped
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
移除对账功能 后期从长计议
2026-01-27 15:29:25 +08:00

4.9 KiB

AGENTS.md - EmailBill Project Guidelines

Full-stack budget tracking app with .NET 10 backend and Vue 3 frontend.

Project Structure

EmailBill/
├── Common/           # Shared utilities and abstractions
├── Entity/           # Database entities (FreeSql ORM)
├── Repository/       # Data access layer
├── Service/          # Business logic layer
├── WebApi/           # ASP.NET Core Web API
├── WebApi.Test/      # Backend tests (xUnit)
└── Web/              # Vue 3 frontend (Vite + Vant UI)

Build & Test Commands

Backend (.NET 10)

# Build and run
dotnet build EmailBill.sln
dotnet run --project WebApi/WebApi.csproj

# Run all tests
dotnet test WebApi.Test/WebApi.Test.csproj

# Run single test class
dotnet test --filter "FullyQualifiedName~BudgetStatsTest"

# Run single test method
dotnet test --filter "FullyQualifiedName~BudgetStatsTest.GetCategoryStats_月度_Test"

# Clean
dotnet clean EmailBill.sln

Frontend (Vue 3)

cd Web

# Setup and dev
pnpm install
pnpm dev

# Build and preview
pnpm build
pnpm preview

# Lint and format
pnpm lint          # ESLint with auto-fix
pnpm format        # Prettier formatting

C# Code Style

Namespaces & Imports:

  • File-scoped namespaces: namespace Entity;
  • Global usings in Common/GlobalUsings.cs
  • Sort using statements alphabetically

Naming:

  • Classes/Methods: PascalCase
  • Interfaces: IPascalCase
  • Private fields: _camelCase
  • Parameters/locals: camelCase

Entities:

  • Inherit from BaseEntity
  • Use [Column] attributes for FreeSql ORM
  • IDs via Snowflake: YitIdHelper.NextId()
  • Use XML docs (///) for public APIs
  • Chinese comments for business logic (per .github/csharpe.prompt.md)

Best Practices:

  • Use modern C# syntax (records, pattern matching, nullable types)
  • Use IDateTimeProvider instead of DateTime.Now for testability
  • Avoid deep nesting, keep code flat and readable
  • Reuse utilities from Common project

Example:

namespace Entity;

/// <summary>
/// 实体基类
/// </summary>
public abstract class BaseEntity
{
    [Column(IsPrimary = true)]
    public long Id { get; set; } = YitIdHelper.NextId();
    
    public DateTime CreateTime { get; set; } = DateTime.Now;
}

Vue/TypeScript Style

Component Structure:

<template>
  <van-config-provider :theme="theme">
    <div class="component-name">
      <!-- Content -->
    </div>
  </van-config-provider>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useMessageStore } from '@/stores/message'

const messageStore = useMessageStore()
</script>

<style scoped lang="scss">
.component-name {
  padding: 16px;
}
</style>

Rules:

  • Composition API with <script setup lang="ts">
  • Import order: Vue APIs → external libs → internal modules
  • Use @/ alias for absolute imports, avoid ../../../
  • Vant UI components: <van-*>
  • Pinia for state, Vue Router for navigation
  • SCSS with BEM naming, mobile-first design

ESLint Rules (see Web/eslint.config.js):

  • 2-space indentation
  • Single quotes, no semicolons
  • const over let, no var
  • Always use === (strict equality)
  • space-before-function-paren: 'always'
  • Max 1 empty line between blocks
  • Vue: multi-word component names disabled

Prettier Rules (see Web/.prettierrc.json):

  • Single quotes, no semicolons
  • Trailing commas: none
  • Print width: 100 chars

Testing

Backend (xUnit + NSubstitute + FluentAssertions):

public class BudgetStatsTest : BaseTest
{
    private readonly IBudgetRepository _repo = Substitute.For<IBudgetRepository>();
    
    [Fact]
    public async Task GetCategoryStats_月度_Test()
    {
        // Arrange
        _repo.GetAllAsync().Returns(testData);
        
        // Act
        var result = await _service.GetCategoryStatsAsync(category, date);
        
        // Assert
        result.Month.Limit.Should().Be(2500);
    }
}
  • Arrange-Act-Assert pattern
  • Constructor injection for dependencies
  • Use Chinese test method names for domain clarity

Frontend:

  • Vue Test Utils for components
  • axios-mock-adapter for API mocking

Development Workflow

  1. Before committing backend: dotnet test
  2. Before committing frontend: pnpm lint && pnpm build
  3. Database migrations: Use FreeSql (check Repository/)
  4. API docs: Scalar OpenAPI viewer

Environment

Required:

  • .NET 10 SDK
  • Node.js 20.19+ or 22.12+
  • pnpm

Database: SQLite (embedded)

Config:

  • Backend: appsettings.json
  • Frontend: .env.development / .env.production

Critical Guidelines (from .github/csharpe.prompt.md)

  • 优先使用新C#语法 (Use modern C# syntax)
  • 优先使用中文注释 (Prefer Chinese comments for business logic)
  • 优先复用已有方法 (Reuse existing methods)
  • 不要深嵌套代码 (Avoid deep nesting)
  • 保持代码简洁易读 (Keep code clean and readable)