时间字段改由业务层生成并传入
This commit is contained in:
18
AGENTS.md
18
AGENTS.md
@@ -162,7 +162,19 @@ OK
|
|||||||
struct ApiResponse<T> { success: bool, message: String, data: Option<T> }
|
struct ApiResponse<T> { success: bool, message: String, data: Option<T> }
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 环境变量
|
### 3. 时间字段约定
|
||||||
|
|
||||||
|
所有表中的 `createdate` 和 `modifydate` **必须由业务层生成并传入**,数据库Schema中**不设置** `DEFAULT CURRENT_TIMESTAMP`,也不使用触发器自动更新。
|
||||||
|
|
||||||
|
- 建表时:
|
||||||
|
```sql
|
||||||
|
createdate TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
|
modifydate TIMESTAMP WITH TIME ZONE NOT NULL
|
||||||
|
```
|
||||||
|
- Rust 代码中使用 `chrono::Utc::now()` 生成时间戳,统一在事务开始前创建 `let now = Utc::now();`,确保同一笔业务中各表时间一致。
|
||||||
|
- `modifydate` 更新时同样需要在业务代码中显式传入 `Utc::now()`。
|
||||||
|
|
||||||
|
### 4. 环境变量
|
||||||
|
|
||||||
所有服务通过环境变量读取配置:
|
所有服务通过环境变量读取配置:
|
||||||
- `DATABASE_URL` — PostgreSQL 连接串(必需)
|
- `DATABASE_URL` — PostgreSQL 连接串(必需)
|
||||||
@@ -171,13 +183,13 @@ OK
|
|||||||
- `JWT_SECRET` — JWT 签名密钥
|
- `JWT_SECRET` — JWT 签名密钥
|
||||||
- `RUST_LOG` — 日志级别
|
- `RUST_LOG` — 日志级别
|
||||||
|
|
||||||
### 3. Docker 构建
|
### 5. Docker 构建
|
||||||
|
|
||||||
- 各微服务 Dockerfile 的构建上下文为**项目根目录**(`docker-compose.yml` 中使用 `context: ../..`)。
|
- 各微服务 Dockerfile 的构建上下文为**项目根目录**(`docker-compose.yml` 中使用 `context: ../..`)。
|
||||||
- 构建采用多阶段(builder + runtime),基于 `rust:1.94.1-alpine3.23` 编译,最终运行在 `alpine:3.23`。
|
- 构建采用多阶段(builder + runtime),基于 `rust:1.94.1-alpine3.23` 编译,最终运行在 `alpine:3.23`。
|
||||||
- 共享代码更新时,需确保 `shared/` 目录在 Dockerfile 中被正确复制。
|
- 共享代码更新时,需确保 `shared/` 目录在 Dockerfile 中被正确复制。
|
||||||
|
|
||||||
### 4. 网关与路由
|
### 6. 网关与路由
|
||||||
|
|
||||||
- Nginx 监听 80/443,开发环境使用自签名证书。
|
- Nginx 监听 80/443,开发环境使用自签名证书。
|
||||||
- 路由前缀约定:
|
- 路由前缀约定:
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
CREATE TABLE IF NOT EXISTS user_main (
|
CREATE TABLE IF NOT EXISTS user_main (
|
||||||
id UUID PRIMARY KEY,
|
id UUID PRIMARY KEY,
|
||||||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
createdate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
createdate TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
modifydate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
|
modifydate TIMESTAMP WITH TIME ZONE NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 用户登录账号表
|
-- 用户登录账号表
|
||||||
@@ -12,8 +12,8 @@ CREATE TABLE IF NOT EXISTS user_login_account (
|
|||||||
user_id UUID NOT NULL,
|
user_id UUID NOT NULL,
|
||||||
account VARCHAR(100) NOT NULL,
|
account VARCHAR(100) NOT NULL,
|
||||||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
createdate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
createdate TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
modifydate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
modifydate TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
CONSTRAINT fk_user_login_account_user_main FOREIGN KEY (user_id) REFERENCES user_main(id)
|
CONSTRAINT fk_user_login_account_user_main FOREIGN KEY (user_id) REFERENCES user_main(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -27,8 +27,8 @@ CREATE TABLE IF NOT EXISTS user_login_password (
|
|||||||
user_id UUID NOT NULL,
|
user_id UUID NOT NULL,
|
||||||
password VARCHAR(255) NOT NULL,
|
password VARCHAR(255) NOT NULL,
|
||||||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
createdate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
createdate TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
modifydate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
modifydate TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
CONSTRAINT fk_user_login_password_user_main FOREIGN KEY (user_id) REFERENCES user_main(id)
|
CONSTRAINT fk_user_login_password_user_main FOREIGN KEY (user_id) REFERENCES user_main(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -41,8 +41,8 @@ CREATE TABLE IF NOT EXISTS user_login_email (
|
|||||||
user_id UUID NOT NULL,
|
user_id UUID NOT NULL,
|
||||||
email VARCHAR(255) NOT NULL,
|
email VARCHAR(255) NOT NULL,
|
||||||
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
createdate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
createdate TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
modifydate TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
modifydate TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||||
CONSTRAINT fk_user_login_email_user_main FOREIGN KEY (user_id) REFERENCES user_main(id)
|
CONSTRAINT fk_user_login_email_user_main FOREIGN KEY (user_id) REFERENCES user_main(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use chrono::Utc;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
@@ -149,12 +150,15 @@ async fn register_handler(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let now = Utc::now();
|
||||||
let user_id = Uuid::now_v7();
|
let user_id = Uuid::now_v7();
|
||||||
|
|
||||||
if let Err(e) = sqlx::query(
|
if let Err(e) = sqlx::query(
|
||||||
"INSERT INTO user_main (id) VALUES ($1)"
|
"INSERT INTO user_main (id, createdate, modifydate) VALUES ($1, $2, $3)"
|
||||||
)
|
)
|
||||||
.bind(user_id)
|
.bind(user_id)
|
||||||
|
.bind(now)
|
||||||
|
.bind(now)
|
||||||
.execute(&mut *tx)
|
.execute(&mut *tx)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -172,11 +176,13 @@ async fn register_handler(
|
|||||||
|
|
||||||
let account_id = Uuid::now_v7();
|
let account_id = Uuid::now_v7();
|
||||||
if let Err(e) = sqlx::query(
|
if let Err(e) = sqlx::query(
|
||||||
"INSERT INTO user_login_account (id, user_id, account) VALUES ($1, $2, $3)"
|
"INSERT INTO user_login_account (id, user_id, account, createdate, modifydate) VALUES ($1, $2, $3, $4, $5)"
|
||||||
)
|
)
|
||||||
.bind(account_id)
|
.bind(account_id)
|
||||||
.bind(user_id)
|
.bind(user_id)
|
||||||
.bind(&req.data.username)
|
.bind(&req.data.username)
|
||||||
|
.bind(now)
|
||||||
|
.bind(now)
|
||||||
.execute(&mut *tx)
|
.execute(&mut *tx)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -194,11 +200,13 @@ async fn register_handler(
|
|||||||
|
|
||||||
let password_id = Uuid::now_v7();
|
let password_id = Uuid::now_v7();
|
||||||
if let Err(e) = sqlx::query(
|
if let Err(e) = sqlx::query(
|
||||||
"INSERT INTO user_login_password (id, user_id, password) VALUES ($1, $2, $3)"
|
"INSERT INTO user_login_password (id, user_id, password, createdate, modifydate) VALUES ($1, $2, $3, $4, $5)"
|
||||||
)
|
)
|
||||||
.bind(password_id)
|
.bind(password_id)
|
||||||
.bind(user_id)
|
.bind(user_id)
|
||||||
.bind(&password_hash)
|
.bind(&password_hash)
|
||||||
|
.bind(now)
|
||||||
|
.bind(now)
|
||||||
.execute(&mut *tx)
|
.execute(&mut *tx)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use chrono::Utc;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use validator::Validate;
|
use validator::Validate;
|
||||||
@@ -149,12 +150,15 @@ async fn register_handler(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let now = Utc::now();
|
||||||
let user_id = Uuid::now_v7();
|
let user_id = Uuid::now_v7();
|
||||||
|
|
||||||
if let Err(e) = sqlx::query(
|
if let Err(e) = sqlx::query(
|
||||||
"INSERT INTO user_main (id) VALUES ($1)"
|
"INSERT INTO user_main (id, createdate, modifydate) VALUES ($1, $2, $3)"
|
||||||
)
|
)
|
||||||
.bind(user_id)
|
.bind(user_id)
|
||||||
|
.bind(now)
|
||||||
|
.bind(now)
|
||||||
.execute(&mut *tx)
|
.execute(&mut *tx)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -172,11 +176,13 @@ async fn register_handler(
|
|||||||
|
|
||||||
let email_id = Uuid::now_v7();
|
let email_id = Uuid::now_v7();
|
||||||
if let Err(e) = sqlx::query(
|
if let Err(e) = sqlx::query(
|
||||||
"INSERT INTO user_login_email (id, user_id, email) VALUES ($1, $2, $3)"
|
"INSERT INTO user_login_email (id, user_id, email, createdate, modifydate) VALUES ($1, $2, $3, $4, $5)"
|
||||||
)
|
)
|
||||||
.bind(email_id)
|
.bind(email_id)
|
||||||
.bind(user_id)
|
.bind(user_id)
|
||||||
.bind(&req.data.email)
|
.bind(&req.data.email)
|
||||||
|
.bind(now)
|
||||||
|
.bind(now)
|
||||||
.execute(&mut *tx)
|
.execute(&mut *tx)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@@ -194,11 +200,13 @@ async fn register_handler(
|
|||||||
|
|
||||||
let password_id = Uuid::now_v7();
|
let password_id = Uuid::now_v7();
|
||||||
if let Err(e) = sqlx::query(
|
if let Err(e) = sqlx::query(
|
||||||
"INSERT INTO user_login_password (id, user_id, password) VALUES ($1, $2, $3)"
|
"INSERT INTO user_login_password (id, user_id, password, createdate, modifydate) VALUES ($1, $2, $3, $4, $5)"
|
||||||
)
|
)
|
||||||
.bind(password_id)
|
.bind(password_id)
|
||||||
.bind(user_id)
|
.bind(user_id)
|
||||||
.bind(&password_hash)
|
.bind(&password_hash)
|
||||||
|
.bind(now)
|
||||||
|
.bind(now)
|
||||||
.execute(&mut *tx)
|
.execute(&mut *tx)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user