Enforce plugin contract purity: single import surface via shopdb.api
Plugins were reaching into internal core paths (shopdb.core.models.*, shopdb.extensions, shopdb.utils.*), coupling them to core's file layout and violating the ADR-001 contract. Consolidate onto one versioned surface. - shopdb.api: expand from 2 helpers to the full plugin import surface - db, cache; BaseModel, AuditMixin; core models (Asset, AssetType, AssetStatus, Vendor, Model, Communication, CommunicationType, Location, Setting, AuditLog, Application, AppVersion, OperatingSystem); response + pagination helpers; employee_connection. Documented in PLUGIN-HOOKS.md. - Migrate all 22 plugin source files to import only from shopdb.api (plus shopdb.plugins.base for the ABC). - Drop the printers plugin's legacy MachineType dependency: remove _ensure_legacy_machine_types and the seed_supplies machinetypeid lookup (Model.machinetypeid is nullable; printers carry type via PrinterType). - Guard test test_plugins_only_import_contract_surface scans plugin source and fails on any core import outside shopdb.api / shopdb.plugins.base. - Scaffold templates updated so generated plugins are contract-pure. - Bump __contract_version__ 0.2.0 -> 0.3.0 (additive surface expansion; manifests pin <1.0.0 so they still satisfy). 145 tests pass, naming/style green, app factory boots all 6 plugins. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -233,6 +233,34 @@ These run when the plugin's installation state changes. All optional.
|
||||
| `on_enable(app)` | When the plugin is enabled at runtime | Subscribe to events, warm caches |
|
||||
| `on_disable(app)` | When the plugin is disabled at runtime | Unsubscribe, drain queues |
|
||||
|
||||
## The import surface (`shopdb.api`)
|
||||
|
||||
`shopdb.api` is the ONLY core module a plugin may import from (besides
|
||||
`shopdb.plugins.base` for `BasePlugin` / `PluginMeta`). Importing internal
|
||||
paths like `shopdb.core.models.*`, `shopdb.extensions`, or `shopdb.utils.*`
|
||||
is a contract violation and fails the test
|
||||
`tests/test_plugin_contract.py::test_plugins_only_import_contract_surface`.
|
||||
|
||||
What `shopdb.api` exposes:
|
||||
|
||||
- Infrastructure: `db`, `cache`
|
||||
- Model bases: `BaseModel`, `AuditMixin`
|
||||
- Core models: `Asset`, `AssetType`, `AssetStatus`, `Vendor`, `Model`,
|
||||
`Communication`, `CommunicationType`, `Location`, `Setting`, `AuditLog`,
|
||||
`Application`, `AppVersion`, `OperatingSystem`
|
||||
- Responses: `success_response`, `error_response`, `paginated_response`,
|
||||
`ErrorCodes`
|
||||
- Pagination: `get_pagination_params`, `paginate_query`
|
||||
- Helpers: `audit_log`, `resolve_asset_position`
|
||||
- Legacy employee directory: `employee_connection`
|
||||
|
||||
```python
|
||||
from shopdb.api import db, Asset, AssetType, success_response, paginate_query
|
||||
```
|
||||
|
||||
Adding a name to `shopdb.api` is an additive (minor) contract bump; removing
|
||||
one is breaking (major). See ADR-002.
|
||||
|
||||
## Helpers exposed to plugins
|
||||
|
||||
The framework provides helper APIs in `shopdb.api` (the public namespace).
|
||||
|
||||
Reference in New Issue
Block a user