MEGAINFRA-WEBAPP/scripts/pb-relax-rules.py

87 lines
3.7 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""Relax API rules on the 17 MEGA INFRASTRUCTURE collections.
Pattern:
list/view/create → any authenticated user
update/delete → superuser only (audit-safe for OCR-verified records)
Override per-collection with the RULES dict if you need different behaviour.
"""
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"
AUTH_RULE = "@request.auth.id != ''" # any logged-in user
NONE_RULE = None # superuser only
RULES = {
"SITES": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"EMPLOYEES": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"PURCHASE_ORDERS": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"PURCHASE_ORDER_ITEMS": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"FIXED_COSTS": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"VEHICLES": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
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": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"TIMESHEETS": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
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": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"CLOCK_EVENTS": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"clock_missed_out_corrections": (NONE_RULE, NONE_RULE, NONE_RULE, NONE_RULE, NONE_RULE),
"clock_correction_locks": (NONE_RULE, NONE_RULE, NONE_RULE, NONE_RULE, NONE_RULE),
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": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"FUEL_LOGS": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
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": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"PLANT_HOURS_LOG": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"INCOME_CLAIMS": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
"DELIVERY_NOTES": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
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": (AUTH_RULE, AUTH_RULE, AUTH_RULE, NONE_RULE, NONE_RULE),
}
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"]
# fetch all collections to map name → id
code, listing = http("GET", "/api/collections?perPage=100", token=TOKEN)
if code != 200:
sys.exit(f"could not list collections: {code}")
by_name = {c["name"]: c["id"] for c in listing["items"]}
for name, (l, v, c, u, d) in RULES.items():
cid = by_name.get(name)
if not cid:
print(f" ✗ {name:25s} not found, skipping")
continue
code, resp = http("PATCH", f"/api/collections/{cid}",
{"listRule": l, "viewRule": v, "createRule": c,
"updateRule": u, "deleteRule": d}, TOKEN)
if code == 200:
print(f" ✓ {name:25s} updated")
else:
print(f" ✗ {name:25s} FAILED: {code} {resp}")
print("\nDone.")