# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

eb-service-api (易借消息服务) — multi-module Java Spring Boot API service providing AI/ML capabilities (OCR, face recognition, image audit, etc.) via REST APIs. Integrates with Alibaba Cloud, Tencent Cloud, and Baidu AI services.

## Tech Stack

- **Core**: Java 8 + Spring Boot 2.6.3 + Spring Cloud Finchley.SR1
- **Data**: MySQL + MyBatis-Plus 3.4.3 + Druid connection pool
- **Cache**: Redis (Jedis client)
- **Messaging**: RabbitMQ (manual ACK)
- **Config**: Nacos (service discovery + config center)
- **Docs**: Knife4j/Swagger 2.6.1
- **Tools**: Lombok 1.18.24 + Hutool 5.8.25 + Fastjson 1.2.75 + OkHttp 4.2.0
- **AI SDKs**: Alibaba Cloud (face, OCR, image audit, object detection, etc.) + Tencent Cloud face + Baidu AI
- **Deploy**: Docker + Kubernetes (Jenkins CI/CD)

## Build Commands

```bash
# Build all modules
mvn clean package -DskipTests

# Build single module with dependencies
mvn clean package -pl api-web/api-interface -am -DskipTests

# Build specific web module
mvn clean package -pl api-web/api-admin -am -DskipTests
mvn clean package -pl api-web/api-job -am -DskipTests
mvn clean package -pl api-gateway -am -DskipTests
```

## Run Services

Each service is a separate Spring Boot application:

| Service       | Port | Main Class                      | Description          |
|---------------|------|---------------------------------|----------------------|
| api-interface | 8888 | `com.heyu.api.ApiUserApiApplication` | User-facing API   |
| api-admin     | 8899 | `com.heyu.api.admin.http.api.ApiAdminHttpApiApplication` | Admin API |
| api-job       | 8877 | `com.heyu.api.job.api.ApiJobApiApplication` | Scheduled jobs |
| api-gateway   | 8080 | `com.heyu.api.gateway.GatewayApplication` | API Gateway (Zuul) |

```bash
# Example: run api-interface in dev mode
java -jar api-web/api-interface/target/api-interface.jar --spring.profiles.active=dev
```

Profiles: `dev`, `pre`, `online`. Config split between local `bootstrap.yml`/`bootstrap-{profile}.yml` and Nacos config center.

## Module Structure

```
eb-service-api (parent pom, groupId: com.lz.eb)
├── api-common          # Shared annotations (@Describe, @AppRealyLogin, @AdminNotNeedLogin)
├── api-mapper          # Data layer: entities, DAOs, services, MyBatis XML mappers, utils, constants
├── api-third           # Third-party integrations (Alibaba Cloud AI, Tencent, Baidu, OSS)
├── api-gateway         # Zuul API gateway with Redis rate limiting
├── api-web
│   ├── api-interface   # User-facing REST controllers + RabbitMQ listeners
│   ├── api-admin       # Admin REST controllers
│   └── api-job         # Scheduled tasks & job listeners
```

### Module Dependencies

```
api-web/* → api-mapper (no dependency on api-web)
api-web/* → api-third → api-mapper
api-web/* → api-common
```

## Architecture Patterns

### Controller Layer

- All controllers extend `BaseController` (Baidu API integration + common helpers)
- Organized by AI domain: `controller/face/`, `controller/ocr/`, `controller/imageaudit/`, `controller/bankcard/`, etc.
- URI prefix convention:
  - App-facing: `/app/*`
  - Merchant-managed: `/mm/*`

### AOP

- `LogAop` — `@Around` on all `@RestController`/`@Controller` methods. Handles:
  - Request/response logging (with trace ID)
  - Authentication (token validation, account info)
  - Tencent Cloud auth header validation (`X-TCloudMarket-Custom-AuthConfig`)
  - `@NotIntercept` annotation bypass
- `ZhenZhenLogAop` — Additional logging aspect

### Authentication Annotations

| Annotation            | Location   | Purpose                                  |
|-----------------------|------------|------------------------------------------|
| `@AppRealyLogin`      | api-common | Endpoint requires real user login        |
| `@AdminNotNeedLogin`  | api-common | Admin endpoint skips authentication      |
| `@EbAuthentication`   | api-mapper | Custom auth bypass                       |
| `@NotIntercept`       | api-mapper | Skip LogAop interception                 |
| `@QPS`                | api-mapper | Rate limiting                            |
| `@CacheResult`        | api-mapper | Result caching                           |
| `@Describe`           | api-common | API method description                   |

### API Response

Unified response class `R<T>` (`com.heyu.api.data.utils.R`):

```java
// Structure: { code, msg, data, traceId }
R.ok()                       // success with no data
R.ok().setData(result)       // success with data
R.error("error message")     // failure
R.error(RespCode.FAILED)     // failure with code
```

