2026-08-18 22:14:47 +00:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
"""Bootstrap PocketBase schema for MEGA INFRASTRUCTURE.
|
|
|
|
|
|
|
|
|
|
|
|
PocketBase v0.39 JSON shape: type-specific options (values, maxSelect,
|
|
|
|
|
|
mimeTypes, collectionId, cascadeDelete, min, max) live at the field
|
|
|
|
|
|
top level — NOT nested under "options".
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
|
|
|
|
|
|
Reflects the post-ingestion-restructure schema (2026-09):
|
|
|
|
|
|
- `data_import_batches` (the shared queue pool) and the deprecated
|
|
|
|
|
|
`plant` alias for `vehicles` are gone.
|
|
|
|
|
|
- `timesheets`, `fuel_sheets` and `plant_hours_sheets` are the
|
|
|
|
|
|
uploaded-document collections; each carries its own
|
|
|
|
|
|
`processing_status` queue fields directly (no separate batch row).
|
|
|
|
|
|
- `timesheets` (old) was renamed `timesheet_entries` — the actual
|
|
|
|
|
|
per-employee-per-day time log.
|
|
|
|
|
|
- `received_items` was renamed `delivery_note_items`.
|
|
|
|
|
|
- `purchase_orders` absorbed the queue fields `data_import_batches`
|
|
|
|
|
|
used to carry, plus `file_hash` and `date_uploaded`.
|
|
|
|
|
|
- `project_code` was removed from every collection except `sites`
|
|
|
|
|
|
(the one place it is canonical); relations to `sites` carry site
|
|
|
|
|
|
attribution everywhere else.
|
|
|
|
|
|
- `qty_outstanding` was removed from `purchase_order_items` — it is
|
|
|
|
|
|
now computed at read time via src/lib/po-fulfilment.ts.
|
|
|
|
|
|
- `fuel_prices` and `income_claims` were always live collections but
|
|
|
|
|
|
were missing from this bootstrap script; both are included now.
|
2026-08-18 22:14:47 +00:00
|
|
|
|
"""
|
|
|
|
|
|
import json
|
|
|
|
|
|
import sys
|
|
|
|
|
|
import urllib.request
|
|
|
|
|
|
import urllib.error
|
|
|
|
|
|
|
|
|
|
|
|
PB = "https://pb.mega.infra.apphub.co.za"
|
|
|
|
|
|
EMAIL = "admin@mega.co.za"
|
|
|
|
|
|
PASSWORD = "12345678"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def http(method, path, body=None, token=None):
|
|
|
|
|
|
url = f"{PB}{path}"
|
|
|
|
|
|
data = json.dumps(body).encode() if body is not None else None
|
|
|
|
|
|
req = urllib.request.Request(url, data=data, method=method)
|
|
|
|
|
|
if body is not None:
|
|
|
|
|
|
req.add_header("Content-Type", "application/json")
|
|
|
|
|
|
if token:
|
|
|
|
|
|
req.add_header("Authorization", token)
|
|
|
|
|
|
try:
|
|
|
|
|
|
with urllib.request.urlopen(req) as r:
|
|
|
|
|
|
txt = r.read().decode()
|
|
|
|
|
|
return r.status, json.loads(txt) if txt else None
|
|
|
|
|
|
except urllib.error.HTTPError as e:
|
|
|
|
|
|
return e.code, json.loads(e.read().decode() or "{}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
code, auth = http("POST", "/api/collections/_superusers/auth-with-password",
|
|
|
|
|
|
{"identity": EMAIL, "password": PASSWORD})
|
|
|
|
|
|
if code != 200:
|
|
|
|
|
|
sys.exit(f"AUTH FAILED: {code} {auth}")
|
|
|
|
|
|
TOKEN = auth["token"]
|
|
|
|
|
|
print(f"auth ok, superuser id={auth['record']['id']}\n")
|
|
|
|
|
|
|
|
|
|
|
|
LOCKED = { # superuser-only access
|
|
|
|
|
|
"listRule": None, "viewRule": None,
|
|
|
|
|
|
"createRule": None, "updateRule": None, "deleteRule": None,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def field(name, type_, **kw):
|
|
|
|
|
|
"""Build a field. Extra kwargs (required, values, maxSelect, etc.)
|
|
|
|
|
|
go at the field top level."""
|
|
|
|
|
|
f = {"name": name, "type": type_}
|
|
|
|
|
|
f.update(kw)
|
|
|
|
|
|
return f
|
|
|
|
|
|
|
|
|
|
|
|
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
# Shared field set for the three "uploaded document" collections
|
|
|
|
|
|
# (timesheets, fuel_sheets, plant_hours_sheets) — each is a
|
|
|
|
|
|
# resumable/idempotent import queue item in its own right, not a row
|
|
|
|
|
|
# in a shared pool.
|
|
|
|
|
|
def sheet_fields(site_required):
|
|
|
|
|
|
return [
|
|
|
|
|
|
field("site", "relation", required=site_required,
|
|
|
|
|
|
collectionId="__SITES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("source_file", "file", required=False,
|
2026-08-18 22:14:47 +00:00
|
|
|
|
maxSelect=1, maxSize=20971520,
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
mimeTypes=["text/csv", "text/plain", "application/vnd.ms-excel",
|
|
|
|
|
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
|
|
|
|
"application/csv"]),
|
|
|
|
|
|
field("content_type", "text", required=False),
|
|
|
|
|
|
field("file_hash", "text", required=False),
|
2026-08-18 22:14:47 +00:00
|
|
|
|
field("date_uploaded", "date", required=False),
|
|
|
|
|
|
field("uploaded_by", "text", required=False),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("processing_status", "select", required=False,
|
|
|
|
|
|
values=["pending", "processing", "processed", "failed", "dead"], maxSelect=1),
|
|
|
|
|
|
field("processed_at", "date", required=False),
|
|
|
|
|
|
field("attempts", "number", required=False),
|
|
|
|
|
|
field("last_error", "text", required=False),
|
|
|
|
|
|
field("rows_total", "number", required=False),
|
|
|
|
|
|
field("rows_created", "number", required=False),
|
|
|
|
|
|
field("rows_failed", "number", required=False),
|
|
|
|
|
|
field("row_errors", "json", required=False),
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEFS = {}
|
2026-08-18 22:14:47 +00:00
|
|
|
|
|
|
|
|
|
|
DEFS["sites"] = {
|
|
|
|
|
|
"name": "SITES", "type": "base",
|
|
|
|
|
|
"fields": [
|
|
|
|
|
|
field("project_code", "text", required=True, min=1, max=64),
|
|
|
|
|
|
field("name", "text", required=False),
|
|
|
|
|
|
field("duration", "text", required=False),
|
|
|
|
|
|
field("contract_value", "number", required=False),
|
|
|
|
|
|
field("work_hours", "number", required=False),
|
|
|
|
|
|
field("hours_per_week", "number", required=False),
|
|
|
|
|
|
field("wages_hours_per_day", "number", required=False),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("latitude", "number", required=False),
|
|
|
|
|
|
field("longitude", "number", required=False),
|
2026-08-25 17:01:56 +00:00
|
|
|
|
field("job_start_date", "date", required=False),
|
2026-09-11 20:24:03 +00:00
|
|
|
|
# How the site counts its own "work months" — e.g. 21 means each
|
|
|
|
|
|
# work-month runs the 21st through the 20th of the next calendar
|
|
|
|
|
|
# month, not the 1st–30th. Unset (or 1) means ordinary calendar
|
|
|
|
|
|
# months. See src/lib/project-calendar.ts.
|
|
|
|
|
|
field("work_month_start_day", "number", required=False, min=1, max=31),
|
2026-08-18 22:14:47 +00:00
|
|
|
|
],
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE UNIQUE INDEX `idx_sites_project_code` ON `sites` (`project_code`)",
|
|
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFS["employees"] = {
|
|
|
|
|
|
"name": "EMPLOYEES", "type": "base",
|
|
|
|
|
|
"fields": [
|
|
|
|
|
|
field("site", "relation", required=False,
|
|
|
|
|
|
collectionId="__SITES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("name", "text", required=False),
|
|
|
|
|
|
field("employee_no", "text", required=False),
|
|
|
|
|
|
field("position", "text", required=False),
|
|
|
|
|
|
field("rate_per_hour", "number", required=False),
|
|
|
|
|
|
field("hours_per_day_standard", "number", required=False),
|
|
|
|
|
|
field("worker_type", "select", required=False,
|
|
|
|
|
|
values=["permanent", "casual"], maxSelect=1),
|
|
|
|
|
|
],
|
|
|
|
|
|
"indexes": [],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-11 16:12:30 +00:00
|
|
|
|
DEFS["suppliers"] = {
|
|
|
|
|
|
"name": "SUPPLIERS", "type": "base",
|
|
|
|
|
|
"fields": [
|
|
|
|
|
|
field("name", "text", required=True, min=1, max=200),
|
|
|
|
|
|
],
|
|
|
|
|
|
"indexes": [],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-18 22:14:47 +00:00
|
|
|
|
DEFS["purchase_orders"] = {
|
|
|
|
|
|
"name": "PURCHASE_ORDERS", "type": "base",
|
|
|
|
|
|
"fields": [
|
|
|
|
|
|
field("purchase_order_number", "text", required=True, min=1, max=128),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("site", "relation", required=True,
|
2026-08-18 22:14:47 +00:00
|
|
|
|
collectionId="__SITES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("supplier", "text", required=False),
|
2026-09-11 16:12:30 +00:00
|
|
|
|
field("supplier_ref", "relation", required=False,
|
|
|
|
|
|
collectionId="__SUPPLIERS_ID__", cascadeDelete=False, maxSelect=1),
|
2026-08-18 22:14:47 +00:00
|
|
|
|
field("required_by_date", "date", required=False),
|
|
|
|
|
|
field("ordered_by", "text", required=False),
|
|
|
|
|
|
field("items_count", "number", required=False),
|
|
|
|
|
|
field("total_value", "number", required=False),
|
|
|
|
|
|
field("purchase_order_file", "file", required=False,
|
|
|
|
|
|
maxSelect=1, maxSize=20971520,
|
|
|
|
|
|
mimeTypes=["application/pdf", "image/jpeg", "image/png", "image/webp"]),
|
|
|
|
|
|
field("raw_ocr_data", "json", required=False),
|
|
|
|
|
|
field("is_verified", "bool", required=False),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("file_hash", "text", required=False),
|
|
|
|
|
|
field("processing_status", "select", required=False,
|
|
|
|
|
|
values=["pending", "processing", "processed", "failed", "dead"], maxSelect=1),
|
|
|
|
|
|
field("attempts", "number", required=False),
|
|
|
|
|
|
field("last_error", "text", required=False),
|
|
|
|
|
|
field("next_retry_at", "date", required=False),
|
|
|
|
|
|
field("last_attempt_at", "date", required=False),
|
|
|
|
|
|
field("date_uploaded", "date", required=False),
|
2026-08-18 22:14:47 +00:00
|
|
|
|
],
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE UNIQUE INDEX `idx_po_number` ON `purchase_orders` (`purchase_order_number`)",
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
"CREATE INDEX `idx_po_site_status` ON `purchase_orders` (`site`, `processing_status`)",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFS["purchase_order_items"] = {
|
|
|
|
|
|
"name": "PURCHASE_ORDER_ITEMS", "type": "base",
|
|
|
|
|
|
"fields": [
|
|
|
|
|
|
field("purchase_order", "relation", required=False,
|
|
|
|
|
|
collectionId="__PURCHASE_ORDERS_ID__", cascadeDelete=True, maxSelect=1),
|
|
|
|
|
|
field("material_code", "text", required=False),
|
|
|
|
|
|
field("cost_code", "text", required=False),
|
|
|
|
|
|
field("description", "text", required=False),
|
|
|
|
|
|
field("qty", "number", required=False),
|
|
|
|
|
|
field("unit", "text", required=False),
|
|
|
|
|
|
field("rate", "number", required=False),
|
|
|
|
|
|
field("disc_percent", "number", required=False),
|
|
|
|
|
|
field("vat_percent", "number", required=False),
|
|
|
|
|
|
field("amount", "number", required=False),
|
|
|
|
|
|
],
|
|
|
|
|
|
"indexes": [],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFS["fixed_costs"] = {
|
|
|
|
|
|
"name": "FIXED_COSTS", "type": "base",
|
|
|
|
|
|
"fields": [
|
|
|
|
|
|
field("site", "relation", required=False,
|
|
|
|
|
|
collectionId="__SITES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("date_logged", "date", required=False),
|
|
|
|
|
|
field("description", "text", required=False),
|
|
|
|
|
|
field("cost", "number", required=False),
|
|
|
|
|
|
field("notes", "text", required=False),
|
2026-08-28 11:43:38 +00:00
|
|
|
|
# bool, no default: PB applies the field default only when the
|
|
|
|
|
|
# value is absent. Defaulting to `true` would also be fine for
|
|
|
|
|
|
# new rows, but we leave the field "unset by default" so explicit
|
|
|
|
|
|
# writes of `false` cannot be silently overridden by a default.
|
|
|
|
|
|
# The partition helper treats undefined/null as monthly via a
|
|
|
|
|
|
# `=== false` check, and the backfill migration patches any
|
|
|
|
|
|
# pre-existing row to `true`.
|
|
|
|
|
|
field("is_recurring", "bool", required=False),
|
2026-08-18 22:14:47 +00:00
|
|
|
|
],
|
|
|
|
|
|
"indexes": [],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFS["vehicles"] = {
|
|
|
|
|
|
"name": "VEHICLES", "type": "base",
|
|
|
|
|
|
"fields": [
|
|
|
|
|
|
field("site", "relation", required=False,
|
|
|
|
|
|
collectionId="__SITES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("description", "text", required=False),
|
|
|
|
|
|
field("standard_work_hours", "text", required=False),
|
|
|
|
|
|
field("fuel_limits", "text", required=False),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("qr_code_id", "text", required=False),
|
|
|
|
|
|
field("cost_per_hour", "number", required=False),
|
|
|
|
|
|
field("attention_dismissed_at", "date", required=False),
|
2026-08-28 13:26:33 +00:00
|
|
|
|
field("unit_type", "select", required=False,
|
2026-08-28 10:32:52 +00:00
|
|
|
|
values=["fuel", "plant"], maxSelect=1, default="fuel"),
|
2026-09-22 19:39:25 +00:00
|
|
|
|
# Latest GPS fix from a MEGA Clock Fleet scan. Denormalised off
|
|
|
|
|
|
# `fuel_logs` so the map page can render every vehicle in a
|
|
|
|
|
|
# single query. Stays null for vehicles never scanned from a
|
|
|
|
|
|
# kiosk phone (e.g. imported only from a pump sheet).
|
|
|
|
|
|
field("last_latitude", "number", required=False),
|
|
|
|
|
|
field("last_longitude", "number", required=False),
|
|
|
|
|
|
field("last_scanned_at", "date", required=False),
|
|
|
|
|
|
field("last_location_accuracy_m", "number", required=False),
|
|
|
|
|
|
],
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE INDEX `idx_vehicles_last_scanned` ON `vehicles` (`last_scanned_at`)",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
DEFS["fuel_prices"] = {
|
|
|
|
|
|
"name": "FUEL_PRICES", "type": "base",
|
|
|
|
|
|
"fields": [
|
|
|
|
|
|
field("effective_from", "date", required=True),
|
|
|
|
|
|
field("price_per_litre", "number", required=True),
|
|
|
|
|
|
field("notes", "text", required=False),
|
|
|
|
|
|
],
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE UNIQUE INDEX `idx_fuel_prices_effective_from` ON `fuel_prices` (`effective_from`)",
|
|
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-18 22:14:47 +00:00
|
|
|
|
DEFS["timesheets"] = {
|
|
|
|
|
|
"name": "TIMESHEETS", "type": "base",
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
"fields": sheet_fields(site_required=True),
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE INDEX `idx_timesheets_hash` ON `timesheets` (`file_hash`)",
|
|
|
|
|
|
"CREATE INDEX `idx_timesheets_status` ON `timesheets` (`processing_status`, `date_uploaded`)",
|
|
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFS["timesheet_entries"] = {
|
|
|
|
|
|
"name": "TIMESHEET_ENTRIES", "type": "base",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
"fields": [
|
|
|
|
|
|
field("employee", "relation", required=False,
|
|
|
|
|
|
collectionId="__EMPLOYEES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("date_logged", "date", required=False),
|
|
|
|
|
|
field("hours_worked", "number", required=False),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
# Stamped from the employee's site at import time — NOT joined at
|
|
|
|
|
|
# read time. This ends historical drift when a worker moves sites.
|
|
|
|
|
|
field("site", "relation", required=True,
|
|
|
|
|
|
collectionId="__SITES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
# Optional forever: empty means captured directly by QR scan, not
|
|
|
|
|
|
# from an uploaded sheet.
|
|
|
|
|
|
field("timesheet", "relation", required=False,
|
|
|
|
|
|
collectionId="__TIMESHEETS_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
],
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE INDEX `idx_ts_entries_site_date` ON `timesheet_entries` (`site`, `date_logged`)",
|
|
|
|
|
|
"CREATE INDEX `idx_ts_entries_emp_date` ON `timesheet_entries` (`employee`, `date_logged`)",
|
|
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-09-11 22:14:13 +00:00
|
|
|
|
DEFS["clock_events"] = {
|
|
|
|
|
|
"name": "CLOCK_EVENTS", "type": "base",
|
|
|
|
|
|
"fields": [
|
|
|
|
|
|
field("employee", "relation", required=True,
|
|
|
|
|
|
collectionId="__EMPLOYEES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("site", "relation", required=True,
|
|
|
|
|
|
collectionId="__SITES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("direction", "select", required=True,
|
|
|
|
|
|
values=["in", "out"], maxSelect=1),
|
|
|
|
|
|
field("scanned_at", "date", required=True),
|
|
|
|
|
|
# Optional: set only on "out" events, pointing at the
|
|
|
|
|
|
# timesheet_entries row that scan created/updated.
|
|
|
|
|
|
field("timesheet_entry", "relation", required=False,
|
|
|
|
|
|
collectionId="__TIMESHEET_ENTRIES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
],
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE INDEX `idx_clock_events_emp_scanned` ON `clock_events` (`employee`, `scanned_at`)",
|
|
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
DEFS["fuel_sheets"] = {
|
|
|
|
|
|
"name": "FUEL_SHEETS", "type": "base",
|
|
|
|
|
|
# site is optional: a pump sheet can span sites, resolved per-row.
|
|
|
|
|
|
"fields": sheet_fields(site_required=False),
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE INDEX `idx_fuel_sheets_hash` ON `fuel_sheets` (`file_hash`)",
|
|
|
|
|
|
"CREATE INDEX `idx_fuel_sheets_status` ON `fuel_sheets` (`processing_status`, `date_uploaded`)",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFS["fuel_logs"] = {
|
|
|
|
|
|
"name": "FUEL_LOGS", "type": "base",
|
|
|
|
|
|
"fields": [
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("site", "relation", required=True,
|
2026-08-18 22:14:47 +00:00
|
|
|
|
collectionId="__SITES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("vehicle", "relation", required=False,
|
|
|
|
|
|
collectionId="__VEHICLES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("date_logged", "date", required=False),
|
|
|
|
|
|
field("litres", "number", required=False),
|
|
|
|
|
|
field("odo_reading", "number", required=False),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("latest_consumption", "number", required=False),
|
2026-09-22 17:59:44 +00:00
|
|
|
|
# GPS fix captured at scan time on the kiosk phone (MEGA Clock
|
|
|
|
|
|
# Fleet tab). Optional — the spreadsheet import path has no GPS
|
|
|
|
|
|
# context, so desktop-imported rows stay null. Range validation
|
|
|
|
|
|
# is the route's job; PB stays permissive.
|
|
|
|
|
|
field("latitude", "number", required=False),
|
|
|
|
|
|
field("longitude", "number", required=False),
|
|
|
|
|
|
field("location_accuracy_m", "number", required=False),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("fuel_sheet", "relation", required=False,
|
|
|
|
|
|
collectionId="__FUEL_SHEETS_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
],
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE INDEX `idx_fuel_logs_site_date` ON `fuel_logs` (`site`, `date_logged`)",
|
|
|
|
|
|
"CREATE INDEX `idx_fuel_logs_vehicle_date` ON `fuel_logs` (`vehicle`, `date_logged`)",
|
|
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DEFS["plant_hours_sheets"] = {
|
|
|
|
|
|
"name": "PLANT_HOURS_SHEETS", "type": "base",
|
|
|
|
|
|
# site is optional, same reasoning as fuel_sheets.
|
|
|
|
|
|
"fields": sheet_fields(site_required=False),
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE INDEX `idx_plant_hours_sheets_hash` ON `plant_hours_sheets` (`file_hash`)",
|
|
|
|
|
|
"CREATE INDEX `idx_plant_hours_sheets_status` ON `plant_hours_sheets` (`processing_status`, `date_uploaded`)",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-28 10:31:17 +00:00
|
|
|
|
DEFS["plant_hours_log"] = {
|
|
|
|
|
|
"name": "PLANT_HOURS_LOG", "type": "base",
|
|
|
|
|
|
"fields": [
|
|
|
|
|
|
field("date_logged", "date", required=True),
|
|
|
|
|
|
field("vehicle_qr", "text", required=True),
|
|
|
|
|
|
field("vehicle", "relation", required=True,
|
|
|
|
|
|
collectionId="__VEHICLES_ID__", cascadeDelete=False, maxSelect=1, minSelect=1),
|
|
|
|
|
|
field("site", "relation", required=True,
|
|
|
|
|
|
collectionId="__SITES_ID__", cascadeDelete=False, maxSelect=1, minSelect=1),
|
|
|
|
|
|
field("start_date", "date", required=True),
|
|
|
|
|
|
field("end_date", "date", required=True),
|
|
|
|
|
|
field("start_time", "text", required=False),
|
|
|
|
|
|
field("end_time", "text", required=False),
|
|
|
|
|
|
field("start_hours", "number", required=True),
|
|
|
|
|
|
field("end_hours", "number", required=True),
|
|
|
|
|
|
field("hours", "number", required=True),
|
|
|
|
|
|
field("notes", "text", required=False),
|
|
|
|
|
|
field("hour_meter_budget", "number", required=True),
|
|
|
|
|
|
field("cost_per_hour", "number", required=True),
|
|
|
|
|
|
field("value", "number", required=True),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("over_budget", "bool", required=False),
|
|
|
|
|
|
field("hours_mismatch", "bool", required=False),
|
2026-08-28 10:31:17 +00:00
|
|
|
|
field("vehicle_unit_type_at_import", "select", required=True,
|
|
|
|
|
|
values=["fuel", "plant"], maxSelect=1),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("plant_hours_sheet", "relation", required=False,
|
|
|
|
|
|
collectionId="__PLANT_HOURS_SHEETS_ID__", cascadeDelete=False, maxSelect=1, minSelect=0),
|
2026-08-28 10:31:17 +00:00
|
|
|
|
],
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE UNIQUE INDEX `idx_plant_hours_log_qr_start` ON `plant_hours_log` (`vehicle_qr`, `start_date`)",
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
"CREATE INDEX `idx_ph_log_vehicle_start` ON `plant_hours_log` (`vehicle`, `start_date`)",
|
2026-08-28 10:31:17 +00:00
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
DEFS["income_claims"] = {
|
|
|
|
|
|
"name": "INCOME_CLAIMS", "type": "base",
|
|
|
|
|
|
"fields": [
|
|
|
|
|
|
field("claim_number", "text", required=True),
|
|
|
|
|
|
field("site", "relation", required=False,
|
|
|
|
|
|
collectionId="__SITES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("period_start", "date", required=False),
|
|
|
|
|
|
field("period_end", "date", required=False),
|
|
|
|
|
|
field("gross_amount", "number", required=False),
|
|
|
|
|
|
field("certified_by", "text", required=False),
|
|
|
|
|
|
field("paid_on", "date", required=False),
|
|
|
|
|
|
field("status", "select", required=False,
|
|
|
|
|
|
values=["draft", "certified", "paid"], maxSelect=1),
|
|
|
|
|
|
field("is_verified", "bool", required=False),
|
|
|
|
|
|
field("notes", "text", required=False),
|
|
|
|
|
|
],
|
|
|
|
|
|
"indexes": [],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-08-18 22:14:47 +00:00
|
|
|
|
DEFS["delivery_notes"] = {
|
|
|
|
|
|
"name": "DELIVERY_NOTES", "type": "base",
|
|
|
|
|
|
"fields": [
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("processing_status", "select", required=False,
|
|
|
|
|
|
values=["pending", "ocr-complete", "auto-verified",
|
|
|
|
|
|
"needs-review", "manual-verified", "failed"], maxSelect=1),
|
2026-08-18 22:14:47 +00:00
|
|
|
|
field("delivery_note_number", "text", required=False),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("site", "relation", required=True,
|
2026-08-18 22:14:47 +00:00
|
|
|
|
collectionId="__SITES_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("purchase_order", "relation", required=False,
|
|
|
|
|
|
collectionId="__PURCHASE_ORDERS_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("date_received", "date", required=False),
|
|
|
|
|
|
field("received_by", "text", required=False),
|
|
|
|
|
|
field("slip_image", "file", required=False,
|
|
|
|
|
|
maxSelect=1, maxSize=20971520,
|
|
|
|
|
|
mimeTypes=["image/jpeg", "image/png", "image/webp", "application/pdf"]),
|
|
|
|
|
|
field("raw_ocr_data", "json", required=False),
|
|
|
|
|
|
field("is_verified", "bool", required=False),
|
2026-08-26 13:33:30 +00:00
|
|
|
|
field("ocr_confidence", "number", required=False),
|
|
|
|
|
|
field("ocr_completed_at", "date", required=False),
|
|
|
|
|
|
field("received_by_name", "text", required=False),
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
field("file_hash", "text", required=False),
|
|
|
|
|
|
],
|
|
|
|
|
|
"indexes": [
|
|
|
|
|
|
"CREATE INDEX `idx_dn_site_date` ON `delivery_notes` (`site`, `date_received`)",
|
|
|
|
|
|
"CREATE INDEX `idx_dn_status` ON `delivery_notes` (`processing_status`)",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
DEFS["delivery_note_items"] = {
|
|
|
|
|
|
"name": "DELIVERY_NOTE_ITEMS", "type": "base",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
"fields": [
|
|
|
|
|
|
field("delivery_note", "relation", required=False,
|
|
|
|
|
|
collectionId="__DELIVERY_NOTES_ID__", cascadeDelete=True, maxSelect=1),
|
|
|
|
|
|
field("purchase_order_item", "relation", required=False,
|
|
|
|
|
|
collectionId="__PURCHASE_ORDER_ITEMS_ID__", cascadeDelete=False, maxSelect=1),
|
|
|
|
|
|
field("qty_received", "number", required=False),
|
|
|
|
|
|
field("condition_notes", "text", required=False),
|
|
|
|
|
|
],
|
|
|
|
|
|
"indexes": [],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
# Dependency order: a collection referencing another via `relation` must be
|
|
|
|
|
|
# created after the collection it points to, so its `collectionId`
|
|
|
|
|
|
# placeholder can be resolved.
|
2026-08-18 22:14:47 +00:00
|
|
|
|
ORDER = [
|
|
|
|
|
|
"sites",
|
|
|
|
|
|
"employees",
|
2026-09-11 16:12:30 +00:00
|
|
|
|
"suppliers",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
"purchase_orders",
|
|
|
|
|
|
"purchase_order_items",
|
|
|
|
|
|
"fixed_costs",
|
|
|
|
|
|
"vehicles",
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
"fuel_prices",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
"timesheets",
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
"timesheet_entries",
|
2026-09-11 22:14:13 +00:00
|
|
|
|
"clock_events",
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
"fuel_sheets",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
"fuel_logs",
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
"plant_hours_sheets",
|
2026-08-28 10:31:17 +00:00
|
|
|
|
"plant_hours_log",
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
"income_claims",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
"delivery_notes",
|
docs(schema): bring bootstrap and data-model docs back to truth
pb-bootstrap-schema.py -- the script a fresh PocketBase instance would
run against -- had fallen ten migrations behind and still described the
pre-restructure world. Rewrote it field-by-field against a live
production dump (17 collections, every field/required-flag/relation/
index verified). Found and fixed two pre-existing gaps unrelated to this
restructure while verifying: fuel_prices and income_claims were entirely
absent from the bootstrap script.
pb-relax-rules.py's collection list updated to match.
No local PocketBase binary is available in this environment, so the
plan's "bootstrap fresh and diff against production" verification step
was replaced with a manual field-by-field comparison against the live
dump -- same goal, different mechanism, documented as a substitution
rather than silently skipped.
Added site scoping to the one agent tool that still lacked it
(list_imports, backed by loadImportBatches) -- every other list_* tool
already had it. Preparation for the future per-user site-allowlist work,
not part of this restructure itself.
Rewrote docs/data-model.md and docs/data-flows.md end to end: the
site-attribution table, the collection reference, the five ingestion
pipelines, and the schema-drift section that was describing the exact
problem this task fixes. Every remaining data_import_batches reference
in both docs is now historical context, not a current description.
This is the last task of the ingestion restructure
(docs/superpowers/plans/2026-09-11-ingestion-restructure.md).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 14:17:41 +00:00
|
|
|
|
"delivery_note_items",
|
2026-08-18 22:14:47 +00:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
ids = {}
|
|
|
|
|
|
for key in ORDER:
|
|
|
|
|
|
body = dict(DEFS[key])
|
|
|
|
|
|
body.update(LOCKED)
|
|
|
|
|
|
for f in body["fields"]:
|
|
|
|
|
|
if f.get("type") == "relation":
|
|
|
|
|
|
cid = f.get("collectionId", "")
|
|
|
|
|
|
# placeholders use collection table name in upper, e.g. __SITES_ID__
|
|
|
|
|
|
for other_key, other_id in ids.items():
|
|
|
|
|
|
collection_name_upper = DEFS[other_key]["name"] # e.g. "SITES"
|
|
|
|
|
|
cid = cid.replace(f"__{collection_name_upper}_ID__", other_id)
|
|
|
|
|
|
if "__" in cid:
|
|
|
|
|
|
sys.exit(f"unresolved placeholder in {key}.{f['name']}: {cid}")
|
|
|
|
|
|
f["collectionId"] = cid
|
|
|
|
|
|
|
|
|
|
|
|
code, resp = http("POST", "/api/collections", body, TOKEN)
|
|
|
|
|
|
if code == 200:
|
|
|
|
|
|
ids[key] = resp["id"]
|
|
|
|
|
|
print(f" ✓ {body['name']:25s} → {resp['id']}")
|
|
|
|
|
|
elif code == 400:
|
|
|
|
|
|
code2, existing = http("GET", f"/api/collections/{body['name']}", token=TOKEN)
|
|
|
|
|
|
if code2 == 200:
|
|
|
|
|
|
ids[key] = existing["id"]
|
|
|
|
|
|
print(f" • {body['name']:25s} → {existing['id']} (already existed)")
|
|
|
|
|
|
else:
|
|
|
|
|
|
print(f" ✗ {body['name']:25s} FAILED: {resp}", file=sys.stderr)
|
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
else:
|
|
|
|
|
|
print(f" ✗ {body['name']:25s} FAILED: {code} {resp}", file=sys.stderr)
|
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
print(f"\nDone. {len(ids)} collections on {PB}.")
|