Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions echo/directus/sync/collections/flows.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"trigger": "operation",
"accountability": "all",
"options": {},
"operation": "11fdc301-7101-40f3-bc82-af3b472fd914",
"operation": "5bea9e07-e6f0-41c6-821d-b426dec3427c",
"_syncId": "17703446-fef0-49e9-bdc4-385db1311137"
Comment on lines +11 to 12
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Updated operation UUID – sanity-check reference exists.

5bea9e07-e6f0-41c6-821d-b426dec3427c must point to an operation object in operations.json. Looks present, but a quick grep never hurts.


🏁 Script executed:

#!/usr/bin/env bash
# Verify that every operation ID referenced from flows exists once in operations.json
jq -r '.[].operation' echo/directus/sync/collections/flows.json |
  grep -v null |
  while read op; do
    count=$(jq -r --arg op "$op" '[.[].key] | length' echo/directus/sync/collections/operations.json)
    if [[ "$count" -eq 0 ]]; then echo "✗ missing $op"; fi
  done

Length of output: 412


Let’s correct the filter and re-run the check to ensure we’re matching on .key:


🏁 Script executed:

#!/usr/bin/env bash
# Verify every “operation” in flows.json actually exists in operations.json
jq -r '.[].operation' echo/directus/sync/collections/flows.json \
  | grep -v null \
  | sort -u \
  | while read op; do
      if ! jq -e --arg op "$op" 'any(.[]; .key == $op)' echo/directus/sync/collections/operations.json > /dev/null; then
        echo "✗ missing $op"
      fi
    done

Length of output: 576


Missing operation UUIDs in operations.json
The following IDs in echo/directus/sync/collections/flows.json (lines 11–12) aren’t present in echo/directus/sync/collections/operations.json:

  • 239c6fea-242d-4b7d-b854-c99d2fe43cf3
  • 5bea9e07-e6f0-41c6-821d-b426dec3427c

Please add these operation objects to operations.json (or correct the UUIDs in flows.json). LGTM once addressed.

🤖 Prompt for AI Agents
In echo/directus/sync/collections/flows.json at lines 11 to 12, the operation
UUIDs referenced are missing from
echo/directus/sync/collections/operations.json. To fix this, either add the
corresponding operation objects with these UUIDs to operations.json or update
the UUIDs in flows.json to match existing entries in operations.json, ensuring
all referenced operations are valid and present.

},
{
Expand Down Expand Up @@ -50,7 +50,7 @@
"project_report"
]
},
"operation": "cb0759e3-a837-4f4b-9f61-276f17958f2b",
"operation": "239c6fea-242d-4b7d-b854-c99d2fe43cf3",
"_syncId": "ec4e7ea5-72de-4365-b66f-d8f11b549495"
Comment on lines +53 to 54
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Second operation link updated – run the same cross-check.

239c6fea-242d-4b7d-b854-c99d2fe43cf3 should likewise exist exactly once.

🤖 Prompt for AI Agents
In echo/directus/sync/collections/flows.json around lines 53 to 54, verify that
the operation ID "239c6fea-242d-4b7d-b854-c99d2fe43cf3" appears exactly once in
the file. If duplicates exist, remove or correct them to ensure this operation
ID is unique within the collection.

}
]
54 changes: 27 additions & 27 deletions echo/directus/sync/collections/operations.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
}
}
},
"resolve": "5f9aad15-ff17-4cb5-8ab8-e9ef169470fd",
"reject": "435e2a60-3c92-4225-91aa-45156884ac2b",
"resolve": "3dbf2ea1-17f8-4bde-aa89-43278fe9a00f",
"reject": "eaeb2c39-32e0-428d-ad03-ff0e6052adcc",
"flow": "17703446-fef0-49e9-bdc4-385db1311137",
"_syncId": "11fdc301-7101-40f3-bc82-af3b472fd914"
"_syncId": "5bea9e07-e6f0-41c6-821d-b426dec3427c"
},
Comment on lines +17 to 21
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Bulk UUID rotation LGTM – but guard against dupes / orphans.

Nothing functional changed; just IDs. Before shipping, run a quick validator to ensure:

  1. every _syncId is globally unique,
  2. every resolve/reject points at an existing _syncId,
  3. no flow/operation references are dangling.

