Agent skill

synnovator

Manage Synnovator platform data: 7 content types (category, post, resource, rule, user, group, interaction) and 9 relationship types via a file-based YAML+Markdown engine. Data stored in PROJECT_DIR/.synnovator/. Use when performing CRUD operations on platform content, managing activities/competitions, teams, posts, user interactions (likes/comments/ratings), or testing user journeys. Trigger: any request involving Synnovator platform data, user journey simulation, or content management.

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/synnovator

SKILL.md

Synnovator

File-based data engine for the Synnovator platform. All records are .md files with YAML frontmatter + Markdown body, stored under PROJECT_DIR/.synnovator/.

Quick Start

bash
# Initialize data directory
uv run python .claude/skills/synnovator/scripts/engine.py --init

# CRUD operations
uv run python .claude/skills/synnovator/scripts/engine.py [--user USER_ID] COMMAND TYPE [OPTIONS]

Commands: create, read, update, delete

Data Model

7 content types stored as .md files in .synnovator/<type>/:

  • category - Activities/competitions (YAML + Markdown body)
  • post - User posts with tags (YAML + Markdown body)
  • resource - File attachments (YAML frontmatter only)
  • rule - Activity rules with scoring criteria (YAML + Markdown body)
  • user - User accounts (YAML frontmatter only)
  • group - Teams/groups (YAML frontmatter only)
  • interaction - Likes, comments, ratings (YAML frontmatter only). Target info is stored in target_interaction relation, not on the interaction itself.

9 relationship types stored in .synnovator/relations/<type>/:

  • category_rule - Activity-to-rule bindings
  • category_post - Activity-to-post submissions
  • category_group - Team activity registration
  • category_category - Activity association (stage / track / prerequisite)
  • post_post - Post references/embeds/replies
  • post_resource - Post-to-attachment links
  • group_user - Group membership (with approval workflow)
  • user_user - User follow/block relationships
  • target_interaction - Content-to-interaction bindings

See references/schema.md for complete field definitions.

Content CRUD

Create

bash
engine.py [--user UID] create <type> --data '<json>' [--body 'markdown content']

Auto-generates: id, created_at, updated_at, deleted_at. Sets created_by from --user.

Read

bash
engine.py read <type> --id <record_id>           # Single record
engine.py read <type> --filters '<json>'          # Filtered list
engine.py read <type> --include-deleted           # Include soft-deleted

Update

bash
engine.py update <type> --id <record_id> --data '<json>'

For tags: "+tagname" appends, "-tagname" removes. Body: "_body": "new markdown".

Delete

bash
engine.py delete <type> --id <record_id>          # Soft delete (default)
engine.py delete <type> --id <record_id> --hard    # Hard delete

Cascades: deleting a post removes its relations and soft-deletes linked interactions.

Relation CRUD

bash
engine.py create <rel_type> --data '<json>'                        # Create
engine.py read <rel_type> --filters '<json>'                       # Read
engine.py update <rel_type> --filters '<json>' --data '<json>'     # Update
engine.py delete <rel_type> --filters '<json>'                     # Delete (hard)

Use _ or : separator: category_rule or category:rule.

Key Behaviors

  • Soft delete: Sets deleted_at, record stays on disk. Default for content types.
  • Hard delete: Removes file. Default for relations.
  • Cache stats: like_count, comment_count, average_rating on posts are read-only — auto-recalculated when target_interaction relations are created/deleted. Manual updates to these fields are silently ignored.
  • Two-step interactions: Creating an interaction requires: (1) create interaction for the record, (2) create target_interaction to link it to a target. Cache updates, duplicate-like checks, and target validation happen at step 2.
  • Group approval: require_approval=true sets join status to pending; owner approves via UPDATE group_user.
  • Uniqueness: Enforced for user (username), (email); like (user, target) at target_interaction creation; relation duplicates; user-per-category-per-group (a user can only belong to one group per category); user_user (source_user_id, target_user_id, relation_type); category_category (source_category_id, target_category_id).
  • Self-reference prevention: user_user and category_category cannot reference the same entity as both source and target.
  • Block enforcement: If user B blocks user A, A cannot follow B.
  • Circular dependency detection: category_category with stage or prerequisite relation types prevents cycles (A→B→C→A).
  • Prerequisite enforcement: Creating a category_group registration checks that all prerequisite categories (via category_category prerequisite) are closed.
  • Cascades: Deleting content cascades to relations and interactions per the schema spec. Notably:
    • Deleting a group cascades to both group_user and category_group relations.
    • Deleting a user cascades to group_user and user_user relations and soft-deletes all user interactions.
    • Deleting a category cascades to category_rule, category_post, category_group, and category_category relations and soft-deletes linked interactions.

Rule Enforcement

Rules linked to a category via category_rule are automatically enforced via a hook system. Rules support two definition styles: fixed fields (backward-compatible shorthand) and declarative checks (extensible condition-action pairs). All rules must pass (AND logic); any single violation rejects the operation.

Hook Points

Operation Phase Validations
create category_post pre Time window, max submissions, submission format, min team size, resource requirements, entry prerequisites
create category_post post Post-submission actions (notifications, etc.)
create group_user pre Max team size (checked against all categories the group is registered for)
create group_user post Post-join actions
create category_group pre Prerequisite categories closed, entry conditions (team/proposal existence)
create category_group post Post-registration actions
update post.status pre allow_public / require_review path enforcement
update post.status post Post-status-change actions
update category.status pre Pre-closure validation
update category.status post Closure actions: disqualification flagging, ranking computation, certificate awarding

