513 lines
24 KiB
Markdown
513 lines
24 KiB
Markdown
# 1C Connector
|
|
|
|
Standalone-ready service for safe interaction with live 1C databases.
|
|
|
|
The connector is read-first and optimized for an operational coding loop where full XML export and EDT sync are too slow for every task.
|
|
|
|
Preferred live architecture:
|
|
|
|
- read-only SQL connector for fast diagnostics and data samples;
|
|
- lightweight 1C agent for metadata, forms, commands, and BSL modules;
|
|
- cached metadata/module snapshots with freshness checks;
|
|
- change proposals as reviewable artifacts, not direct production writes.
|
|
|
|
The connector is responsible for:
|
|
|
|
- metadata reads;
|
|
- BSL module search/read;
|
|
- read-only query validation and execution;
|
|
- metadata/module snapshots;
|
|
- change proposals without direct apply.
|
|
|
|
Contracts:
|
|
|
|
- `contracts/openapi.yaml`
|
|
- `policies/read-only-query.yaml`
|
|
- `policies/change-workflow.yaml`
|
|
- `policies/config-layer-write-policy.yaml`
|
|
- `policies/sql-base-access-policy.yaml`
|
|
- `policies/xml-decoding-reference-policy.yaml`
|
|
|
|
The model must use this connector instead of inventing metadata or directly changing a live database.
|
|
|
|
XML exports are development-time evidence only. They may be analyzed by
|
|
repository scripts to infer and test generic SQL payload decoders, but the
|
|
running connector is configured only with a SQL entry for `base_id`. It does
|
|
not mount or read XML and rejects XML path arguments in runtime requests.
|
|
|
|
## Standalone boundary
|
|
|
|
This directory is the service boundary for the adapter. It is still developed
|
|
inside the current monorepo, but it should be kept movable as an independent
|
|
project.
|
|
|
|
Service-owned files:
|
|
|
|
- `adapter_1c_server.py`
|
|
- `contracts/openapi.yaml`
|
|
- `policies/*.yaml`
|
|
- `Dockerfile`
|
|
- `docker-compose.yml`
|
|
- `.env.example`
|
|
- `pyproject.toml`
|
|
- `service.yaml`
|
|
- sibling package `../parser`
|
|
|
|
Repository-owned integration files:
|
|
|
|
- `plugins/1c/mcp/adapter_1c_mcp.py`
|
|
- `plugins/1c/agent/`
|
|
- `plugins/1c/rag/`
|
|
- `plugins/1c/training/`
|
|
- top-level health and contract scripts under `scripts/`
|
|
|
|
The connector must not depend on RAG, training, or agent code. MCP and agent
|
|
code may depend on the connector contract.
|
|
|
|
## Local Run
|
|
|
|
From `plugins/1c`:
|
|
|
|
```powershell
|
|
python connector/adapter_1c_server.py
|
|
```
|
|
|
|
From `plugins/1c/connector` after installing package dependencies:
|
|
|
|
```powershell
|
|
python adapter_1c_server.py
|
|
```
|
|
|
|
Health without a concrete base:
|
|
|
|
```powershell
|
|
Invoke-RestMethod http://localhost:8011/health
|
|
```
|
|
|
|
Live database calls require `base_id` and SQL connection configuration.
|
|
|
|
## Configuration repository operations
|
|
|
|
Repository access is configured per `base_id`, preferably as a `repository`
|
|
object inside the same JSON entry used by `ONEC_SQL_BASES_JSON_FILE`. The
|
|
repository backend is never inferred from a bridge name or endpoint. Set
|
|
`backend` explicitly to `direct` or `karman_bridge`; both backends execute the
|
|
standard 1C Designer repository commands, while a Karman/Filebox bridge only
|
|
relays the native opaque TCP stream.
|
|
|
|
See `config/1c_repository_bases.example.json` for a secret-free example.
|
|
Passwords are resolved only from the configured environment-variable names.
|
|
The adapter does not return them or store them in lock-session state.
|
|
|
|
When the adapter runs in a Linux container and Designer is installed on the
|
|
Windows Docker host, use `runner.kind=http`. Run
|
|
`scripts/run_1c_repository_runner.py` on Windows with its own external base
|
|
configuration (example: `config/1c_repository_runner_bases.example.json`). The
|
|
container sends only `base_id`, action, public object names, and commit comment;
|
|
infobase/repository credentials remain on the Windows runner. Protect the
|
|
runner with `ONEC_REPOSITORY_RUNNER_TOKEN` and a host firewall rule limited to
|
|
the Docker host/container network.
|
|
|
|
The guarded workflow is:
|
|
|
|
1. `repository.status` (optionally `probe=true`);
|
|
2. `repository.lock.plan` with public 1C object names;
|
|
3. `repository.lock` with `allow_repository_lock=true`;
|
|
4. pass the returned `lock_session_id` to write preflight/apply;
|
|
5. `repository.commit.plan` and explicit `repository.commit`, or
|
|
`repository.unlock` for only that adapter-owned session.
|
|
|
|
Apply operations are blocked for a repository-configured base unless an active
|
|
adapter-owned lock session is supplied. Structural add/delete/rename plans are
|
|
kept blocked for confirmation because parent and reference objects can also be
|
|
required.
|
|
|
|
## Docker Run
|
|
|
|
Create a local `.env` from `.env.example`, keep real passwords outside git, and
|
|
run:
|
|
|
|
```powershell
|
|
docker compose -f plugins/1c/connector/docker-compose.yml --env-file plugins/1c/connector/.env up -d --build
|
|
```
|
|
|
|
The compose build context is `plugins/1c` because the adapter imports the
|
|
sibling `parser` package. If this service is moved to a separate repository,
|
|
copy `plugins/1c/parser` into that repository or publish it as a package.
|
|
|
|
## Standalone Extraction Checklist
|
|
|
|
When the adapter is eventually moved out of this monorepo:
|
|
|
|
1. Copy `connector/` and `parser/`.
|
|
2. Keep `contracts/openapi.yaml` versioned with releases.
|
|
3. Keep policies with the service.
|
|
4. Keep `service.yaml`, `pyproject.toml`, `Dockerfile`, `docker-compose.yml`,
|
|
and `.env.example`.
|
|
5. Move or duplicate contract checks that assert public behavior:
|
|
`check_1c_write_plan_contract.py`,
|
|
`check_1c_extension_action_contract.py`,
|
|
`check_1c_module_origin_contract.py`, and
|
|
`check_1c_code_symbol_contract.py`.
|
|
6. Do not move RAG datasets, training configs, or agent prompts into the
|
|
adapter service unless they become runtime dependencies.
|
|
|
|
## Live database access
|
|
|
|
### Web management
|
|
|
|
The runtime SQL connection list can be viewed and edited at
|
|
`http://<adapter-host>:8011/admin/`. The screen supports adding, editing, and
|
|
deleting entries and writes them atomically to `ONEC_SQL_BASES_JSON_FILE`
|
|
(normally `/data/onec-sql-bases.json`). Production-style deployments should set
|
|
`ONEC_ADAPTER_SERVICE_TOKEN`; the browser keeps it only in session storage. For
|
|
the isolated test profile, `ONEC_ADAPTER_ALLOW_UNAUTHENTICATED_ADMIN=true`
|
|
explicitly permits access without a token. Stored SQL passwords are never
|
|
returned by the API in either profile.
|
|
|
|
When `ONEC_SQL_BASES_JSON` is set directly, web editing is disabled because the
|
|
environment value would override the file. Move the connection map to the
|
|
configured JSON file before using the screen.
|
|
|
|
The adapter is not tied to one 1C database. Requests that read database-specific
|
|
sources must pass `base_id`; otherwise the adapter returns `base_id_required`.
|
|
|
|
### Mandatory SQL base access rule
|
|
|
|
`base_id` is the required settings key. Its entry contains the SQL server IP or
|
|
host, SQL database name, login, and password (preferably through
|
|
`password_env`). The adapter uses only that entry's existing credentials. It
|
|
must never create or change SQL logins, database users, roles, or permissions.
|
|
|
|
Application data and the metadata structure are read-only. The only SQL write
|
|
exception is a reviewed metadata saved-state change:
|
|
|
|
- base configuration metadata → `ConfigSave`;
|
|
- extension metadata → `ConfigCASSave`.
|
|
|
|
The exception does not permit writes to application-data tables, `Config`, or
|
|
`ConfigCAS`, and does not activate the saved configuration. Saved-state writes
|
|
remain gated by explicit opt-in, SHA-1 precondition, backup, transaction, and
|
|
readback verification. The binding policy is
|
|
`policies/sql-base-access-policy.yaml`.
|
|
|
|
Configure every base explicitly. Prefer `password_env` so secrets stay outside
|
|
repository files:
|
|
|
|
```json
|
|
{
|
|
"upo_test": {
|
|
"server": "sql-host.example.local",
|
|
"database": "upo_test",
|
|
"user": "configured_login",
|
|
"password_env": "ONEC_SQL_PASSWORD_UPO_TEST"
|
|
}
|
|
}
|
|
```
|
|
|
|
Set it as `ONEC_SQL_BASES_JSON` and pass the password separately as
|
|
`ONEC_SQL_PASSWORD_UPO_TEST`, or mount the same JSON outside the repository and
|
|
set `ONEC_SQL_BASES_JSON_FILE` to its container path. There is no implicit or
|
|
default database connection.
|
|
|
|
Current live methods:
|
|
|
|
- `query.validate`
|
|
- `query.run`
|
|
- `extensions.list`
|
|
- `schema.tables.list`
|
|
- `storage.files.list`
|
|
- `storage.file.get`
|
|
- `metadata.dbnames.summary`
|
|
- `metadata.kinds`
|
|
- `metadata.objects.list`
|
|
- `metadata.object.get`
|
|
- `metadata.object.properties`
|
|
- `metadata.object.decode`
|
|
- `metadata.object.parts`
|
|
- `metadata.object.modules`
|
|
- `metadata.object.related`
|
|
- `metadata.object.forms`
|
|
- `metadata.object.templates`
|
|
- `metadata.object.template.details`
|
|
- `templates.read`
|
|
- `templates.analyze`
|
|
- `templates.map`
|
|
- `metadata.route.resolve`
|
|
- `metadata.form.decode`
|
|
- `metadata.object.attributes`
|
|
- `metadata.object.full`
|
|
- `metadata.snapshot`
|
|
- `codec.decode`
|
|
- `codec.encode`
|
|
- `extension.objects.find`
|
|
- `modules.search`
|
|
- `modules.read`
|
|
|
|
Metadata methods require `base_id` and read live `Params`, `Config`, and
|
|
`ConfigCAS` storage through SQL. They do not use filesystem route indexes as a
|
|
source of truth. High-level metadata methods return 1C-facing data by default:
|
|
object identity, synonyms, decoded semantic sections, forms, modules, and
|
|
counts. Physical SQL table names, `_Fld...` columns, DBNames indexes, and
|
|
storage routes are internal diagnostics and are exposed only by low-level
|
|
methods (`storage.*`, `schema.*`, `query.*`, `metadata.dbnames.*`) or by
|
|
passing `include_storage=true`.
|
|
|
|
Object-scoped adapter methods accept the same public selector shapes:
|
|
`ref`, `kind` + `name`, `guid`, or MCP-friendly
|
|
`object_type`/`object_name`/`object_guid`. `ref` may use Russian or English
|
|
qualified metadata names such as `Обработка.<Name>` or `Document.<Name>`.
|
|
Client, MCP, and agent code must not add conditions for concrete object names;
|
|
the adapter owns generic selector normalization.
|
|
|
|
Layer write policy:
|
|
|
|
- `Config` and `ConfigCAS` are **active-applied** and must be treated as read-only in adapter workflows.
|
|
- `ConfigSave` and `ConfigCASSave` are **saved, not yet applied** layers and are the only writable targets for connector staging changes.
|
|
- Base vs extension mapping:
|
|
- base config → `ConfigSave`
|
|
- extension config → `ConfigCASSave`
|
|
- Production apply to active layers is out of scope for this connector and requires a separate human-controlled deployment path.
|
|
|
|
Agent-facing code write rule:
|
|
|
|
- BSL edits must use `code.write`, not low-level SQL/write helpers.
|
|
- The agent passes 1C names (`object_type`/`object_name`/`routine_name`) or a
|
|
public path such as `<extension>.<form>.<routine>` plus full code text.
|
|
- `code.write` automatically targets the saved-state layer and reports
|
|
`write_mode.target=saved_state` with `activation_state=not_activated`.
|
|
- Use `code.read`/`code.search` with the default working state for current
|
|
programming-time code; use `state=both` only when an explicit saved vs active
|
|
comparison is needed.
|
|
|
|
`metadata.object.get` returns a live object card and decoded semantic sections
|
|
without physical SQL/storage traces by default. `metadata.object.decode` also
|
|
returns a 1C-facing decoded object profile by default; pass
|
|
`include_storage=true` only when adapter diagnostics need the underlying decoded
|
|
payload metadata, record containers, or DBNames/storage routes.
|
|
|
|
`metadata.object.properties` is the unified property endpoint for every 1C
|
|
metadata kind. It selects a kind-specific SQL decoder for `Configuration`,
|
|
`Constant`, `DocumentNumerator`, `IntegrationService`, `CommandGroup`,
|
|
`ScheduledJob`, and `DocumentJournal`, and otherwise returns the generic live
|
|
semantic profile. XML exports are analysis evidence only and are never a
|
|
runtime source for this method or any other adapter method.
|
|
|
|
Managed form bodies in base `Config` are resolved from the public form GUID to
|
|
the sibling `<guid>.0` SQL payload. Command-bar buttons expose public command
|
|
names when their SQL binding points to a common command or a recognized
|
|
platform standard command; standard reference field `-5` is exposed as a
|
|
public `...Ref` data path. Callers never need the internal GUIDs or field codes.
|
|
Element event GUIDs are converted to platform event names (for example
|
|
`OnChange`, `ChoiceProcessing`, `AutoComplete`, `Selection`, and table row
|
|
events) and linked to their BSL handlers when the routine is present.
|
|
|
|
`metadata.object.attributes` is the preferred method for "show object
|
|
attributes/requisites" questions. It returns 1C metadata attribute names and
|
|
tabular section names from the live Config payload. For tabular sections, it
|
|
also returns decoded column names when nested column records are present.
|
|
Attributes and columns include decoded type evidence (`date`, `boolean`,
|
|
`string`, `number`, `reference`) and visible type parameters such as string
|
|
length, number precision/scale, or reference type GUID. Reference type GUIDs are
|
|
resolved back to live metadata object names and synonyms when the referenced
|
|
type exists in the base metadata. It must be preferred over SQL table/column
|
|
inspection for user-facing answers. The object can be selected by `guid`, by
|
|
`kind` + `name`, or by 1-based `ordinal` within `metadata.objects.list` for that
|
|
kind.
|
|
|
|
`metadata.object.full` is the preferred high-level method for agent answers like
|
|
"show everything about this document". It combines the live object card,
|
|
semantic sections, decoded forms, BSL module profiles, and counts in one
|
|
1C-facing response. Module profiles include routine lists and lightweight BSL
|
|
structural validation. Streams with BSL markers that are not complete modules
|
|
are kept, but marked as `completeness: fragment_or_invalid`. Full module text is
|
|
returned only with `include_module_text=true`. The method hides SQL/storage
|
|
traces by default; pass `include_storage=true` only for adapter diagnostics.
|
|
|
|
`metadata.object.parts` returns object part roles by evidence: metadata
|
|
payloads, form payloads, BSL stream containers, templates, and help/html
|
|
payloads. Physical Config part keys and numeric suffixes are hidden by default
|
|
and returned only with `include_storage=true`.
|
|
|
|
`metadata.object.modules` lists BSL stream modules discovered in those live
|
|
parts. Public responses use 1C-facing names such as `Модуль объекта`; physical
|
|
`module_id` values are returned only with `include_storage=true`.
|
|
|
|
`metadata.object.related` reads live related `Config` records referenced by
|
|
known object-kind sections, such as document forms and templates. Missing
|
|
references are returned explicitly with `source_missing`. Physical section paths
|
|
and Config file names are hidden unless `include_storage=true`.
|
|
|
|
`metadata.object.forms` resolves object forms through `metadata.object.related`
|
|
and then reads each form's live parts, including root `4` form payloads. Public
|
|
responses show form names and part roles; physical payload keys are hidden unless
|
|
`include_storage=true`.
|
|
|
|
`extension.objects.find` is the preferred first step for extension-specific
|
|
tasks. It searches live extension metadata by `extension`, `query`, `kind`, or
|
|
`guid`, returns object/template routes, and provides safe `read_selector`
|
|
payloads for follow-up calls. It can recover extension manifest routes even
|
|
when DBNames-Ext is incomplete; owner mismatches are returned as diagnostics
|
|
instead of silently hiding the object.
|
|
|
|
`metadata.route.resolve` resolves ConfigCAS/DBNames routes for extension
|
|
objects and child objects. Use it when a previous search returned a route
|
|
handle or when the caller has a CAS file name but needs the live object route.
|
|
|
|
`templates.read` and `templates.analyze` read MXL/MOXCEL templates by owner
|
|
selector, template selector, or direct ConfigCAS route. They return decoded
|
|
template structure: dimensions, named areas with row/column ranges, text and
|
|
parameter cells, column widths, cell text identifiers, cell parameters,
|
|
area-to-cell coverage, area intersections, shape variants, and explicit
|
|
capability flags. `merged_ranges` are reserved for authoritative merged-cell
|
|
records; until the MOXCEL merge record is decoded, possible merges are exposed
|
|
as `merged_range_candidates` with `confidence: low`.
|
|
|
|
Use `view=summary|structure|full`, `sections`, and `max_*` limits to keep
|
|
responses small for agents. `templates.map` is the compact agent-facing wrapper
|
|
over `templates.analyze`; it defaults to `view=summary` and is preferred when an
|
|
agent needs a quick layout map instead of all decoded lists.
|
|
|
|
1C templates are not only tabular MXL/MOXCEL documents. The 1C template
|
|
constructor offers these template types:
|
|
|
|
- `Табличный документ` - tabular document, MXL/MOXCEL. This is the current deep
|
|
decoder focus.
|
|
- `Текстовый документ` - plain or structured text payload.
|
|
- `Двоичные данные` - arbitrary binary payload.
|
|
- `Active document` - Active document payload.
|
|
- `HTML документ` - HTML payload.
|
|
- `Географическая схема` - geographic schema.
|
|
- `Графическая схема` - graphical schema.
|
|
- `Схема компоновки данных` - data composition schema.
|
|
- `Макет оформления компоновки данных` - data composition appearance template.
|
|
- `Внешняя компонента` - external component payload.
|
|
|
|
Always identify the template type before applying a decoder. Current
|
|
`templates.*` decoding is evidence-first for tabular documents; non-tabular
|
|
templates should be surfaced with type, raw route, payload markers, preview, and
|
|
explicit capability gaps until dedicated decoders are implemented.
|
|
|
|
For MOXCEL reverse engineering, request `sections=moxel_records,diagnostics`
|
|
and optionally `max_moxel_records`. The response includes parser-level record
|
|
head counts, grouped head samples with `tree_position`, and coordinate-like
|
|
samples. Use `top_level_records` with a larger `max_moxel_records` to inspect
|
|
ordered MOXCEL sections around a specific tree position. These diagnostics are
|
|
not authoritative merged-cell records. For a narrow ordered window, pass
|
|
`moxel_record_start` and `moxel_record_end`, for example `431..460`.
|
|
Use `moxel_record_heads` to keep only selected top-level record head codes,
|
|
for example `1049761,1413047`. Add `moxel_record_context` to include neighbor
|
|
records around matched top-level records; context records are marked with
|
|
`match: false`. `top_level_record_summary` summarizes the returned record
|
|
window with position range, head counts, match count, and compact numeric-field
|
|
variation by head. Its `field_hints` are low-confidence labels such as
|
|
`flag_like`, `small_enum_like`, or `coordinate_or_offset_like`; use them as
|
|
navigation hints, not as authoritative MOXCEL decoding. `numeric_field_matrix`
|
|
then shows those hinted/varying field values per `tree_position` without
|
|
returning every numeric item again, and `field_runs` compresses adjacent equal
|
|
values in that matrix. `field_transitions` lists the switch points between
|
|
those runs. `cell_style_candidates` exposes inline MOXCEL text cells with
|
|
nearby scalar style evidence and following metadata nodes; treat it as a
|
|
controlled-diff aid until border/font/alignment semantics are decoded.
|
|
`top_level_shapes`
|
|
groups top-level records by structural shape
|
|
(`head`, list length, numeric/string counts) and includes sample positions.
|
|
`top_level_shape_candidates` ranks rare/long/numeric-heavy shapes as
|
|
low-confidence hints for manual layout/merge investigation. Each candidate can
|
|
include `rank` and `suggested_windows` with a ready `request_hint` for the next
|
|
focused `templates.map` call. Pass `moxel_candidate_rank` to focus
|
|
`top_level_records` on that 1-based candidate rank without copying the request
|
|
hint manually. Use `moxel_candidate_window_index` to select a later suggested
|
|
window from the same candidate when the structural shape appears more than
|
|
once. Use `moxel_candidate_reasons`, for example
|
|
`coordinate_like_prefix,long_record`, to return only candidates containing all
|
|
requested reason codes. Use `moxel_candidate_min_score` to keep only candidates
|
|
above a heuristic score threshold. `top_level_candidate_summary` reports score
|
|
and reason distributions plus the count returned after filters. Use
|
|
`moxel_candidate_heads` to filter the candidate list by head code; use
|
|
`moxel_record_heads` when filtering actual top-level records in a focused
|
|
window. Use `moxel_candidate_start`/`moxel_candidate_end` to filter candidates
|
|
by their top-level positions; use `moxel_record_start`/`moxel_record_end` when
|
|
filtering returned records.
|
|
|
|
`metadata.form.decode` decodes one form payload into an evidence-first profile:
|
|
event handlers, form items, attributes, commands, auxiliary table/command-bar
|
|
records, and the embedded form module summary. Form records include stable
|
|
paths back into the decoded tree for names, ids, localized titles, handler
|
|
names, and known platform event ids. Counts include both returned and total
|
|
record numbers so truncated responses are explicit. The profile also links form
|
|
events and form commands to module routines, links command buttons to commands
|
|
by GUID evidence, and marks handlers as `resolved` or `missing`.
|
|
|
|
`modules.search` searches live BSL text and returns snippets by default.
|
|
Physical module ids and payload coordinates are hidden unless
|
|
`include_storage=true`. Every public match includes a `read_selector` with
|
|
`method: "modules.read"` and either an object selector or an opaque
|
|
`module_ref`; agents should pass that selector to the next read call instead of
|
|
requesting storage details. When `resolve_owners=true`, results also include
|
|
`counts.owner_resolved`, `counts.owner_unresolved`, and
|
|
`diagnostics.owner_resolution` so incomplete owner recovery is explicit.
|
|
`modules.read` reads by object selector (`ref`, `guid`, `kind` + `name`,
|
|
`object_type`/`object_name`/`object_guid`, or `kind` + 1-based object
|
|
`ordinal`) and optional 1-based `module_ordinal`; it also accepts `module_ref`
|
|
from a prior search result. The response hides source and payload metadata
|
|
unless `include_storage=true`.
|
|
|
|
`code.search` is the agent-facing wrapper over module search. Its items include
|
|
`read_selector.method: "code.read"` and preserve `module_ref` when that is the
|
|
best available safe handle. `code.read` can consume that selector directly.
|
|
|
|
`metadata.definition.find` accepts public object references such as
|
|
`Обработка.<Name>` or `Document.<Name>` in `query` and the common object
|
|
selector aliases for scoped lookup. A single metadata object match is promoted
|
|
to the top-level `object` field and the response includes `related_selectors`
|
|
for the next public calls (`metadata.object.get`,
|
|
`metadata.object.full`, `metadata.object.modules`, `metadata.object.form.details`,
|
|
`code.search`, `modules.search`, and similar selectors allowed by the object's
|
|
capabilities).
|
|
|
|
`metadata.adapter.audit` reports recognized metadata kinds, public kind counts,
|
|
missing supported kinds when `include_missing=true`, and unmapped DBNames roles
|
|
when `include_unmapped=true`.
|
|
|
|
`codec.decode` and `codec.encode` are low-level lossless helpers. A no-op encode
|
|
from a live source keeps the original bytes exactly; modified text/tree payloads
|
|
are encoded back using the original compression and text encoding envelope.
|
|
|
|
`changes.propose` reads one live storage payload, checks an optional
|
|
`expected_sha1`, applies `edits` to decoded brace-tree paths in memory, and
|
|
returns the re-encoded payload metadata for review. It never writes to SQL.
|
|
Each edit has `path`, `value`, optional `node_type` (`auto`, `atom`, `string`),
|
|
and optional `expected_old`. For stream payloads, an edit can use
|
|
`stream_index` with either full `text` replacement or `replace: {old, new}`,
|
|
plus optional `expected_contains`; stream headers are rebuilt with updated
|
|
byte lengths before the payload is encoded back. Diagnostic `source.module_id`
|
|
values returned by `metadata.object.modules` with `include_storage=true` or
|
|
accepted by `modules.read` can be used directly; when the module id includes
|
|
`#stream:<index>`, stream edits inherit that index unless an edit specifies its
|
|
own `stream_index`. The response
|
|
includes `validation`, produced by re-decoding the encoded proposal in memory.
|
|
For BSL stream edits, validation also runs lightweight structural checks for
|
|
routine, region, and preprocessor-block balance. Stream edits can also target
|
|
a whole BSL routine with `routine: {operation, name, text}` where operation is
|
|
`replace`, `append`, or `upsert`. Routine edits accept
|
|
`expected_old_contains` and `expected_old_sha1` as live preconditions against
|
|
the current routine text; failed preconditions reject the proposal before any
|
|
encoded review artifact is returned.
|
|
|
|
`storage.*` methods read 1C storage rows directly from SQL tables
|
|
`Params`, `Config`, `ConfigSave`, `ConfigCAS`, and `ConfigCASSave`. They are
|
|
diagnostic building blocks for the live metadata decoder; they do not create or
|
|
read filesystem indexes.
|
|
|
|
## Cache policy
|
|
|
|
The source of truth is the live database. A filesystem cache may be added only
|
|
as a derived acceleration layer for expensive decoded metadata/module payloads,
|
|
not for current table data. Cache entries must carry `base_id`, source
|
|
fingerprint, generation time, TTL, and `fresh/stale` status. If freshness cannot
|
|
be proven, the adapter must re-read live SQL or return an explicit stale-cache
|
|
error.
|
|
|
|
Operational runbook: `docs/runbooks/1c-operational-coding.md`.
|