Also applies to: 43-47, 63-67, 80-81, 94-95, 108-109, 119-123, 146-150, 163-164, 182-186, 205-209, 222-223, 251-254, 282-285, 300-301


🏁 Script executed:

#!/usr/bin/env python
"""
Cross-validate Directus sync IDs & operation references.
"""
import json, pathlib, sys, collections, itertools, sys

base = pathlib.Path("echo/directus/sync/collections")
files = list(base.glob("*.json"))

# Load all arrays
data = {}
for f in files:
    data[f.stem] = json.loads(f.read_text())

# 1. global uniqueness for _syncId
sync_ids = [item["_syncId"] for items in data.values() for item in items if "_syncId" in item]
dupes = [x for x, n in collections.Counter(sync_ids).items() if n > 1]
if dupes:
    print("✗ duplicate _syncId:", dupes)

# 2. build lookup of _syncId → item
lookup = {item["_syncId"]: item for items in data.values() for item in items if "_syncId" in item}

# 3. Check resolve/reject pointers
bad = []
for op in data["operations"]:
    for field in ("resolve", "reject"):
        ref = op.get(field)
        if ref and ref not in lookup:
            bad.append((op["key"], field, ref))
if bad:
    print("✗ dangling refs:", bad)

# 4. Check flow.operation links
for flow in data["flows"]:
    op_id = flow.get("operation")
    if op_id and op_id not in lookup:
        print("✗ flow", flow["name"], "points to missing operation", op_id)

if not (dupes or bad):
    print("✓ all good")

Length of output: 607


🏁 Script executed:

#!/usr/bin/env bash
python3 - << 'EOF'
import json, pathlib, collections

base = pathlib.Path("echo/directus/sync/collections")
files = list(base.glob("*.json"))

# Load all JSON files
data = {}
for f in files:
    data[f.stem] = json.loads(f.read_text())

# 1. Global uniqueness for _syncId
sync_ids = [item["_syncId"] for items in data.values() for item in items if "_syncId" in item]
dupes = [x for x, n in collections.Counter(sync_ids).items() if n > 1]
if dupes:
    print("✗ duplicate _syncId:", dupes)

# 2. Build lookup of _syncId → item
lookup = {item["_syncId"]: item for items in data.values() for item in items if "_syncId" in item}

# 3. Check resolve/reject pointers in operations.json
bad_refs = []
for op in data.get("operations", []):
    for field in ("resolve", "reject"):
        ref = op.get(field)
        if ref and ref not in lookup:
            bad_refs.append((op.get("key"), field, ref))
if bad_refs:
    print("✗ dangling refs in operations:", bad_refs)

# 4. Check flow → operation links in flows.json
dangling_flows = []
for flow in data.get("flows", []):
    op_id = flow.get("operation")
    if op_id and op_id not in lookup:
        dangling_flows.append((flow.get("name"), op_id))
if dangling_flows:
    for name, op_id in dangling_flows:
        print(f"✗ flow '{name}' points to missing operation: {op_id}")

# Final result
if not (dupes or bad_refs or dangling_flows):
    print("✓ all good")
EOF

Length of output: 73


🏁 Script executed:

