{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "dodo-app configuration",
    "description": "Schema for the dodo-app configuration object describing user services and infrastructure components they require to be provided by the dodo platform.",
    "type": "object",
    "properties": {
        "service": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/Service"
            }
        },
        "agent": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/Agent"
            }
        },
        "volume": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/Volume"
            }
        },
        "postgresql": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/PostgreSQL"
            }
        },
        "mongodb": {
            "type": "array",
            "items": {
                "$ref": "#/definitions/MongoDB"
            }
        }
    },
    "definitions": {
        "ServiceType": {
            "type": "string",
            "description": "Base image used by the service.",
            "enum": [
                "deno:2.2.0",
                "golang:1.20.0",
                "golang:1.22.0",
                "golang:1.24.0",
                "hugo:latest",
                "php:8.2-apache",
                "nextjs:deno-2.0.0",
                "nodejs:23.1.0",
                "nodejs:24.0.2"
            ]
        },
        "VolumeType": {
            "type": "string",
            "description": "Describes how many pods and nodes (node is a collection of pods) can use this volume concurrently. ReadWriteOnce allows only one node to read and write from the volume. ReadOnlyMany volume can be mounted to many nodes in read only mode. ReadWriteMany multiple nodes can read and write from volume. ReadWriteOncePod volume can by used by only a single pod to read and write from it.",
            "enum": [
                "ReadWriteOnce",
                "ReadOnlyMany",
                "ReadWriteMany",
                "ReadWriteOncePod"
            ]
        },
        "Domain": {
            "type": "object",
            "description": "TODO",
            "properties": {
                "network": {
                    "type": "string",
                    "description": "Identifier for the network."
                },
                "subdomain": {
                    "type": "string",
                    "description": "The subdomain for the service."
                }
            },
            "required": ["network", "subdomain"]
        },
        "PortValue": {
            "description": "References port either by it's name or the numeric value.",
            "oneOf": [
                {
                    "type": "object",
                    "properties": {
                        "name": {
                            "type": "string",
                            "description": "Name of the port (e.g., 'HTTP')."
                        }
                    },
                    "required": ["name"]
                },
                {
                    "type": "object",
                    "properties": {
                        "value": {
                            "type": "number",
                            "description": "Numeric value of the port (e.g., 80)."
                        }
                    },
                    "required": ["value"]
                }
            ]
        },
        "PortDomain": {
            "description": "Combination of the Domain and PortValue",
            "allOf": [
                {
                    "$ref": "#/definitions/Domain"
                },
                {
                    "type": "object",
                    "properties": {
                        "port": {
                            "$ref": "#/definitions/PortValue"
                        },
                        "nodeId": {
                            "type": "string",
                            "description": "Identifier of the node this resource is assigned to. Generated by server."
                        }
                    },
                    "required": ["port"]
                }
            ]
        },
        "Auth": {
            "description": "Describes authentication and authorization requirements.",
            "oneOf": [
                {
                    "type": "object",
                    "title": "AuthDisabled",
                    "properties": {
                        "enabled": {
                            "type": "boolean",
                            "const": false,
                            "description": "Authentication is disabled."
                        }
                    },
                    "required": ["enabled"]
                },
                {
                    "type": "object",
                    "title": "AuthEnabled",
                    "properties": {
                        "enabled": {
                            "type": "boolean",
                            "const": true,
                            "description": "Authentication is enabled."
                        },
                        "groups": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            },
                            "description": "List of groups allowed access."
                        },
                        "noAuthPathPatterns": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            },
                            "description": "List of path patterns that do not require authentication."
                        }
                    },
                    "required": ["enabled", "groups", "noAuthPathPatterns"]
                }
            ]
        },
        "Ingress": {
            "type": "object",
            "description": "Describes HTTPS endpoint service can be published at, with optional authentication configuration.",
            "properties": {
                "network": {
                    "type": "string",
                    "description": "Identifier for the network this ingress belongs to."
                },
                "subdomain": {
                    "type": "string",
                    "description": "The subdomain for this ingress."
                },
                "port": {
                    "oneOf": [
                        {
                            "type": "object",
                            "properties": {
                                "name": {
                                    "type": "string",
                                    "description": "Name of the target port on the service."
                                }
                            },
                            "required": ["name"]
                        },
                        {
                            "type": "object",
                            "properties": {
                                "value": {
                                    "type": "string",
                                    "description": "Value of the target port on the service (if specified by string, though typically number in service definition)."
                                }
                            },
                            "required": ["value"]
                        }
                    ],
                    "description": "The port on the service this ingress targets."
                },
                "auth": {
                    "$ref": "#/definitions/Auth"
                },
                "nodeId": {
                    "type": "string",
                    "description": "Identifier of the node this resource is assigned to. Generated by server."
                }
            },
            "required": ["network", "subdomain", "port", "auth"]
        },
        "Service": {
            "type": "object",
            "description": "User implemented service definition, including information how to build it, what kind of environment variables it needs (which translates to infrastructure dependencies), how to run it and ports it exposes.",
            "properties": {
                "type": {
                    "$ref": "#/definitions/ServiceType"
                },
                "name": {
                    "type": "string",
                    "description": "Name of the service."
                },
                "source": {
                    "type": "object",
                    "description": "Defines where to pull the source code from.",
                    "properties": {
                        "repository": {
                            "type": "string",
                            "format": "uri",
                            "description": "SSH URL of the Git repository."
                        },
                        "branch": {
                            "type": "string",
                            "description": "Branch to deploy from."
                        },
                        "rootDir": {
                            "type": "string",
                            "description": "Root directory within the repository for this service."
                        }
                    },
                    "required": ["repository", "branch", "rootDir"]
                },
                "ports": {
                    "type": "array",
                    "description": "List of ports this service exposes when started.",
                    "items": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string",
                                "description": "Name of the port (e.g., 'http', 'grpc'). Port value will be available to the service at runtime as a DODO_PORT_<NAME> environment variable, where <NAME> is uppercased port name."
                            },
                            "value": {
                                "type": "number",
                                "description": "Port number."
                            },
                            "protocol": {
                                "type": "string",
                                "enum": ["TCP", "UDP"]
                            }
                        },
                        "required": ["name", "value", "protocol"]
                    }
                },
                "env": {
                    "type": "array",
                    "description": "List of environment variables.",
                    "items": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string",
                                "description": "Name of the environment variable as used by the service."
                            },
                            "alias": {
                                "type": "string",
                                "description": "Original name of the environment variable if aliased."
                            }
                        },
                        "required": ["name"]
                    }
                },
                "ingress": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/Ingress"
                    },
                    "description": "HTTPS ingress definitions for this service."
                },
                "expose": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/PortDomain"
                    },
                    "description": "TCP/UDP exposure definitions for this service."
                },
                "volume": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    },
                    "description": "Names of volumes to be mounted to this service."
                },
                "preBuildCommands": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "bin": {
                                "type": "string",
                                "description": "A command to run before building/starting the service."
                            }
                        },
                        "required": ["bin"]
                    }
                },
                "dev": {
                    "type": "object",
                    "description": "Describes to run this service in development mode or not.",
                    "properties": {
                        "enabled": {
                            "type": "boolean",
                            "description": "Whether development mode is enabled for this service."
                        },
                        "username": {
                            "type": "string",
                            "description": "Username for SSH/Code-server access in dev mode."
                        },
                        "ssh": {
                            "$ref": "#/definitions/Domain",
                            "description": "Network exposure for SSH in dev mode."
                        },
                        "codeServer": {
                            "$ref": "#/definitions/Domain",
                            "description": "Network exposure for Code-server in dev mode."
                        }
                    },
                    "required": ["enabled"]
                },
                "nodeId": {
                    "type": "string",
                    "description": "Identifier of the node this resource is assigned to. Generated by server."
                }
            },
            "required": ["type", "name", "source"]
        },
        "Agent": {
            "type": "object",
            "description": "AI Agent definition, which user can communicate with to implement new service or add new features to already existing one.",
            "properties": {
                "name": {
                    "type": "string",
                    "description": "Name of the AI Agent."
                },
                "geminiApiKey": {
                    "type": "string",
                    "description": "Gemini API Key"
                },
                "source": {
                    "type": "object",
                    "description": "If provided, defines where to pull the source code from.",
                    "properties": {
                        "repository": {
                            "type": "string",
                            "format": "uri",
                            "description": "SSH URL of the Git repository."
                        },
                        "branch": {
                            "type": "string",
                            "description": "Branch to deploy from."
                        },
                        "rootDir": {
                            "type": "string",
                            "description": "Root directory within the repository for this service."
                        }
                    },
                    "required": ["repository", "branch", "rootDir"]
                },
                "ports": {
                    "type": "array",
                    "description": "List of ports this service exposes when started.",
                    "items": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string",
                                "description": "Name of the port (e.g., 'http', 'grpc'). Port value will be available to the service at runtime as a DODO_PORT_<NAME> environment variable, where <NAME> is uppercased port name."
                            },
                            "value": {
                                "type": "number",
                                "description": "Port number."
                            },
                            "protocol": {
                                "type": "string",
                                "enum": ["TCP", "UDP"]
                            }
                        },
                        "required": ["name", "value", "protocol"]
                    }
                },
                "env": {
                    "type": "array",
                    "description": "List of environment variables.",
                    "items": {
                        "type": "object",
                        "properties": {
                            "name": {
                                "type": "string",
                                "description": "Name of the environment variable as used by the service."
                            },
                            "alias": {
                                "type": "string",
                                "description": "Original name of the environment variable if aliased."
                            }
                        },
                        "required": ["name"]
                    }
                },
                "ingress": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/Ingress"
                    },
                    "description": "HTTPS ingress definitions for this service."
                },
                "expose": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/PortDomain"
                    },
                    "description": "TCP/UDP exposure definitions for this service."
                },
                "volume": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    },
                    "description": "Names of volumes to be mounted to this service."
                },
                "preBuildCommands": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "properties": {
                            "bin": {
                                "type": "string",
                                "description": "A command to run before building/starting the service."
                            }
                        },
                        "required": ["bin"]
                    }
                },
                "dev": {
                    "type": "object",
                    "description": "Describes to run this service in development mode or not.",
                    "properties": {
                        "enabled": {
                            "type": "boolean",
                            "description": "Whether development mode is enabled for this service."
                        },
                        "username": {
                            "type": "string",
                            "description": "Username for SSH/Code-server access in dev mode."
                        },
                        "ssh": {
                            "$ref": "#/definitions/Domain",
                            "description": "Network exposure for SSH in dev mode."
                        },
                        "codeServer": {
                            "$ref": "#/definitions/Domain",
                            "description": "Network exposure for Code-server in dev mode."
                        }
                    },
                    "required": ["enabled"]
                },
                "nodeId": {
                    "type": "string",
                    "description": "Identifier of the node this resource is assigned to. Generated by server."
                }
            },
            "required": ["name"]
        },
        "Volume": {
            "type": "object",
            "description": "Volume definition which can be mounted to services and other infrastructure components. When mounted to the service, it's mount location is exposed as DODO_VOLUME_<NAME> env variable where <NAME> represents name of the volume (name is upper cased).",
            "properties": {
                "name": {
                    "type": "string",
                    "description": "Name of the volume."
                },
                "accessMode": {
                    "$ref": "#/definitions/VolumeType"
                },
                "size": {
                    "type": "string",
                    "pattern": "^[0-9]+(Gi|Mi|Ti)$",
                    "description": "Size of the volume (e.g., '1Gi', '500Mi')."
                },
                "nodeId": {
                    "type": "string",
                    "description": "Identifier of the node this resource is assigned to. Generated by server."
                }
            },
            "required": ["name", "accessMode", "size"]
        },
        "PostgreSQL": {
            "type": "object",
            "description": "Describes PostgreSQL instance to run. It's connection string is exposed to other services as DODO_POSTGRESQL_<NAME>_URL where <NAME> represents name of the PostgreSQL instance (name is upper cased).",
            "properties": {
                "name": {
                    "type": "string",
                    "description": "Name of the PostgreSQL instance."
                },
                "size": {
                    "type": "string",
                    "pattern": "^[0-9]+(Gi|Mi|Ti)$",
                    "description": "Storage size for the PostgreSQL instance."
                },
                "expose": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/PortDomain"
                    },
                    "description": "Network exposure definitions for this PostgreSQL instance."
                },
                "nodeId": {
                    "type": "string",
                    "description": "Identifier of the node this resource is assigned to. Generated by server."
                }
            },
            "required": ["name", "size"]
        },
        "MongoDB": {
            "type": "object",
            "description": "Describes MongoDB instance to run. It's connection string is exposed to other services as DODO_MONGODB_<NAME>_URL where <NAME> represents name of the MongoDB instance (name is upper cased).",
            "properties": {
                "name": {
                    "type": "string",
                    "description": "Name of the MongoDB instance."
                },
                "size": {
                    "type": "string",
                    "pattern": "^[0-9]+(Gi|Mi|Ti)$",
                    "description": "Storage size for the MongoDB instance."
                },
                "expose": {
                    "type": "array",
                    "items": {
                        "$ref": "#/definitions/PortDomain"
                    },
                    "description": "Network exposure definitions for this MongoDB instance."
                },
                "nodeId": {
                    "type": "string",
                    "description": "Identifier of the node this resource is assigned to. Generated by server."
                }
            },
            "required": ["name", "size"]
        }
    }
}
