diff --git a/apps/canvas/front/src/lib/state.ts b/apps/canvas/front/src/lib/state.ts
index 2492642..0749fbb 100644
--- a/apps/canvas/front/src/lib/state.ts
+++ b/apps/canvas/front/src/lib/state.ts
@@ -1,275 +1,302 @@
-import { v4 as uuidv4 } from "uuid";
-import { create } from 'zustand';
-import { addEdge, applyNodeChanges, applyEdgeChanges, Connection, EdgeChange, useNodes } from '@xyflow/react';
-import type {
-  Edge,
-  Node,
-  OnNodesChange,
-  OnEdgesChange,
-  OnConnect,
-} from '@xyflow/react';
-import type { DeepPartial } from "react-hook-form";
 import { Category, defaultCategories } from "./categories";
 import { CreateValidators, Validator } from "./config";
+import { GitHubService, GitHubServiceImpl } from "./github";
+import type { Edge, Node, OnConnect, OnEdgesChange, OnNodesChange } from "@xyflow/react";
+import { addEdge, applyEdgeChanges, applyNodeChanges, Connection, EdgeChange, useNodes } from "@xyflow/react";
+import type { DeepPartial } from "react-hook-form";
+import { v4 as uuidv4 } from "uuid";
 import { z } from "zod";
-import { GitHubService, GitHubServiceImpl } from './github';
+import { create } from "zustand";
 
 export type InitData = {
-  label: string;
-  envVars: BoundEnvVar[];
-  ports: Port[];
+	label: string;
+	envVars: BoundEnvVar[];
+	ports: Port[];
 };
 
 export type NodeData = InitData & {
-  activeField?: string | undefined;
-  state: string | null;
+	activeField?: string | undefined;
+	state: string | null;
 };
 
 export type PortConnectedTo = {
-  serviceId: string;
-  portId: string;
-}
+	serviceId: string;
+	portId: string;
+};
 
 export type NetworkData = NodeData & {
-  domain: string;
+	domain: string;
 };
 
 export type NetworkNode = Node<NetworkData> & {
-  type: "network";
+	type: "network";
 };
 
 export type GatewayHttpsData = NodeData & {
-  network?: string;
-  subdomain?: string;
-  https?: PortConnectedTo;
-  auth?: {
-    enabled: boolean;
-    groups: string[];
-    noAuthPathPatterns: string[];
-  }
+	network?: string;
+	subdomain?: string;
+	https?: PortConnectedTo;
+	auth?: {
+		enabled: boolean;
+		groups: string[];
+		noAuthPathPatterns: string[];
+	};
 };
 
 export type GatewayHttpsNode = Node<GatewayHttpsData> & {
-  type: "gateway-https";
+	type: "gateway-https";
 };
 
 export type GatewayTCPData = NodeData & {
-  network?: string;
-  subdomain?: string;
-  exposed: PortConnectedTo[];
-  selected?: {
-    serviceId?: string;
-    portId?: string;
-  };
+	network?: string;
+	subdomain?: string;
+	exposed: PortConnectedTo[];
+	selected?: {
+		serviceId?: string;
+		portId?: string;
+	};
 };
 
 export type GatewayTCPNode = Node<GatewayTCPData> & {
-  type: "gateway-tcp";
+	type: "gateway-tcp";
 };
 
 export type Port = {
-  id: string;
-  name: string;
-  value: number;
+	id: string;
+	name: string;
+	value: number;
 };
 
 export const ServiceTypes = [
-  "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",
-  "node-23.1.0"
+	"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",
+	"node-23.1.0",
 ] as const;
