Конвенции
Работен процес с Git
- Push само към
main. Правете къмити директно вmain; без функционални клонове (feature branches) и без pull request-и. - Conventional commits:
feat: …,fix: …,docs: …,feat(agent): …,fix(api): …. - Всеки push към
mainсе разгръща в продукция (Непрекъснато разгръщане), а промените вentrosity-axis-agent/,entrosity-axis-connector/илиentrosity-shared-go/също доставят dev изграждане до агентите (Издания на агента). - Всяка промяна в кода обновява тази документация в същия къмит (Писане на документация).
Генериране на код
Генерираният код се къмитва:
entrosity-axis.backend/internal/db/gen/(sqlc),entrosity-axis.backend/internal/http/gen/(oapi-codegen),src/api/schema.d.tsвъв всяко приложение (openapi-typescript, от къмитнатата моментна снимкаapi/openapi.yaml),src/routeTree.gen.tsвъв всяко приложение (TanStack Router).
Никога не ги редактирайте. Променете .sql заявката, миграцията или
entrosity-axis.backend/api/openapi.yaml и изпълнете make gen.
- Добавете заявка в
entrosity-axis.backend/db/queries/<domain>.sqlсъс заглавен ред като-- name: ListDevicesByTenant :many. - Добавете крайна точка (endpoint) в
openapi.yamlпърво; обработчикът имплементира генерирания интерфейс. След това добавете правилото ѝ за достъп вentrosity-axis.backend/internal/http/portal/access.goи ред в теста на RBAC матрицата.
Go
- Стандартна структура с пакети в
internal/; грешките се обвиват с%w; sentinel грешки за всеки домейн (device.ErrNotFound); контексти навсякъде; без глобално състояние освен конфигурацията. - Код, използван от повече от един сървър (бекенда на Axis и Entrosity Hub),
се намира в модула
shared, без достъп до база данни:entrosity-shared-go/apperr(грешки на домейна),entrosity-shared-go/reqctx(IP адрес на клиента, user agent, ID на заявката),entrosity-shared-go/secretbox(AES-GCM тайни в покой с ротация на ключове),entrosity-shared-go/authkit(argon2id пароли, политика за пароли, непрозрачни токени, помощни функции за TOTP, QR кодове) иentrosity-shared-go/mailkit(SMTP и рендиране на шаблони). Всеки сървър има собствена база данни, миграции и шаблони за имейли. - Обработчиците превеждат грешките на домейна в problem+json на едно място
(
internal/http/errors.go); грешките на домейна носят стабилен код (apperr.New(kind, "code", "message"),entrosity-shared-go/apperr). Новите кодове се добавят в Кодове на грешки. - Всеки метод на хранилище (repository), ограничен до тенант, приема
tenantIDкато първи аргумент следctx. - Всяко извикване на услуга, което променя данни, записва одитен запис в същата транзакция.
Портал
- Папки по функционалност:
src/features/<feature>/{api.ts, keys.ts, components/}; ключовете на заявките са вkeys.tsза всяка функционалност. - Без
any. Формите използватreact-hook-form+zod. Loader-ите на маршрутите зареждат данни предварително сqueryClient.ensureQueryData. - Стилизиране: само utility класове на Tailwind, без вграден
style, без CSS освен токените на темата. - Графиките използват компонента за графики на shadcn/ui
(
@entrosity/ui/chart:ChartContainer,ChartTooltip+ChartTooltipContent,ChartLegend+ChartLegendContent) около примитивите на Recharts. Всяка серия се декларира вChartConfigс етикета и цвета си и се рисува сvar(--color-<key>). Цветовете идват от цветовете на тематаchart-1…chart-10чрезchartColor(i)(src/lib/chart.ts), така че графиките следват светлия и тъмния режим. Ключовете на сериите трябва да са валидни CSS идентификатори (буквите на дискове катоC:получават безопасен ключ). - Споделеният UI се намира в
entrosity-ui(@entrosity/ui) и се използва от всяко уеб приложение: примитивите на shadcn/ui (@entrosity/ui/button, …), споделените компоненти (@entrosity/ui/components/DataTable,BrandLogo,ConfirmDialog,PageHeader, …),cn()(@entrosity/ui/lib/utils), дизайн токените (@entrosity/ui/tokens.css, импортирани отsrc/index.cssна приложението) и Tailwind preset-ът. Добавете компонент там, когато второ приложение се нуждае от него; компонентите, специфични за продукта, остават в приложението. Неговият README обяснява как се добавя примитив на shadcn/ui. - Състоянията се показват с
@entrosity/ui/components/StatusBadge: една таблица (statusTones) дава цвета на всяко състояние (good: зелено, busy: синьо, warning: кехлибарено, bad: червено, neutral: сиво), приложението подава преведения етикет, аtoneпроменя цвета, където състоянието означава друго. Новите състояния се добавят вstatusTones, не като цветове в приложението. - Заглавната лента на всяко приложение има
@entrosity/ui/components/BackButton, свързан сuseCanGoBack()иrouter.history.back()на рутера. - Всеки видим за потребителя текст е преведен (английски, по подразбиране,
и български). Текстовете са в пакети със съобщения до кода
(
src/features/<feature>/messages.ts), създадени сdefineMessages({ en, bg })от@entrosity/ui/lib/i18n; българската таблица трябва да има точно английските ключове, така че липсващ превод проваля проверката на типовете. Компонентите ги четат сuseT(bundle)(@entrosity/ui/components/LocaleProvider), останалият код – сtranslate(bundle, key)в момента на извикване, никога при зареждане на модула. Множественото число използваkey_one/key_otherс числовоcount. Датите и числата минават през помощните функции вsrc/lib/format.ts, които следват езика на интерфейса. Терминологията следва българската документация. Изборът на език се пази в localStorage (entrosity.locale), общ за Hub и Axis; превключването монтира страницата наново. - Брандиране: знакът на Entrosity и името на продукта „Entrosity Axis“
(
src/lib/brand.ts: словесната марка е „Entrosity“ плюс приглушено „Axis“); основен цвят — виолетовото на Entrosity#7b35f5(акценти#4c17b8). Уеб приложенията и този сайт използват ръчно рисувания вид по-долу.
Ръчно рисуван вид (Ink & Strata)
Всяко уеб приложение (сайтът, Hub, Axis, Edge, Matrix, Sphere) и този сайт
с документация следват графиката на марката: сива хартия, неравни черни
мастилени контури с неправилни ъгли, виолетови пластове от вълни, които
навлизат от ъглите, драсканици # и //// и мек отблясък.
@entrosity/ui (0.6.0 и по-нови) го реализира; приложенията само избират
класовете и компонентите.
Токени (tokens.css, HSL тройки, използвани като hsl(var(--ink));
също цветовете на Tailwind ink и wave-1 … wave-6):
| Токен | Значение |
|---|---|
--background, --card | Хартията и по-светлата хартия на панелите |
--ink | Цветът на рисуваните контури (почти черен; тебешир в тъмния режим) |
--shadow-ink | Твърдите изместени сенки (мастило; тъмновиолетово в тъмния режим) |
--wave-1 … --wave-6 | Пластовете, от 1 най-наситен до 6 най-блед |
--wave-highlight | Светлите щрихи върху вълните |
--glare | Мекият кръгъл отблясък върху хартията |
Тъмният режим е „мастило във виолетова нощ“: виолетово-черна хартия
(#120d1f), тебеширено мастило и по-тъмни пластове. Шрифтът е Geist
Variable. shadow-sm … shadow-xl на Tailwind са твърди мастилени
отмествания (shadow е 3px 3px 0), никога размазани.
Класове (sketch.css):
| Клас | Употреба |
|---|---|
sketch | Неравен мастилен контур, рисуван от ::before; запазете класа border на елемента (прозрачен, за оформлението). Прави елемента position: relative |
sketch-sm, sketch-lg | Набори ъгли за малки контроли и етикети и за големи панели |
sketch-double | Втора, по-бледа изместена линия (::after) за карти и диалози |
sketch-field | Полета, текстови области и падащи списъци: истинска мастилена рамка 1,5px с неправилните ъгли |
sketch-shape | Само неправилните ъгли, за запълване при посочване и избор и за блокове с код |
sketch-edge-r, -l, -t, -b | Един ръчно начертан мастилен ръб (странични ленти, заглавни ленти); линия във фона, затова остава на превъртащи се панели |
sketch-panel | Истинска ръчно начертана мастилена рамка за панели, които се превъртат (диалози) |
sketch-underline | Ръчно рисувана вълнообразна линия под текст; sketch-underline-primary я рисува във виолетово, sketch-underline-hover я показва само при посочване и фокус |
hatch-grid, hatch-tally | Драсканиците # и //// в цвета на мастилото |
paper | Фонът на страницата: хартия плюс отблясъка |
Компоненти:
SketchWaves(@entrosity/ui/components/SketchWaves): пластовете от ъгъл,corner="tr|tl|br|bl",bands3–6,highlights. Запълва кутията, която му даваclassName, и е декоративен (aria-hidden).HatchMark: една драсканица,variant="grid|tally", с размер и място отclassName.SketchFrame: графиката като контейнер (хартия, двоен контур, вълни в горния десен и долния ляв ъгъл, драсканици) за страниците за вход и заглавни секции;waves="sm|md|lg",hatches,contentClassName.SketchDefs: SVG филтрите, които правят контурите неравни; поставя иsketch-readyна<html>, което включва неравността (без него контурите са прави).ThemeProviderго монтира; монтирайте го сами само безThemeProvider.BrandLogoсunderlineрисува ръчната линия под словесната марка.SketchIllustration(0.7.0): малки илюстрации в стила на рисунката,name="empty|not-found|error|search|devices|shield|camera|network|done"; декоративни, освен ако иматtitle.EmptyState(0.7.0): илюстрация, заглавие, описание и действие за празни списъци, липса на резултати и страници 404;compactв карти.DatePicker(@entrosity/ui/date-picker, 0.7.0): ръчно начертан календар в изскачащ панел, сwithTimeза дата и час. Чете и записва същите низове като<input type="date">иtype="datetime-local"и ги заменя във всички приложения. Обикновените полетаtype="time"остават стандартни.- Графиките в
ChartContainerса начертани в същия стил (баровете и секторите с мастилен контур, неравни линии, молив за мрежата); палитрата започва с виолетовото на пластовете (--chart-1), после зелено, кехлибарено, синьо и червено.
Button, Card, Dialog, Sheet, Popover, DropdownMenu, Select, Tabs, Tooltip, Toast, Badge, StatusBadge, Table, DataTable, PageHeader и контролите на формите от библиотеката вече използват този вид.
Правила:
- Никога не слагайте
sketchна<input>,<textarea>,<select>или<img>: те не могат да имат::before. За полетата използвайтеsketch-field; изображенията оставете или очертайте контейнера им. - Не комбинирайте
sketch,sketch-fieldилиsketch-shapeсrounded-*: utility класът заменя неправилните ъгли. Кръглите точки (rounded-full) остават както са. - Сенките са твърди мастилени отмествания (
shadow-sm,shadow, …); не добавяйте размазани или цветни сенки. - Панелите, писани на ръка, са
sketch border …(sketch-doubleза големи карти,sketch-smза етикети), неrounded-md border …. - Всяка страница работи от 320px ширина нагоре: без хоризонтално превъртане на страницата, широките таблици се превъртат в собствената си кутия, филтрите и формите се подреждат един под друг на телефон, мрежите минават на една колона, диалозите се побират на екрана и се превъртат отвътре.
- Празните списъци, липсата на резултати и страниците 404 използват
EmptyState; полетата за дата използватDatePicker. - Филтърът за неравни линии се включва изрично (
sketch-wobble, @entrosity/ui 0.7.2) и само за единични елементи катоSketchFrame: SVG филтър върху всеки контрол, графика или ред от списък се преизчислява при всяко прерисуване и забавя натоварените страници. По същата причина безbackdrop-blurна залепващи заглавни ленти. - Вълните и драсканиците са украса: без текст върху вълните без плътен фон, и запазете пръстените на фокуса. В режим с висок контраст на Windows рисуваното мастило се скрива и се показват обикновени рамки.
- Този сайт копира токените и правилата в
src/css/custom.cssи филтрите вsrc/theme/Root.tsx(не зависи от@entrosity/ui); вълните на началната страница саstatic/img/waves.svgиwaves-dark.svg. Поддържайте ги в съответствие с библиотеката.