From 1a3756f47ce05576cb06bff0f8b4a31da7928ed0 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Thu, 4 Dec 2025 00:51:30 -0600 Subject: [PATCH] docs: add basic docs for batch feature --- docs/conf.py | 1 + docs/glossary.rst | 13 +++---- docs/index.rst | 1 + docs/narr/batch/handlers.rst | 38 ++++++++++++++++++ docs/narr/batch/index.rst | 49 ++++++++++++++++++++++++ docs/narr/batch/model.rst | 74 ++++++++++++++++++++++++++++++++++++ 6 files changed, 169 insertions(+), 7 deletions(-) create mode 100644 docs/narr/batch/handlers.rst create mode 100644 docs/narr/batch/index.rst create mode 100644 docs/narr/batch/model.rst diff --git a/docs/conf.py b/docs/conf.py index ad12c1a..5ce3986 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -43,6 +43,7 @@ intersphinx_mapping = { "rich": ("https://rich.readthedocs.io/en/latest/", None), "sqlalchemy": ("http://docs.sqlalchemy.org/en/latest/", None), "wutta-continuum": ("https://docs.wuttaproject.org/wutta-continuum/", None), + "wuttasync": ("https://docs.wuttaproject.org/wuttasync/", None), } diff --git a/docs/glossary.rst b/docs/glossary.rst index c01a4ec..6550ea0 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -77,16 +77,15 @@ Glossary See also :class:`~wuttjamaican.auth.AuthHandler`. batch - This refers to a process whereby bulk data operations may be + This refers to a feature whereby bulk data operations may be performed, with preview and other tools to allow the user to - refine as needed before "executing" the batch. + refine as needed before "executing" the batch. For more info see + :doc:`narr/batch/index`. The term "batch" may refer to such a feature overall, or the :term:`data model` used, or the specific data for a single batch, - etc. - - See also :term:`batch handler` and :term:`batch row`, and the - :class:`~wuttjamaican.db.model.batch.BatchMixin` base class. + etc. See also :term:`batch type`, :term:`batch handler` and + :term:`batch row`. batch handler This refers to a :term:`handler` meant to process a given type of @@ -94,7 +93,7 @@ Glossary There may be multiple handlers registered for a given :term:`batch type`, but (usually) only one will be configured for - use. + use. See also :doc:`narr/batch/handlers`. batch row A row of data within a :term:`batch`. diff --git a/docs/index.rst b/docs/index.rst index 88a01a1..c7c64a0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -64,6 +64,7 @@ Contents narr/email/index narr/handlers/index narr/providers/index + narr/batch/index .. toctree:: :maxdepth: 1 diff --git a/docs/narr/batch/handlers.rst b/docs/narr/batch/handlers.rst new file mode 100644 index 0000000..ffebbee --- /dev/null +++ b/docs/narr/batch/handlers.rst @@ -0,0 +1,38 @@ + +Batch Handlers +============== + +The :term:`batch handler` is responsible for all logic surrounding a +:term:`batch`: creation, updates, execution. + +Each batch handler is associated with one :term:`batch type`. There +may be more than one handler defined for a given batch type. However +only one handler will be designated as the "default" for each batch +type (based on config and app defaults). + + +Class Definition +---------------- + +A new batch handler class should inherit from +:class:`~wuttjamaican.batch.BatchHandler`, which provides most of the +typical housekeeping logic etc. + +Note that it also must declare the +:attr:`~wuttjamaican.batch.BatchHandler.model_class`, which ultimately +determines the handler's :term:`batch type`. + +You will need to define/override some methods for the new handler to +be useful:: + + from wuttjamaican.batch import BatchHandler + from poser.db.model import InventoryBatch + + class InventoryBatchHandler(BatchHandler): + """ Handler for inventory count batches """ + + # direct reference to batch model class + model_class = InventoryBatch + + def execute(self, batch, user=None, progress=None, **kwargs): + """ export batch row data to CSV """ diff --git a/docs/narr/batch/index.rst b/docs/narr/batch/index.rst new file mode 100644 index 0000000..fba0b0d --- /dev/null +++ b/docs/narr/batch/index.rst @@ -0,0 +1,49 @@ + +Batches +======= + +A :term:`batch` is essentially a temporary table with row data of a +certain type, which can be previewed and finalized before "executing" +it. For instance it might be used to handle import of CSV files +uploaded by the user, but there are many other use cases. + +.. note:: + + While a batch may be used to import data, these are different + concepts. A true data import process is normally automated, with + no preview tooling per se. A batch normally has preview tooling + but its execution may or may not import data per se. + + For true data import see :doc:`wuttasync:index`. + +The batch concept (as used here) comes from Rattail; see also +:doc:`rattail:narr/batches`. + +Each batch will be of a certain :term:`batch type`. Each instance of +the :term:`app` will have just one :term:`batch handler` responsible +for each batch type. + +Batch data may come from CSV file, SQL query, external API etc. In +some cases (e.g. creating a purchase order, or counting inventory) the +data is added over time by the user. + +The user can review all data in the batch before executing. Some +batches may allow the user to add/remove/modify rows (or other data) +in the batch prior to execution. + +Upon execution the batch handler's +:meth:`~wuttjamaican.batch.BatchHandler.execute()` method is invoked, +so that will determine what is done with the batch data. Once a batch +is executed, it is "frozen" with no further modifications allowed to +it. + + +.. toctree:: + :maxdepth: 3 + + model + handlers + + +.. image:: https://rattailproject.org/images/batch-pattern.png + diff --git a/docs/narr/batch/model.rst b/docs/narr/batch/model.rst new file mode 100644 index 0000000..11af076 --- /dev/null +++ b/docs/narr/batch/model.rst @@ -0,0 +1,74 @@ + +Batch Models +============ + +Each :term:`batch type` will involve 2 tables in the :term:`app +database`. Each table is mapped to a :term:`data model` as shown +below. + +Note that the model should only describe the data structure; all logic +belongs in the :term:`batch handler`. + + +Batch (header) +-------------- + +The model class for the batch header should inherit from +:class:`~wuttjamaican.db.model.batch.BatchMixin`, which gives it the +base set of columns for identifying the batch creator/executor etc. + +Declaring the +:attr:`~wuttjamaican.db.model.batch.BatchMixin.batch_type` is +optional; if not specified the table name is used. Remember the batch +type is used for batch handler lookup (among other things). + +Additional columns may be added as needed, per the nature of the batch +type:: + + import sqlalchemy as sa + from wuttjamaican.db import model + + class InventoryBatch(model.BatchMixin, model.Base): + """ Simple batch for counting inventory. """ + + # name of table within the app DB + __tablename__ = "poser_batch_inventory" + + # unique identifier for this batch type + batch_type = "inventory" + + device = sa.Column(sa.String(length=255), nullable=True, doc=""" + Name of the scanning device used when counting. + """) + + +Batch Row +--------- + +The model class for batch rows should inherit from +:class:`~wuttjamaican.db.model.batch.BatchRowMixin`, which gives it +the base set of columns for tracking status etc. + +Note that it also must declare the +:attr:`~wuttjamaican.db.model.batch.BatchRowMixin.__batch_class__` for +things to work correctly. + +Additional columns may be added as needed, per the nature of the batch +type:: + + class InventoryBatchRow(model.BatchRowMixin, model.Base): + """ Item entry row for inventory counting. """ + + # name of table within the app DB + __tablename__ = "poser_batch_inventory_row" + + # direct reference to batch model class + __batch_class__ = InventoryBatch + + scancode = sa.Column(sa.String(length=14), nullable=False, doc=""" + Scanned UPC of the item. + """) + + quantity = sa.Column(sa.Numeric(precision=6, scale=2), nullable=False, default=0, doc=""" + Quantity of the item. + """)