#!/usr/bin/env bash
grep -R "2446660a-ab6c-4801-ad69-5711030cba83" -n echo/directus/sync/collections/*.json

Length of output: 10000


Duplicate _syncId Detected – Action Required

We’ve uncovered that _syncId: "2446660a-ab6c-4801-ad69-5711030cba83" is defined twice, which violates global uniqueness:

  • echo/directus/sync/collections/policies.json: _syncId at line 48
  • echo/directus/sync/collections/roles.json: _syncId at line 14
    – also used as parent at line 27
  • referenced extensively under policy in permissions.json

Please regenerate a fresh UUID for one of these entries (and update any pointers, e.g. parent or policy fields), then rerun the validator script to confirm no more duplicates or dangling refs.

🤖 Prompt for AI Agents
In echo/directus/sync/collections/policies.json line 48 and
echo/directus/sync/collections/roles.json line 14, the _syncId
"2446660a-ab6c-4801-ad69-5711030cba83" is duplicated, violating uniqueness.
Generate a new UUID for one of these _syncId values, update all references to it
including the parent field at line 27 in roles.json and any policy references in
permissions.json, then rerun the validator to ensure no duplicates or broken
references remain.

{
"name": "Check Report Language",
Expand All @@ -40,10 +40,10 @@
},
"collection": "project_report"
},
"resolve": "6fba7361-0b76-40b0-b4ae-ef094d896bb6",
"resolve": "efb3982e-5703-4c07-8982-a6e1b5218e4a",
"reject": null,
"flow": "ec4e7ea5-72de-4365-b66f-d8f11b549495",
"_syncId": "7be4966b-477b-4961-a341-26c663f9d27a"
"_syncId": "d154ee34-0931-43f3-aaca-9168f88fa04b"
},
{
"name": "Dutch",
Expand All @@ -60,10 +60,10 @@
}
}
},
"resolve": "21b8e36a-a71d-4912-b428-9ee67c1df1ba",
"reject": "13856746-f10a-402a-bf4b-68a4213b6c21",
"resolve": "34fb6ee5-2813-484a-a1cc-f97de097509b",
"reject": "8d8d787a-dbc4-44f9-9ab4-28e3f3d5f31c",
"flow": "17703446-fef0-49e9-bdc4-385db1311137",
"_syncId": "435e2a60-3c92-4225-91aa-45156884ac2b"
"_syncId": "eaeb2c39-32e0-428d-ad03-ff0e6052adcc"
},
{
"name": "Email Send Operation Failed",
Expand All @@ -77,7 +77,7 @@
"resolve": null,
"reject": null,
"flow": "17703446-fef0-49e9-bdc4-385db1311137",
"_syncId": "16319ea2-0cdf-4e50-9e83-d62cd9f29d71"
"_syncId": "920bd181-b2a2-4f0d-94dc-3b1a08c3f4ef"
},
{
"name": "Email Send Operation Failed Dutch",
Expand All @@ -91,7 +91,7 @@
"resolve": null,
"reject": null,
"flow": "17703446-fef0-49e9-bdc4-385db1311137",
"_syncId": "97bc1561-dd12-4fbf-9ebd-4b44c06d4fb9"
"_syncId": "84c38ea6-5d15-429f-8c24-9485d54ba7be"
},
{
"name": "failed",
Expand All @@ -105,7 +105,7 @@
"resolve": null,
"reject": null,
"flow": "17703446-fef0-49e9-bdc4-385db1311137",
"_syncId": "13856746-f10a-402a-bf4b-68a4213b6c21"
"_syncId": "8d8d787a-dbc4-44f9-9ab4-28e3f3d5f31c"
},
{
"name": "Filter Emails",
Expand All @@ -116,10 +116,10 @@
"options": {
"code": "module.exports = async function(data) {\n\n const submissions = data.get_all_participants;\n \n // Filter submissions to only include those where email_opt_in is true\n const filteredSubmissions = submissions.filter(sub => sub.email_opt_in === true);\n\n // Create an array with email, project_id and an email_opt_out token for each submission\n const result = filteredSubmissions.map(sub => ({\n project_name: data.project_data[0].name || '',\n\t\tdefault_conversation_title: data.project_data[0].default_conversation_title || '',\n\t\tconversation_name: sub.conversation_id.participant_name || '',\n email: sub.email,\n project_id: sub.project_id || '',\n token: sub.email_opt_out_token,\n language: data.check_report_language[0].language || 'empty',\n ADMIN_BASE_URL: \"{{ $env.ADMIN_BASE_URL }}\" || \"http://localhost:5173\",\n PARTICIPANT_BASE_URL: \"{{ $env.PARTICIPANT_BASE_URL }}\" || \"http://localhost:5174\", \n }));\n \n return result;\n};"
},
"resolve": "b10f5a01-3355-4884-8e37-308caf3c56d7",
"resolve": "e101f00d-2fb8-4f40-9e0e-4d24da5bb1e9",
"reject": null,
"flow": "ec4e7ea5-72de-4365-b66f-d8f11b549495",
"_syncId": "6fba7361-0b76-40b0-b4ae-ef094d896bb6"
"_syncId": "efb3982e-5703-4c07-8982-a6e1b5218e4a"
},
{
"name": "Get All Participants",
Expand All @@ -143,10 +143,10 @@
},
"collection": "project_report_notification_participants"
},
"resolve": "7be4966b-477b-4961-a341-26c663f9d27a",
"resolve": "d154ee34-0931-43f3-aaca-9168f88fa04b",
"reject": null,
"flow": "ec4e7ea5-72de-4365-b66f-d8f11b549495",
"_syncId": "dad81699-20ef-435d-a3e3-a7c09ed97c42"
"_syncId": "107ebc18-7d2d-4299-9d98-b7d1e7322b7c"
},
{
"name": "log environment vars",
Expand All @@ -160,7 +160,7 @@
"resolve": null,
"reject": null,
"flow": "ec4e7ea5-72de-4365-b66f-d8f11b549495",
"_syncId": "9c98061e-46a1-4947-804d-0cddfdf05b69"
"_syncId": "da5f4cce-eff0-426d-a207-d61366899d1f"
},
{
"name": "PROCEED_ONLY_IF \"published\" in payload",
Expand All @@ -179,10 +179,10 @@
}
}
},
"resolve": "57fb6535-6c26-413d-858d-9ccf89846205",
"reject": "60af30e5-dd72-422c-b51c-8bff6d5bc614",
"resolve": "ea051ae4-776f-490b-8b02-eaf4099243ef",
"reject": "84852456-3f3a-4906-be94-8b750159883b",
"flow": "ec4e7ea5-72de-4365-b66f-d8f11b549495",
"_syncId": "cb0759e3-a837-4f4b-9f61-276f17958f2b"
"_syncId": "239c6fea-242d-4b7d-b854-c99d2fe43cf3"
},
{
"name": "Project Data",
Expand All @@ -202,10 +202,10 @@
}
}
},
"resolve": "dad81699-20ef-435d-a3e3-a7c09ed97c42",
"resolve": "107ebc18-7d2d-4299-9d98-b7d1e7322b7c",
"reject": null,
"flow": "ec4e7ea5-72de-4365-b66f-d8f11b549495",
"_syncId": "57fb6535-6c26-413d-858d-9ccf89846205"
"_syncId": "ea051ae4-776f-490b-8b02-eaf4099243ef"
},
{
"name": "Report Not Published",
Expand All @@ -219,7 +219,7 @@
"resolve": null,
"reject": null,
"flow": "ec4e7ea5-72de-4365-b66f-d8f11b549495",
"_syncId": "60af30e5-dd72-422c-b51c-8bff6d5bc614"
"_syncId": "84852456-3f3a-4906-be94-8b750159883b"
},
{
"name": "Send Email Dutch",
Expand Down Expand Up @@ -248,9 +248,9 @@
]
},
"resolve": null,
"reject": "97bc1561-dd12-4fbf-9ebd-4b44c06d4fb9",
"reject": "84c38ea6-5d15-429f-8c24-9485d54ba7be",
"flow": "17703446-fef0-49e9-bdc4-385db1311137",
"_syncId": "21b8e36a-a71d-4912-b428-9ee67c1df1ba"
"_syncId": "34fb6ee5-2813-484a-a1cc-f97de097509b"
},
{
"name": "Send Email English",
Expand Down Expand Up @@ -279,9 +279,9 @@
]
},
"resolve": null,
"reject": "16319ea2-0cdf-4e50-9e83-d62cd9f29d71",
"reject": "920bd181-b2a2-4f0d-94dc-3b1a08c3f4ef",
"flow": "17703446-fef0-49e9-bdc4-385db1311137",
"_syncId": "5f9aad15-ff17-4cb5-8ab8-e9ef169470fd"
"_syncId": "3dbf2ea1-17f8-4bde-aa89-43278fe9a00f"
},
{
"name": "Trigger Email Flow",
Expand All @@ -297,6 +297,6 @@
"resolve": null,
"reject": null,
"flow": "ec4e7ea5-72de-4365-b66f-d8f11b549495",
"_syncId": "b10f5a01-3355-4884-8e37-308caf3c56d7"
"_syncId": "e101f00d-2fb8-4f40-9e0e-4d24da5bb1e9"
}
]
2 changes: 1 addition & 1 deletion echo/directus/sync/collections/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@
"public_registration_verify_email": true,
"public_registration_role": "feebe863-90b1-41d1-a7ef-9694ddee3844",
"public_registration_email_filter": null,
"_syncId": "a8c0b698-e6ed-45f9-a157-fe3a2c6eb849"
"_syncId": "b6e2bbfa-b958-4062-b100-186514c3e197"
}
]