refactor: enforce enum machine codes

Use owner enums for error and T-Bank protocol values with ESLint regression checks.

Preserve open wire fallbacks and keep protocol imports independent of DI and Prisma.

Verified npm ci, verify, 226 unit tests, 262 isolated e2e tests and unchanged OpenAPI.
This commit is contained in:
2026-09-28 16:37:01 +03:00
committed by ksv741
parent 183b7f1efd
commit 33592c1d5f
47 changed files with 432 additions and 164 deletions
+43
View File
@@ -107,4 +107,47 @@ export default defineConfig(
'jest/expect-expect': ['error', { assertFunctionNames: ['expect', '**.expect'] }],
},
},
{
files: [
'src/**/*.ts',
],
ignores: [
'**/*.spec.ts',
'test/**/*.ts',
],
rules: {
'no-restricted-syntax': [
'error',
{
selector: 'Literal[value=/^(?:(?:INSTRUMENT_ID_TYPE|INSTRUMENT_TYPE|OPERATION_STATE|OPERATION_TYPE|ACCOUNT_STATUS|ACCOUNT_TYPE|CANDLE_INTERVAL|COUPON_TYPE|BANK|INVALID)_[A-Z0-9]+(?:_[A-Z0-9]+)*|[A-Z][A-Z0-9_]*_(?:ERROR|UNAVAILABLE|NOT_FOUND|NOT_CONNECTED|CONFLICT|AMBIGUOUS|REGISTERED)|P[0-9]{4}|UNAUTHORIZED|FORBIDDEN|BAD_REQUEST|NOT_FOUND|UNSUPPORTED_MEDIA_TYPE)$/]:not(TSEnumMember > Literal)',
message: 'Use the owning enum member for machine codes and protocol values.',
},
{
selector: 'TemplateElement[value.cooked=/^(?:(?:INSTRUMENT_ID_TYPE|INSTRUMENT_TYPE|OPERATION_STATE|OPERATION_TYPE|ACCOUNT_STATUS|ACCOUNT_TYPE|CANDLE_INTERVAL|COUPON_TYPE|BANK|INVALID)_[A-Z0-9]+(?:_[A-Z0-9]+)*|[A-Z][A-Z0-9_]*_(?:ERROR|UNAVAILABLE|NOT_FOUND|NOT_CONNECTED|CONFLICT|AMBIGUOUS|REGISTERED)|P[0-9]{4}|UNAUTHORIZED|FORBIDDEN|BAD_REQUEST|NOT_FOUND|UNSUPPORTED_MEDIA_TYPE)$/]:not(TSEnumMember TemplateElement)',
message: 'Use the owning enum member instead of a template machine code.',
},
{
selector: 'Property:matches([key.name=/^(code|errorCode|idType|instrumentKind)$/], [key.value=/^(code|errorCode|idType|instrumentKind)$/]) > Literal.value[value=type(string)]',
message: 'Use an enum member instead of an inline code or protocol value.',
},
{
selector: 'Property:matches([key.name=/^(code|errorCode|idType|instrumentKind)$/], [key.value=/^(code|errorCode|idType|instrumentKind)$/]) > TemplateLiteral.value',
message: 'Use an enum member instead of constructing a code or protocol value.',
},
{
selector: 'Property[computed=false][key.name=/^(OPERATION_TYPE|ACCOUNT_TYPE)_/]',
message: 'Use a computed enum member as the protocol mapping key.',
},
{
selector: 'BinaryExpression:has(> :matches(MemberExpression[property.name=/^(code|errorCode)$/], Identifier[name=/^(code|errorCode)$/])) > Literal[value=type(string)]',
message: 'Compare codes with their enum members, not string literals.',
},
{
selector: 'PropertyDefinition[definite=true], VariableDeclarator[definite=true]',
message: 'Definite assignment assertions are forbidden. Initialize owned values; use declare only for externally populated DTO fields.',
},
],
'@typescript-eslint/no-unsafe-enum-comparison': 'error',
},
},
);