precis-cli 0.1.7__tar.gz → 0.1.8__tar.gz
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.
- {precis_cli-0.1.7/precis_cli.egg-info → precis_cli-0.1.8}/PKG-INFO +1 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/dependencies.py +42 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/models/full_validation.py +6 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/models/validation.py +6 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/hardware.py +5 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/utils.py +8 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/core/data_sources.py +1 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/core/reporting.py +1 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/preview/header_row.py +1 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/helpers.py +1 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/projects/open.py +1 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/projects/scan.py +1 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/validation/common.py +3 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/services/full_validation_response_builder.py +3 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shared_services/config_ops.py +2 -2
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/io/yaml.py +3 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/registry.py +4 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/reporter/reporters/__init__.py +1 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/allowed_values.py +6 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/charset.py +15 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/composite.py +4 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/conditional.py +31 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/date_logic.py +80 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/foreign_key.py +12 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/not_null.py +6 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/range.py +20 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/regex.py +14 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/scripted.py +12 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/unique.py +8 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/yaml_io.py +1 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/service.py +29 -9
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/validators/adapter.py +32 -11
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/validators/base.py +8 -4
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/validators/composite.py +8 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/validators/date_logic.py +48 -6
- {precis_cli-0.1.7 → precis_cli-0.1.8/precis_cli.egg-info}/PKG-INFO +1 -1
- {precis_cli-0.1.7 → precis_cli-0.1.8}/precis_cli.egg-info/SOURCES.txt +0 -4
- {precis_cli-0.1.7 → precis_cli-0.1.8}/pyproject.toml +1 -1
- precis_cli-0.1.7/app/cli_main.py +0 -52
- precis_cli-0.1.7/app/shared/core/manifest_schema/types.py +0 -99
- precis_cli-0.1.7/app/shared/services/ai/types.py +0 -213
- precis_cli-0.1.7/app/shared/services/llm/models.py +0 -104
- {precis_cli-0.1.7 → precis_cli-0.1.8}/MANIFEST.in +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/PYPI_README.md +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/README.md +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/main.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/middleware/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/middleware/exception_handler.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/middleware/request_logging.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/middleware/token_auth.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/models/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/models/connection_rules.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/models/files.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/models/project.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/models/projects.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/models/schema.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/models/v2_responses.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/models/workspace.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/chat.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/generate.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/jobs.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/migrate.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/models.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/ollama.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/providers.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/router.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/ai/stream.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/core/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/core/connection_rules.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/core/regex.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/files/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/files/ops.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/files/transfer.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/preview/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/preview/content_mode.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/preview/models.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/preview/path_mode.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/preview/router.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/constraint.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/full_config.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/full_config_writer.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/inspection_fix.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/manifest.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/models.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/pattern.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/regex.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/scanner.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/schema.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/schema_helpers.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/settings.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/template.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/validation.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/view.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/project/workspaces.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/projects/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/projects/create.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/validation/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/validation/content_mode.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/validation/history.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/validation/inline_mode.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/validation/path_mode.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/routers/validation/router.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/services/io_error_messages.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/api/services/preview_service.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/__main__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shared_services/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shared_services/generation_ops.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shared_services/project_ops.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/agent_interaction.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/chat.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/delete.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/diff.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/display.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/executor.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/executor_utils.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/generate.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/interaction.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/migrate.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/resolver.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/status.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/switch.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/ai/utils.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/config/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/config/base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/config/check.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/config/edit.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/config/get.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/config/init.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/config/inspect.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/config/list.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/config/set.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/config/show.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/exit.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/help.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/infer_schema.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/open.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/project.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/provider.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/system.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/commands/validate.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/completer.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/config_storage.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/exceptions.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/formatter.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/interactive_menu.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/main.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/shell/parser.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/cli/start.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/mcp_server.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/app_version.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/config/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/config/server.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/converter.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/csv_loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/excel_loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/extractor.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/json_loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/registry.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/sql_loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/strategies/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/strategies/array_parser.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/strategies/lines_parser.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/loaders/strategies/object_parser.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/schema_info.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/specs/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/specs/base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/specs/csv_source.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/specs/excel_source.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/specs/file_base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/specs/json_source.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/data_source/specs/sql_source.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/encoding.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/io/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/manifest_schema/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/manifest_schema/version.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/patterns/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/patterns/loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/patterns/writer.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/builders/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/builders/base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/builders/composite.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/builders/conditional.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/builders/foreign_key.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/builders/registry.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/builders/scripted.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/builders/single_column.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/builders/unique.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/factory.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/reader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/types/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/types/constraint_file.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/types/refs.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/constraint/writer.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/config_inspector.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/embedded_constraints.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/file_loaders.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/inspection_ids.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/inspector_helpers.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/inspector_id_checks.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/inspector_reference_checks.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/inspector_uniqueness_checks.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/loading_error_messages.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/main.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/path_validation.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/loader_parts/runtime.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/loader/types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/coverage.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/reader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types_parts/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types_parts/constants.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types_parts/data_source.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types_parts/info.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types_parts/manifest.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types_parts/refs.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types_parts/settings.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types_parts/settings_file_processing.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types_parts/settings_script_security.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types_parts/settings_validation.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/types_parts/template.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manifest/writer.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manual_data/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/manual_data/types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/regex/reader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/regex/types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/regex/writer.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema/reader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema/types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema/types_parts/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema/types_parts/column.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema/types_parts/column_utils.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema/types_parts/constraint.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema/types_parts/schema_id.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema/types_parts/source.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema/types_parts/source_options.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema/types_parts/table.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema/writer.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/schema_ref_check.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/template/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/template/expander.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/template/reader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/template/types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/transform/reader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/transform/types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/project/transform/writer.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/pydantic_messages.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/reporter/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/reporter/reporter.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/reporter/reporters/base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/reporter/reporters/dingtalk_app_reporter.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/reporter/reporters/email_reporter.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/reporter/reporters/feishu_app_reporter.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/reporter/reporters/local_file_reporter.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/reporter/reporters/wecom_app_reporter.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/utils/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/utils/path_utils.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/core/utils/regex_extract.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/condition_registry.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/constraints/key_normalization.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/data_engine.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/data_types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/data_types_parts/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/data_types_parts/base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/data_types_parts/composite.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/data_types_parts/expression.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/data_types_parts/extracted.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/data_types_parts/json_types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/data_types_parts/scalars.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/data_types_parts/sequence.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/dataset_schema.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/eval_sandbox.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/expression_system.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/regex_flags.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/schema/builder.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/schema/models.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/aggregate.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/cast_type.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/concat.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/conditional_assign.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/date_format.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/digits.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/drop_duplicates.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/fill_na.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/filter_rows.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/lookup.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/lower_case.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/map_value.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/math_expr.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/modulo.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/regex_extract.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/registry.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/replace.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/sort_rows.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/string_split.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/strip.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/substring.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/upper_case.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/transforms/weighted_sum.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/domain/validation_constraints.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/chat_tools/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/chat_tools/apply_actions.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/chat_tools/ask_user.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/chat_tools/read_canvas.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/chat_tools/read_project.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/chat_tools/read_table.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/chat_tools/schemas.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/chat_tools/validate_table.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/executor.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/memory.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/planner.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/tool_registry.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/tools/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/tools/config_generate.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/tools/config_refine.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/tools/config_validate.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/tools/merge_results.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/tools/plan_chunks.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/tools/script_parse.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/agent/types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/chat_agent_runner.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/chat_orchestrator.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/failure_messages.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/job_storage.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/migrate_service.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/streaming/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/streaming/event_journal.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/streaming/orchestrator.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/streaming/pending_interaction_store.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/streaming/sse_response.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/streaming/types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/ai/utils.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/diff/config_diff.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/hardware.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/_canvas_validator.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/_constraint_validator.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/_regex_validator.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/_schema_validator.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/_settings_validator.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/_transform_validator.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/action_handlers.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/action_parser.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/action_processor.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/action_validator.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/diff_compute.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/regex_handlers.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/registry.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/schema_handlers.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/settings_handlers.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/specs.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/transform_handlers.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/actions/validation_types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/cache/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/cache/response_cache.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/chat/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/chat/chat_system_prompt.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/chat/response_parser.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/config/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/config/crypto.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/config/loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/config/models.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/config/presets.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/config_generator.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/constraints/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/constraints/constraint_builder.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/constraints/constraint_deletion.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/constraints/constraint_id.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/constraints/frontend_instructions.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/constraints/inline_batch.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/discovery/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/discovery/scanner.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/generation/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/generation/agent_wiring.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/generation/config_builder.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/generation/errors.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/generation/existing_config.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/generation/profiler.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/generation/prompt_builder.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/generation/response_parser.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/generation/service.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/providers/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/providers/base.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/providers/cached_provider.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/providers/fake.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/providers/ollama.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/providers/openai.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/providers/registry.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/schema_resolver.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/suggestion_utils.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/llm/validate_executor.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/preview/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/preview/loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/preview/path_validation.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/project_loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/schema_inference.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/schema_runtime_builder.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/chunked_loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/dag/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/dag/builder.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/dag/executor.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/dag/sorter.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/data_loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/engine.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/executor.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/extractors.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/history.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/json_payload.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/loader.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/memory_monitor.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/postprocess.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/progress.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/report_export.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/resolver.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/types.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/shared/services/validation/validators/__init__.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/app/start_server.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/precis_cli.egg-info/dependency_links.txt +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/precis_cli.egg-info/entry_points.txt +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/precis_cli.egg-info/requires.txt +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/precis_cli.egg-info/top_level.txt +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/setup.cfg +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/tests/test_local_file_reporter.py +0 -0
- {precis_cli-0.1.7 → precis_cli-0.1.8}/tests/test_schema_builder.py +0 -0
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
# backend/app/api/dependencies.py
|
|
38
38
|
import os
|
|
39
|
+
from urllib.parse import quote, unquote
|
|
39
40
|
|
|
40
41
|
from fastapi import Depends, Header, HTTPException
|
|
41
42
|
|
|
@@ -65,6 +66,44 @@ class ProjectStore:
|
|
|
65
66
|
self.project_path = project_path
|
|
66
67
|
|
|
67
68
|
|
|
69
|
+
def _decode_header_path(value: str) -> str:
|
|
70
|
+
"""还原 HTTP header 携带的非 ASCII 路径。
|
|
71
|
+
|
|
72
|
+
两种线上契约并存,按特征识别、互不干扰:
|
|
73
|
+
|
|
74
|
+
1. GUI 契约(axios/fetch):前端在出口处对路径做 encodeURIComponent(纯
|
|
75
|
+
ASCII 百分号转义)。浏览器 XHR/fetch 的 header 值只接受 ByteString
|
|
76
|
+
(ISO-8859-1),中文原值会被 XHR 直接拒绝;axios 1.18 的
|
|
77
|
+
toByteStringHeaderValue 还会把 latin1 之外的字符静默删除——不转义的
|
|
78
|
+
中文路径会以"删字后的错误路径"上线且无从在服务端还原。判定是否为
|
|
79
|
+
规范转义串用 round-trip 校验(quote(unquote(v)) == v),字面上含 % 的
|
|
80
|
+
合法路径通常不会被误解码(例外:字面 "%XX" 恰为合法 UTF-8 转义序列
|
|
81
|
+
的路径会被还原,随后走校验链报错而非指向任意目录)。round-trip 的
|
|
82
|
+
转义集必须与 encodeURIComponent 的不转义集对齐:JS 保留
|
|
83
|
+
`!'()*` 五字符原样上线,校验端 quote 的 safe 集须包含它们,否则含
|
|
84
|
+
括号/感叹号的中文路径(如 `D:/项目(备份)`)契约判定必败,被契约 2
|
|
85
|
+
原样放行后以百分号串走校验链 400/404。
|
|
86
|
+
2. TUI/脚本契约(reqwest FromBytes、curl 等):UTF-8 原始字节按 obs-text
|
|
87
|
+
上线。ASGI 服务器把 header 字节按 latin-1 解码成乱码,latin-1 与字节流
|
|
88
|
+
双射,编码回字节再按 UTF-8 解码即可无损还原;非 UTF-8 字节保持原值,
|
|
89
|
+
交由后续校验链正常报错。
|
|
90
|
+
"""
|
|
91
|
+
# 契约 1:规范百分号转义(GUI)。safe 集对齐 encodeURIComponent 的保留集
|
|
92
|
+
# (`!'()*`),Python quote 恒不转义字母数字与 `_.-~`,两者已一致
|
|
93
|
+
if "%" in value:
|
|
94
|
+
try:
|
|
95
|
+
decoded = unquote(value, errors="strict")
|
|
96
|
+
except UnicodeDecodeError:
|
|
97
|
+
decoded = None
|
|
98
|
+
if decoded is not None and decoded != value and quote(decoded, safe="!'()*") == value:
|
|
99
|
+
return decoded
|
|
100
|
+
# 契约 2:UTF-8 原始字节(TUI/脚本)
|
|
101
|
+
try:
|
|
102
|
+
return value.encode("latin-1").decode("utf-8")
|
|
103
|
+
except (UnicodeEncodeError, UnicodeDecodeError):
|
|
104
|
+
return value
|
|
105
|
+
|
|
106
|
+
|
|
68
107
|
async def get_project_config_path(
|
|
69
108
|
x_project_config_path: str = Header(..., description="项目根目录的绝对路径(须含 project.precis.yaml)"),
|
|
70
109
|
) -> str:
|
|
@@ -121,6 +160,9 @@ def _validate_project_root(raw_path: str | None) -> str:
|
|
|
121
160
|
"""
|
|
122
161
|
if not raw_path:
|
|
123
162
|
raise HTTPException(status_code=400, detail="X-Project-Config-Path header 不能为空。")
|
|
163
|
+
# 还原 header 编码乱码(见 _decode_header_path):中文路径经 UTF-8 上线、
|
|
164
|
+
# latin-1 解码后 isdir 必失败,必须先还原再做后续校验
|
|
165
|
+
raw_path = _decode_header_path(raw_path)
|
|
124
166
|
# 步骤1:先校验原始输入是否为绝对路径
|
|
125
167
|
# 在 Windows 下,os.path.abspath 会把相对路径(如 "../project")解析成绝对路径,
|
|
126
168
|
# 导致后续 isabs 检查无法拒绝相对路径。因此必须在规范化之前先做判断。
|
|
@@ -438,6 +438,12 @@ class FullValidationErrorItem(BaseModel):
|
|
|
438
438
|
source_sheet: str | None = Field(
|
|
439
439
|
default=None, description="配置文件内定义的 Excel Sheet 名(可选)"
|
|
440
440
|
) # schema 配置中 source.sheet 定义的 Excel 工作表名称,可选
|
|
441
|
+
error_code: str | None = Field(
|
|
442
|
+
default=None, description="稳定错误码(UPPER_SNAKE),供前端映射 i18n key 按当前语言渲染"
|
|
443
|
+
) # 与 message 同时给出:message 为后端默认语言的兜底文案
|
|
444
|
+
error_params: dict | None = Field(
|
|
445
|
+
default=None, description="错误码对应的插值参数(JSON 标量),如 {column: 'Total'}"
|
|
446
|
+
) # 供前端 t(key, params) 插值
|
|
441
447
|
|
|
442
448
|
|
|
443
449
|
class ValidationPassedItem(BaseModel):
|
|
@@ -257,6 +257,12 @@ class ValidationErrorRow(BaseModel):
|
|
|
257
257
|
error_message: str | None = Field(
|
|
258
258
|
None, description="错误信息"
|
|
259
259
|
) # 校验失败的具体错误描述,如"值不在允许列表中",可选
|
|
260
|
+
error_code: str | None = Field(
|
|
261
|
+
None, description="稳定错误码(UPPER_SNAKE),供前端映射 i18n key 按当前语言渲染"
|
|
262
|
+
) # 与 error_message 同时给出:message 为后端默认语言的兜底文案
|
|
263
|
+
error_params: dict | None = Field(
|
|
264
|
+
None, description="错误码对应的插值参数(JSON 标量),如 {column: 'Total', row: 1}"
|
|
265
|
+
) # 供前端 t(key, params) 插值
|
|
260
266
|
|
|
261
267
|
|
|
262
268
|
class ValidationResult(BaseModel):
|
|
@@ -117,7 +117,11 @@ def diagnose_hardware() -> HardwareDiagnoseResponse:
|
|
|
117
117
|
import subprocess
|
|
118
118
|
|
|
119
119
|
result = subprocess.run(
|
|
120
|
-
["nvidia-smi", "--query-gpu=name,memory.total", "--format=csv,noheader"],
|
|
120
|
+
["nvidia-smi", "--query-gpu=name,memory.total", "--format=csv,noheader"],
|
|
121
|
+
capture_output=True,
|
|
122
|
+
text=True,
|
|
123
|
+
encoding="utf-8",
|
|
124
|
+
errors="replace", # 中文 Windows 下 text=True 默认按 GBK 解码会乱码/抛错
|
|
121
125
|
)
|
|
122
126
|
if result.returncode == 0:
|
|
123
127
|
for line in result.stdout.strip().split("\n"):
|
|
@@ -138,12 +138,19 @@ def expand_paths(
|
|
|
138
138
|
|
|
139
139
|
数据文件类型:.xlsx, .xls, .csv, .json, .jsonl
|
|
140
140
|
"""
|
|
141
|
+
# 还原 header 线上编码(GUI 契约 percent-encode / TUI 原始 UTF-8 字节,见
|
|
142
|
+
# app.api.dependencies._decode_header_path):前端出口统一转义后,未解码的
|
|
143
|
+
# 百分号串作 base 解析相对路径会全 miss,中文项目下静默返回空列表
|
|
144
|
+
from app.api.dependencies import _decode_header_path
|
|
145
|
+
|
|
146
|
+
base_path = _decode_header_path(x_project_config_path) if x_project_config_path else None
|
|
147
|
+
|
|
141
148
|
result = []
|
|
142
149
|
seen = set()
|
|
143
150
|
|
|
144
151
|
for raw_path in paths:
|
|
145
152
|
# 1. 解析为绝对路径
|
|
146
|
-
path = _resolve_path(raw_path,
|
|
153
|
+
path = _resolve_path(raw_path, base_path)
|
|
147
154
|
|
|
148
155
|
# 2. 如果是目录,递归展开
|
|
149
156
|
if os.path.isdir(path):
|
|
@@ -86,7 +86,7 @@ def load_workspace_config(project_root: str) -> dict[str, Any]:
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
try:
|
|
89
|
-
with open(config_path, encoding="utf-8") as f:
|
|
89
|
+
with open(config_path, encoding="utf-8-sig") as f:
|
|
90
90
|
return yaml.safe_load(f) or {}
|
|
91
91
|
except Exception as e:
|
|
92
92
|
raise HTTPException(
|
|
@@ -223,7 +223,7 @@ def get_reporting_config(store: ProjectStore = Depends(get_project_store)) -> Re
|
|
|
223
223
|
)
|
|
224
224
|
try:
|
|
225
225
|
# 读取并解析 YAML 配置文件
|
|
226
|
-
with open(config_path, encoding="utf-8") as f:
|
|
226
|
+
with open(config_path, encoding="utf-8-sig") as f:
|
|
227
227
|
config_data = yaml.safe_load(f)
|
|
228
228
|
return ReportingConfig(**config_data)
|
|
229
229
|
except Exception as e:
|
|
@@ -106,7 +106,7 @@ def handle_header_row_changed(
|
|
|
106
106
|
|
|
107
107
|
if os.path.exists(schema_path):
|
|
108
108
|
try:
|
|
109
|
-
with open(schema_path, encoding="utf-8") as f:
|
|
109
|
+
with open(schema_path, encoding="utf-8-sig") as f:
|
|
110
110
|
schema_content = yaml.safe_load(f)
|
|
111
111
|
|
|
112
112
|
if "header_row" not in schema_content:
|
|
@@ -36,7 +36,7 @@ def _get_project_name(project_path: str) -> str:
|
|
|
36
36
|
"""从 project.precis.yaml 中读取项目名称,失败时返回目录名。"""
|
|
37
37
|
manifest_path = os.path.join(project_path, "project.precis.yaml")
|
|
38
38
|
try:
|
|
39
|
-
with open(manifest_path, encoding="utf-8") as f:
|
|
39
|
+
with open(manifest_path, encoding="utf-8-sig") as f:
|
|
40
40
|
manifest = yaml.safe_load(f)
|
|
41
41
|
if isinstance(manifest, dict):
|
|
42
42
|
project = manifest.get("project", {})
|
|
@@ -69,7 +69,7 @@ def scan_projects(
|
|
|
69
69
|
def _parse_project(project_path: str, manifest_path: str) -> ProjectInfo | None:
|
|
70
70
|
"""解析单个项目的 manifest 文件获取元信息。"""
|
|
71
71
|
try:
|
|
72
|
-
with open(manifest_path, encoding="utf-8") as f:
|
|
72
|
+
with open(manifest_path, encoding="utf-8-sig") as f:
|
|
73
73
|
manifest = yaml.safe_load(f)
|
|
74
74
|
except Exception:
|
|
75
75
|
return None
|
|
@@ -189,11 +189,14 @@ def execute_dataframe_validation(
|
|
|
189
189
|
)
|
|
190
190
|
|
|
191
191
|
# 将原始错误行列表转换为标准化的 ValidationErrorRow 对象列表
|
|
192
|
+
# error_code/error_params 透传给前端,供按当前语言渲染错误文案
|
|
192
193
|
error_rows = [
|
|
193
194
|
ValidationErrorRow(
|
|
194
195
|
row_index=err.get("row_index", 0),
|
|
195
196
|
cell_value=str(err.get("cell_value", "")),
|
|
196
197
|
error_message=err.get("error_message"),
|
|
198
|
+
error_code=err.get("error_code"),
|
|
199
|
+
error_params=err.get("error_params"),
|
|
197
200
|
)
|
|
198
201
|
for err in result.error_rows
|
|
199
202
|
]
|
|
@@ -150,6 +150,9 @@ class FullValidationResponseBuilder:
|
|
|
150
150
|
source_path=err.get("source_path"),
|
|
151
151
|
source_file=err.get("source_file"),
|
|
152
152
|
source_sheet=err.get("source_sheet"),
|
|
153
|
+
# i18n:稳定错误码 + 插值参数透传,message 保留兜底文案
|
|
154
|
+
error_code=err.get("error_code"),
|
|
155
|
+
error_params=err.get("error_params"),
|
|
153
156
|
)
|
|
154
157
|
)
|
|
155
158
|
|
|
@@ -371,7 +371,7 @@ def set_config_value_in_file(project_path: str, filename: str, key_path: str, va
|
|
|
371
371
|
yaml_parser.preserve_quotes = True
|
|
372
372
|
|
|
373
373
|
try:
|
|
374
|
-
with open(config_path, encoding="utf-8") as f:
|
|
374
|
+
with open(config_path, encoding="utf-8-sig") as f:
|
|
375
375
|
data = yaml_parser.load(f)
|
|
376
376
|
except RuamelYAMLError as e:
|
|
377
377
|
return False, f"YAML 解析失败: {e}"
|
|
@@ -482,7 +482,7 @@ def load_config_content(project_path: str, filename: str) -> dict | str:
|
|
|
482
482
|
if not config_path:
|
|
483
483
|
return f"配置文件不存在: {filename}"
|
|
484
484
|
try:
|
|
485
|
-
with open(config_path, encoding="utf-8") as f:
|
|
485
|
+
with open(config_path, encoding="utf-8-sig") as f:
|
|
486
486
|
content = yaml.safe_load(f)
|
|
487
487
|
if content:
|
|
488
488
|
return content if isinstance(content, dict) else str(content)
|
|
@@ -162,7 +162,9 @@ def read_yaml(path: Path) -> dict[str, Any]:
|
|
|
162
162
|
:raises FileNotFoundError: 当指定路径的文件不存在时抛出
|
|
163
163
|
:raises yaml.YAMLError: 当 YAML 格式错误时抛出
|
|
164
164
|
"""
|
|
165
|
-
|
|
165
|
+
# utf-8-sig:兼容记事本等编辑器保存的"UTF-8 带 BOM"(BOM 若混入会被
|
|
166
|
+
# yaml 误认Control Character抛错);无 BOM 时解码行为与 utf-8 完全一致
|
|
167
|
+
with open(path, encoding="utf-8-sig") as f:
|
|
166
168
|
return cast(dict[str, Any], yaml.safe_load(f))
|
|
167
169
|
|
|
168
170
|
|
|
@@ -141,6 +141,8 @@ class AllowedValuesConstraint(Constraint):
|
|
|
141
141
|
errors.append(
|
|
142
142
|
{
|
|
143
143
|
"error_type": "ConstraintConfigError",
|
|
144
|
+
"error_code": "ALLOWED_VALUES_TABLE_NOT_FOUND",
|
|
145
|
+
"error_params": {"table": self.table},
|
|
144
146
|
"table": self.table,
|
|
145
147
|
"column": self.column,
|
|
146
148
|
"message": f"允许值约束失败: 表 '{self.table}' 不在数据集中。",
|
|
@@ -155,6 +157,8 @@ class AllowedValuesConstraint(Constraint):
|
|
|
155
157
|
errors.append(
|
|
156
158
|
{
|
|
157
159
|
"error_type": "ConstraintConfigError",
|
|
160
|
+
"error_code": "ALLOWED_VALUES_COLUMN_NOT_FOUND",
|
|
161
|
+
"error_params": {"column": self.column, "table": self.table},
|
|
158
162
|
"table": self.table,
|
|
159
163
|
"column": self.column,
|
|
160
164
|
"message": f"允许值约束失败: 列 '{self.column}' 在表 '{self.table}' 中不存在。",
|
|
@@ -194,6 +198,8 @@ class AllowedValuesConstraint(Constraint):
|
|
|
194
198
|
row_index = int(index) if index is not None else 0
|
|
195
199
|
error: dict[str, Any] = {
|
|
196
200
|
"error_type": "AllowedValuesViolation",
|
|
201
|
+
"error_code": "ALLOWED_VALUES_NOT_PERMITTED",
|
|
202
|
+
"error_params": {"value": str(value), "allowed": str(self.allowed_values)},
|
|
197
203
|
"table": self.table,
|
|
198
204
|
"row_index": row_index,
|
|
199
205
|
"column": self.column,
|
|
@@ -149,6 +149,8 @@ class CharsetConstraint(Constraint):
|
|
|
149
149
|
errors.append(
|
|
150
150
|
{
|
|
151
151
|
"error_type": "ConstraintConfigError",
|
|
152
|
+
"error_code": "CHARSET_TABLE_NOT_FOUND",
|
|
153
|
+
"error_params": {"table": self.table},
|
|
152
154
|
"table": self.table,
|
|
153
155
|
"column": self.column,
|
|
154
156
|
"message": f"字符集约束失败: 表 '{self.table}' 不在数据集中。",
|
|
@@ -163,6 +165,8 @@ class CharsetConstraint(Constraint):
|
|
|
163
165
|
errors.append(
|
|
164
166
|
{
|
|
165
167
|
"error_type": "ConstraintConfigError",
|
|
168
|
+
"error_code": "CHARSET_COLUMN_NOT_FOUND",
|
|
169
|
+
"error_params": {"column": self.column, "table": self.table},
|
|
166
170
|
"table": self.table,
|
|
167
171
|
"column": self.column,
|
|
168
172
|
"message": f"字符集约束失败: 列 '{self.column}' 在表 '{self.table}' 中不存在。",
|
|
@@ -186,6 +190,11 @@ class CharsetConstraint(Constraint):
|
|
|
186
190
|
errors.append(
|
|
187
191
|
{
|
|
188
192
|
"error_type": "ConstraintConfigError",
|
|
193
|
+
"error_code": "CHARSET_INVALID_MODE",
|
|
194
|
+
"error_params": {
|
|
195
|
+
"charset_mode": self.charset_mode,
|
|
196
|
+
"valid_modes": ", ".join(sorted(valid_modes)),
|
|
197
|
+
},
|
|
189
198
|
"table": self.table,
|
|
190
199
|
"column": self.column,
|
|
191
200
|
"message": (
|
|
@@ -216,6 +225,12 @@ class CharsetConstraint(Constraint):
|
|
|
216
225
|
errors.append(
|
|
217
226
|
{
|
|
218
227
|
"error_type": "CharsetViolation",
|
|
228
|
+
"error_code": "CHARSET_INVALID_CHARACTER",
|
|
229
|
+
"error_params": {
|
|
230
|
+
"value": cell_value_str,
|
|
231
|
+
"charset_mode": self.charset_mode,
|
|
232
|
+
"charset_name": charset_name,
|
|
233
|
+
},
|
|
219
234
|
"table": self.table,
|
|
220
235
|
"row_index": int(index) if index is not None else 0,
|
|
221
236
|
"column": self.column,
|
|
@@ -138,6 +138,8 @@ class CompositeConstraint(Constraint):
|
|
|
138
138
|
final_errors = [
|
|
139
139
|
{
|
|
140
140
|
"error_type": "CompositeConstraint",
|
|
141
|
+
"error_code": "COMPOSITE_ANY_ALL_FAILED",
|
|
142
|
+
"error_params": {"total": len(sub_results)},
|
|
141
143
|
"message": (
|
|
142
144
|
f"复合约束(logic=any)要求至少一个子约束通过,但全部 {len(sub_results)} 个子约束均失败"
|
|
143
145
|
),
|
|
@@ -151,6 +153,8 @@ class CompositeConstraint(Constraint):
|
|
|
151
153
|
final_errors = [
|
|
152
154
|
{
|
|
153
155
|
"error_type": "CompositeConstraint",
|
|
156
|
+
"error_code": "COMPOSITE_NONE_HAS_PASSED",
|
|
157
|
+
"error_params": {"passed": passed_count},
|
|
154
158
|
"message": (f"复合约束(logic=none)要求全部子约束失败,但有 {passed_count} 个子约束通过"),
|
|
155
159
|
"table": self.table,
|
|
156
160
|
}
|
|
@@ -352,6 +352,8 @@ class ConditionalConstraint(Constraint):
|
|
|
352
352
|
errors.append(
|
|
353
353
|
{
|
|
354
354
|
"error_type": "ConstraintConfigError",
|
|
355
|
+
"error_code": "CONDITIONAL_TABLE_NOT_FOUND",
|
|
356
|
+
"error_params": {"table": self.table},
|
|
355
357
|
"table": self.table,
|
|
356
358
|
"column": self.then_column,
|
|
357
359
|
"message": f"条件约束失败: 表 '{self.table}' 不在数据集中。",
|
|
@@ -366,6 +368,8 @@ class ConditionalConstraint(Constraint):
|
|
|
366
368
|
errors.append(
|
|
367
369
|
{
|
|
368
370
|
"error_type": "ConstraintConfigError",
|
|
371
|
+
"error_code": "CONDITIONAL_COLUMN_NOT_FOUND",
|
|
372
|
+
"error_params": {"column": self.then_column, "table": self.table},
|
|
369
373
|
"table": self.table,
|
|
370
374
|
"column": self.then_column,
|
|
371
375
|
"message": f"条件约束失败: 列 '{self.then_column}' 不在表 '{self.table}' 中。",
|
|
@@ -382,6 +386,8 @@ class ConditionalConstraint(Constraint):
|
|
|
382
386
|
errors.append(
|
|
383
387
|
{
|
|
384
388
|
"error_type": "ConstraintConfigError",
|
|
389
|
+
"error_code": "CONDITIONAL_REF_COLUMN_NOT_FOUND",
|
|
390
|
+
"error_params": {"column": ref_col, "table": self.table},
|
|
385
391
|
"table": self.table,
|
|
386
392
|
"column": ref_col,
|
|
387
393
|
"message": f"条件约束失败: 引用列 '{ref_col}' 不在表 '{self.table}' 中。",
|
|
@@ -406,6 +412,13 @@ class ConditionalConstraint(Constraint):
|
|
|
406
412
|
errors.append(
|
|
407
413
|
{
|
|
408
414
|
"error_type": "ConstraintConfigError",
|
|
415
|
+
"error_code": "CONDITIONAL_THEN_THRESHOLD_NOT_NUMERIC",
|
|
416
|
+
"error_params": {
|
|
417
|
+
"operator": _then_op,
|
|
418
|
+
"threshold": str(_then_threshold),
|
|
419
|
+
"column": self.then_column,
|
|
420
|
+
"table": self.table,
|
|
421
|
+
},
|
|
409
422
|
"table": self.table,
|
|
410
423
|
"column": self.then_column,
|
|
411
424
|
"message": (
|
|
@@ -494,6 +507,8 @@ class ConditionalConstraint(Constraint):
|
|
|
494
507
|
errors.append(
|
|
495
508
|
{
|
|
496
509
|
"error_type": "ConstraintConfigError",
|
|
510
|
+
"error_code": "CONDITIONAL_UNKNOWN_IF_LOGIC",
|
|
511
|
+
"error_params": {"if_logic": self.if_logic},
|
|
497
512
|
"table": self.table,
|
|
498
513
|
"message": f"条件约束失败: 未知的 if_logic '{self.if_logic}',支持的值为: and, or。",
|
|
499
514
|
}
|
|
@@ -506,6 +521,8 @@ class ConditionalConstraint(Constraint):
|
|
|
506
521
|
errors.append(
|
|
507
522
|
{
|
|
508
523
|
"error_type": "ConstraintConfigError",
|
|
524
|
+
"error_code": "CONDITIONAL_IF_COLUMN_NOT_FOUND",
|
|
525
|
+
"error_params": {"column": missing, "table": self.table},
|
|
509
526
|
"table": self.table,
|
|
510
527
|
"column": missing,
|
|
511
528
|
"message": f"条件约束失败: 列 '{missing}' 不在表 '{self.table}' 中。",
|
|
@@ -516,6 +533,8 @@ class ConditionalConstraint(Constraint):
|
|
|
516
533
|
errors.append(
|
|
517
534
|
{
|
|
518
535
|
"error_type": "ConstraintConfigError",
|
|
536
|
+
"error_code": "CONDITIONAL_INVALID_IF_CONDITION",
|
|
537
|
+
"error_params": {"detail": str(e)},
|
|
519
538
|
"table": self.table,
|
|
520
539
|
"message": f"条件约束失败: {e}",
|
|
521
540
|
}
|
|
@@ -540,6 +559,8 @@ class ConditionalConstraint(Constraint):
|
|
|
540
559
|
errors.append(
|
|
541
560
|
{
|
|
542
561
|
"error_type": "ConstraintConfigError",
|
|
562
|
+
"error_code": "CONDITIONAL_IF_COLUMN_NOT_FOUND",
|
|
563
|
+
"error_params": {"column": self.if_column, "table": self.table},
|
|
543
564
|
"table": self.table,
|
|
544
565
|
"column": self.if_column,
|
|
545
566
|
"message": f"条件约束失败: 列 '{self.if_column}' 不在表 '{self.table}' 中。",
|
|
@@ -552,6 +573,8 @@ class ConditionalConstraint(Constraint):
|
|
|
552
573
|
errors.append(
|
|
553
574
|
{
|
|
554
575
|
"error_type": "ConstraintConfigError",
|
|
576
|
+
"error_code": "CONDITIONAL_IF_VALUE_MISSING",
|
|
577
|
+
"error_params": {"if_column": self.if_column},
|
|
555
578
|
"table": self.table,
|
|
556
579
|
"column": self.if_column,
|
|
557
580
|
"message": (
|
|
@@ -580,6 +603,8 @@ class ConditionalConstraint(Constraint):
|
|
|
580
603
|
errors.append(
|
|
581
604
|
{
|
|
582
605
|
"error_type": "Timeout",
|
|
606
|
+
"error_code": "CONDITIONAL_TIMEOUT",
|
|
607
|
+
"error_params": {"processed": i, "total": len(triggered_dict)},
|
|
583
608
|
"stage": "constraint",
|
|
584
609
|
"table": self.table,
|
|
585
610
|
"message": (
|
|
@@ -619,6 +644,12 @@ class ConditionalConstraint(Constraint):
|
|
|
619
644
|
errors.append(
|
|
620
645
|
{
|
|
621
646
|
"error_type": "ConditionalViolation",
|
|
647
|
+
"error_code": "CONDITIONAL_THEN_VIOLATION",
|
|
648
|
+
"error_params": {
|
|
649
|
+
"column": self.then_column,
|
|
650
|
+
"value": str(value_to_check),
|
|
651
|
+
"condition": self._condition_str,
|
|
652
|
+
},
|
|
622
653
|
"table": self.table,
|
|
623
654
|
"row_index": row_index,
|
|
624
655
|
"value": {**if_value_payload, self.then_column: value_to_check},
|