framework_eng/skills/bsl-practices/api-design/SKILL.md
Use for designing and reviewing the public API of 1C subsystems. Helps classify export methods into 5 categories, verify backward compatibility, and design versioning with deprecated wrappers.
npx skillsauth add steelmorgan/1c-agent-based-dev-framework api-designInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Based on the Infostart article "API Base": https://infostart.ru/1c/articles/2683808/.
1C in enterprise solutions is a modular monolith: libraries consist of functional subsystems, and subsystems communicate through declared interfaces. An arbitrary call across subsystem boundaries is an architectural defect, not a convenient technique. This skill teaches the agent to classify export methods correctly, determine whether changes are allowed, and design APIs with compatibility in mind.
| Trigger | Action |
|---------|---------|
| Designing a new common module or export method | Apply interface classification (5 categories), document the contract |
| Changing the signature of an existing export method | Check backward compatibility against the table below |
| Adding a parameter to an export method | Determine whether it is mandatory or optional; assess the impact on the version |
| Deleting or renaming an export method | Create a deprecated wrapper in УстаревшиеПроцедурыИФункции |
| Code review: calling a method from another subsystem | Check the category of the called method (is the call allowed?) |
| Code review: changing behavior without changing the signature | Check whether this breaks the contract (ПрограммныйИнтерфейс) |
| Question about a version bump when releasing changes | Apply versioning rules (section "Versioning") |
Each export method must belong to exactly one of the 5 categories. The category is determined by the module #Область in which the method is located.
#Область ПрограммныйИнтерфейсPublic contract for external consumers - other libraries, application solutions, integrations.
#Область ПрограммныйИнтерфейс
// Возвращает курс валюты на указанную дату.
//
// Параметры:
// Валюта - СправочникСсылка.Валюты - валюта, курс которой нужно получить.
// ДатаКурса - Дата - дата, на которую нужен курс.
// Если не указана, используется текущая дата сеанса.
//
// Возвращаемое значение:
// Число - курс валюты. 0 если курс не найден.
//
Функция КурсВалюты(Валюта, ДатаКурса = Неопределено) Экспорт
Возврат РаботаСВалютами.КурсВалюты(Валюта, ДатаКурса);
КонецФункции
#КонецОбласти
#Область СлужебныйПрограммныйИнтерфейсContract for calls from other modules within the same library (not for external consumers).
#Область СлужебныйПрограммныйИнтерфейс
// Обновляет кэш курсов валют при изменении данных.
// Вызывается только из подписки на событие РаботаСВалютамиОбновлениеКурсов.
//
Процедура ОбновитьКэшКурсовВалют() Экспорт
// ...
КонецПроцедуры
#КонецОбласти
#Область ПереопределяемыйИнтерфейсExtension point: the library calls a consumer method (through overridable modules).
// Модуль: РаботаСФайламиПереопределяемый
#Область ПереопределяемыйИнтерфейс
// Определяет настройки хранения присоединённых файлов.
//
// Параметры:
// НастройкиХранения - Структура - настройки, которые нужно заполнить.
//
Процедура ОпределитьНастройкиХраненияФайлов(НастройкиХранения) Экспорт
// Обязательно вызовите Базовую реализацию или заполните структуру самостоятельно.
КонецПроцедуры
#КонецОбласти
#Область ДляВызоваИзДругихПодсистемStable integration zone between subsystems of one solution.
#Область СлужебныеПроцедурыИФункцииInternal implementation of one functional subsystem. Not exported.
Export or move it to the appropriate category.| Change | Condition |
|--------|-----------|
| Adding an optional parameter | Old calls work without it |
| Adding a new method to ПрограммныйИнтерфейс | Does not conflict with consumer names |
| Changing the implementation without changing behavior | The contract is not violated |
| Fixing a bug in the implementation | Documented in the changelog |
| Change | Requirement |
|--------|-------------|
| Adding a mandatory parameter | Preserve the old signature as deprecated, the new method must have a new name or overload |
| Removing a method from ПрограммныйИнтерфейс | Deprecated wrapper in УстаревшиеПроцедурыИФункции + migration path |
| Renaming a method | Deprecated wrapper with the old name |
| Changing a parameter type (incompatible) | Deprecated wrapper, new parameter through an optional parameter or overload |
| Changing the meaning of a parameter (behavior break) | New parameter name or documenting the breaking change |
| Direct access to another subsystem's data | Forbidden without an explicit API |
Backward compatibility requirements override cosmetic standards. You cannot rename a public method "for better style" without a deprecated wrapper.
When deprecating a method:
#Область УстаревшиеПроцедурыИФункции.// Deprecated. Use <NewMethod>().#Область УстаревшиеПроцедурыИФункции
// Устарела. Используйте КурсВалютыНаДату().
// Будет удалена в версии 4.0.
//
// Параметры:
// Валюта - СправочникСсылка.Валюты
// ДатаКурса - Дата
//
// Возвращаемое значение:
// Число
//
Функция ПолучитьКурсВалюты(Валюта, ДатаКурса) Экспорт
Возврат КурсВалютыНаДату(Валюта, ДатаКурса);
КонецФункции
#КонецОбласти
| Change type | Bump |
|-------------|------|
| Fixing a bug without changing API behavior | build (x.x.x.N) |
| New optional parameter, new method in PI | minor (x.N.0.0) |
| Breaking change with a deprecated wrapper | minor + documentation |
| Removal of a deprecated method, incompatible type | major (N.0.0.0) |
Forbidden: introducing a public API expansion (new methods, new parameters) in a release with only a build bump. Build is for bug fixes only.
Use code-navigation (grep over source files) to search for:
#Область.#Область УстаревшиеПроцедурыИФункции sections - check for deprecated wrappers.// Поиск объявления метода
// grep: "Функция КурсВалюты" или "Процедура КурсВалюты"
// Поиск вызовов
// grep: "РаботаСВалютами.КурсВалюты"
// Поиск deprecated-области
// grep: "Устаревшие процедуры и функции"
Determine which category the method belongs to, and choose from the table below:
| Change type | Method category | Requirement |
|-------------|-----------------|-------------|
| New method | Any | Place it in the correct #Область |
| New optional parameter | ПрограммныйИнтерфейс | Allowed, version bump |
| New mandatory parameter | ПрограммныйИнтерфейс | Deprecated wrapper required |
| Method removal | ПрограммныйИнтерфейс | Deprecated wrapper required |
| Behavior change | ПрограммныйИнтерфейс | Considered a breaking change |
| Any change | СлужебныеПроцедурыИФункции | Free (within the subsystem) |
| New mandatory parameter | ПереопределяемыйИнтерфейс | Forbidden |
syntax-checkingAfter changing the signature:
Every method in ПрограммныйИнтерфейс and ПереопределяемыйИнтерфейс must have:
Context: developer asks to add the ПолучитьОстатокТоваров() function to the common module УправлениеЗапасами.
Steps:
#Область ПрограммныйИнтерфейс.СлужебныеПроцедурыИФункции).Context: reviewer receives a PR where a new mandatory parameter ИсточникКурса has been added to РаботаСВалютами.КурсВалюты().
Steps:
code-navigation: find all calls to РаботаСВалютами.КурсВалюты( - assess the number of consumers.#Область - if it is ПрограммныйИнтерфейс, then it is a breaking change.УстаревшиеПроцедурыИФункции with a call to the new method.КурсВалютыИзИсточника) or the parameter should be made optional.Context: architect is designing a new extension point for a notification mechanism.
Steps:
#Область ПереопределяемыйИнтерфейс.Context: reviewer notices a call to ЧастнаяПодсистема.ВнутреннийМетод() from another module.
Steps:
#Область of the called method.СлужебныеПроцедурыИФункции, it is a defect; record it in the review comment.ДляВызоваИзДругихПодсистем or ПрограммныйИнтерфейс.СлужебныйПрограммныйИнтерфейс and the call comes from another library, request an explicit agreement or a refactor.| Mistake | Consequence | How to avoid |
|---------|-------------|--------------|
| Calling СлужебныеПроцедурыИФункции from another subsystem | Fragile integration, break during refactoring | Check #Область before calling |
| Adding a mandatory parameter without a deprecated wrapper | Breaks all calls in CI | Always create an adapter in УстаревшиеПроцедурыИФункции |
| API expansion in a build-only release | Versioning violation, confusion for consumers | Build is for bug fixes only |
| A method in ПереопределяемыйИнтерфейс with a new mandatory parameter | Errors in all existing implementations | Only optional parameters in overridable interfaces |
| Changing the meaning of a parameter without documentation | Silent behavioral break | Document in the changelog, consider a version bump |
| Suppressing BSL LS warnings without a reason | Hidden breaking changes | Always document the reason for suppression |
| Direct access to another subsystem's data tables | Tight coupling, architectural debt | Use only documented API |
Before implementing a new API:
#Область) is chosen for each method#Область), rules for commenting export methodshttps://infostart.ru/1c/articles/2683808/depends_on:
testing
MUST use BEFORE making a judgment about the cause of a conflict, a test failure, or an artifact dispute. Defines the end-to-end verification method L1→L6 and the classification of the first broken link.
development
MUST use AFTER a work cycle with ≥2 iterations (wrote → error → fixed → success). Provides the retrospective procedure and the format for recording practice/anti-patterns in references/learned-patterns.md or {project}/.context/learned-patterns.md.
tools
MUST use WHEN you are writing reusable knowledge into RLM (pattern / architectural decision / stable domain fact) OR reading it before a non-trivial task/solution in the domain. Provides the breakdown of native-push vs RLM-pull, tools for writing and reading RLM, H-MEM levels, and hygiene.
testing
MUST use WHEN the task is classified as simple (< 20 lines, 1 file, no new metadata objects, no architectural decisions). Provides a short cycle of 3 steps with a guard on the self path and mandatory verify.