@boxa-devops/depo-shared 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -0
- package/dist/LangSwitch.d.ts +22 -0
- package/dist/LangSwitch.d.ts.map +1 -0
- package/dist/LangSwitch.js +26 -0
- package/dist/LangSwitch.js.map +1 -0
- package/dist/PartPhoto.d.ts +13 -0
- package/dist/PartPhoto.d.ts.map +1 -0
- package/dist/PartPhoto.js +21 -0
- package/dist/PartPhoto.js.map +1 -0
- package/dist/api.d.ts +20739 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +6 -0
- package/dist/api.js.map +1 -0
- package/dist/errors.d.ts +18 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +18 -0
- package/dist/errors.js.map +1 -0
- package/dist/i18nGuard.d.ts +29 -0
- package/dist/i18nGuard.d.ts.map +1 -0
- package/dist/i18nGuard.js +75 -0
- package/dist/i18nGuard.js.map +1 -0
- package/dist/i18nKeys.d.ts +16 -0
- package/dist/i18nKeys.d.ts.map +1 -0
- package/dist/i18nKeys.js +16 -0
- package/dist/i18nKeys.js.map +1 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/lang.d.ts +7 -0
- package/dist/lang.d.ts.map +1 -0
- package/dist/lang.js +24 -0
- package/dist/lang.js.map +1 -0
- package/dist/status.d.ts +3 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +23 -0
- package/dist/status.js.map +1 -0
- package/error_codes.json +699 -0
- package/openapi.json +42042 -0
- package/package.json +53 -0
- package/permissions.json +70 -0
- package/src/LangSwitch.tsx +44 -0
- package/src/PartPhoto.tsx +48 -0
- package/src/api.ts +20739 -0
- package/src/errors.ts +25 -0
- package/src/i18nGuard.ts +77 -0
- package/src/i18nKeys.ts +15 -0
- package/src/index.ts +168 -0
- package/src/lang.ts +26 -0
- package/src/status.ts +23 -0
- package/tokens.css +141 -0
package/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# depo-contract
|
|
2
|
+
|
|
3
|
+
Контракт между сервисами электронной инвентаризации локомотивного депо:
|
|
4
|
+
сгенерированные типы API, design-токены, общие guard-функции и документация,
|
|
5
|
+
которую читают все репозитории.
|
|
6
|
+
|
|
7
|
+
Публикует npm-пакет **`@boxa-devops/depo-shared`** в GitHub Packages.
|
|
8
|
+
|
|
9
|
+
## Репозитории
|
|
10
|
+
|
|
11
|
+
| репозиторий | что |
|
|
12
|
+
|---|---|
|
|
13
|
+
| `depo-api` | FastAPI-ядро: БД, журнал событий, API-поверхность |
|
|
14
|
+
| `depo-terminal` | киоск цеха: React + Dexie, офлайн-очередь |
|
|
15
|
+
| `depo-admin` | платформа начальника/админа: аналитика, справочники |
|
|
16
|
+
| `depo-contract` | этот репозиторий |
|
|
17
|
+
|
|
18
|
+
Клонировать все четыре рядом, одним уровнем: `depo-api/make contract`
|
|
19
|
+
пишет сюда по относительному пути, а CLAUDE.md сервисов ссылаются на
|
|
20
|
+
`../depo-contract/docs/TZ.md`.
|
|
21
|
+
|
|
22
|
+
## Документация
|
|
23
|
+
|
|
24
|
+
| файл | что |
|
|
25
|
+
|---|---|
|
|
26
|
+
| `docs/TZ.md` | ТЗ и модель данных — источник истины |
|
|
27
|
+
| `docs/DEBT.md` | техдолг, реестр «на бэке готово, фронт ждёт» |
|
|
28
|
+
| `docs/DEPLOY.md` | Railway, переменные, релиз пакета |
|
|
29
|
+
| `docs/CHANGELOG-mono.md` | история до разреза (заморожена) |
|
|
30
|
+
| `docs/archive/` | GATES B20, REFACTOR_PLAN, README монорепо |
|
|
31
|
+
|
|
32
|
+
## Команды
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
pnpm install
|
|
36
|
+
pnpm generate # openapi.json -> src/api.ts (после ../depo-api: make contract)
|
|
37
|
+
pnpm lint
|
|
38
|
+
pnpm typecheck # единственный гейт, видящий ошибку типов внутри пакета
|
|
39
|
+
pnpm test
|
|
40
|
+
pnpm build # dist/: ESM + .d.ts + sourcemaps
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Релиз
|
|
44
|
+
|
|
45
|
+
1. `cd ../depo-api && make contract` — перегенерировать контракт сюда.
|
|
46
|
+
2. `pnpm generate && pnpm lint && pnpm typecheck && pnpm test && pnpm build`.
|
|
47
|
+
3. **Прогнать `pnpm test` в `depo-terminal` и `depo-admin`** — одной
|
|
48
|
+
командой на оба это больше не сделать (было `pnpm -r test`).
|
|
49
|
+
4. Посмотреть `git diff openapi.json` глазами, поднять версию, записать
|
|
50
|
+
в `CHANGELOG.md`.
|
|
51
|
+
5. Человек: `git commit`, `git tag vX.Y.Z`, `git push --follow-tags` →
|
|
52
|
+
workflow публикует пакет.
|
|
53
|
+
|
|
54
|
+
Правила версионирования и остальные детали — `CLAUDE.md`.
|
|
55
|
+
|
|
56
|
+
## Аутентификация к GitHub Packages
|
|
57
|
+
|
|
58
|
+
Локально нужен classic PAT со **только** `read:packages`:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
setx NODE_AUTH_TOKEN <pat> # один раз, затем новая консоль
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`.npmrc` в каждом JS-репозитории подставляет его из окружения — сам токен
|
|
65
|
+
в файлы не попадает. Публикацию делает CI под `secrets.GITHUB_TOKEN`,
|
|
66
|
+
отдельный PAT для неё не нужен.
|
|
67
|
+
|
|
68
|
+
## Происхождение
|
|
69
|
+
|
|
70
|
+
Выделен из монорепозитория `depo_mono` (коммит `c142574`, тег `pre-split`);
|
|
71
|
+
там это был `packages/shared` плюс `docs/`. Монорепозиторий сохранён как
|
|
72
|
+
архив и только для чтения.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** RU/UZ toggle. i18next re-renders every consumer on change, so no reload.
|
|
2
|
+
* Two sizes: "desk" for the admin header, "kiosk" for 48px monoblock targets.
|
|
3
|
+
* `type` is part of the preset on purpose — the desk switch sits inside the
|
|
4
|
+
* login <form> and has always rendered a default (submit) button; changing
|
|
5
|
+
* that is a behaviour change, see docs/DEBT.md. */
|
|
6
|
+
declare const PRESET: {
|
|
7
|
+
desk: {
|
|
8
|
+
wrap: string;
|
|
9
|
+
type: "submit";
|
|
10
|
+
cls: (on: boolean) => string;
|
|
11
|
+
};
|
|
12
|
+
kiosk: {
|
|
13
|
+
wrap: string;
|
|
14
|
+
type: "button";
|
|
15
|
+
cls: (on: boolean) => string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export declare function LangSwitch({ size }: {
|
|
19
|
+
size?: keyof typeof PRESET;
|
|
20
|
+
}): import("react").JSX.Element;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=LangSwitch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LangSwitch.d.ts","sourceRoot":"","sources":["../src/LangSwitch.tsx"],"names":[],"mappings":"AAIA;;;;oDAIoD;AACpD,QAAA,MAAM,MAAM;;;;kBAIE,OAAO;;;;;kBAQP,OAAO;;CAEpB,CAAC;AAEF,wBAAgB,UAAU,CAAC,EAAE,IAAa,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,OAAO,MAAM,CAAA;CAAE,+BAkB3E"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation } from "react-i18next";
|
|
3
|
+
import { LANGS, setLanguage } from "./lang.js";
|
|
4
|
+
/** RU/UZ toggle. i18next re-renders every consumer on change, so no reload.
|
|
5
|
+
* Two sizes: "desk" for the admin header, "kiosk" for 48px monoblock targets.
|
|
6
|
+
* `type` is part of the preset on purpose — the desk switch sits inside the
|
|
7
|
+
* login <form> and has always rendered a default (submit) button; changing
|
|
8
|
+
* that is a behaviour change, see docs/DEBT.md. */
|
|
9
|
+
const PRESET = {
|
|
10
|
+
desk: {
|
|
11
|
+
wrap: "gap-0.5",
|
|
12
|
+
type: "submit",
|
|
13
|
+
cls: (on) => `rounded-md px-2 py-1 text-xs font-medium uppercase transition ${on ? "bg-accent-tint text-accent" : "text-ink-3 hover:bg-hover hover:text-ink"}`,
|
|
14
|
+
},
|
|
15
|
+
kiosk: {
|
|
16
|
+
wrap: "gap-1",
|
|
17
|
+
type: "button",
|
|
18
|
+
cls: (on) => `chip font-semibold uppercase ${on ? "chip-active" : ""}`,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
export function LangSwitch({ size = "desk" }) {
|
|
22
|
+
const { i18n, t } = useTranslation();
|
|
23
|
+
const p = PRESET[size];
|
|
24
|
+
return (_jsx("div", { className: `flex items-center ${p.wrap}`, role: "group", "aria-label": t("lang.switch"), children: LANGS.map((l) => (_jsx("button", { type: p.type, onClick: () => setLanguage(l), "aria-pressed": i18n.language === l, className: p.cls(i18n.language === l), children: l }, l))) }));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=LangSwitch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LangSwitch.js","sourceRoot":"","sources":["../src/LangSwitch.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE/C;;;;oDAIoD;AACpD,MAAM,MAAM,GAAG;IACb,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,QAAiB;QACvB,GAAG,EAAE,CAAC,EAAW,EAAE,EAAE,CACnB,iEACE,EAAE,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,0CACtC,EAAE;KACL;IACD,KAAK,EAAE;QACL,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,QAAiB;QACvB,GAAG,EAAE,CAAC,EAAW,EAAE,EAAE,CAAC,gCAAgC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE;KAChF;CACF,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,GAAG,MAAM,EAAkC;IAC1E,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,cAAc,EAAE,CAAC;IACrC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,CACL,cAAK,SAAS,EAAE,qBAAqB,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAC,OAAO,gBAAa,CAAC,CAAC,aAAa,CAAC,YACrF,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAChB,iBAEE,IAAI,EAAE,CAAC,CAAC,IAAI,EACZ,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,kBACf,IAAI,CAAC,QAAQ,KAAK,CAAC,EACjC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,CAAC,YAEpC,CAAC,IANG,CAAC,CAOC,CACV,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** The picture of a part TYPE, with the fallback that matters more than the
|
|
2
|
+
* picture: a type with no photo gets its CODE on a coloured plate, not an
|
|
3
|
+
* empty frame. The colour is derived from the code, so the same type keeps
|
|
4
|
+
* the same plate on every screen and a master recognises it by shape+colour
|
|
5
|
+
* long before reading it. */
|
|
6
|
+
export declare function PartPhoto({ photoKey, code, name, className, }: {
|
|
7
|
+
photoKey: string | null | undefined;
|
|
8
|
+
code: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
/** sizing/rounding of the box — the caller owns the geometry */
|
|
11
|
+
className?: string;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=PartPhoto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PartPhoto.d.ts","sourceRoot":"","sources":["../src/PartPhoto.tsx"],"names":[],"mappings":"AAAA;;;;8BAI8B;AAS9B,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,IAAI,EACJ,IAAI,EACJ,SAAc,GACf,EAAE;IACD,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAuBA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/** The picture of a part TYPE, with the fallback that matters more than the
|
|
3
|
+
* picture: a type with no photo gets its CODE on a coloured plate, not an
|
|
4
|
+
* empty frame. The colour is derived from the code, so the same type keeps
|
|
5
|
+
* the same plate on every screen and a master recognises it by shape+colour
|
|
6
|
+
* long before reading it. */
|
|
7
|
+
/** Stable hue for a code — plain FNV-ish walk, no hashing library. */
|
|
8
|
+
function hueOf(code) {
|
|
9
|
+
let h = 0;
|
|
10
|
+
for (const ch of code)
|
|
11
|
+
h = (h * 31 + ch.codePointAt(0)) % 360;
|
|
12
|
+
return h;
|
|
13
|
+
}
|
|
14
|
+
export function PartPhoto({ photoKey, code, name, className = "", }) {
|
|
15
|
+
if (photoKey) {
|
|
16
|
+
return (_jsx("img", { src: `/api/v1/attachments/${photoKey}`, alt: name ?? code, loading: "lazy", className: `object-cover ${className}` }));
|
|
17
|
+
}
|
|
18
|
+
const hue = hueOf(code);
|
|
19
|
+
return (_jsx("div", { role: "img", "aria-label": name ?? code, "data-placeholder": code, className: `flex items-center justify-center overflow-hidden px-1 text-center font-mono font-bold leading-none tracking-tight ${className}`, style: { background: `hsl(${hue} 55% 88%)`, color: `hsl(${hue} 70% 26%)` }, children: code }));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=PartPhoto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PartPhoto.js","sourceRoot":"","sources":["../src/PartPhoto.tsx"],"names":[],"mappings":";AAAA;;;;8BAI8B;AAE9B,sEAAsE;AACtE,SAAS,KAAK,CAAC,IAAY;IACzB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,MAAM,EAAE,IAAI,IAAI;QAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,GAAG,GAAG,CAAC;IAC/D,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EACxB,QAAQ,EACR,IAAI,EACJ,IAAI,EACJ,SAAS,GAAG,EAAE,GAOf;IACC,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,CACL,cACE,GAAG,EAAE,uBAAuB,QAAQ,EAAE,EACtC,GAAG,EAAE,IAAI,IAAI,IAAI,EACjB,OAAO,EAAC,MAAM,EACd,SAAS,EAAE,gBAAgB,SAAS,EAAE,GACtC,CACH,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;IACxB,OAAO,CACL,cACE,IAAI,EAAC,KAAK,gBACE,IAAI,IAAI,IAAI,sBACN,IAAI,EACtB,SAAS,EAAE,qHAAqH,SAAS,EAAE,EAC3I,KAAK,EAAE,EAAE,UAAU,EAAE,OAAO,GAAG,WAAW,EAAE,KAAK,EAAE,OAAO,GAAG,WAAW,EAAE,YAEzE,IAAI,GACD,CACP,CAAC;AACJ,CAAC"}
|