- 新增《项目后端结构说明》,梳理仓库布局、internal 分层与请求链路 - 《数据库表结构与关系说明》新增第 11 节,记录公司隔离发布后的表、约束与升级阻断规则 - 公司隔离计划补充精简版测试策略,并勾选 Task 2、Task 8 完成项与验收记录
87 lines
6.0 KiB
Markdown
87 lines
6.0 KiB
Markdown
# 项目后端结构说明
|
||
|
||
本文介绍仓库的整体布局,重点是后端 `internal/` 的分层职责:每个文件负责什么、一次请求经过哪些环节。配套阅读:《[数据库表结构与关系说明](数据库表结构与关系说明.md)》《[API 文档](api.md)》。
|
||
|
||
## 仓库顶层布局
|
||
|
||
| 目录/文件 | 说明 |
|
||
| --- | --- |
|
||
| `cmd/server/` | 后端入口 `main.go`:读 DSN、连库、建默认用户、校验 schema、注册路由并启动 |
|
||
| `internal/` | 后端内核,见下文分层说明 |
|
||
| `pkg/` | 通用基础包:`database`(连接与 DSN 规范化)、`response`(统一响应格式与状态码封装) |
|
||
| `frontend/` | 前端源码与构建产物(`frontend/dist` 为后端静态托管的目录) |
|
||
| `scripts/` | `init.sql`、增量升级 SQL 与校验脚本 |
|
||
| `docs/` | 项目文档 |
|
||
|
||
## 整体
|
||
|
||
`cmd/server/main.go` 是入口(注册路由、连库、校验 schema),`internal/` 只是内核。一次请求的链路是:
|
||
|
||
```
|
||
middleware(认证/公司校验)→ handler(绑参、回响应)→ service(业务规则、校验、组装)→ repository(纯 SQL)→ model(结构体)
|
||
```
|
||
|
||
响应统一走 `pkg/response`,连库在 `pkg/database`。
|
||
|
||
## handler/(HTTP 层)
|
||
|
||
`api.go` 是大头(1604 行)。
|
||
|
||
| 文件 | 职责 |
|
||
| --- | --- |
|
||
| [api.go](../internal/handler/api.go) | `Handler` 聚合全部 service;`RegisterRoutes` 定义所有路由与中间件挂载;物料、出入库、库存、用户、申请等主体 handler |
|
||
| [admin_master.go](../internal/handler/admin_master.go) | 管理端:公司、角色、权限、物料分类、单位、编码规则、往来单位、仓库/库位,另含 `organizationID` / `pathID` / `bind` 三个公共小工具 |
|
||
| [organization_context.go](../internal/handler/organization_context.go) | 公司切换器:列出可访问公司、切换当前公司上下文 |
|
||
| [upload.go](../internal/handler/upload.go) | 图片上传 |
|
||
| [websocket.go](../internal/handler/websocket.go) | 库存变更实时推送的 Hub、Client、广播,以及 `/ws` 握手(凭一次性票据 + 实时复核授权) |
|
||
|
||
## middleware/(3 个)
|
||
|
||
| 文件 | 职责 |
|
||
| --- | --- |
|
||
| [auth.go](../internal/middleware/auth.go) | JWT 解析、`AdminOnly`、`OptionalAuth`,以及取 userID / username / roles 的辅助函数 |
|
||
| [organization.go](../internal/middleware/organization.go) | 校验 `X-Organization-ID` 头并确认该用户能访问这家公司,通过后写进 context |
|
||
| [rate_limiter.go](../internal/middleware/rate_limiter.go) | 登录失败次数限流 + 定期清理 |
|
||
|
||
## service/(业务规则)
|
||
|
||
| 文件 | 职责 |
|
||
| --- | --- |
|
||
| [material.go](../internal/service/material.go) | 物料增改查、作废/恢复 |
|
||
| [inbound.go](../internal/service/inbound.go) / [outbound.go](../internal/service/outbound.go) | 出入库单的业务校验与库存联动 |
|
||
| [stock.go](../internal/service/stock.go) | 库存查询、预警分类、变动量计算 |
|
||
| [inventory_scope.go](../internal/service/inventory_scope.go) | 公司维度的仓库/库位解析:库存读写一律由服务端从库里推导,不收前端传的 ID;写操作要求启用状态 |
|
||
| [material_log.go](../internal/service/material_log.go) | 物料变更日志的 diff 生成与中文描述 |
|
||
| [application.go](../internal/service/application.go) | 物料申请单的提交/审批/驳回/撤销 |
|
||
| [auth.go](../internal/service/auth.go) | 登录、签发与校验 token session、密码哈希 |
|
||
| [admin_master.go](../internal/service/admin_master.go) | 公司、主数据(分类/单位/编码规则)、往来单位、仓库四组服务 |
|
||
| [organization_access.go](../internal/service/organization_access.go) | 公司可访问范围与切换 |
|
||
| [websocket_ticket.go](../internal/service/websocket_ticket.go) | WebSocket 一次性票据的签发/消费 |
|
||
| [errors.go](../internal/service/errors.go) | 共享哨兵错误(库存不足、公司维度不可用等),供 handler 映射状态码 |
|
||
|
||
## repository/(纯 SQL)
|
||
|
||
| 文件 | 职责 |
|
||
| --- | --- |
|
||
| [material.go](../internal/repository/material.go) | 物料,含事务版新增(锁编码规则、判重)/更新/作废/恢复 |
|
||
| [inbound.go](../internal/repository/inbound.go) / [outbound.go](../internal/repository/outbound.go) | 出入库单及明细读写,共用 `orderQuerier` 接口 |
|
||
| [stock.go](../internal/repository/stock.go) | 库存余额、流水、预警规则,含 upsert |
|
||
| [master_data.go](../internal/repository/master_data.go) | 分类/单位/编码规则 |
|
||
| [material_log.go](../internal/repository/material_log.go) | 物料日志落库与查询 |
|
||
| [warehouse.go](../internal/repository/warehouse.go) | 仓库/库位,含 `Summary`(按公司取唯一仓库 + 库位) |
|
||
| [partner.go](../internal/repository/partner.go) | 往来单位 |
|
||
| [user.go](../internal/repository/user.go) | 用户与角色,含保护最后一个超管、建默认用户/表 |
|
||
| [user_organization.go](../internal/repository/user_organization.go) | 用户-公司关联的替换与批量加载 |
|
||
| [organization.go](../internal/repository/organization.go) / [organization_access.go](../internal/repository/organization_access.go) | 公司基础 CRUD;`ListAccessible` / `CanAccess` 的授权判定(每次查库,不依赖 JWT 里的角色快照) |
|
||
| [organization_audit.go](../internal/repository/organization_audit.go) | 公司相关操作的审计日志写入 |
|
||
| [application.go](../internal/repository/application.go) | 申请单及明细 |
|
||
| [update.go](../internal/repository/update.go) | `execExpectingRow`:UPDATE 后校验影响行数,避免"0 行也当成功" |
|
||
|
||
## model/(数据结构,无逻辑)
|
||
|
||
[model.go](../internal/model/model.go) 集中了大部分结构体(物料、出入库单与明细、库存与流水、用户、申请单,以及各类 Request/Response);后来又按业务域另拆出 `inventory.go`、`master_data.go`、`organization.go`、`partner.go`、`warehouse.go` 五个文件。
|
||
|
||
## testutil/
|
||
|
||
`fixtures.go`、`isolation.go`、`testdb.go` 是测试辅助包,不属于业务代码。
|