-export type ServiceType = typeof ServiceTypes[number];
+export type ServiceType = (typeof ServiceTypes)[number];
 
 export type ServiceData = NodeData & {
-  type: ServiceType;
-  repository: {
-    id: string;
-  } | {
-    id: string;
-    branch: string;
-  } | {
-    id: string;
-    branch: string;
-    rootDir: string;
-  };
-  env: string[];
-  volume: string[];
-  preBuildCommands: string;
-  isChoosingPortToConnect: boolean;
+	type: ServiceType;
+	repository:
+		| {
+				id: string;
+		  }
+		| {
+				id: string;
+				branch: string;
+		  }
+		| {
+				id: string;
+				branch: string;
+				rootDir: string;
+		  };
+	env: string[];
+	volume: string[];
+	preBuildCommands: string;
+	isChoosingPortToConnect: boolean;
 };
 
 export type ServiceNode = Node<ServiceData> & {
-  type: "app";
+	type: "app";
 };
 
 export type VolumeType = "ReadWriteOnce" | "ReadOnlyMany" | "ReadWriteMany" | "ReadWriteOncePod";
 
 export type VolumeData = NodeData & {
-  type: VolumeType;
-  size: string;
-  attachedTo: string[];
+	type: VolumeType;
+	size: string;
+	attachedTo: string[];
 };
 
 export type VolumeNode = Node<VolumeData> & {
-  type: "volume";
+	type: "volume";
 };
 
 export type PostgreSQLData = NodeData & {
-  volumeId: string;
+	volumeId: string;
 };
 
 export type PostgreSQLNode = Node<PostgreSQLData> & {
-  type: "postgresql";
+	type: "postgresql";
 };
 
 export type MongoDBData = NodeData & {
-  volumeId: string;
+	volumeId: string;
 };
 
 export type MongoDBNode = Node<MongoDBData> & {
-  type: "mongodb";
+	type: "mongodb";
 };
 
 export type GithubData = NodeData & {
-  repository?: {
-    id: number;
-    sshURL: string;
-  };
+	repository?: {
+		id: number;
+		sshURL: string;
+	};
 };
 
 export type GithubNode = Node<GithubData> & {
-  type: "github";
+	type: "github";
 };
 
 export type NANode = Node<NodeData> & {
-  type: undefined;
+	type: undefined;
 };
 
-export type AppNode = NetworkNode | GatewayHttpsNode | GatewayTCPNode | ServiceNode | VolumeNode | PostgreSQLNode | MongoDBNode | GithubNode | NANode;
+export type AppNode =
+	| NetworkNode
+	| GatewayHttpsNode
+	| GatewayTCPNode
+	| ServiceNode
+	| VolumeNode
+	| PostgreSQLNode
+	| MongoDBNode
+	| GithubNode
+	| NANode;
 
 export function nodeLabel(n: AppNode): string {
-  switch (n.type) {
-    case "network": return n.data.domain;
-    case "app": return n.data.label || "Service";
-    case "github": return n.data.repository?.sshURL || "Github";
-    case "gateway-https": {
-      if (n.data && n.data.network && n.data.subdomain) {
-        return `https://${n.data.subdomain}.${n.data.network}`;
-      } else {
-        return "HTTPS Gateway";
-      }
-    }
-    case "gateway-tcp": {
-      if (n.data && n.data.network && n.data.subdomain) {
-        return `${n.data.subdomain}.${n.data.network}`;
-      } else {
-        return "TCP Gateway";
-      }
-    }
-    case "mongodb": return n.data.label || "MongoDB";
-    case "postgresql": return n.data.label || "PostgreSQL";
-    case "volume": return n.data.label || "Volume";
-    case undefined: throw new Error("MUST NOT REACH!");
-  }
+	switch (n.type) {
+		case "network":
+			return n.data.domain;
+		case "app":
+			return n.data.label || "Service";
+		case "github":
+			return n.data.repository?.sshURL || "Github";
+		case "gateway-https": {
+			if (n.data && n.data.network && n.data.subdomain) {
+				return `https://${n.data.subdomain}.${n.data.network}`;
+			} else {
+				return "HTTPS Gateway";
+			}
+		}
+		case "gateway-tcp": {
+			if (n.data && n.data.network && n.data.subdomain) {
+				return `${n.data.subdomain}.${n.data.network}`;
+			} else {
+				return "TCP Gateway";
+			}
+		}
+		case "mongodb":
+			return n.data.label || "MongoDB";
+		case "postgresql":
+			return n.data.label || "PostgreSQL";
+		case "volume":
+			return n.data.label || "Volume";
+		case undefined:
+			throw new Error("MUST NOT REACH!");
+	}
 }
 
 export function nodeIsConnectable(n: AppNode, handle: string): boolean {
-  switch (n.type) {
-    case "network":
-      return true;
-    case "app":
-      if (handle === "ports") {
-        return n.data !== undefined && n.data.ports !== undefined && n.data.ports.length > 0;
-      } else if (handle === "repository") {
-        if (!n.data || !n.data.repository || !n.data.repository.id) {
-          return true;
-        }
-        return false;
-      }
-      return false;
-    case "github":
-      if (n.data.repository?.id !== undefined) {
-        return true;
-      }
-      return false;
-    case "gateway-https":
-      if (handle === "subdomain") {
-        return n.data.network === undefined;
-      }
-      return n.data === undefined || n.data.https === undefined;
-    case "gateway-tcp":
-      if (handle === "subdomain") {
-        return n.data.network === undefined;
-      }
-      return true;
-    case "mongodb":
-      return true;
-    case "postgresql":
-      return true;
-    case "volume":
-      if (n.data === undefined || n.data.type === undefined) {
-        return false;
-      }
-      if (n.data.type === "ReadWriteOnce" || n.data.type === "ReadWriteOncePod") {
-        return n.data.attachedTo === undefined || n.data.attachedTo.length === 0;
-      }
-      return true;
-    case undefined: throw new Error("MUST NOT REACH!");
-  }
+	switch (n.type) {
+		case "network":
+			return true;
+		case "app":
+			if (handle === "ports") {
+				return n.data !== undefined && n.data.ports !== undefined && n.data.ports.length > 0;
+			} else if (handle === "repository") {
+				if (!n.data || !n.data.repository || !n.data.repository.id) {
+					return true;
+				}
+				return false;
+			}
+			return false;
+		case "github":
+			if (n.data.repository?.id !== undefined) {
+				return true;
+			}
+			return false;
+		case "gateway-https":
+			if (handle === "subdomain") {
+				return n.data.network === undefined;
+			}
+			return n.data === undefined || n.data.https === undefined;
+		case "gateway-tcp":
+			if (handle === "subdomain") {
+				return n.data.network === undefined;
+			}
+			return true;
+		case "mongodb":
+			return true;
+		case "postgresql":
+			return true;
+		case "volume":
+			if (n.data === undefined || n.data.type === undefined) {
+				return false;
+			}
+			if (n.data.type === "ReadWriteOnce" || n.data.type === "ReadWriteOncePod") {
+				return n.data.attachedTo === undefined || n.data.attachedTo.length === 0;
+			}
+			return true;
+		case undefined:
+			throw new Error("MUST NOT REACH!");
+	}
 }
 
