# Optional Neo4j Aura handoff

Neo4j Aura can hold a queryable copy of Synthome's public graph. Git remains the canonical source, and this handoff does not change the live explorer, API, MCP server, or PostgreSQL configuration. NetworkX analysis runs independently of Aura.

This is a lightweight property graph schema: resources, topics, publishers, proposed weeks, and typed relationships. It does not introduce a full ontology, inference rules, or automated factual reasoning. Submitted classifications retain their review status and provenance. Community assignments and centrality scores are derived analysis; they must not be treated as factual classification arcs.

## Generate the import file locally

From `integrations/synthome-library`, run:

```powershell
node scripts/export-neo4j.mjs
```

The default output is `analysis/synthome-neo4j.cypher`. An optional output path can follow the script name. Generation reads the sanitized public projection and writes a local file. It does not connect to a database, provision Aura, or request credentials. Keep the generated file with the Git commit and graph revision used to produce it.

The export preserves public fields in JSON together with native properties suitable for filtering and graph queries. Private course fields are excluded by the same projection used for publication.

## Export schema

| Record | Neo4j representation |
| --- | --- |
| Public graph node | `:SynthomeNode` plus `:SynthomeResource`, `:SynthomeTopic`, `:SynthomePublisher`, or `:SynthomeWeek` |
| Classification arc | Original directed `CLASSIFIED_AS`, `PUBLISHED_BY`, or `PROPOSED_FOR` relationship, retaining its stable `id` |
| Public dataset metadata | One `:SynthomeDataset` node with `id: 'synthome-public'`, `metaJson`, `submissionsJson`, `revision`, `nodeCount`, `arcCount`, and `sourceRowCount` |

Every graph node and arc has a `payloadJson` property containing its complete original public record. Simple fields such as `id`, `title`, `type`, and `reviewStatus` are also native properties. Nested fields use JSON properties such as `provenanceJson` and `stalenessJson`. The dataset's `submissionsJson` retains all 604 source rows; they are not additional graph nodes.

The ownership marker is `synthomeSchema: 'synthome-public-v1'`. Uniqueness constraints cover `SynthomeNode.id`, `SynthomeDataset.id`, and `id` on each of the three relationship types. `MERGE` matches both stable ID and schema marker. Reusing an ID under an incompatible marker, or moving an existing arc ID to different endpoints, fails the uniqueness guard instead of silently taking ownership.

Use current Aura or Neo4j 5.7 or later: the export requires [relationship property uniqueness constraints](https://neo4j.com/docs/cypher-manual/5/constraints/create-constraints/), introduced in 5.7.

## Import into a dedicated Aura database

1. Create or select an **empty, dedicated database** for this copy. In Aura's Query tool, confirm the selected instance and database, then run `MATCH (n) RETURN count(n) AS existingNodes;`. A first import should start at zero. The [Aura connection guide](https://neo4j.com/docs/aura/getting-started/connect-instance/) explains database selection and connection details.
2. Review the generated file and its schema declarations. The import uses stable IDs, fixed labels and relationship types, uniqueness constraints, and `MERGE`. Constraints protect identity; incompatible pre-existing data or schema must be investigated before continuing. `IF NOT EXISTS` does not bypass conflicting constraints or duplicate data. See the official [constraint syntax](https://neo4j.com/docs/cypher-manual/current/schema/syntax/) and [MERGE behavior](https://neo4j.com/docs/cypher-manual/current/clauses/merge/).
3. Install the current Cypher Shell from Neo4j's distribution and use your instance's connection details locally. The following placeholders are not a working connection:

```powershell
cypher-shell -a "neo4j+s://YOUR-INSTANCE.databases.neo4j.io" -u "YOUR-USERNAME" -d "YOUR-DATABASE" --fail-fast -f "analysis/synthome-neo4j.cypher"
```

Enter the password when prompted; do not put it in the command, export, repository, or public site. `-f` executes the file and exits; `--fail-fast` stops at the first failing statement. Cypher Shell can also execute a file from an interactive session with `:source`. Installation requirements and command options are in the [Cypher Shell manual](https://neo4j.com/docs/operations-manual/current/cypher-shell/).

This artifact is an executable Cypher script. Aura's separate Import interface uses data sources and a mapped model; its [mapping guide](https://neo4j.com/docs/aura/import/mapping/) describes that alternative workflow. Use Cypher Shell for this supplied script.

## Verify the copy

Check the shell's exit status and read any errors. Individual statements may already have committed before a later statement fails; file execution is not a promise of one transaction covering the entire import.

In Aura Query, inspect the schema, graph counts, and imported relationship types:

```cypher
SHOW CONSTRAINTS;
```

```cypher
MATCH (n:SynthomeNode {synthomeSchema: 'synthome-public-v1'})
RETURN n.type AS nodeType, count(*) AS count
ORDER BY nodeType;
```

```cypher
MATCH (:SynthomeNode)-[r]->(:SynthomeNode)
WHERE r.synthomeSchema = 'synthome-public-v1'
RETURN type(r) AS relation, count(*) AS count
ORDER BY relation;
```

For the initial public snapshot, expect 603 resources, 292 topics, 287 publishers, and six weeks: 1,188 `SynthomeNode` records, plus one separate dataset node. Classification counts are 1,776 `CLASSIFIED_AS`, 601 `PUBLISHED_BY`, and 1,098 `PROPOSED_FOR`: 3,475 arcs. Compare with the generated file's revision and counts when importing a later snapshot.

To view a small resource/topic neighborhood:

```cypher
MATCH (r:SynthomeResource)-[a:CLASSIFIED_AS]->(t:SynthomeTopic)
WHERE a.synthomeSchema = 'synthome-public-v1'
RETURN r, a, t
LIMIT 30;
```

Inspect a resource's title, URL, review status, serialized provenance, and connections against the same source revision before using the copy for analysis. Record the source commit, export revision, import date, database name, and verification outcome in your local handoff notes. Export generation alone does not establish that an Aura import succeeded.

## Re-import behavior and ownership

The script appends missing records and upserts matching stable IDs. `SET +=` refreshes supplied export properties while preserving unrelated properties. Fields absent from a later export can remain as older native properties, so `payloadJson` is the authoritative record for that snapshot. Keep independent annotations separate. It never deletes nodes. Removed source arcs remain in an existing Aura copy, and changed endpoints for an existing arc ID trigger a constraint error; an upsert is not an exact snapshot replacement. A clean database per revision provides an unambiguous comparison without deleting an earlier copy.

An Aura import is a downstream copy. Editing it does not update Git, the public explorer, MCP results, or NetworkX outputs. Any future switch of the live storage backend requires separate implementation and verification; this export does not enable student writes.