Third-party wrapper `ApiR<T>` (`com.heyu.api.data.utils.ApiR`):

```java
ApiR.setData(resp)           // success
ApiR.error("error message")  // failure
```

### Data Layer (api-mapper)

Package `com.heyu.api.data`:

| Path                        | Purpose                        |
|-----------------------------|--------------------------------|
| `entity/{domain}/`          | MyBatis-Plus entity classes    |
| `dao/{domain}/`             | MyBatis mapper interfaces      |
| `service/{domain}/`         | Service interfaces             |
| `service/impl/{domain}/`    | Service implementations        |
| `mapper/{domain}/*Mapper.xml` | MyBatis XML mappings         |
| `constants/`                | `ApiConstants`, `RedisConstans` |
| `utils/`                    | `RedisUtils`, `Base64Utils`, `DateUtils`, etc. |
| `dto/`                      | DTOs including `RespCode`      |

MyBatis-Plus config:
- Mapper scan: `com.heyu.api.data.**.dao`
- Entity scan: `com.heyu.api.data.**.entity`
- XML locations: `classpath*:mapper/**/*Mapper.xml,classpath*:mapper/**/*Dao.xml`
- Soft delete: `logic-delete-value: -1`, `logic-not-delete-value: 0`
- Camel case mapping enabled
- ID type: AUTO (database auto-increment)

### RabbitMQ Listeners

Listeners in `com.heyu.api.listener` (api-interface) and `com.heyu.api.job.api.listener` (api-job):

| Listener                              | Purpose                  |
|---------------------------------------|--------------------------|
| `VVUrlQueueSimpleRabbitListener`      | URL statistics logging   |
| `CreateDataQueueSimpleRabbitListener` | Data creation processing |
| `DelaySimpleRabbitListener`           | Delayed message handling |
| `PostCodeQueueSimpleRabbitListener`   | Postal code processing   |
| `SendDingDingQueueSimpleRabbitListener` | DingTalk notifications |
| `AccountQueueSimpleRabbitListener`    | Account amount processing|

All use manual ACK (`channel.basicAck()`) and `@RabbitHandler` + `@RabbitListener`.

Queue names configured in `bootstrap.yml` under `eb.config.rabbitQueue`.

### Third-Party Integrations (api-third)

| Package     | Service                    |
|-------------|----------------------------|
| `alibaba/`  | Alibaba Cloud AI (face, OCR, image audit, object detection, image enhancement, goods recognition) |
| `tencent/`  | Tencent Cloud face recognition (FaceID SDK) |
| `baidu/`    | Baidu AI (token cached in Redis, accessed via `BaseController`) |
| `oss/`      | Alibaba Cloud OSS file storage |
| `jsapi/`    | WeChat Pay JSAPI integration |

## Code Standards

### Naming Conventions

- **Entity**: no special suffix, plain class names (e.g., `User`, `VvAllData`)
- **DAO/Mapper**: `XxxDao` interface + `XxxDao.xml` XML mapping
- **Constants**: `ApiConstants` (general), `RedisConstans` (Redis key prefixes + TTL)
- **Utils**: `XxxUtils` (e.g., `RedisUtils`, `DateUtils`, `Base64Utils`)

### Redis

- Key prefix constants in `RedisConstans` (e.g., `AI::TYPE::info::`, `device::info::`)
- TTL constants in seconds: `ONE_DAY`, `ONE_HOUR`, `SECOND_OF_ONE_7_DAY`, etc.
- Always set expiration via `RedisUtils.set(key, value, expire)`

### Logging

- Use `@Slf4j` (Lombok)
- Logback config per profile: `log/logback-{profile}.xml`
- Trace ID via MDC (`logid` or `X-B3-TraceId` from Spring Cloud Sleuth)
- Key fields in logs: `className#methodName`, IP, URI

### Error Handling

- `R.error(msg)` for API response errors
- `ApiR.error(msg)` for third-party call errors
- `RespCode` enum: `SUCCESS("200")`, `FAILED("400")`
- Gateway: `GatewayExceptionHandler` for reactive error handling

## Environment

- JDK 8 (source/target 1.8)
- Maven 3.6+
- MySQL 5.7+ (Druid pool)
- Redis 5.0+
- RabbitMQ 3.8+
- Nacos 2.x (service discovery + config center)

## Deployment

Docker + Kubernetes via Jenkins CI/CD:
- Base image: `alpine-jdk11:3.0`
- Health check: `/actuator/health`
- Resource limit: 1024Mi memory
- Log volume: `/home/heyu/logs` → NFS `/nfs/data/heyu/api/logs`
- Rolling update: 50% max surge/unavailable