-export type BoundEnvVar = {
-  id: string;
-  source: string | null;
-} | {
-  id: string;
-  source: string | null;
-  name: string;
-  isEditting: boolean;
-} | {
-  id: string;
-  source: string | null;
-  name: string;
-  alias: string;
-  isEditting: boolean;
-} | {
-  id: string;
-  source: string | null;
-  portId: string;
-  name: string;
-  alias: string;
-  isEditting: boolean;
-};
+export type BoundEnvVar =
+	| {
+			id: string;
+			source: string | null;
+	  }
+	| {
+			id: string;
+			source: string | null;
+			name: string;
+			isEditting: boolean;
+	  }
+	| {
+			id: string;
+			source: string | null;
+			name: string;
+			alias: string;
+			isEditting: boolean;
+	  }
+	| {
+			id: string;
+			source: string | null;
+			portId: string;
+			name: string;
+			alias: string;
+			isEditting: boolean;
+	  };
 
 export type EnvVar = {
-  name: string;
-  value: string;
+	name: string;
+	value: string;
 };
 
 export function nodeEnvVarNamePort(n: AppNode, portName: string): string {
-  return `DODO_SERVICE_${n.data.label.toUpperCase()}_ADDRESS_${portName.toUpperCase()}`;
+	return `DODO_SERVICE_${n.data.label.toUpperCase()}_ADDRESS_${portName.toUpperCase()}`;
 }
 
 export function nodeEnvVarNames(n: AppNode): string[] {
-  switch (n.type) {
-    case "app": return [
-      `DODO_SERVICE_${n.data.label.toUpperCase()}_ADDRESS`,
-      ...(n.data.ports || []).map((p) => nodeEnvVarNamePort(n, p.name)),
-    ];
-    case "github": return [];
-    case "gateway-https": return [];
-    case "gateway-tcp": return [];
-    case "mongodb": return [`DODO_MONGODB_${n.data.label.toUpperCase()}_URL`];
-    case "postgresql": return [`DODO_POSTGRESQL_${n.data.label.toUpperCase()}_URL`];
-    case "volume": return [`DODO_VOLUME_${n.data.label.toUpperCase()}_PATH`];
-    case undefined: throw new Error("MUST NOT REACH");
-    default: throw new Error("MUST NOT REACH");
-  }
+	switch (n.type) {
+		case "app":
+			return [
+				`DODO_SERVICE_${n.data.label.toUpperCase()}_ADDRESS`,
+				...(n.data.ports || []).map((p) => nodeEnvVarNamePort(n, p.name)),
+			];
+		case "github":
+			return [];
+		case "gateway-https":
+			return [];
+		case "gateway-tcp":
+			return [];
+		case "mongodb":
+			return [`DODO_MONGODB_${n.data.label.toUpperCase()}_URL`];
+		case "postgresql":
+			return [`DODO_POSTGRESQL_${n.data.label.toUpperCase()}_URL`];
+		case "volume":
+			return [`DODO_VOLUME_${n.data.label.toUpperCase()}_PATH`];
+		case undefined:
+			throw new Error("MUST NOT REACH");
+		default:
+			throw new Error("MUST NOT REACH");
+	}
 }
 
 export type NodeType = Exclude<Pick<AppNode, "type">["type"], undefined>;
