{
  "$id": "urn:manifest:config:prisma-projection-v1",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Prisma projection options (v1)",
  "description": "Consumer-facing config surface for @manifest/projection-prisma. Supplied to the projection at compile time via `projections.prisma.options` in manifest.config.yaml. NONE of these keys exist in Manifest core grammar or IR; they all live here on the projection side.",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "provider": {
      "description": "Optional Prisma datasource provider. When set, the projection emits a datasource block.",
      "enum": ["postgresql", "mysql", "sqlite", "sqlserver", "mongodb", "cockroachdb"]
    },
    "output": {
      "description": "Output path hint for the emitted artifact. Default: 'schema.prisma'. The projection itself does not write files; this value flows to ProjectionArtifact.pathHint.",
      "type": "string"
    },
    "relationMode": {
      "description": "Datasource relationMode. Emitted as relationMode = \"...\" on the datasource block. Use \"prisma\" when relations are enforced in the client (PlanetScale, Neon pooled, etc.) rather than via DB foreign keys.",
      "enum": ["prisma", "foreignKeys"]
    },
    "generator": {
      "description": "Fields for the emitted `generator client { ... }` block, each rendered verbatim as key = \"value\". Defaults to { provider: \"prisma-client-js\" }. Override to select the newer prisma-client generator and set output/moduleFormat/generatedFileExtension/importFileExtension.",
      "type": "object",
      "additionalProperties": { "type": "string" }
    },
    "tableMappings": {
      "description": "Per-entity table-name override. Key = IR entity name; value = literal table name. Emits @@map(\"...\").",
      "type": "object",
      "additionalProperties": { "type": "string" }
    },
    "columnMappings": {
      "description": "Per-entity, per-property column-name override. Nested shape: Record<EntityName, Record<PropertyName, string>>. NO dotted-string \"Entity.property\" keys are accepted at this layer.",
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "additionalProperties": { "type": "string" }
      }
    },
    "precision": {
      "description": "Per-entity, per-property decimal precision and scale. Nested shape: Record<EntityName, Record<PropertyName, {precision, scale}>>. Locked at Checkpoint 1 amendment — no flattened keys.",
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "additionalProperties": {
          "type": "object",
          "required": ["precision", "scale"],
          "additionalProperties": false,
          "properties": {
            "precision": { "type": "integer", "minimum": 1 },
            "scale": { "type": "integer", "minimum": 0 }
          }
        }
      }
    },
    "indexes": {
      "description": "Per-entity composite/named index definitions. Each entry is either a column-name array (composite @@index) or an object with `fields` and optional `name`.",
      "type": "object",
      "additionalProperties": {
        "type": "array",
        "items": {
          "oneOf": [
            { "type": "array", "items": { "type": "string" }, "minItems": 1 },
            {
              "type": "object",
              "required": ["fields"],
              "additionalProperties": false,
              "properties": {
                "fields": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
                "name": { "type": "string" }
              }
            }
          ]
        }
      }
    },
    "typeMappings": {
      "description": "Per-entity, per-property type override. Bypasses the default IR-type-name → Prisma-type table. Nested shape: Record<EntityName, Record<PropertyName, string>>. Value is a Prisma scalar literal (e.g. 'Int', 'Decimal').",
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "additionalProperties": { "type": "string" }
      }
    },
    "foreignKeys": {
      "description": "Per-entity, per-relationship FK field name or structured config. Overrides the default `${relationshipName}Id` (and the IR's `foreignKey` annotation) for belongsTo/ref relations. Value is either a plain string field name, or an object with fields/references/onDelete/onUpdate for full referential-action control.",
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "additionalProperties": {
          "oneOf": [
            { "type": "string" },
            {
              "type": "object",
              "required": ["fields"],
              "additionalProperties": false,
              "properties": {
                "fields": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
                "references": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
                "onDelete": { "type": "string" },
                "onUpdate": { "type": "string" }
              }
            }
          ]
        }
      }
    },
    "dbAttributes": {
      "description": "Per-entity, per-property native @db.* attribute string (without the @db. prefix). Applied after the type scalar but before @default. Example: { Order: { amount: 'Decimal(14,2)' } } emits @db.Decimal(14,2).",
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "additionalProperties": { "type": "string" }
      }
    },
    "fieldAttributes": {
      "description": "Per-entity, per-property array of verbatim Prisma field attributes appended after type and dbAttributes. Example: { Order: { code: ['@unique', '@default(cuid())'] } }. Use for @unique, @updatedAt, @default(...), etc.",
      "type": "object",
      "additionalProperties": {
        "type": "object",
        "additionalProperties": {
          "type": "array",
          "items": { "type": "string" }
        }
      }
    },
    "urlEnvVar": {
      "description": "Environment variable name for the database connection URL in the emitted prisma.config.ts companion. Defaults to 'DATABASE_URL'. Only relevant when provider is set.",
      "type": "string"
    },
    "multiSchema": {
      "description": "Preserve the model's module layout as database schemas instead of flattening into one schema. Emits @@schema(...) per model and schemas=[...] on the datasource. PostgreSQL / CockroachDB / SQL Server only.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "enabled": {
          "description": "Master switch. Default false (flat layout, fully back-compatible).",
          "type": "boolean",
          "default": false
        },
        "schemas": {
          "description": "Explicit datasource schema list. Order preserved; any schema used by a model but missing here is appended (sorted) so the datasource lists every referenced schema.",
          "type": "array",
          "items": { "type": "string" }
        },
        "entitySchema": {
          "description": "Per-entity schema override. Key = IR entity name; value = schema name. Takes precedence over the entity's IR module.",
          "type": "object",
          "additionalProperties": { "type": "string" }
        },
        "defaultSchema": {
          "description": "Schema for entities with neither an entitySchema override nor an IR module. Default 'public'.",
          "type": "string",
          "default": "public"
        },
        "splitFiles": {
          "description": "Config G6 — emit root datasource/generator at output plus one .prisma file per database schema under dir. Requires multiSchema.enabled. Prisma merges sibling files.",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "enabled": {
              "description": "Master switch. Default false (single combined schema file).",
              "type": "boolean",
              "default": false
            },
            "dir": {
              "description": "Directory path hint for per-schema .prisma partitions. Default 'prisma/schemas'.",
              "type": "string",
              "default": "prisma/schemas"
            }
          }
        }
      }
    },
    "autoBackRelations": {
      "description": "Auto-emit the inverse relation field on a target model for any belongsTo/ref that lacks an explicit opposite. Default false. When true, emits `<pluralCamelOwner> Owner[]` on the target (with a deterministic @relation name for ambiguous pairs), removing the need to hand-author inverse hasMany on hub entities.",
      "type": "boolean",
      "default": false
    },
    "naming": {
      "description": "Automatic identifier-casing convention. Opt-in; only ever adds @map/@@map (the Prisma model name and field identifiers stay the IR name, so relations/indexes are unaffected). Explicit tableMappings/columnMappings override it. String shorthand 'snake_case' ≡ { table: 'snake_case', column: 'snake_case', pluralizeTables: true }.",
      "oneOf": [
        { "type": "string", "enum": ["snake_case"] },
        {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "table": {
              "description": "Case style for table physical names (@@map). Default 'preserve'.",
              "enum": ["snake_case", "camelCase", "PascalCase", "preserve"]
            },
            "column": {
              "description": "Case style for column physical names (@map). Default 'preserve'.",
              "enum": ["snake_case", "camelCase", "preserve"]
            },
            "pluralizeTables": {
              "description": "Pluralize resolved table names. Default true.",
              "type": "boolean"
            }
          }
        }
      ]
    }
  }
}
