一键导入
staging-database-expert
Specialized skill for managing, enriching, and consolidating the Neo4j staging database.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Specialized skill for managing, enriching, and consolidating the Neo4j staging database.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Create Onto2AI product demo narration and OpenAI cedar audio files aligned to demo manifests.
Generate Onto2AI demo manifests, presentation-style review videos, and future screen-recording demo skeletons.
Instructions for identifying ontology enumeration classes and rendering them in generated application models.
Rules for creating OWL ontologies strictly following the FIBO naming and documentation conventions.
Instructions for loading the Financial Industry Business Ontology (FIBO) into Neo4j.
Instructions for maintaining, running, and extending the Onto2AI MCP Server.
| name | Staging Database Expert |
| description | Specialized skill for managing, enriching, and consolidating the Neo4j staging database. |
You are a master of the Staging Database (typically stagingdb). Use this skill to move data from the primary ontology to staging, enrich classes with properties, create custom classes, manage named individuals, and clean up/flatten the staging schema for production use.
stagingdb for schema/model work: staged ontology subsets, class enrichment, enumeration discovery, generated schema artifacts, and validation before packaging.testdb for sample data or runtime-style smoke tests. Dataset databases must not contain ontology schema nodes such as owl__Class, owl__Ontology, owl__Restriction, or ontology-only relationships such as rdf__type and rdfs__subClassOf unless the task explicitly requires schema validation there.onto2ai_entitlement/ and onto2ai_parcel/.When creating local classes, relationships, or datatypes that do not come from FIBO or another source ontology, use the Onto2AI URI convention unless the user gives a domain-specific URI:
http://www.onto2ai-toolset.com/ontology/<domain>/<OntologyName>/<Fragment>
Use source ontology URIs for copied FIBO/LCC/standards concepts and Onto2AI URIs only for local target ontology additions.
Use staging_materialized_schema to copy classes and relationships to the staging database.
flatten_inheritance=True if you want to copy ancestor relationships directly to the child classes during extraction.Use get_materialized_schema to discover available properties for a class, then write them to staging with Cypher.
Workflow:
get_materialized_schema(class_names=["person"]) to see all available relationshipsMATCH (c:owl__Class {rdfs__label: 'person'})-[r]->(t) RETURN type(r), t.rdfs__labelMERGE and relationships with CREATEExample — Enriching Person:
MATCH (person:owl__Class {rdfs__label: 'person'})
SET person.skos__definition = 'individual human being, with consciousness of self',
person.uri = 'https://spec.edmcouncil.org/fibo/ontology/FND/AgentsAndPeople/People/Person'
MERGE (personName:owl__Class {uri: 'https://spec.edmcouncil.org/fibo/ontology/FND/AgentsAndPeople/People/PersonName'})
ON CREATE SET personName.rdfs__label = 'person name',
personName.skos__definition = 'designation by which someone is known in some context'
CREATE (person)-[:hasName {
materialized: true,
uri: 'https://www.omg.org/spec/Commons/Designators/hasName',
skos__definition: 'is known by',
cardinality: '0..*'
}]->(personName)
Key rules for enrichment relationships:
materialized: true on relationship propertiesuri, skos__definition, and cardinality on each relationshipMERGE for target nodes (to avoid duplicates) and CREATE for relationships1, 0..1, 0..*, 1..*When FIBO or the source ontology does not have a class you need, create it in staging with the target ontology URI namespace.
Example — Creating Tax Payer:
CREATE (tp:owl__Class {
rdfs__label: 'tax payer',
uri: 'http://www.onto2ai-toolset.com/ontology/tax/Tax/TaxPayer',
skos__definition: 'A person who is obligated to pay taxes and is identified by a tax identifier.'
})
// Inheritance
WITH tp
MATCH (person:owl__Class {rdfs__label: 'person'})
CREATE (tp)-[:rdfs__subClassOf {
materialized: true,
skos__definition: 'A tax payer is a person.'
}]->(person)
// Associations
WITH tp
MATCH (taxId:owl__Class {rdfs__label: 'tax identifier'})
CREATE (tp)-[:hasTaxId {
materialized: true,
uri: 'http://www.onto2ai-toolset.com/ontology/tax/Tax/hasTaxId',
skos__definition: 'The tax identifier assigned to a tax payer.',
cardinality: '1..*'
}]->(taxId)
Rules for custom classes:
http://www.onto2ai-toolset.com/ontology/<domain>/<OntologyName>/rdfs__label (e.g., 'tax payer')TaxPayer)skos__definitionrdfs__subClassOf for inheritance relationshipsFor simple value-type properties, create rdfs__Datatype nodes directly instead of full classes.
Example — Enriching Conventional Street Address as US Physical Address:
MATCH (addr:owl__Class {rdfs__label: 'conventional street address'})
MERGE (sa:rdfs__Datatype {uri: '...'})
ON CREATE SET sa.rdfs__label = 'streetAddress', sa.xsd__type = 'xsd:string',
sa.skos__definition = 'primary address number, street name, suffix'
MERGE (zip:rdfs__Datatype {uri: '...'})
ON CREATE SET zip.rdfs__label = 'zipCode', zip.xsd__type = 'xsd:string',
zip.skos__definition = 'US postal ZIP code'
MERGE (city:rdfs__Datatype {uri: '...'})
ON CREATE SET city.rdfs__label = 'city', city.xsd__type = 'xsd:string'
MERGE (state:rdfs__Datatype {uri: '...'})
ON CREATE SET state.rdfs__label = 'state', state.xsd__type = 'xsd:string'
CREATE (addr)-[:hasStreetAddress {materialized: true, cardinality: '1'}]->(sa)
CREATE (addr)-[:hasZipCode {materialized: true, cardinality: '1'}]->(zip)
CREATE (addr)-[:hasCity {materialized: true, cardinality: '1'}]->(city)
CREATE (addr)-[:hasState {materialized: true, cardinality: '1'}]->(state)
Common XSD types:
xsd:string — names, codes, identifiers, addressesxsd:date — dates (dateOfBirth, dateOfDeath)xsd:integer — whole numbers (age)xsd:decimal — monetary amountsxsd:boolean — true/false flagsPrimitive XSD staging rule:
http://www.w3.org/2001/XMLSchema#string, #integer, #boolean, #date, or similar, normalize that node as :rdfs__Datatype.rdfs__label to the primitive local name only, such as string, integer, boolean, or date.:Resource nodes.Create instances of classes using owl__NamedIndividual nodes with rdf__type links.
Example — Creating United States of America:
MATCH (country:owl__Class {rdfs__label: 'country'})
CREATE (usa:owl__NamedIndividual {
rdfs__label: 'United States of America',
uri: 'https://www.omg.org/spec/LCC/Countries/ISO3166-1-CountryCodes/UnitedStatesOfAmerica',
skos__definition: 'country in North America'
})
CREATE (usa)-[:rdf__type {materialized: true}]->(country)
// Link to a class that uses this individual
WITH usa
MATCH (addr:owl__Class {rdfs__label: 'conventional street address'})
CREATE (addr)-[:defaultCountry {materialized: true, cardinality: '1'}]->(usa)
If you need instance data attributes (for example, ISO codes), model them as relationships to rdfs__Datatype nodes instead of inline properties.
Rules for named individuals:
owl__NamedIndividualrdf__type relationship to its classrdfs__label, uri, skos__definition)rdfs__Datatype nodesIf data is already in staging but still has parent-child links, use consolidate_inheritance.
flatten_inheritance during the initial copy.Use consolidate_staging_db to convert complex classes into simpler datatypes.
Example — Converting date classes to datatypes:
consolidate_staging_db(transformations=[
{"old_label": "date of birth", "new_label": "dateOfBirth", "xsd_type": "xsd:date"},
{"old_label": "date of death", "new_label": "dateOfDeath", "xsd_type": "xsd:date"},
{"old_label": "person name", "new_label": "personName", "xsd_type": "xsd:string"},
{"old_label": "age", "new_label": "age", "xsd_type": "xsd:integer"}
])
When to consolidate:
For location-type classes (place of birth, headquarters, etc.), use a mix of datatypes and class references.
Example — Enriching Place of Birth:
MATCH (pob:owl__Class {rdfs__label: 'place of birth'})
MERGE (city:rdfs__Datatype {rdfs__label: 'city', xsd__type: 'xsd:string'})
MERGE (state:rdfs__Datatype {rdfs__label: 'stateOrProvince', xsd__type: 'xsd:string'})
MATCH (country:owl__Class {rdfs__label: 'country'})
CREATE (pob)-[:hasCity {materialized: true, cardinality: '0..1'}]->(city)
CREATE (pob)-[:hasStateOrProvince {materialized: true, cardinality: '0..1'}]->(state)
CREATE (pob)-[:hasCountry {materialized: true, cardinality: '1'}]->(country)
Pattern: Use datatypes for simple text fields (city, state names) and class references for complex objects (country with its own properties).
For nodes (Classes) and relationships in stagingdb that are missing semantic documentation, use the LLM to generate skos__definition based on the context.
Class Enrichment Workflow:
MATCH (n:owl__Class) WHERE n.skos__definition IS NULL RETURN n.rdfs__label, n.uriMATCH (n:owl__Class {uri: $uri}) SET n.skos__definition = $definitionRelationship Enrichment Workflow:
MATCH (n:owl__Class)-[r]->(m) WHERE r.skos__definition IS NULL RETURN n.rdfs__label, type(r), m.rdfs__label, r.uristagingdb.Maintain a textual representation of the entire graph schema for easy reference and LLM context.
Tool: generate_neo4j_schema_description(database='stagingdb')
Purpose: Generates a structured Markdown/text description:
TaxPayer:Person, Form1040_2025:IndividualTaxReturn).rdfs__subClassOf is excluded — inheritance is encoded in multi-label notation instead.(label, property, type, mandatory). Subclass label column uses multi-label notation. Includes Data Type and Mandatory status.rdfs__subClassOf edges are omitted.owl__NamedIndividual members grouped by class.Enum Visibility Standard:
owl__NamedIndividual members and rdf__type links are represented in schema artifacts.To ensure data integrity, maintain a Cypher constraints file for the finalized domain deliverable (for example, onto2ai_entitlement/staging/neo4j_constraint.cypher or onto2ai_parcel/staging/neo4j_constraint.cypher) that defines the physical constraints of the Neo4j database.
Core Principles:
uri, skos__definition, and rdfs__label should NOT have constraints or persistent indexes in the archival script (keep them as comments only).1) MUST have existence constraints (IS NOT NULL).stagingdb before applying.IS NOT NULL constraints for datatype-backed node properties).After changing enum classes, named individuals, subclass relationships, or mandatory relationships, regenerate in this order:
extract_data_model(database='stagingdb') → transient local review output under staging/
rdfs__subClassOf relationships are automatically included in the extracted model.generate_schema_code(target_type='pydantic', database='stagingdb') → transient local review output under staging/
generate_neo4j_schema_description(database='stagingdb') → transient local review output under staging/
Child:Parent multi-label in all five sections.generate_neo4j_schema_constraint(database='stagingdb') → transient local review output under staging/python -m onto2ai_entitlement.staging.schema_to_data_flow_smoke_testtestdbtestdb by default for manual reviewTo ensure generated application code models are fully compatible with the graph, follow these modeling standards. Pydantic is one supported target; the underlying contract should also support future application code model targets.
Key Patterns:
SemanticModel base class that includes an optional uri: str field.Field(alias="...") to map Python field names to their ontological counterparts (the Neo4j relationship types or property names). This allows for clean Python code while maintaining strict graph parity.
taxableIncome: Optional[MonetaryAmount] = Field(alias="hasTaxableIncome", ...)PydanticNeo4jBridge utility to automate the conversion between Pydantic objects and Neo4j MERGE queries. This utility leverages the aliases to identify the correct graph predicates.Why: This 1:1 parity between the domain model and the graph schema enables type-safe, automated data ingestion and extraction without manual Cypher mapping.
When generating final documentation (like staging_schema.md), use instance counts and topological activity to distinguish between primary Entity Classes and metadata/flattened classes.
Filtering Logic (Effective Label Calculation):
count > 0 in the database is considered an effective Entity Class.Person, Employer, Account, Form1010) are always kept regardless of instances.enumValues, named individuals, or xsd_type in metadata) from the Classes table.Why: This ensures the documentation matches the actual implemented model (where many ontological classes are flattened into properties) rather than listing every technical label used in the graph.
NEVER store data attributes as inline properties on owl__NamedIndividual nodes. All attributes must be modeled as relationships to rdfs__Datatype nodes.
❌ WRONG — inline properties:
CREATE (w2:owl__NamedIndividual {
rdfs__label: 'W-2',
box1_wages: 'decimal', // WRONG: inline property
box2_taxWithheld: 'decimal' // WRONG: inline property
})
✅ CORRECT — relationships to datatypes:
CREATE (w2:owl__NamedIndividual {
rdfs__label: 'W-2',
uri: '...',
skos__definition: '...'
})
MERGE (wages:rdfs__Datatype {rdfs__label: 'wagesTipsOtherComp'})
ON CREATE SET wages.xsd__type = 'xsd:decimal',
wages.skos__definition = 'Box 1: Total wages, tips, and other compensation'
CREATE (w2)-[:hasWagesTipsOtherComp {materialized: true, cardinality: '1'}]->(wages)
Why: Named individuals should only have metadata properties (rdfs__label, uri, skos__definition). All domain attributes must be expressed as graph relationships so they appear correctly in UML/Pydantic visualizations and can be properly queried.
When a concept represents a type/template (e.g., a form type, document type), model it as owl__Class with rdfs__subClassOf, NOT as owl__NamedIndividual with rdf__type.
Use owl__NamedIndividual ONLY for true singleton instances (e.g., "United States of America", "US Dollar").
❌ WRONG — form type as named individual:
CREATE (f:owl__NamedIndividual {rdfs__label: 'Form 1040'})
CREATE (f)-[:rdf__type]->(report) // WRONG: rdf__type implies instance
✅ CORRECT — form type as class:
CREATE (f:owl__Class {rdfs__label: 'Form 1040', uri: '...', skos__definition: '...'})
CREATE (f)-[:rdfs__subClassOf {materialized: true}]->(report) // Subclass hierarchy
To convert existing named individuals to classes:
MATCH (f:owl__NamedIndividual {rdfs__label: 'Form 1040'})
REMOVE f:owl__NamedIndividual
SET f:owl__Class
WITH f
MATCH (f)-[oldType:rdf__type]->(c)
DELETE oldType
WITH DISTINCT f
MATCH (parent:owl__Class {rdfs__label: 'report'})
MERGE (f)-[:rdfs__subClassOf {materialized: true}]->(parent)
When to use which:
| Concept | Node Type | Relationship |
|---|---|---|
| W-2 form, Form 1040, Form 1120 | owl__Class | rdfs__subClassOf → report |
| United States of America | owl__NamedIndividual | rdf__type → country |
| US Dollar, Euro | owl__NamedIndividual | rdf__type → currency |
stagingdb to avoid polluting the main ontology.MATCH (c {rdfs__label: '...'})-[r]->(t) RETURN type(r), t.rdfs__labelMERGE target nodes by URI to avoid duplicates (e.g., country, city datatypes).consolidate_staging_db tool automatically de-duplicates URIs, labels, and relationships.consolidate_staging_db automatically deletes named individuals linked via rdf__type when converting a class to a datatype.xmllint.