@@ -277,68 +304,72 @@
 export type MessageType = "INFO" | "WARNING" | "FATAL";
 
 export type Message = {
-  id: string;
-  type: MessageType;
-  nodeId?: string;
-  message: string;
-  onHighlight?: (state: AppState) => void;
-  onLooseHighlight?: (state: AppState) => void;
-  onClick?: (state: AppState) => void;
+	id: string;
+	type: MessageType;
+	nodeId?: string;
+	message: string;
+	onHighlight?: (state: AppState) => void;
+	onLooseHighlight?: (state: AppState) => void;
+	onClick?: (state: AppState) => void;
 };
 
 export const envSchema = z.object({
-  deployKey: z.optional(z.string().min(1)),
-  networks: z.array(z.object({
-    name: z.string().min(1),
-    domain: z.string().min(1),
-  })).default([]),
-  integrations: z.object({
-    github: z.boolean(),
-  }),
+	deployKey: z.optional(z.string().min(1)),
+	networks: z
+		.array(
+			z.object({
+				name: z.string().min(1),
+				domain: z.string().min(1),
+			}),
+		)
+		.default([]),
+	integrations: z.object({
+		github: z.boolean(),
+	}),
 });
 
 export type Env = z.infer<typeof envSchema>;
 
 const defaultEnv: Env = {
-  deployKey: undefined,
-  networks: [],
-  integrations: {
-    github: false,
-  }
+	deployKey: undefined,
+	networks: [],
+	integrations: {
+		github: false,
+	},
 };
 
 export type Project = {
-  id: string;
-  name: string;
-}
+	id: string;
+	name: string;
+};
 
 export type IntegrationsConfig = {
-  github: boolean;
+	github: boolean;
 };
 
 type NodeUpdate<T extends NodeType> = DeepPartial<Extract<AppNode, { type: T }>>;
 type NodeDataUpdate<T extends NodeType> = DeepPartial<Extract<AppNode, { type: T }>["data"]>;
 
 export type AppState = {
-  projectId: string | undefined;
-  projects: Project[];
-  nodes: AppNode[];
-  edges: Edge[];
-  categories: Category[];
-  messages: Message[];
-  env: Env;
-  githubService: GitHubService | null;
-  setHighlightCategory: (name: string, active: boolean) => void;
-  onNodesChange: OnNodesChange<AppNode>;
-  onEdgesChange: OnEdgesChange;
-  onConnect: OnConnect;
-  setNodes: (nodes: AppNode[]) => void;
-  setEdges: (edges: Edge[]) => void;
-  setProject: (projectId: string | undefined) => void;
-  updateNode: <T extends NodeType>(id: string, node: NodeUpdate<T>) => void;
-  updateNodeData: <T extends NodeType>(id: string, data: NodeDataUpdate<T>) => void;
-  replaceEdge: (c: Connection, id?: string) => void;
-  refreshEnv: () => Promise<void>;
+	projectId: string | undefined;
+	projects: Project[];
+	nodes: AppNode[];
+	edges: Edge[];
+	categories: Category[];
+	messages: Message[];
+	env: Env;
+	githubService: GitHubService | null;
+	setHighlightCategory: (name: string, active: boolean) => void;
+	onNodesChange: OnNodesChange<AppNode>;
+	onEdgesChange: OnEdgesChange;
+	onConnect: OnConnect;
+	setNodes: (nodes: AppNode[]) => void;
+	setEdges: (edges: Edge[]) => void;
+	setProject: (projectId: string | undefined) => void;
+	updateNode: <T extends NodeType>(id: string, node: NodeUpdate<T>) => void;
+	updateNodeData: <T extends NodeType>(id: string, data: NodeDataUpdate<T>) => void;
+	replaceEdge: (c: Connection, id?: string) => void;
+	refreshEnv: () => Promise<void>;
 };
 
 const projectIdSelector = (state: AppState) => state.projectId;