Phases

  • pre: Runs before the operation. on_fail: deny blocks the operation. on_fail: warn allows with warning. on_fail: flag marks but allows.
  • post: Runs after a successful operation. Never blocks. Used for compute/award/notify actions.

Validation Chain

category_post:   category → category_rule → rule.checks[trigger=create_relation(category_post)]
group_user:      group → category_group → category → category_rule → rule.checks[trigger=create_relation(group_user)]
category_group:  category → category_category(prerequisite) + category_rule → rule.checks[trigger=create_relation(category_group)]
post.status:     post → category_post → category → category_rule → rule.checks[trigger=update_content(post.status)]
category.status: category → category_rule → rule.checks[trigger=update_content(category.status)]

Fixed Fields as Syntactic Sugar

Fixed fields on Rule (max_submissions, min_team_size, submission_format, etc.) are automatically expanded into equivalent checks entries by the engine. User-defined checks are appended after expanded entries.

Fixed Field Expands To
submission_start / submission_deadline time_window check on create_relation(category_post) pre
max_submissions count check on create_relation(category_post) pre
submission_format resource_format check on create_relation(category_post) pre
min_team_size count check on create_relation(category_post) pre
max_team_size count check on create_relation(group_user) pre
allow_public / require_review field_match check on update_content(post.status) pre

Condition Types

Type Description
time_window Current time within [start, end]
count Entity/relation count satisfies op + value
exists Entity/relation exists (or must not exist)
field_match Entity field matches a predicate
resource_format Post resources match allowed formats
resource_required Post has minimum required resources
unique_per_scope Uniqueness within a scope
aggregate Aggregated value (count/sum/avg) meets threshold

Action Types (post phase only)

Action Description
flag_disqualified Mark entities that fail post-closure checks
compute_ranking Calculate rankings from average_rating
award_certificate Auto-create certificate resources and posts per rank range
notify Send notifications (reserved, not yet implemented)

Behavior

  • No rules linked → no constraints, operation proceeds normally.
  • Rule field absent → that constraint is skipped (e.g., no submission_deadline means no time limit).
  • Violation (pre) → operation rejected with error: Rule '<name>': <reason>.
  • Violation (post) → action executes (flag/compute/award), does not rollback.
  • Posts not linked to any category are unconstrained (rules only apply through category_post).

See docs/rule-engine.md for the full specification.

File Format

Each record is a .md file:

markdown
---
name: 2025 AI Hackathon
type: competition
status: published
id: cat_abc123
created_by: user_alice
created_at: '2025-01-01T00:00:00Z'
---

## Activity Description

Markdown content here.

Testing

Tests are organized as modular files under scripts/tests/, one per test-case spec in specs/testcases/.

bash
# Run all tests
uv run python .claude/skills/synnovator/scripts/tests/run_all.py

# Run specific test files by number
uv run python .claude/skills/synnovator/scripts/tests/run_all.py 3 4 11

# Run a single test file directly
uv run python .claude/skills/synnovator/scripts/tests/test_11_user_journeys.py

Test File Map

# File TC Prefix Coverage
1 test_01_user.py TC-USER-* User CRUD
2 test_02_category.py TC-CAT-* Category CRUD
3 test_03_rule.py TC-RULE-* Rule CRUD + enforcement
4 test_04_group.py TC-GRP-* Group CRUD + approval
5 test_05_post.py TC-POST-* Post CRUD + visibility
6 test_06_resource.py TC-RES-* Resource CRUD
7 test_07_interaction.py TC-IACT-* Interaction CRUD
8 test_08_relations.py TC-REL-* All 9 relation types
9 test_09_cascade_delete.py TC-DEL-* Cascade delete
10 test_10_permissions.py TC-PERM-* Access control
11 test_11_user_journeys.py TC-JOUR-* Integration (sequential)
12 test_12_resource_transfer.py TC-TRANSFER-* Resource transfer
13 test_13_user_follow.py TC-FRIEND-* Follow/block
14 test_14_category_association.py TC-STAGE/TRACK/PREREQ/CATREL-* Category associations
15 test_15_entry_rules.py TC-ENTRY-* Entry preconditions
16 test_16_closure_rules.py TC-CLOSE-* Closure rules
17 test_17_rule_engine.py TC-ENGINE-* Rule engine conditions/actions

Each file uses isolated data directories for parallel-safe execution. Shared fixtures are in scripts/tests/base.py.

See references/endpoints.md for detailed API examples. See references/schema.md for complete field and enum definitions.

Documentation Sync

This skill's data model is the implementation of the canonical specs in docs/ and specs/. When modifying the skill's schema, engine logic, or data model, must sync the following docs:

Skill file Canonical docs Sync what
references/schema.md docs/data-types.md, docs/relationships.md Field definitions, enums, required fields, relation schemas
scripts/engine.py (CRUD logic) docs/crud-operations.md, specs/data-integrity.md CRUD operations, cascade strategies, uniqueness constraints
scripts/engine.py (cache) specs/cache-strategy.md Cache stats triggers, read-only enforcement
scripts/tests/test_11_user_journeys.py docs/user-journeys.md User journey steps, data operation sequences
scripts/tests/test_*.py specs/testcases/*.md Test cases aligned 1:1 with spec numbering

Checklist when updating the skill:

  1. Update skill code (engine.py) and tests (scripts/tests/test_*.py)
  2. Update skill reference docs (references/schema.md, references/endpoints.md)
  3. Update canonical docs (docs/data-types.md, docs/relationships.md, docs/crud-operations.md, docs/user-journeys.md)
  4. Run uv run python .claude/skills/synnovator/scripts/tests/run_all.py to verify

Didn't find tool you were looking for?

Be as detailed as possible for better results