$ cat workspace-template.yaml

D

Drive Materials to Ontology

// Maps course documents already in Drive onto the organization ontology as CourseMaterial objects, linked to the Course they belong to. The assignment rule lives on the canvas as an editable JSON node, because nothing in Drive states which course a document serves — that mapping is a modelling choice.

Automation
#ontology#drive#documents#erp#pipeline

// Canvas Preview

canvas.flow

// Instruction

instruction.md

Drive Materials to Ontology

Overview

Maps course documents that already live in Drive onto the ontology as CourseMaterial objects, each linked to its Course by material_of. It reads Drive, it does not write to it.

Nothing in Drive states which course a document serves — these documents sit at root with no per-course folder. The assignment is therefore a modelling choice, and it lives on the canvas in the "Material Rules" node so it can be read and argued with rather than buried in code.

Requires the seven ontology types and the Course objects (run the Odoo to Ontology Feeder first, or materials will upsert with nothing to link to).

Workflow Chain

"Material Rules"[value] ──► "Upsert Course Materials"[rules] ──[summary]──► "Sync Result"

Node Reference

  • "Material Rules" (JSON Object) — course code → regex over the document NAME. Rules are evaluated in order, first match wins, so a document lands in exactly one course and the counts sum to the population. Put specific topics before broad ones. Configurable: value.
  • "Upsert Course Materials" (Custom Code) — pages Drive, applies the rules, de-duplicates (01 - Foo.pdf and Foo are one material, preferring the row with a file extension), and mints CourseMaterial + material_of. Documents matching no rule are counted and reported, never silently dropped. Configurable: maxItems.
  • "Sync Result" (Preview) — shows the per-course breakdown on the canvas.

Execution Strategy

You MUST complete both phases in order: Phase 1 → Phase 2. Do NOT skip either.

Writing to the ontology is a side effect. It is gated once, in Phase 1.

Phase 1: Confirm the mapping

  1. applyCanvasData to commit the template, then nodeFinder for ids — preview ids are stale.
  2. nodeFinder "Material Rules" and getNodeOutput, or read its value, and show the user the rules in full. They decide the taxonomy, not you.
  3. Call requestUserDecision ONCE: "These rules assign each Drive document to a course, first match wins. Apply them?", allowFreeText: false, options proceed / edit / cancel. On edit, ask which rule to change, upsertNode the new value, and ask again. On cancel or cancelled: true, STOP and write nothing.

Phase 1 complete. Now proceed to Phase 2.

Phase 2: Load and report

  1. nodeExecutor "Upsert Course Materials", then "Sync Result".
  2. getNodeOutput and read summary and perCourse. Report the per-course counts, and say explicitly how many documents matched no rule — an unmatched document is a gap in the taxonomy, not a failure.
  3. If linkedCount is lower than materialCount, say which courses were missing: materials were created but have nothing to hang off, which means the feeder has not run.
  4. Call verification with the counts, then followUp offering to (a) refine the rules and re-run, (b) open the ontology graph view, (c) run the console.

Configuration Tips

User saysConfigure
"this document is in the wrong course""Material Rules" — move its keyword to an earlier rule, or add a more specific one above
"add a fourth course"Add a "CYB-401": "<regex>" entry ABOVE the fundamentals catch-all
"we have more documents now"Raise maxItems; it pages Drive 100 at a time
"only scan one folder"Not supported by the rules node — the scan is Drive-wide by design, because the documents are not foldered

Error Handling

ErrorCauseFix
rules must be a JSON object"Material Rules" holds an array or a stringSet value to { "CODE": "regex" }
rule for X is not a valid regexBad patternFix the pattern; the message names the rule
object type 'CourseMaterial' not foundTypes not seededRun seed_ontology_types.py
Everything reports "no matching Course object"Course objects absentRun the Odoo to Ontology Feeder first
Counts look far too highA broad rule sits above the specific onesRules are first-match-wins — reorder

// Dependencies

requirements.py
1from input import JSONObject2from process import CustomCode3from control import Preview