@@ -348,326 +379,325 @@
 const envSelector = (state: AppState) => state.env;
 
 export function useProjectId(): string | undefined {
-  return useStateStore(projectIdSelector);
+	return useStateStore(projectIdSelector);
 }
 
 export function useCategories(): Category[] {
-  return useStateStore(categoriesSelector);
+	return useStateStore(categoriesSelector);
 }
 
 export function useMessages(): Message[] {
-  return useStateStore(messagesSelector);
+	return useStateStore(messagesSelector);
 }
 
 export function useNodeMessages(id: string): Message[] {
-  return useMessages().filter((m) => m.nodeId === id);
+	return useMessages().filter((m) => m.nodeId === id);
 }
 
 export function useNodeLabel(id: string): string {
-  return nodeLabel(useNodes<AppNode>().find((n) => n.id === id)!);
+	return nodeLabel(useNodes<AppNode>().find((n) => n.id === id)!);
 }
 
 export function useNodePortName(id: string, portId: string): string {
-  return (useNodes<AppNode>().find((n) => n.id === id)!.data.ports || []).find((p) => p.id === portId)!.name;
+	return (useNodes<AppNode>().find((n) => n.id === id)!.data.ports || []).find((p) => p.id === portId)!.name;
 }
 
 export function useEnv(): Env {
-  return useStateStore(envSelector);
+	return useStateStore(envSelector);
 }
 
 export function useGithubService(): GitHubService | null {
-  return useStateStore(githubServiceSelector);
+	return useStateStore(githubServiceSelector);
 }
 
 const v: Validator = CreateValidators();
 
 export const useStateStore = create<AppState>((set, get): AppState => {
-  const setN = (nodes: AppNode[]) => {
-    set((state) => ({
-      ...state,
-      nodes,
-    }));
-  };
+	const setN = (nodes: AppNode[]) => {
+		set((state) => ({
+			...state,
+			nodes,
+		}));
+	};
 
-  function updateNodeData<T extends NodeType>(id: string, data: NodeDataUpdate<T>): void {
-    setN(
-      get().nodes.map((n) => {
-        if (n.id === id) {
-          return {
-            ...n,
-            data: {
-              ...n.data,
-              ...data,
-            },
-          } as Extract<AppNode, { type: T }>;
-        }
-        return n;
-      })
-    );
-  }
+	function updateNodeData<T extends NodeType>(id: string, data: NodeDataUpdate<T>): void {
+		setN(
+			get().nodes.map((n) => {
+				if (n.id === id) {
+					return {
+						...n,
+						data: {
+							...n.data,
+							...data,
+						},
+					} as Extract<AppNode, { type: T }>;
+				}
+				return n;
+			}),
+		);
+	}
 
-  function updateNode<T extends NodeType>(id: string, node: NodeUpdate<T>): void {
-    setN(
-      get().nodes.map((n) => {
-        if (n.id === id) {
-          return {
-            ...n,
-            ...node,
-          } as Extract<AppNode, { type: T }>;
-        }
-        return n;
-      })
-    );
-  }
+	function updateNode<T extends NodeType>(id: string, node: NodeUpdate<T>): void {
+		setN(
+			get().nodes.map((n) => {
+				if (n.id === id) {
+					return {
+						...n,
+						...node,
+					} as Extract<AppNode, { type: T }>;
+				}
+				return n;
+			}),
+		);
+	}
 
-  function onConnect(c: Connection) {
-    const { nodes, edges } = get();
-    set({
-      edges: addEdge(c, edges),
-    });
-    const sn = nodes.filter((n) => n.id === c.source)[0]!;
-    const tn = nodes.filter((n) => n.id === c.target)[0]!;
-    if (tn.type === "network") {
-      if (sn.type === "gateway-https") {
-        updateNodeData<"gateway-https">(sn.id, {
-          network: tn.data.domain,
-        });
-      } else if (sn.type === "gateway-tcp") {
-        updateNodeData<"gateway-tcp">(sn.id, {
-          network: tn.data.domain,
-        });
-      }
-    }
-    if (tn.type === "app") {
-      if (c.sourceHandle === "env_var" && c.targetHandle === "env_var") {
-        const sourceEnvVars = nodeEnvVarNames(sn);
-        if (sourceEnvVars.length === 0) {
-          throw new Error("MUST NOT REACH!");
-        }
-        const id = uuidv4();
-        if (sourceEnvVars.length === 1) {
-          updateNode<"app">(c.target, {
-            ...tn,
-            data: {
-              ...tn.data,
-              envVars: [
-                ...(tn.data.envVars || []),
-                {
-                  id: id,
-                  source: c.source,
-                  name: sourceEnvVars[0],
-                  isEditting: false,
-                },
-              ],
-            },
-          });
-        } else {
-          updateNode<"app">(c.target, {
-            ...tn,
-            data: {
-              ...tn.data,
-              envVars: [
-                ...(tn.data.envVars || []),
-                {
-                  id: id,
-                  source: c.source,
-                },
-              ],
-            },
-          });
-        }
-      }
-      if (c.sourceHandle === "ports" && c.targetHandle === "env_var") {
-        const sourcePorts = sn.data.ports || [];
-        const id = uuidv4();
-        if (sourcePorts.length === 1) {
-          updateNode<"app">(c.target, {
-            ...tn,
-            data: {
-              ...tn.data,
-              envVars: [
-                ...(tn.data.envVars || []),
-                {
-                  id: id,
-                  source: c.source,
-                  name: nodeEnvVarNamePort(sn, sourcePorts[0].name),
-                  portId: sourcePorts[0].id,
-                  isEditting: false,
-                },
-              ],
-            },
-          });
-        }
-      }
-    }
-    if (c.sourceHandle === "volume") {
-      updateNodeData<"volume">(c.source, {
-        attachedTo: ((sn as VolumeNode).data.attachedTo || []).concat(c.source),
-      });
-    }
-    if (c.targetHandle === "volume") {
-      if (tn.type === "postgresql" || tn.type === "mongodb") {
-        updateNodeData(c.target, {
-          volumeId: c.source,
-        });
-      }
-    }
-    if (c.targetHandle === "https") {
-      if ((sn.data.ports || []).length === 1) {
-        updateNodeData<"gateway-https">(c.target, {
-          https: {
-            serviceId: c.source,
-            portId: sn.data.ports![0].id,
-          }
-        });
-      } else {
-        updateNodeData<"gateway-https">(c.target, {
-          https: {
-            serviceId: c.source,
-            portId: "", // TODO(gio)
-          }
-        });
-      }
-    }
-    if (c.targetHandle === "tcp") {
-      const td = tn.data as GatewayTCPData;
-      if ((sn.data.ports || []).length === 1) {
-        updateNodeData<"gateway-tcp">(c.target, {
-          exposed: (td.exposed || []).concat({
-            serviceId: c.source,
-            portId: sn.data.ports![0].id,
-          }),
-        });
-      } else {
-        updateNodeData<"gateway-tcp">(c.target, {
-          selected: {
-            serviceId: c.source,
-            portId: undefined,
-          },
-        });
-      }
-    }
-    if (sn.type === "app") {
-      if (c.sourceHandle === "ports") {
-        updateNodeData<"app">(sn.id, {
-          isChoosingPortToConnect: true,
-        });
-      }
-    }
-    if (tn.type === "app") {
-      if (c.targetHandle === "repository") {
-        updateNodeData<"app">(tn.id, {
-          repository: {
-            id: c.source,
-            branch: "master",
-            rootDir: "/",
-          }
-        });
-      }
-    }
-  }
-  return {
-    projectId: undefined,
-    projects: [],
-    nodes: [],
-    edges: [],
-    categories: defaultCategories,
-    messages: v([]),
-    env: defaultEnv,
-    githubService: null,
-    setHighlightCategory: (name, active) => {
-      set({
-        categories: get().categories.map(
-          (c) => {
-            if (c.title.toLowerCase() !== name.toLowerCase()) {
-              return c;
-            } else {
-              return {
-                ...c,
-                active,
-              }
-            }
-          })
-      });
-    },
-    onNodesChange: (changes) => {
-      const nodes = applyNodeChanges(changes, get().nodes);
-      setN(nodes);
-    },
-    onEdgesChange: (changes) => {
-      set({
-        edges: applyEdgeChanges(changes, get().edges),
-      });
-    },
-    setNodes: (nodes) => {
-      setN(nodes);
-    },
-    setEdges: (edges) => {
-      set({ edges });
-    },
-    replaceEdge: (c, id) => {
-      let change: EdgeChange;
-      if (id === undefined) {
-        change = {
-          type: "add",
-          item: {
-            id: uuidv4(),
-            ...c,
-          }
-        };
-        onConnect(c);
-      } else {
-        change = {
-          type: "replace",
-          id,
-          item: {
-            id,
-            ...c,
-          }
-        };
-      }
-      set({
-        edges: applyEdgeChanges([change], get().edges),
-      })
-    },
-    updateNode,
-    updateNodeData,
-    onConnect,
-    refreshEnv: async () => {
-      const projectId = get().projectId;
-      let env: Env = defaultEnv;
+	function onConnect(c: Connection) {
+		const { nodes, edges } = get();
+		set({
+			edges: addEdge(c, edges),
+		});
+		const sn = nodes.filter((n) => n.id === c.source)[0]!;
+		const tn = nodes.filter((n) => n.id === c.target)[0]!;
+		if (tn.type === "network") {
+			if (sn.type === "gateway-https") {
+				updateNodeData<"gateway-https">(sn.id, {
+					network: tn.data.domain,
+				});
+			} else if (sn.type === "gateway-tcp") {
+				updateNodeData<"gateway-tcp">(sn.id, {
+					network: tn.data.domain,
+				});
+			}
+		}
+		if (tn.type === "app") {
+			if (c.sourceHandle === "env_var" && c.targetHandle === "env_var") {
+				const sourceEnvVars = nodeEnvVarNames(sn);
+				if (sourceEnvVars.length === 0) {
+					throw new Error("MUST NOT REACH!");
+				}
+				const id = uuidv4();
+				if (sourceEnvVars.length === 1) {
+					updateNode<"app">(c.target, {
+						...tn,
+						data: {
+							...tn.data,
+							envVars: [
+								...(tn.data.envVars || []),
+								{
+									id: id,
+									source: c.source,
+									name: sourceEnvVars[0],
+									isEditting: false,
+								},
+							],
+						},
+					});
+				} else {
+					updateNode<"app">(c.target, {
+						...tn,
+						data: {
+							...tn.data,
+							envVars: [
+								...(tn.data.envVars || []),
+								{
+									id: id,
+									source: c.source,
+								},
+							],
+						},
+					});
+				}
+			}
+			if (c.sourceHandle === "ports" && c.targetHandle === "env_var") {
+				const sourcePorts = sn.data.ports || [];
+				const id = uuidv4();
+				if (sourcePorts.length === 1) {
+					updateNode<"app">(c.target, {
+						...tn,
+						data: {
+							...tn.data,
+							envVars: [
+								...(tn.data.envVars || []),
+								{
+									id: id,
+									source: c.source,
+									name: nodeEnvVarNamePort(sn, sourcePorts[0].name),
+									portId: sourcePorts[0].id,
+									isEditting: false,
+								},
+							],
+						},
+					});
+				}
+			}
+		}
+		if (c.sourceHandle === "volume") {
+			updateNodeData<"volume">(c.source, {
+				attachedTo: ((sn as VolumeNode).data.attachedTo || []).concat(c.source),
+			});
+		}
+		if (c.targetHandle === "volume") {
+			if (tn.type === "postgresql" || tn.type === "mongodb") {
+				updateNodeData(c.target, {
+					volumeId: c.source,
+				});
+			}
+		}
+		if (c.targetHandle === "https") {
+			if ((sn.data.ports || []).length === 1) {
+				updateNodeData<"gateway-https">(c.target, {
+					https: {
+						serviceId: c.source,
+						portId: sn.data.ports![0].id,
+					},
+				});
+			} else {
+				updateNodeData<"gateway-https">(c.target, {
+					https: {
+						serviceId: c.source,
+						portId: "", // TODO(gio)
+					},
+				});
+			}
+		}
+		if (c.targetHandle === "tcp") {
+			const td = tn.data as GatewayTCPData;
+			if ((sn.data.ports || []).length === 1) {
+				updateNodeData<"gateway-tcp">(c.target, {
+					exposed: (td.exposed || []).concat({
+						serviceId: c.source,
+						portId: sn.data.ports![0].id,
+					}),
+				});
+			} else {
+				updateNodeData<"gateway-tcp">(c.target, {
+					selected: {
+						serviceId: c.source,
+						portId: undefined,
+					},
+				});
+			}
+		}
+		if (sn.type === "app") {
+			if (c.sourceHandle === "ports") {
+				updateNodeData<"app">(sn.id, {
+					isChoosingPortToConnect: true,
+				});
+			}
+		}
+		if (tn.type === "app") {
+			if (c.targetHandle === "repository") {
+				updateNodeData<"app">(tn.id, {
+					repository: {
+						id: c.source,
+						branch: "master",
+						rootDir: "/",
+					},
+				});
+			}
+		}
+	}
+	return {
+		projectId: undefined,
+		projects: [],
+		nodes: [],
+		edges: [],
+		categories: defaultCategories,
+		messages: v([]),
+		env: defaultEnv,
+		githubService: null,
+		setHighlightCategory: (name, active) => {
+			set({
+				categories: get().categories.map((c) => {
+					if (c.title.toLowerCase() !== name.toLowerCase()) {
+						return c;
+					} else {
+						return {
+							...c,
+							active,
+						};
+					}
+				}),
+			});
+		},
+		onNodesChange: (changes) => {
+			const nodes = applyNodeChanges(changes, get().nodes);
+			setN(nodes);
+		},
+		onEdgesChange: (changes) => {
+			set({
+				edges: applyEdgeChanges(changes, get().edges),
+			});
+		},
+		setNodes: (nodes) => {
+			setN(nodes);
+		},
+		setEdges: (edges) => {
+			set({ edges });
+		},
+		replaceEdge: (c, id) => {
+			let change: EdgeChange;
+			if (id === undefined) {
+				change = {
+					type: "add",
+					item: {
+						id: uuidv4(),
+						...c,
+					},
+				};
+				onConnect(c);
+			} else {
+				change = {
+					type: "replace",
+					id,
+					item: {
+						id,
+						...c,
+					},
+				};
+			}
+			set({
+				edges: applyEdgeChanges([change], get().edges),
+			});
+		},
+		updateNode,
+		updateNodeData,
+		onConnect,
+		refreshEnv: async () => {
+			const projectId = get().projectId;
+			let env: Env = defaultEnv;
 
-      try {
-        if (projectId) {
-          const response = await fetch(`/api/project/${projectId}/env`);
-          if (response.ok) {
-            const data = await response.json();
-            const result = envSchema.safeParse(data);
-            if (result.success) {
-              env = result.data;
-            } else {
-              console.error("Invalid env data:", result.error);
-            }
-          }
-        }
-      } catch (error) {
-        console.error("Failed to fetch integrations:", error);
-      } finally {
-        set({ env: env });
-        if (env.integrations.github) {
-          set({ githubService: new GitHubServiceImpl(projectId!) });
-        } else {
-          set({ githubService: null });
-        }
-      }
-    },
-    setProject: (projectId) => {
-      set({
-        projectId,
-      });
-      if (projectId) {
-        get().refreshEnv();
-      }
-    },
-  };
+			try {
+				if (projectId) {
+					const response = await fetch(`/api/project/${projectId}/env`);
+					if (response.ok) {
+						const data = await response.json();
+						const result = envSchema.safeParse(data);
+						if (result.success) {
+							env = result.data;
+						} else {
+							console.error("Invalid env data:", result.error);
+						}
+					}
+				}
+			} catch (error) {
+				console.error("Failed to fetch integrations:", error);
+			} finally {
+				set({ env: env });
+				if (env.integrations.github) {
+					set({ githubService: new GitHubServiceImpl(projectId!) });
+				} else {
+					set({ githubService: null });
+				}
+			}
+		},
+		setProject: (projectId) => {
+			set({
+				projectId,
+			});
+			if (projectId) {
+				get().refreshEnv();
+			}
+		},
+	};
 });
