85 lines
3.1 KiB
Markdown
85 lines
3.1 KiB
Markdown
# portal-common
|
||
|
||
Shared Go-библиотека для микросервисов портала.
|
||
|
||
## Состав
|
||
|
||
- `db/` — pgxpool init + slow-query tracer. Заменяет идентичный код в 9 сервисах.
|
||
- `middleware/` — `InternalAuth` (X-Internal-Key + X-User-*) + хелперы для кастомных заголовков.
|
||
- `portal/` — HTTP-клиент portal-сервиса: directory с кэшем+stale fallback, notifications, deactivate user.
|
||
- `audit/` — общий контракт business-audit событий и клиент отправки в Portal.
|
||
|
||
## Использование
|
||
|
||
В каждом сервисе:
|
||
|
||
```go
|
||
import (
|
||
"gitea.estateliga.work/admin/portal-common/audit"
|
||
"gitea.estateliga.work/admin/portal-common/db"
|
||
"gitea.estateliga.work/admin/portal-common/middleware"
|
||
"gitea.estateliga.work/admin/portal-common/portal"
|
||
)
|
||
|
||
pool, _ := db.ConnectURL(cfg.DatabaseURL)
|
||
|
||
r := chi.NewRouter()
|
||
r.Use(middleware.InternalAuth(cfg.InternalAPIKey))
|
||
|
||
portalCli := portal.New(cfg.PortalBaseURL, cfg.PortalAPIKey)
|
||
auditCli := audit.NewClient(cfg.PortalBaseURL, cfg.PortalAPIKey)
|
||
_ = auditCli.Send(ctx, audit.Event{
|
||
Action: "tasks.task_create",
|
||
EntityType: "task",
|
||
EntityID: taskID,
|
||
UserID: actorID,
|
||
UserName: actorName,
|
||
Details: map[string]any{
|
||
"request_id": requestID,
|
||
},
|
||
})
|
||
```
|
||
|
||
## Business audit vocabulary
|
||
|
||
События именуются в формате `<service>.<entity>_<verb>`:
|
||
|
||
- `service`: короткий код сервиса (`tasks`, `files`, `tg`, `pf`, `telephony`, `portal`).
|
||
- `entity`: бизнес-сущность (`task`, `node`, `channel`, `project`, `call`).
|
||
- `verb`: действие в прошедшем бизнес-смысле или команда (`create`, `update`, `delete`, `retry`, `share`, `move`).
|
||
|
||
В `Details` можно класть диагностический контекст (`request_id`, `scope`,
|
||
`status`, `error_code`), но нельзя класть токены, пароли и API-ключи. Пакет
|
||
`audit` дополнительно вырезает чувствительные ключи перед отправкой.
|
||
|
||
## Dev-режим (без push в Gitea)
|
||
|
||
В `go.mod` сервиса добавить `replace`:
|
||
|
||
```
|
||
replace gitea.estateliga.work/admin/portal-common => ../portal-common
|
||
```
|
||
|
||
Когда библиотека стабилизируется, заменить на pinned тег:
|
||
|
||
```
|
||
require gitea.estateliga.work/admin/portal-common v0.3.0
|
||
```
|
||
|
||
## Release
|
||
|
||
После изменения публичных пакетов:
|
||
|
||
```bash
|
||
go test ./...
|
||
git tag v0.3.0
|
||
git push origin main --tags
|
||
```
|
||
|
||
Сервисы обновляются только после публикации тега, без коммита локального
|
||
`replace`.
|
||
|
||
## Зачем
|
||
|
||
До этого 9 сервисов копировали один в один: pgxpool init, slow-query tracer (500ms threshold), InternalAuth middleware. Tweak'ать tuning централизованно было невозможно. Сейчас изменения идут в одном репо, сервисы пересобираются.
|