aboa 0.1.0__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.
- aboa-0.1.0/AUTHORS +5 -0
- aboa-0.1.0/LICENSE +19 -0
- aboa-0.1.0/MANIFEST.in +3 -0
- aboa-0.1.0/PKG-INFO +374 -0
- aboa-0.1.0/README.md +344 -0
- aboa-0.1.0/pyproject.toml +59 -0
- aboa-0.1.0/setup.cfg +4 -0
- aboa-0.1.0/src/aboa/__init__.py +4 -0
- aboa-0.1.0/src/aboa/config/archive_configurations.xml +8 -0
- aboa-0.1.0/src/aboa/config/datamodel.json +12 -0
- aboa-0.1.0/src/aboa/config/engine.json +10 -0
- aboa-0.1.0/src/aboa/datamodel/__init__.py +1 -0
- aboa-0.1.0/src/aboa/datamodel/aboa_data_model.sql +365 -0
- aboa-0.1.0/src/aboa/datamodel/archived_files.py +407 -0
- aboa-0.1.0/src/aboa/datamodel/base.py +22 -0
- aboa-0.1.0/src/aboa/datamodel/errors.py +23 -0
- aboa-0.1.0/src/aboa/datamodel/functions.py +40 -0
- aboa-0.1.0/src/aboa/engine/__init__.py +1 -0
- aboa-0.1.0/src/aboa/engine/commands.py +788 -0
- aboa-0.1.0/src/aboa/engine/engine.py +1508 -0
- aboa-0.1.0/src/aboa/engine/errors.py +64 -0
- aboa-0.1.0/src/aboa/engine/functions.py +207 -0
- aboa-0.1.0/src/aboa/engine/operators.py +18 -0
- aboa-0.1.0/src/aboa/engine/parsing.py +161 -0
- aboa-0.1.0/src/aboa/engine/query.py +619 -0
- aboa-0.1.0/src/aboa/engine/retention.py +155 -0
- aboa-0.1.0/src/aboa/engine/xpath_functions.py +32 -0
- aboa-0.1.0/src/aboa/logging.py +107 -0
- aboa-0.1.0/src/aboa/processors/__init__.py +1 -0
- aboa-0.1.0/src/aboa/processors/base_processor.py +41 -0
- aboa-0.1.0/src/aboa/schemas/aboa_archive_configurations.xsd +53 -0
- aboa-0.1.0/src/aboa/scripts/__init__.py +3 -0
- aboa-0.1.0/src/aboa/scripts/aboa_archive.py +17 -0
- aboa-0.1.0/src/aboa/scripts/aboa_clean_up.py +17 -0
- aboa-0.1.0/src/aboa/scripts/aboa_delete.py +17 -0
- aboa-0.1.0/src/aboa/scripts/aboa_init.py +143 -0
- aboa-0.1.0/src/aboa/scripts/aboa_init_ddbb.sh +107 -0
- aboa-0.1.0/src/aboa/scripts/aboa_recover.py +17 -0
- aboa-0.1.0/src/aboa/scripts/aboa_retrieve.py +17 -0
- aboa-0.1.0/src/aboa/scripts/initialize_aboa_ddbb.sh +20 -0
- aboa-0.1.0/src/aboa/scripts/start_aboa.sh +6 -0
- aboa-0.1.0/src/aboa.egg-info/PKG-INFO +374 -0
- aboa-0.1.0/src/aboa.egg-info/SOURCES.txt +45 -0
- aboa-0.1.0/src/aboa.egg-info/dependency_links.txt +1 -0
- aboa-0.1.0/src/aboa.egg-info/entry_points.txt +7 -0
- aboa-0.1.0/src/aboa.egg-info/requires.txt +8 -0
- aboa-0.1.0/src/aboa.egg-info/top_level.txt +1 -0
aboa-0.1.0/AUTHORS
ADDED
aboa-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright 2026-2026 BOA authors and contributors <see AUTHORS file>.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
5
|
+
the Software without restriction, including without limitation the rights to
|
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
8
|
+
so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
aboa-0.1.0/MANIFEST.in
ADDED
aboa-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aboa
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Archive for Business Operations Analysis
|
|
5
|
+
Author: Daniel Brosnan Blázquez
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Daniel-Brosnan-Blazquez/aboa
|
|
8
|
+
Project-URL: Repository, https://github.com/Daniel-Brosnan-Blazquez/aboa
|
|
9
|
+
Project-URL: Issues, https://github.com/Daniel-Brosnan-Blazquez/aboa/issues
|
|
10
|
+
Keywords: archive,inventory,postgresql,retention
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: POSIX
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Topic :: System :: Archiving
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
License-File: AUTHORS
|
|
22
|
+
Requires-Dist: sqlalchemy==1.3.22
|
|
23
|
+
Requires-Dist: psycopg2-binary==2.9.11
|
|
24
|
+
Requires-Dist: python-dateutil==2.9.0.post0
|
|
25
|
+
Requires-Dist: lxml==6.0.2
|
|
26
|
+
Provides-Extra: tests
|
|
27
|
+
Requires-Dist: pytest==8.4.2; extra == "tests"
|
|
28
|
+
Requires-Dist: pytest-cov==7.0.0; extra == "tests"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# ABOA
|
|
32
|
+
|
|
33
|
+
Archive for Business Operations Analysis.
|
|
34
|
+
|
|
35
|
+
ABOA stores files on a POSIX filesystem and keeps a PostgreSQL inventory of the
|
|
36
|
+
archived payloads, metadata, configuration history, root-directory history,
|
|
37
|
+
operation failures, trash queues, retention cleanup, and recovery state. The
|
|
38
|
+
current implementation exposes both command line tools and Python interfaces
|
|
39
|
+
through `aboa.engine.engine.Engine` and `aboa.engine.query.Query`.
|
|
40
|
+
|
|
41
|
+
## Contents
|
|
42
|
+
|
|
43
|
+
- [What ABOA Provides](#what-aboa-provides)
|
|
44
|
+
- [Quick Start With Docker](#quick-start-with-docker)
|
|
45
|
+
- [Local Python Setup](#local-python-setup)
|
|
46
|
+
- [Install From PyPI](#install-from-pypi)
|
|
47
|
+
- [Runtime Configuration](#runtime-configuration)
|
|
48
|
+
- [Archive Configuration XML](#archive-configuration-xml)
|
|
49
|
+
- [Command Line Tools](#command-line-tools)
|
|
50
|
+
- [Python API](#python-api)
|
|
51
|
+
- [Operation Flow Schematics](#operation-flow-schematics)
|
|
52
|
+
- [Data Model](#data-model)
|
|
53
|
+
- [Development Layout](#development-layout)
|
|
54
|
+
- [Tests](#tests)
|
|
55
|
+
- [Publishing](#publishing)
|
|
56
|
+
|
|
57
|
+
## What ABOA Provides
|
|
58
|
+
|
|
59
|
+
- Archive files into a managed root directory using configurable routing rules.
|
|
60
|
+
- Keep inventory metadata in SQLAlchemy/PostgreSQL tables.
|
|
61
|
+
- Track active archive roots and active XML archive-configuration history.
|
|
62
|
+
- Detect duplicate archived file names and route archive failures into the
|
|
63
|
+
internal `error` area when the input can still be brought under ABOA control.
|
|
64
|
+
- Retrieve inventory rows and optionally copy payloads to a destination folder.
|
|
65
|
+
- Logically delete files, move payloads to trash, permanently delete payloads, or
|
|
66
|
+
purge inventory entries when no managed payload remains.
|
|
67
|
+
- Recover files from trash or from logical-only deletion.
|
|
68
|
+
- Apply retention cleanup and final trash removal cleanup.
|
|
69
|
+
- Record failed operations in `archive_operations` while successful operations
|
|
70
|
+
are written only to the log.
|
|
71
|
+
|
|
72
|
+
## Quick Start With Docker
|
|
73
|
+
|
|
74
|
+
The development compose file starts an ABOA container and a PostgreSQL/PostGIS
|
|
75
|
+
database container. The source checkout is mounted into the ABOA container at
|
|
76
|
+
`/aboa`.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
docker compose -f compose_dev.yml up -d --build
|
|
80
|
+
docker compose -f compose_dev.yml exec aboa initialize_aboa_ddbb.sh
|
|
81
|
+
docker compose -f compose_dev.yml exec aboa aboa_archive.py --file /aboa/src/tests/inputs/sample.txt
|
|
82
|
+
docker compose -f compose_dev.yml exec aboa aboa_retrieve.py --name sample.txt --list
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`initialize_aboa_ddbb.sh` calls `aboa_init.py -y` and recreates the configured
|
|
86
|
+
database from `src/aboa/datamodel/aboa_data_model.sql`, so it deletes existing ABOA
|
|
87
|
+
inventory data for that database.
|
|
88
|
+
|
|
89
|
+
## Local Python Setup
|
|
90
|
+
|
|
91
|
+
For local development outside Docker, use Python 3.9 or newer and install from
|
|
92
|
+
the repository root:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
python3 -m venv .venv
|
|
96
|
+
source .venv/bin/activate
|
|
97
|
+
python -m pip install -e ".[tests]"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Set the runtime paths before importing or running ABOA:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
export ABOA_RESOURCES_PATH="$PWD/src/aboa/config"
|
|
104
|
+
export ABOA_LOG_PATH="$PWD/log"
|
|
105
|
+
export ABOA_DEFAULT_ARCHIVE_PATH="/tmp/aboa_archive"
|
|
106
|
+
mkdir -p "$ABOA_LOG_PATH" "$ABOA_DEFAULT_ARCHIVE_PATH"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Install From PyPI
|
|
110
|
+
|
|
111
|
+
Once the first release is published, install ABOA in a virtual environment on a
|
|
112
|
+
POSIX system with Python 3.9 or newer:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
python -m pip install aboa
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
ABOA requires a PostgreSQL server and the PostgreSQL `psql` command to initialize
|
|
119
|
+
the database. Copy the bundled defaults to a writable configuration directory:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
export ABOA_RESOURCES_PATH="$PWD/aboa-config"
|
|
123
|
+
export ABOA_LOG_PATH="$PWD/log"
|
|
124
|
+
export ABOA_DEFAULT_ARCHIVE_PATH="$PWD/archive"
|
|
125
|
+
mkdir -p "$ABOA_RESOURCES_PATH" "$ABOA_LOG_PATH" "$ABOA_DEFAULT_ARCHIVE_PATH"
|
|
126
|
+
python -c 'import os, shutil, aboa; from pathlib import Path; shutil.copytree(Path(aboa.__file__).parent / "config", os.environ["ABOA_RESOURCES_PATH"], dirs_exist_ok=True)'
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Edit `datamodel.json` for the database connection and set `root_directory` in
|
|
130
|
+
`archive_configurations.xml` to the archive directory. Then run `aboa_init.py`
|
|
131
|
+
and follow its confirmation prompt. Initialization requires PostgreSQL
|
|
132
|
+
administrator access and recreates the configured database.
|
|
133
|
+
|
|
134
|
+
## Runtime Configuration
|
|
135
|
+
|
|
136
|
+
ABOA reads JSON and XML runtime resources from `ABOA_RESOURCES_PATH`, falling
|
|
137
|
+
back to bundled defaults when it is unset. The XML schema is bundled with the
|
|
138
|
+
`aboa` package.
|
|
139
|
+
|
|
140
|
+
Required environment variables:
|
|
141
|
+
|
|
142
|
+
- `ABOA_LOG_PATH`: directory where rotating log files are written.
|
|
143
|
+
|
|
144
|
+
Optional environment variables:
|
|
145
|
+
|
|
146
|
+
- `ABOA_RESOURCES_PATH`: directory containing `datamodel.json`,
|
|
147
|
+
`engine.json`, and `archive_configurations.xml`; defaults to the packaged
|
|
148
|
+
configuration directory.
|
|
149
|
+
- `ABOA_DEFAULT_ARCHIVE_PATH`: fallback archive root used when the XML archive
|
|
150
|
+
configuration cannot be activated.
|
|
151
|
+
- `ABOA_DDBB_HOST`: overrides the host from `datamodel.json`.
|
|
152
|
+
- `ABOA_LOG_LEVEL`: overrides the log level from `engine.json`.
|
|
153
|
+
- `ABOA_STREAM_LOG`: enables stream logging in addition to the rotating file log.
|
|
154
|
+
- `ABOA_LOG_MAX_BYTES` and `ABOA_LOG_MAX_BACKUP`: override log rotation limits.
|
|
155
|
+
|
|
156
|
+
`src/aboa/config/engine.json` configures logging and archive cleanup behavior:
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"LOG": {
|
|
161
|
+
"LEVEL": "INFO",
|
|
162
|
+
"MAX_BYTES": 50000000,
|
|
163
|
+
"MAX_BACKUP": 30
|
|
164
|
+
},
|
|
165
|
+
"ARCHIVE": {
|
|
166
|
+
"FINAL_REMOVAL_DELAY_DAYS": 30
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Archived payloads are stored below the active root using:
|
|
172
|
+
|
|
173
|
+
```text
|
|
174
|
+
<root_directory>/<target_directory>/<YEAR>/<MONTH>/<DAY>/<file_name>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The reserved target directories are `unknown`, `error`, and `trash`.
|
|
178
|
+
|
|
179
|
+
## Archive Configuration XML
|
|
180
|
+
|
|
181
|
+
The default configuration lives at `src/aboa/config/archive_configurations.xml`.
|
|
182
|
+
ABOA validates this file with `src/aboa/schemas/aboa_archive_configurations.xsd`.
|
|
183
|
+
|
|
184
|
+
```xml
|
|
185
|
+
<archive_configurations root_directory="/tmp/aboa_archive">
|
|
186
|
+
<archive_configuration file_group="invoices">
|
|
187
|
+
<file_mask>*.pdf</file_mask>
|
|
188
|
+
<file_directory>invoices</file_directory>
|
|
189
|
+
<retention_policy active="true" key="archive_date">P180D</retention_policy>
|
|
190
|
+
</archive_configuration>
|
|
191
|
+
<retention_policies>
|
|
192
|
+
<retention_policy active="true" key="validity_stop_date">P365D</retention_policy>
|
|
193
|
+
</retention_policies>
|
|
194
|
+
</archive_configurations>
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Archive rules are evaluated by file mask. A matching rule sets the target
|
|
198
|
+
directory, file group, optional processor module, and optional retention policy.
|
|
199
|
+
If no rule matches, ABOA stores the file in the internal `unknown` area with file
|
|
200
|
+
group `unknown`.
|
|
201
|
+
|
|
202
|
+
Processors are importable Python modules that expose `process(file_path)` and
|
|
203
|
+
return a metadata dictionary. Supported metadata includes file type, class,
|
|
204
|
+
version, validity dates, generation date, and expiration date.
|
|
205
|
+
|
|
206
|
+
Retention policies use XML duration values such as `P30D` and can use
|
|
207
|
+
`generation_date`, `reception_date`, `archive_date`, or `validity_stop_date` as
|
|
208
|
+
the base key.
|
|
209
|
+
|
|
210
|
+
## Command Line Tools
|
|
211
|
+
|
|
212
|
+
The package installs these console commands:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
aboa_init.py [-f /path/to/aboa_data_model.sql] [-y]
|
|
216
|
+
aboa_archive.py --file /path/to/file [--delete] [--expiration-date DATETIME]
|
|
217
|
+
aboa_retrieve.py [filters] [--list] [--destination-path /path/to/output]
|
|
218
|
+
aboa_delete.py [filters] [--physical | --permanent] [--purge-entry] [--reason TEXT]
|
|
219
|
+
aboa_recover.py [archived-file filters | trash filters] [--list]
|
|
220
|
+
aboa_clean_up.py [--dry-run]
|
|
221
|
+
aboa_clean_up.py --final-removal [--dry-run]
|
|
222
|
+
aboa_clean_up.py --empty-trash [--dry-run]
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Common examples:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
aboa_archive.py --file /data/incoming/report.txt --delete
|
|
229
|
+
aboa_archive.py --file /data/incoming/invoice.pdf --expiration-date 2026-12-31T00:00:00
|
|
230
|
+
aboa_retrieve.py --name "%.txt" --order-by archive_date --descending --list
|
|
231
|
+
aboa_retrieve.py --uuid <file_uuid> --destination-path /tmp/retrieved
|
|
232
|
+
aboa_delete.py --uuid <file_uuid> --reason manual_delete
|
|
233
|
+
aboa_delete.py --uuid <file_uuid> --physical
|
|
234
|
+
aboa_delete.py --uuid <file_uuid> --permanent --purge-entry
|
|
235
|
+
aboa_recover.py --uuid <file_uuid>
|
|
236
|
+
aboa_recover.py --trash-uuid <file_to_remove_uuid>
|
|
237
|
+
aboa_clean_up.py --dry-run
|
|
238
|
+
aboa_clean_up.py --final-removal
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Retrieve, delete, and recover commands share many inventory filters, including:
|
|
242
|
+
|
|
243
|
+
- Text filters: `--uuid`, `--name`, `--path`, `--root-directory-uuid`,
|
|
244
|
+
`--file-group`, `--file-type`, `--file-class`, `--file-version`,
|
|
245
|
+
`--archive-configuration-uuid`, `--delete-archive-configuration-uuid`,
|
|
246
|
+
`--removal-justification`, and `--checksum`.
|
|
247
|
+
- Date filters: `--reception-date`, `--archive-date`, `--last-access-date`,
|
|
248
|
+
`--validity-start-date`, `--validity-stop-date`, `--generation-date`,
|
|
249
|
+
`--expiration-date`, and `--removal-date`.
|
|
250
|
+
- Numeric and boolean filters: `--file-size`, `--available`, and
|
|
251
|
+
`--physically-available`.
|
|
252
|
+
- Trash recovery filters: `--trash-uuid`, `--trash-path`,
|
|
253
|
+
`--trash-root-directory-uuid`, and `--trash-removal-date`.
|
|
254
|
+
|
|
255
|
+
Filter values may use operators such as `==`, `!=`, `<`, `<=`, `>`, and `>=`
|
|
256
|
+
for arithmetic/date filters. Text filters also expose `--<filter>-op` options
|
|
257
|
+
for text operators. Run any command with `--help` for the exact supported options.
|
|
258
|
+
|
|
259
|
+
## Python API
|
|
260
|
+
|
|
261
|
+
Use `Engine` for mutating operations and `Query` for read-only inventory access.
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
from aboa.engine.engine import Engine
|
|
265
|
+
from aboa.engine.query import Query
|
|
266
|
+
|
|
267
|
+
engine = Engine()
|
|
268
|
+
try:
|
|
269
|
+
engine.archive_file("/data/incoming/report.txt", delete=True)
|
|
270
|
+
rows = engine.retrieve_files(
|
|
271
|
+
filters={"names": {"filter": "%.txt", "op": "like"}},
|
|
272
|
+
order_by={"field": "archive_date", "descending": True},
|
|
273
|
+
)
|
|
274
|
+
finally:
|
|
275
|
+
engine.close_session()
|
|
276
|
+
|
|
277
|
+
query = Query()
|
|
278
|
+
try:
|
|
279
|
+
active_root = query.get_active_root_directory()
|
|
280
|
+
failures = query.get_archive_operations(
|
|
281
|
+
operations={"filter": "archive", "op": "like"}
|
|
282
|
+
)
|
|
283
|
+
finally:
|
|
284
|
+
query.close_session()
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Important write-side methods include `archive_file`, `retrieve_files`,
|
|
288
|
+
`delete_files`, `delete_archived_file_entries`, `recover_files_from_trash`,
|
|
289
|
+
`move_archived_file_to_trash`, and `delete_archived_file_permanently`.
|
|
290
|
+
|
|
291
|
+
## Operation Flow Schematics
|
|
292
|
+
|
|
293
|
+
### Shared Operation Rules
|
|
294
|
+
|
|
295
|
+

|
|
296
|
+
|
|
297
|
+
### Load Archive Configuration
|
|
298
|
+
|
|
299
|
+

|
|
300
|
+
|
|
301
|
+
### Archive Operation
|
|
302
|
+
|
|
303
|
+

|
|
304
|
+
|
|
305
|
+
### Retrieve Operation
|
|
306
|
+
|
|
307
|
+

|
|
308
|
+
|
|
309
|
+
### Delete Operation
|
|
310
|
+
|
|
311
|
+

|
|
312
|
+
|
|
313
|
+
### Physical Deletion And Trash
|
|
314
|
+
|
|
315
|
+

|
|
316
|
+
|
|
317
|
+
### Recovery Operation
|
|
318
|
+
|
|
319
|
+

|
|
320
|
+
|
|
321
|
+
### Retention Cleanup
|
|
322
|
+
|
|
323
|
+

|
|
324
|
+
|
|
325
|
+
### Final Removal Cleanup
|
|
326
|
+
|
|
327
|
+

|
|
328
|
+
|
|
329
|
+
## Data Model
|
|
330
|
+
|
|
331
|
+
The DDBB model, stored in `src/aboa/datamodel/aboa_data_model.dbm`, is built using pgModeler. The tool is then used to generate the SQL instructions, stored in `src/aboa/datamodel/aboa_data_model.sql`, to initialize the DDBB.
|
|
332
|
+
|
|
333
|
+

|
|
334
|
+
|
|
335
|
+
Main inventory tables:
|
|
336
|
+
|
|
337
|
+
- `archive_root_directories`: active and historical archive roots.
|
|
338
|
+
- `archive_configurations`: active and historical XML configuration snapshots.
|
|
339
|
+
- `archived_files`: metadata for archived payloads and logical/physical
|
|
340
|
+
availability.
|
|
341
|
+
- `archive_operations`: failed operation records.
|
|
342
|
+
- `files_to_be_removed`: trash payloads queued for final removal.
|
|
343
|
+
|
|
344
|
+
## Development Layout
|
|
345
|
+
|
|
346
|
+
- `src/aboa/datamodel`: SQLAlchemy model, database configuration, exported SQL,
|
|
347
|
+
and pgModeler model.
|
|
348
|
+
- `src/aboa/engine`: archive, query, configuration, retention, and CLI logic.
|
|
349
|
+
- `src/aboa/processors`: metadata processor contract.
|
|
350
|
+
- `src/aboa/config`: default runtime configuration.
|
|
351
|
+
- `src/aboa/schemas`: bundled XML schemas.
|
|
352
|
+
- `src/aboa/scripts`: console script entry points and database initialization helpers.
|
|
353
|
+
- `src/tests`: pytest-based test suite.
|
|
354
|
+
- `development_plans`: design notes, requirements, and operation flow details.
|
|
355
|
+
- `doc/fig`: data model and operation-flow diagrams.
|
|
356
|
+
|
|
357
|
+
## Tests
|
|
358
|
+
|
|
359
|
+
Install the test extra and run the suite from the repository root:
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
python -m pip install -e ".[tests]"
|
|
363
|
+
export ABOA_RESOURCES_PATH="$PWD/src/aboa/config"
|
|
364
|
+
export ABOA_LOG_PATH="$PWD/log"
|
|
365
|
+
export ABOA_DEFAULT_ARCHIVE_PATH="/tmp/aboa_archive"
|
|
366
|
+
mkdir -p "$ABOA_LOG_PATH" "$ABOA_DEFAULT_ARCHIVE_PATH"
|
|
367
|
+
python -m pytest src/tests
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Publishing
|
|
371
|
+
|
|
372
|
+
See [the publishing guide](https://github.com/Daniel-Brosnan-Blazquez/aboa/blob/main/doc/publishing.md)
|
|
373
|
+
for local build checks, PyPI Trusted Publisher setup, and the GitHub release
|
|
374
|
+
workflow. Package metadata and the release version live in `pyproject.toml`.
|