diff --git a/apps/canvas/front/src/lib/config.ts b/apps/canvas/front/src/lib/config.ts
new file mode 100644
index 0000000..fcea7c3
--- /dev/null
+++ b/apps/canvas/front/src/lib/config.ts
@@ -0,0 +1,385 @@
+import { AppNode, Env, GatewayHttpsNode, Message, MessageType, NodeType, ServiceType, VolumeType } from "./state";
+
+export type AuthDisabled = {
+    enabled: false;
+};
+
+export type AuthEnabled = {
+    enabled: true;
+    groups: string[];
+    noAuthPathPatterns: string[];
+};
+
+export type Auth = AuthDisabled | AuthEnabled;
+
+export type Ingress = {
+    network: string;
+    subdomain: string;
+    port: { name: string; } | { value: string; };
+    auth: Auth;
+};
+
+export type Domain = {
+    network: string;
+    subdomain: string;
+};
+
+export type PortValue = {
+    name: string;
+} | {
+    value: number;
+};
+
+export type PortDomain = Domain & {
+    port: PortValue;
+}
+
+export type Service = {
+    type: ServiceType;
+    name: string;
+    source: {
+        repository: string;
+        branch: string;
+        rootDir: string;
+    };
+    ports?: {
+        name: string;
+        value: number;
+        protocol: "TCP" | "UDP";
+    }[];
+    env?: {
+        name: string;
+        alias?: string;
+    }[]
+    ingress?: Ingress[];
+    expose?: PortDomain[];
+    volume?: string[];
+};
+
+export type Volume = {
+    name: string;
+    accessMode: VolumeType;
+    size: string;
+};
+
+export type PostgreSQL = {
+    name: string;
+    size: string;
+    expose?: Domain[];
+};
+
+export type MongoDB = {
+    name: string;
+    size: string;
+    expose?: Domain[];
+};
+
+export type Config = {
+    service?: Service[];
+    volume?: Volume[];
+    postgresql?: PostgreSQL[];
+    mongodb?: MongoDB[];
+};
+
+export function generateDodoConfig(nodes: AppNode[], env: Env): Config | null {
+    try {
+        const networkMap = new Map(env.networks.map((n) => [n.domain, n.name]));
+        const ingressNodes = nodes.filter((n) => n.type === "gateway-https").filter((n) => n.data.https !== undefined);
+        const tcpNodes = nodes.filter((n) => n.type === "gateway-tcp").filter((n) => n.data.exposed !== undefined);
+        const findExpose = (n: AppNode): PortDomain[] => {
+            return n.data.ports.map((p) => [n.id, p.id, p.name]).flatMap((sp) => {
+                return tcpNodes.flatMap((i) => (i.data.exposed || []).filter((t) => t.serviceId === sp[0] && t.portId === sp[1]).map(() => ({
+                    network: networkMap.get(i.data.network!)!,
+                    subdomain: i.data.subdomain!,
+                    port: { name: sp[2] },
+                })));
+            });
+        };
+        return {
+            service: nodes.filter((n) => n.type === "app").map((n): Service => {
+                return {
+                    type: n.data.type,
+                    name: n.data.label,
+                    source: {
+                        repository: nodes.filter((i) => i.type === "github").find((i) => i.id === n.data.repository.id)!.data.address,
+                        branch: n.data.repository.branch,
+                        rootDir: n.data.repository.rootDir,
+                    },
+                    ports: (n.data.ports || []).map((p) => ({
+                        name: p.name,
+                        value: p.value,
+                        protocol: "TCP", // TODO(gio)
+                    })),
+                    env: (n.data.envVars || []).filter((e) => "name" in e).map((e) => ({
+                        name: e.name,
+                        alias: "alias" in e ? e.alias : undefined,
+                    })),
+                    ingress: ingressNodes.filter((i) => i.data.https!.serviceId === n.id).map((i: GatewayHttpsNode): Ingress => ({
+                        network: networkMap.get(i.data.network!)!,
+                        subdomain: i.data.subdomain!,
+                        port: {
+                            name: n.data.ports.find((p) => p.id === i.data.https!.portId)!.name,
+                        },
+                        auth: { enabled: false },
+                    })),
+                    expose: findExpose(n),
+                };
+            }),
+            volume: nodes.filter((n) => n.type === "volume").map((n): Volume => ({
+                name: n.data.label,
+                accessMode: n.data.type,
+                size: n.data.size,
+            })),
+            postgresql: nodes.filter((n) => n.type === "postgresql").map((n): PostgreSQL => ({
+                name: n.data.label,
+                size: "1Gi", // TODO(gio)
+                expose: findExpose(n).map((e) => ({ network: e.network, subdomain: e.subdomain })),
+            })),
+            mongodb: nodes.filter((n) => n.type === "mongodb").map((n): MongoDB => ({
+                name: n.data.label,
+                size: "1Gi", // TODO(gio)
+                expose: findExpose(n).map((e) => ({ network: e.network, subdomain: e.subdomain })),
+            })),
+        };
+    } catch (e) {
+        console.log(e);
+        return null;
+    }
+}
+
+export interface Validator {
+    (nodes: AppNode[]): Message[];
+}
+
+function CombineValidators(...v: Validator[]): Validator {
+    return (n) => v.flatMap((v) => v(n));
+}
+
+function MessageTypeToNumber(t: MessageType) {
+    switch (t) {
+        case "FATAL": return 0;
+        case "WARNING": return 1;
+        case "INFO": return 2;
+    }
+}
+
+function NodeTypeToNumber(t?: NodeType) {
+    switch (t) {
+        case "github": return 0;
+        case "app": return 1;
+        case "volume": return 2;
+        case "postgresql": return 3;
+        case "mongodb": return 4;
+        case "gateway-https": return 5;
+        case undefined: return 100;
+    }
+}
+
+function SortingValidator(v: Validator): Validator {
+    return (n) => {
+        const nt = new Map(n.map((n) => [n.id, NodeTypeToNumber(n.type)]))
+        return v(n).sort((a, b) => {
+            const at = MessageTypeToNumber(a.type);
+            const bt = MessageTypeToNumber(b.type);
+            if (a.nodeId === undefined && b.nodeId === undefined) {
+                if (at !== bt) {
+                    return at - bt;
+                }
+                return a.id.localeCompare(b.id);
+            }
+            if (a.nodeId === undefined) {
+                return -1;
+            }
+            if (b.nodeId === undefined) {
+                return 1;
+            }
+            if (a.nodeId === b.nodeId) {
+                if (at !== bt) {
+                    return at - bt;
+                }
+                return a.id.localeCompare(b.id);
+            }
+            const ant = nt.get(a.id)!;
+            const bnt = nt.get(b.id)!;
+            if (ant !== bnt) {
+                return ant - bnt;
+            }
+            return a.id.localeCompare(b.id);
+        });
+    };
+}
+
+export function CreateValidators(): Validator {
+    return SortingValidator(
+        CombineValidators(
+            EmptyValidator, 
+            GitRepositoryValidator,
+            ServiceValidator,
+            GatewayHTTPSValidator,
+            GatewayTCPValidator,
+        )
+    );
+}
+
+function EmptyValidator(nodes: AppNode[]): Message[] {
+    if (nodes.length > 0) {
+        return [];
+    }
+    return [{   
+        id: "no-nodes",
+        type: "FATAL",
+        message: "Start by importing application source code",
+        onHighlight: (store) => store.setHighlightCategory("repository", true),
+        onLooseHighlight: (store) => store.setHighlightCategory("repository", false),
+    }];
+}
+
+function GitRepositoryValidator(nodes: AppNode[]): Message[] {
+    const git = nodes.filter((n) => n.type === "github");
+    const noAddress: Message[] = git.filter((n) => n.data == null || n.data.address == null || n.data.address === "").map((n) => ({
+        id: `${n.id}-no-address`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Configure repository address",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    } satisfies Message));
+    const noApp = git.filter((n) => !nodes.some((i) => i.type === "app" && i.data?.repository?.id === n.id)).map((n) => ({
+        id: `${n.id}-no-app`,
+        type: "WARNING",
+        nodeId: n.id,
+        message: "Connect to service",
+        onHighlight: (store) => store.setHighlightCategory("Services", true),
+        onLooseHighlight: (store) => store.setHighlightCategory("Services", false),
+} satisfies Message));
+    return noAddress.concat(noApp);
+}
+
+function ServiceValidator(nodes: AppNode[]): Message[] {
+    const apps = nodes.filter((n) => n.type === "app");
+    const noName = apps.filter((n) => n.data == null || n.data.label == null || n.data.label === "").map((n): Message => ({
+        id: `${n.id}-no-name`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Name the service",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+        onClick: (store) => {
+            store.updateNode(n.id, { selected: true });
+            store.updateNodeData<"app">(n.id, { 
+                activeField: "name" ,
+            });
+        },
+    }));
+    const noSource = apps.filter((n) => n.data == null || n.data.repository == null || n.data.repository.id === "").map((n): Message => ({
+        id: `${n.id}-no-repo`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Connect to source repository",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    const noRuntime = apps.filter((n) => n.data == null || n.data.type == null).map((n): Message => ({
+        id: `${n.id}-no-runtime`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Choose runtime",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+        onClick: (store) => {
+            store.updateNode(n.id, { selected: true });
+            store.updateNodeData<"app">(n.id, { 
+                activeField: "type" ,
+            });
+        },
+    }));
+    const noPorts = apps.filter((n) => n.data == null || n.data.ports == null || n.data.ports.length === 0).map((n): Message => ({
+        id: `${n.id}-no-ports`,
+        type: "INFO",
+        nodeId: n.id,
+        message: "Expose ports",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    const noIngress = apps.flatMap((n): Message[] => {
+        if (n.data == null) {
+            return [];
+        }
+        return (n.data.ports || []).filter((p) => !nodes.filter((i) => i.type === "gateway-https").some((i) => {
+            if (i.data && i.data.https && i.data.https.serviceId === n.id && i.data.https.portId === p.id) {
+                return true;
+            }
+            return false;
+        })).map((p): Message => ({
+            id: `${n.id}-${p.id}-no-ingress`,
+            type: "WARNING",
+            nodeId: n.id,
+            message: `Connect to ingress: ${p.name} - ${p.value}`,
+            onHighlight: (store) => {
+                store.updateNode(n.id, { selected: true });
+                store.setHighlightCategory("gateways", true);
+            },
+            onLooseHighlight: (store) => {
+                store.updateNode(n.id, { selected: false });
+                store.setHighlightCategory("gateways", false);    
+            },
+        }));
+    });
+    const multipleIngress = apps.filter((n) => n.data != null && n.data.ports != null).flatMap((n) => n.data.ports.map((p): Message | undefined => {
+        const ing = nodes.filter((i) => i.type === "gateway-https").filter((i) => i.data && i.data.https && i.data.https.serviceId === n.id && i.data.https.portId === p.id);
+        if (ing.length < 2) {
+            return undefined;
+        }
+        return {
+            id: `${n.id}-${p.id}-multiple-ingress`,
+            type: "FATAL",
+            nodeId: n.id,
+            message: `Can not expose same port using multiple ingresses: ${p.name} - ${p.value}`,
+            onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+            onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),        
+        };
+    })).filter((m) => m !== undefined);
+    return noName.concat(noSource).concat(noRuntime).concat(noPorts).concat(noIngress).concat(multipleIngress);
+}
+
+function GatewayHTTPSValidator(nodes: AppNode[]): Message[] {
+    const ing = nodes.filter((n) => n.type === "gateway-https");
+    const noNetwork: Message[] = ing.filter((n) => n.data == null || n.data.network == null || n.data.network == "" || n.data.subdomain == null || n.data.subdomain == "").map((n): Message => ({
+        id: `${n.id}-no-network`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Network and subdomain must be defined",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    const notConnected: Message[] = ing.filter((n) => n.data == null || n.data.https == null || n.data.https.serviceId == null || n.data.https.serviceId == "" || n.data.https.portId == null || n.data.https.portId == "").map((n) => ({
+        id: `${n.id}-not-connected`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Connect to a service port",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    return noNetwork.concat(notConnected);
+}
+
+function GatewayTCPValidator(nodes: AppNode[]): Message[] {
+    const ing = nodes.filter((n) => n.type === "gateway-tcp");
+    const noNetwork: Message[] = ing.filter((n) => n.data == null || n.data.network == null || n.data.network == "" || n.data.subdomain == null || n.data.subdomain == "").map((n): Message => ({
+        id: `${n.id}-no-network`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Network and subdomain must be defined",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    const notConnected: Message[] = ing.filter((n) => n.data == null || n.data.exposed == null || n.data.exposed.length === 0).map((n) => ({
+        id: `${n.id}-not-connected`,
+        type: "FATAL",
+        nodeId: n.id,
+        message: "Connect to a service port",
+        onHighlight: (store) => store.updateNode(n.id, { selected: true }),
+        onLooseHighlight: (store) => store.updateNode(n.id, { selected: false }),
+    }));
+    return noNetwork.concat(notConnected);
+}
\ No newline at end of file
