diff --git a/.gitignore b/.gitignore index 36f85dc78e..0c89564230 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules .next +.yarn ### NextJS ### # Dependencies diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 0000000000..3186f3f079 --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 68ef89085d..03d667f4ae 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,11 +35,12 @@ This helps us triage and manage issues more efficiently. ### Requirements -- Node.js version v16.18.0 +- Docker Engine installed and running +- Node.js version 20+ [LTS version](https://nodejs.org/en/about/previous-releases) - Python version 3.8+ - Postgres version v14 - Redis version v6.2.7 -- **Memory**: Minimum **12 GB RAM** recommended +- **Memory**: Minimum **12 GB RAM** recommended > ⚠️ Running the project on a system with only 8 GB RAM may lead to setup failures or memory crashes (especially during Docker container build/start or dependency install). Use cloud environments like GitHub Codespaces or upgrade local RAM if possible. ### Setup the project @@ -68,6 +69,17 @@ chmod +x setup.sh docker compose -f docker-compose-local.yml up ``` +5. Start web apps: + +```bash +yarn dev +``` + +6. Open your browser to http://localhost:3001/god-mode/ and register yourself as instance admin +7. Open up your browser to http://localhost:3000 then log in using the same credentials from the previous step + +That’s it! You’re all set to begin coding. Remember to refresh your browser if changes don’t auto-reload. Happy contributing! 🎉 + ## Missing a Feature? If a feature is missing, you can directly _request_ a new one [here](https://github.com/makeplane/plane/issues/new?assignees=&labels=feature&template=feature_request.yml&title=%F0%9F%9A%80+Feature%3A+). You also can do the same by choosing "🚀 Feature" when raising a [New Issue](https://github.com/makeplane/plane/issues/new/choose) on our GitHub Repository. @@ -93,7 +105,7 @@ To ensure consistency throughout the source code, please keep these rules in min - **Improve documentation** - fix incomplete or missing [docs](https://docs.plane.so/), bad wording, examples or explanations. ## Contributing to language support -This guide is designed to help contributors understand how to add or update translations in the application. +This guide is designed to help contributors understand how to add or update translations in the application. ### Understanding translation structure @@ -108,7 +120,7 @@ packages/i18n/src/locales/ ├── fr/ │ └── translations.json └── [language]/ - └── translations.json + └── translations.json ``` #### Nested structure To keep translations organized, we use a nested structure for keys. This makes it easier to manage and locate specific translations. For example: @@ -128,14 +140,14 @@ To keep translations organized, we use a nested structure for keys. This makes i We use [IntlMessageFormat](https://formatjs.github.io/docs/intl-messageformat/) to handle dynamic content, such as variables and pluralization. Here's how to format your translations: #### Examples -- **Simple variables** +- **Simple variables** ```json { "greeting": "Hello, {name}!" } ``` -- **Pluralization** +- **Pluralization** ```json { "items": "{count, plural, one {Work item} other {Work items}}" @@ -160,15 +172,15 @@ We use [IntlMessageFormat](https://formatjs.github.io/docs/intl-messageformat/) ### Adding new languages Adding a new language involves several steps to ensure it integrates seamlessly with the project. Follow these instructions carefully: -1. **Update type definitions** +1. **Update type definitions** Add the new language to the TLanguage type in the language definitions file: ```typescript // types/language.ts export type TLanguage = "en" | "fr" | "your-lang"; - ``` + ``` -2. **Add language configuration** +2. **Add language configuration** Include the new language in the list of supported languages: ```typescript @@ -179,14 +191,14 @@ Include the new language in the list of supported languages: ]; ``` -3. **Create translation files** +3. **Create translation files** 1. Create a new folder for your language under locales (e.g., `locales/your-lang/`). 2. Add a `translations.json` file inside the folder. 3. Copy the structure from an existing translation file and translate all keys. -4. **Update import logic** +4. **Update import logic** Modify the language import logic to include your new language: ```typescript diff --git a/README.md b/README.md index dad8b45588..da57f38d86 100644 --- a/README.md +++ b/README.md @@ -47,10 +47,10 @@ Meet [Plane](https://plane.so/), an open-source project management tool to track Getting started with Plane is simple. Choose the setup that works best for you: -- **Plane Cloud** +- **Plane Cloud** Sign up for a free account on [Plane Cloud](https://app.plane.so)—it's the fastest way to get up and running without worrying about infrastructure. -- **Self-host Plane** +- **Self-host Plane** Prefer full control over your data and infrastructure? Install and run Plane on your own servers. Follow our detailed [deployment guides](https://developers.plane.so/self-hosting/overview) to get started. | Installation methods | Docs link | @@ -62,22 +62,22 @@ Prefer full control over your data and infrastructure? Install and run Plane on ## 🌟 Features -- **Issues** +- **Issues** Efficiently create and manage tasks with a robust rich text editor that supports file uploads. Enhance organization and tracking by adding sub-properties and referencing related issues. -- **Cycles** +- **Cycles** Maintain your team’s momentum with Cycles. Track progress effortlessly using burn-down charts and other insightful tools. -- **Modules** -Simplify complex projects by dividing them into smaller, manageable modules. +- **Modules** +Simplify complex projects by dividing them into smaller, manageable modules. -- **Views** +- **Views** Customize your workflow by creating filters to display only the most relevant issues. Save and share these views with ease. -- **Pages** +- **Pages** Capture and organize ideas using Plane Pages, complete with AI capabilities and a rich text editor. Format text, insert images, add hyperlinks, or convert your notes into actionable items. -- **Analytics** +- **Analytics** Access real-time insights across all your Plane data. Visualize trends, remove blockers, and keep your projects moving forward. - **Drive** (_coming soon_): The drive helps you share documents, images, videos, or any other files that make sense to you or your team and align on the problem/solution. @@ -85,38 +85,7 @@ Access real-time insights across all your Plane data. Visualize trends, remove b ## 🛠️ Local development -### Pre-requisites -- Ensure Docker Engine is installed and running. - -### Development setup -Setting up your local environment is simple and straightforward. Follow these steps to get started: - -1. Clone the repository: - ``` - git clone https://github.com/makeplane/plane.git - ``` -2. Navigate to the project folder: - ``` - cd plane - ``` -3. Create a new branch for your feature or fix: - ``` - git checkout -b - ``` -4. Run the setup script in the terminal: - ``` - ./setup.sh - ``` -5. Open the project in an IDE such as VS Code. - -6. Review the `.env` files in the relevant folders. Refer to [Environment Setup](./ENV_SETUP.md) for details on the environment variables used. - -7. Start the services using Docker: - ``` - docker compose -f docker-compose-local.yml up -d - ``` - -That’s it! You’re all set to begin coding. Remember to refresh your browser if changes don’t auto-reload. Happy contributing! 🎉 +See [CONTRIBUTING](./CONTRIBUTING.md) ## ⚙️ Built with [![Next JS](https://img.shields.io/badge/next.js-000000?style=for-the-badge&logo=nextdotjs&logoColor=white)](https://nextjs.org/) @@ -194,7 +163,7 @@ Feel free to ask questions, report bugs, participate in discussions, share ideas If you discover a security vulnerability in Plane, please report it responsibly instead of opening a public issue. We take all legitimate reports seriously and will investigate them promptly. See [Security policy](https://github.com/makeplane/plane/blob/master/SECURITY.md) for more info. -To disclose any security issues, please email us at security@plane.so. +To disclose any security issues, please email us at security@plane.so. ## 🤝 Contributing @@ -219,4 +188,4 @@ Please read [CONTRIBUTING.md](https://github.com/makeplane/plane/blob/master/CON ## License -This project is licensed under the [GNU Affero General Public License v3.0](https://github.com/makeplane/plane/blob/master/LICENSE.txt). \ No newline at end of file +This project is licensed under the [GNU Affero General Public License v3.0](https://github.com/makeplane/plane/blob/master/LICENSE.txt). diff --git a/admin/.env.example b/admin/.env.example index fdeb05c4d7..15d7a36a9d 100644 --- a/admin/.env.example +++ b/admin/.env.example @@ -1,3 +1,12 @@ -NEXT_PUBLIC_API_BASE_URL="" +NEXT_PUBLIC_API_BASE_URL="http://localhost:8000" + +NEXT_PUBLIC_WEB_BASE_URL="http://localhost:3000" + +NEXT_PUBLIC_ADMIN_BASE_URL="http://localhost:3001" NEXT_PUBLIC_ADMIN_BASE_PATH="/god-mode" -NEXT_PUBLIC_WEB_BASE_URL="" \ No newline at end of file + +NEXT_PUBLIC_SPACE_BASE_URL="http://localhost:3002" +NEXT_PUBLIC_SPACE_BASE_PATH="/spaces" + +NEXT_PUBLIC_LIVE_BASE_URL="http://localhost:3100" +NEXT_PUBLIC_LIVE_BASE_PATH="/live" diff --git a/admin/package.json b/admin/package.json index a809ef1b13..9a7bff0058 100644 --- a/admin/package.json +++ b/admin/package.json @@ -17,10 +17,10 @@ "@headlessui/react": "^1.7.19", "@plane/constants": "*", "@plane/hooks": "*", + "@plane/services": "*", "@plane/types": "*", "@plane/ui": "*", "@plane/utils": "*", - "@plane/services": "*", "@tailwindcss/typography": "^0.5.9", "@types/lodash": "^4.17.0", "autoprefixer": "10.4.14", diff --git a/apiserver/.env.example b/apiserver/.env.example index b56494c356..7fdffd1793 100644 --- a/apiserver/.env.example +++ b/apiserver/.env.example @@ -1,7 +1,7 @@ # Backend # Debug value for api server use it as 0 for production use DEBUG=0 -CORS_ALLOWED_ORIGINS="http://localhost" +CORS_ALLOWED_ORIGINS="http://localhost:3000,http://localhost:3001,http://localhost:3002,http://localhost:3100" # Database Settings POSTGRES_USER="plane" @@ -27,7 +27,7 @@ RABBITMQ_VHOST="plane" AWS_REGION="" AWS_ACCESS_KEY_ID="access-key" AWS_SECRET_ACCESS_KEY="secret-key" -AWS_S3_ENDPOINT_URL="http://plane-minio:9000" +AWS_S3_ENDPOINT_URL="http://localhost:9000" # Changing this requires change in the nginx.conf for uploads if using minio setup AWS_S3_BUCKET_NAME="uploads" # Maximum file upload limit @@ -37,22 +37,31 @@ FILE_SIZE_LIMIT=5242880 DOCKERIZED=1 # deprecated # set to 1 If using the pre-configured minio setup -USE_MINIO=1 +USE_MINIO=0 # Nginx Configuration NGINX_PORT=80 # Email redirections and minio domain settings -WEB_URL="http://localhost" +WEB_URL="http://localhost:8000" # Gunicorn Workers GUNICORN_WORKERS=2 # Base URLs -ADMIN_BASE_URL= -SPACE_BASE_URL= -APP_BASE_URL= +ADMIN_BASE_URL="http://localhost:3001" +ADMIN_BASE_PATH="/god-mode" +SPACE_BASE_URL="http://localhost:3002" +SPACE_BASE_PATH="/spaces" + +APP_BASE_URL="http://localhost:3000" +APP_BASE_PATH="" + +LIVE_BASE_URL="http://localhost:3100" +LIVE_BASE_PATH="/live" + +LIVE_SERVER_SECRET_KEY="secret-key" # Hard delete files after days HARD_DELETE_AFTER_DAYS=60 diff --git a/apiserver/plane/authentication/utils/host.py b/apiserver/plane/authentication/utils/host.py index c4625279c4..64f1916859 100644 --- a/apiserver/plane/authentication/utils/host.py +++ b/apiserver/plane/authentication/utils/host.py @@ -14,17 +14,29 @@ def base_host(request: Request | HttpRequest, is_admin: bool = False, is_space: # Admin redirections if is_admin: + admin_base_path = getattr(settings, "ADMIN_BASE_PATH", "/god-mode/") + if not admin_base_path.startswith("/"): + admin_base_path = "/" + admin_base_path + if not admin_base_path.endswith("/"): + admin_base_path += "/" + if settings.ADMIN_BASE_URL: - return settings.ADMIN_BASE_URL + return settings.ADMIN_BASE_URL + admin_base_path else: - return base_origin + "/god-mode/" + return base_origin + admin_base_path # Space redirections if is_space: + space_base_path = getattr(settings, "SPACE_BASE_PATH", "/spaces/") + if not space_base_path.startswith("/"): + space_base_path = "/" + space_base_path + if not space_base_path.endswith("/"): + space_base_path += "/" + if settings.SPACE_BASE_URL: - return settings.SPACE_BASE_URL + return settings.SPACE_BASE_URL + space_base_path else: - return base_origin + "/spaces/" + return base_origin + space_base_path # App Redirection if is_app: diff --git a/apiserver/plane/settings/common.py b/apiserver/plane/settings/common.py index 76db7a928a..86a5921285 100644 --- a/apiserver/plane/settings/common.py +++ b/apiserver/plane/settings/common.py @@ -312,9 +312,13 @@ CSRF_FAILURE_VIEW = "plane.authentication.views.common.csrf_failure" # Base URLs ADMIN_BASE_URL = os.environ.get("ADMIN_BASE_URL", None) +ADMIN_BASE_PATH = os.environ.get("ADMIN_BASE_PATH", None) SPACE_BASE_URL = os.environ.get("SPACE_BASE_URL", None) +SPACE_BASE_PATH = os.environ.get("SPACE_BASE_PATH", None) APP_BASE_URL = os.environ.get("APP_BASE_URL") +APP_BASE_PATH = os.environ.get("APP_BASE_PATH", None) LIVE_BASE_URL = os.environ.get("LIVE_BASE_URL") +LIVE_BASE_PATH = os.environ.get("LIVE_BASE_PATH") WEB_URL = os.environ.get("WEB_URL") HARD_DELETE_AFTER_DAYS = int(os.environ.get("HARD_DELETE_AFTER_DAYS", 60)) diff --git a/apiserver/plane/utils/host.py b/apiserver/plane/utils/host.py index c4914d7ffb..7c8635836f 100644 --- a/apiserver/plane/utils/host.py +++ b/apiserver/plane/utils/host.py @@ -19,17 +19,29 @@ def base_host(request: Request | HttpRequest, is_admin: bool = False, is_space: # Admin redirections if is_admin: + admin_base_path = getattr(settings, "ADMIN_BASE_PATH", "/god-mode/") + if not admin_base_path.startswith("/"): + admin_base_path = "/" + admin_base_path + if not admin_base_path.endswith("/"): + admin_base_path += "/" + if settings.ADMIN_BASE_URL: - return settings.ADMIN_BASE_URL + return settings.ADMIN_BASE_URL + admin_base_path else: - return base_origin + "/god-mode/" + return base_origin + admin_base_path # Space redirections if is_space: + space_base_path = getattr(settings, "SPACE_BASE_PATH", "/spaces/") + if not space_base_path.startswith("/"): + space_base_path = "/" + space_base_path + if not space_base_path.endswith("/"): + space_base_path += "/" + if settings.SPACE_BASE_URL: - return settings.SPACE_BASE_URL + return settings.SPACE_BASE_URL + space_base_path else: - return base_origin + "/spaces/" + return base_origin + space_base_path # App Redirection if is_app: diff --git a/docker-compose-local.yml b/docker-compose-local.yml index 392c55a113..86457615a9 100644 --- a/docker-compose-local.yml +++ b/docker-compose-local.yml @@ -6,6 +6,8 @@ services: - dev_env volumes: - redisdata:/data + ports: + - "6379:6379" plane-mq: image: rabbitmq:3.13.6-management-alpine @@ -26,7 +28,15 @@ services: restart: unless-stopped networks: - dev_env - command: server /export --console-address ":9090" + entrypoint: > + /bin/sh -c " + mkdir -p /export/${AWS_S3_BUCKET_NAME} && + minio server /export --console-address ':9090' & + sleep 5 && + mc alias set myminio http://localhost:9000 ${AWS_ACCESS_KEY_ID} ${AWS_SECRET_ACCESS_KEY} && + mc mb myminio/${AWS_S3_BUCKET_NAME} -p || true + && tail -f /dev/null + " volumes: - uploads:/export env_file: @@ -34,6 +44,9 @@ services: environment: MINIO_ROOT_USER: ${AWS_ACCESS_KEY_ID} MINIO_ROOT_PASSWORD: ${AWS_SECRET_ACCESS_KEY} + ports: + - "9000:9000" + - "9090:9090" plane-db: image: postgres:15.7-alpine @@ -47,63 +60,65 @@ services: - .env environment: PGDATA: /var/lib/postgresql/data + ports: + - "5432:5432" - web: - build: - context: . - dockerfile: ./web/Dockerfile.dev - restart: unless-stopped - networks: - - dev_env - volumes: - - ./web:/app/web - env_file: - - ./web/.env - depends_on: - - api - - worker + # web: + # build: + # context: . + # dockerfile: ./web/Dockerfile.dev + # restart: unless-stopped + # networks: + # - dev_env + # volumes: + # - ./web:/app/web + # env_file: + # - ./web/.env + # depends_on: + # - api + # - worker - space: - build: - context: . - dockerfile: ./space/Dockerfile.dev - restart: unless-stopped - networks: - - dev_env - volumes: - - ./space:/app/space - depends_on: - - api - - worker - - web + # space: + # build: + # context: . + # dockerfile: ./space/Dockerfile.dev + # restart: unless-stopped + # networks: + # - dev_env + # volumes: + # - ./space:/app/space + # depends_on: + # - api + # - worker + # - web - admin: - build: - context: . - dockerfile: ./admin/Dockerfile.dev - restart: unless-stopped - networks: - - dev_env - volumes: - - ./admin:/app/admin - depends_on: - - api - - worker - - web + # admin: + # build: + # context: . + # dockerfile: ./admin/Dockerfile.dev + # restart: unless-stopped + # networks: + # - dev_env + # volumes: + # - ./admin:/app/admin + # depends_on: + # - api + # - worker + # - web - live: - build: - context: . - dockerfile: ./live/Dockerfile.dev - restart: unless-stopped - networks: - - dev_env - volumes: - - ./live:/app/live - depends_on: - - api - - worker - - web + # live: + # build: + # context: . + # dockerfile: ./live/Dockerfile.dev + # restart: unless-stopped + # networks: + # - dev_env + # volumes: + # - ./live:/app/live + # depends_on: + # - api + # - worker + # - web api: build: @@ -122,6 +137,9 @@ services: depends_on: - plane-db - plane-redis + - plane-mq + ports: + - "8000:8000" worker: build: @@ -179,25 +197,25 @@ services: - plane-db - plane-redis - proxy: - build: - context: ./nginx - dockerfile: Dockerfile.dev - restart: unless-stopped - networks: - - dev_env - ports: - - ${NGINX_PORT}:80 - env_file: - - .env - environment: - FILE_SIZE_LIMIT: ${FILE_SIZE_LIMIT:-5242880} - BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-uploads} - depends_on: - - web - - api - - space - - admin + # proxy: + # build: + # context: ./nginx + # dockerfile: Dockerfile.dev + # restart: unless-stopped + # networks: + # - dev_env + # ports: + # - ${NGINX_PORT}:80 + # env_file: + # - .env + # environment: + # FILE_SIZE_LIMIT: ${FILE_SIZE_LIMIT:-5242880} + # BUCKET_NAME: ${AWS_S3_BUCKET_NAME:-uploads} + # depends_on: + # - api + # - web + # - space + # - admin volumes: redisdata: diff --git a/live/.env.example b/live/.env.example index 3203db8479..064258253f 100644 --- a/live/.env.example +++ b/live/.env.example @@ -1,8 +1,13 @@ -API_BASE_URL="http://api:8000" +API_BASE_URL="http://localhost:8000" + +WEB_BASE_URL="http://localhost:3000" + +LIVE_BASE_URL="http://localhost:3100" LIVE_BASE_PATH="/live" -REDIS_URL="redis://plane-redis:6379/" +LIVE_SERVER_SECRET_KEY="secret-key" # If you prefer not to provide a Redis URL, you can set the REDIS_HOST and REDIS_PORT environment variables instead. REDIS_PORT=6379 -REDIS_HOST=plane-redis \ No newline at end of file +REDIS_HOST=localhost +REDIS_URL="redis://localhost:6379/" diff --git a/packages/decorators/package.json b/packages/decorators/package.json index 92c49b9690..433b5c11a4 100644 --- a/packages/decorators/package.json +++ b/packages/decorators/package.json @@ -17,15 +17,15 @@ "lint:errors": "eslint src --ext .ts,.tsx --quiet" }, "dependencies": { - "reflect-metadata": "^0.2.2", - "express": "^4.21.2" + "express": "^4.21.2", + "reflect-metadata": "^0.2.2" }, "devDependencies": { "@plane/eslint-config": "*", - "@types/express": "^4.17.21", - "@types/reflect-metadata": "^0.1.0", "@plane/typescript-config": "*", + "@types/express": "^4.17.21", "@types/node": "^20.14.9", + "@types/reflect-metadata": "^0.1.0", "@types/ws": "^8.5.10", "tsup": "8.4.0", "typescript": "^5.3.3" diff --git a/setup.sh b/setup.sh index 2dcaba80f2..c19a29abf9 100755 --- a/setup.sh +++ b/setup.sh @@ -22,14 +22,14 @@ echo -e "${BOLD}Setting up your development environment...${NC}\n" copy_env_file() { local source=$1 local destination=$2 - + if [ ! -f "$source" ]; then echo -e "${RED}Error: Source file $source does not exist.${NC}" return 1 fi - + cp "$source" "$destination" - + if [ $? -eq 0 ]; then echo -e "${GREEN}✓${NC} Copied $destination" else @@ -52,7 +52,7 @@ for service in "${services[@]}"; do if [ "$service" != "" ]; then prefix="./$service/" fi - + copy_env_file "${prefix}.env.example" "${prefix}.env" || success=false done @@ -60,7 +60,7 @@ done if [ -f "./apiserver/.env" ]; then echo -e "\n${YELLOW}Generating Django SECRET_KEY...${NC}" SECRET_KEY=$(tr -dc 'a-z0-9' < /dev/urandom | head -c50) - + if [ -z "$SECRET_KEY" ]; then echo -e "${RED}Error: Failed to generate SECRET_KEY.${NC}" echo -e "${RED}Ensure 'tr' and 'head' commands are available on your system.${NC}" @@ -74,6 +74,11 @@ else success=false fi +# Activate Yarn (version set in package.json) +corepack enable yarn || success=false +# Install Node dependencies +yarn install || success=false + # Summary echo -e "\n${YELLOW}Setup status:${NC}" if [ "$success" = true ]; then diff --git a/space/.env.example b/space/.env.example index 33939c7e20..15d7a36a9d 100644 --- a/space/.env.example +++ b/space/.env.example @@ -1,3 +1,12 @@ -NEXT_PUBLIC_API_BASE_URL="" -NEXT_PUBLIC_WEB_BASE_URL="" -NEXT_PUBLIC_SPACE_BASE_PATH="/spaces" \ No newline at end of file +NEXT_PUBLIC_API_BASE_URL="http://localhost:8000" + +NEXT_PUBLIC_WEB_BASE_URL="http://localhost:3000" + +NEXT_PUBLIC_ADMIN_BASE_URL="http://localhost:3001" +NEXT_PUBLIC_ADMIN_BASE_PATH="/god-mode" + +NEXT_PUBLIC_SPACE_BASE_URL="http://localhost:3002" +NEXT_PUBLIC_SPACE_BASE_PATH="/spaces" + +NEXT_PUBLIC_LIVE_BASE_URL="http://localhost:3100" +NEXT_PUBLIC_LIVE_BASE_PATH="/live" diff --git a/space/package.json b/space/package.json index 25db458953..4dd54ca6e3 100644 --- a/space/package.json +++ b/space/package.json @@ -22,9 +22,9 @@ "@plane/constants": "*", "@plane/editor": "*", "@plane/i18n": "*", + "@plane/services": "*", "@plane/types": "*", "@plane/ui": "*", - "@plane/services": "*", "axios": "^1.8.3", "clsx": "^2.0.0", "date-fns": "^4.1.0", diff --git a/web/.env.example b/web/.env.example index ad5ac4173d..15d7a36a9d 100644 --- a/web/.env.example +++ b/web/.env.example @@ -1,10 +1,12 @@ -NEXT_PUBLIC_API_BASE_URL="" +NEXT_PUBLIC_API_BASE_URL="http://localhost:8000" -NEXT_PUBLIC_ADMIN_BASE_URL="" +NEXT_PUBLIC_WEB_BASE_URL="http://localhost:3000" + +NEXT_PUBLIC_ADMIN_BASE_URL="http://localhost:3001" NEXT_PUBLIC_ADMIN_BASE_PATH="/god-mode" -NEXT_PUBLIC_SPACE_BASE_URL="" +NEXT_PUBLIC_SPACE_BASE_URL="http://localhost:3002" NEXT_PUBLIC_SPACE_BASE_PATH="/spaces" -NEXT_PUBLIC_LIVE_BASE_URL="" -NEXT_PUBLIC_LIVE_BASE_PATH="/live" \ No newline at end of file +NEXT_PUBLIC_LIVE_BASE_URL="http://localhost:3100" +NEXT_PUBLIC_LIVE_BASE_PATH="/live"