refactor: update environment configuration, enhance installation script, and add migration scripts for database setup
This commit is contained in:
+20
-11
@@ -1,14 +1,23 @@
|
|||||||
# ─── Supabase (Zorunlu) ───────────────────────────────────────
|
# Neta self-host environment
|
||||||
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
|
|
||||||
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
|
|
||||||
|
|
||||||
# Müşteri Portalı hesabı oluşturmak için gerekli (Freelancer panelinde kullanılır)
|
# Public URL where users open Neta.
|
||||||
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key
|
NEXT_PUBLIC_SITE_URL=http://localhost:3000
|
||||||
|
|
||||||
# ─── AI Sağlayıcılar (Opsiyonel — uygulama içi ayarlardan da tanımlanabilir) ───
|
# Host port mapped to the Neta container's internal port 3000.
|
||||||
# OPENAI_API_KEY=your_openai_api_key
|
NETA_PORT=3000
|
||||||
# GROQ_API_KEY=your_groq_api_key
|
|
||||||
# GEMINI_API_KEY=your_gemini_api_key
|
|
||||||
|
|
||||||
# ─── Supabase Auth (Self-host'ta gerekli olabilir) ───────────
|
# Supabase API URL. For a hosted project this looks like:
|
||||||
# NEXT_PUBLIC_SITE_URL=https://neta.example.com
|
# https://your-project.supabase.co
|
||||||
|
# For a bundled/self-hosted Supabase setup this is usually your public API URL.
|
||||||
|
NEXT_PUBLIC_SUPABASE_URL=
|
||||||
|
|
||||||
|
# Supabase anon/public API key.
|
||||||
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=
|
||||||
|
|
||||||
|
# Supabase service role key. Required for creating client portal accounts.
|
||||||
|
# Keep this secret. It is only used server-side.
|
||||||
|
SUPABASE_SERVICE_ROLE_KEY=
|
||||||
|
|
||||||
|
# Optional: direct Postgres connection string used only by bash ./scripts/apply-migrations.sh.
|
||||||
|
# Do not expose this to browsers. It is not required by the web container.
|
||||||
|
# DATABASE_URL=postgresql://postgres:password@host:5432/postgres
|
||||||
|
|||||||
@@ -50,32 +50,45 @@ Neta is engineered using modern, high-performance web technologies:
|
|||||||
|
|
||||||
## Installation and Deployment
|
## Installation and Deployment
|
||||||
|
|
||||||
Neta is designed to be easily self-hosted. Follow these steps to deploy the application on your own infrastructure.
|
Neta is designed for self-hosting. The current Docker Compose file runs the Neta web application and connects it to a Supabase-compatible backend. A bundled Supabase Compose profile is planned for the full-stack self-host mode.
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
- Docker and Docker Compose
|
- Docker and Docker Compose
|
||||||
- Node.js (for local development)
|
- A Supabase project or self-hosted Supabase backend
|
||||||
- A Supabase instance (Cloud or Self-Hosted)
|
- Supabase API URL, anon key, and service role key
|
||||||
|
- A direct Postgres `DATABASE_URL` if you want the installer to apply migrations automatically
|
||||||
|
|
||||||
### 1-Click Installation (Recommended)
|
### 1-Click Installation (Recommended)
|
||||||
|
|
||||||
You can install and start Neta immediately using our automated setup script. Simply run the following command in your terminal:
|
You can install Neta using the interactive setup script:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -sL https://raw.githubusercontent.com/poyrazavsever/neta/main/install.sh | bash
|
curl -sL https://raw.githubusercontent.com/poyrazavsever/neta/main/install.sh | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The installer asks for the required Supabase values, writes a `.env` file, optionally applies database migrations, validates Docker Compose configuration, and starts the application.
|
||||||
|
|
||||||
### Manual Installation
|
### Manual Installation
|
||||||
|
|
||||||
If you prefer to set up Neta manually:
|
If you prefer to set up Neta manually:
|
||||||
|
|
||||||
1. Clone the repository: `git clone https://github.com/poyrazavsever/neta.git`
|
1. Clone the repository: `git clone https://github.com/poyrazavsever/neta.git`
|
||||||
2. Navigate to the directory and copy the `.env.example` file to `.env.local`.
|
2. Navigate to the directory and copy the `.env.example` file to `.env`.
|
||||||
3. Build and start the Docker container:
|
3. Fill every required value in `.env`.
|
||||||
|
4. Apply database migrations:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose up -d --build
|
DATABASE_URL='postgresql://postgres:password@host:5432/postgres' bash ./scripts/apply-migrations.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
5. Build and start the Docker container:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
Docker Compose intentionally fails fast when required Supabase environment values are missing.
|
||||||
|
|
||||||
### First Administrator Account
|
### First Administrator Account
|
||||||
To ensure data security, Neta is locked to a single administrator. Upon launching the application for the first time, navigate to the `/register` route to create the initial admin account. Once this account is created, public registration is permanently disabled.
|
To ensure data security, Neta is locked to a single administrator. Upon launching the application for the first time, navigate to the `/register` route to create the initial admin account. Once this account is created, public registration is permanently disabled.
|
||||||
|
|
||||||
|
|||||||
+8
-10
@@ -4,18 +4,16 @@ services:
|
|||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
args:
|
args:
|
||||||
NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL}
|
NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL:?Set NEXT_PUBLIC_SUPABASE_URL in .env}
|
||||||
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY}
|
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY:?Set NEXT_PUBLIC_SUPABASE_ANON_KEY in .env}
|
||||||
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-http://localhost:3000}
|
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-http://localhost:3000}
|
||||||
container_name: neta-web
|
container_name: neta-web
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "${NETA_PORT:-3000}:3000"
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
NODE_ENV: production
|
||||||
- NEXT_PUBLIC_SUPABASE_URL=${NEXT_PUBLIC_SUPABASE_URL}
|
NEXT_PUBLIC_SUPABASE_URL: ${NEXT_PUBLIC_SUPABASE_URL:?Set NEXT_PUBLIC_SUPABASE_URL in .env}
|
||||||
- NEXT_PUBLIC_SUPABASE_ANON_KEY=${NEXT_PUBLIC_SUPABASE_ANON_KEY}
|
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${NEXT_PUBLIC_SUPABASE_ANON_KEY:?Set NEXT_PUBLIC_SUPABASE_ANON_KEY in .env}
|
||||||
- SUPABASE_SERVICE_ROLE_KEY=${SUPABASE_SERVICE_ROLE_KEY}
|
SUPABASE_SERVICE_ROLE_KEY: ${SUPABASE_SERVICE_ROLE_KEY:?Set SUPABASE_SERVICE_ROLE_KEY in .env}
|
||||||
- NEXT_PUBLIC_SITE_URL=${NEXT_PUBLIC_SITE_URL:-http://localhost:3000}
|
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL:-http://localhost:3000}
|
||||||
env_file:
|
|
||||||
- .env.local
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# 0004 - Business OS Tables
|
||||||
|
|
||||||
|
SQL file: `supabase/migrations/0004_add_business_os_tables.sql`
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Adds business document and recurring cost tables used by the freelancer business layer.
|
||||||
|
|
||||||
|
## What It Creates
|
||||||
|
|
||||||
|
- `proposals`
|
||||||
|
- `contracts`
|
||||||
|
- `invoices`
|
||||||
|
- `subscriptions`
|
||||||
|
|
||||||
|
## RLS
|
||||||
|
|
||||||
|
Every table has `user_id` and row level security policies that allow users to select, insert, update, and delete only their own rows.
|
||||||
|
|
||||||
|
## Execution
|
||||||
|
|
||||||
|
Run after `0003_add_project_planning_assets.sql`.
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# 0005 - Advanced CRM Tables
|
||||||
|
|
||||||
|
SQL file: `supabase/migrations/0005_add_advanced_crm_tables.sql`
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Extends client management with pipeline and activity tracking fields.
|
||||||
|
|
||||||
|
## What It Changes
|
||||||
|
|
||||||
|
The `clients` table receives:
|
||||||
|
|
||||||
|
- `pipeline_stage`
|
||||||
|
- `next_follow_up_date`
|
||||||
|
- `last_contact_date`
|
||||||
|
- `client_value_score`
|
||||||
|
|
||||||
|
## What It Creates
|
||||||
|
|
||||||
|
- `client_activities`
|
||||||
|
|
||||||
|
## RLS
|
||||||
|
|
||||||
|
`client_activities` is user-scoped through `user_id` and has select, insert, update, and delete policies for the owning user.
|
||||||
|
|
||||||
|
## Execution
|
||||||
|
|
||||||
|
Run after `0004_add_business_os_tables.sql`.
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# 0006 - pgvector And Embeddings
|
||||||
|
|
||||||
|
SQL file: `supabase/migrations/0006_add_pgvector_and_embeddings.sql`
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Adds vector storage for future retrieval augmented generation features.
|
||||||
|
|
||||||
|
## What It Creates
|
||||||
|
|
||||||
|
- `vector` extension
|
||||||
|
- `document_embeddings`
|
||||||
|
- `match_documents()`
|
||||||
|
|
||||||
|
## RLS
|
||||||
|
|
||||||
|
Embeddings are scoped by `user_id`; users can manage only their own embedding rows.
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
The migration expects the target Postgres/Supabase environment to support the `vector` extension.
|
||||||
|
|
||||||
|
## Execution
|
||||||
|
|
||||||
|
Run after `0005_add_advanced_crm_tables.sql`.
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# 0007 - Client Portal Tables
|
||||||
|
|
||||||
|
SQL file: `supabase/migrations/0007_add_client_portal_tables.sql`
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Adds client portal access and revision request support.
|
||||||
|
|
||||||
|
## What It Changes
|
||||||
|
|
||||||
|
- Adds `profiles.role`
|
||||||
|
- Adds `clients.client_auth_id`
|
||||||
|
- Adds `tasks.is_public_to_client`
|
||||||
|
|
||||||
|
## What It Creates
|
||||||
|
|
||||||
|
- `project_revisions`
|
||||||
|
|
||||||
|
## RLS
|
||||||
|
|
||||||
|
Freelancers manage revisions for their own projects. Clients can view their linked client record, related projects, public project tasks, project planning sections, and their own revision requests.
|
||||||
|
|
||||||
|
## Execution
|
||||||
|
|
||||||
|
Run after `0006_add_pgvector_and_embeddings.sql`.
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
# 0008 - Project Progress And Quota
|
||||||
|
|
||||||
|
SQL file: `supabase/migrations/0008_add_project_progress_and_quota.sql`
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
|
||||||
|
Adds project progress mode and revision quota support.
|
||||||
|
|
||||||
|
## What It Changes
|
||||||
|
|
||||||
|
The `projects` table receives:
|
||||||
|
|
||||||
|
- `progress_type`
|
||||||
|
- `revision_quota`
|
||||||
|
|
||||||
|
## What It Creates
|
||||||
|
|
||||||
|
- `update_project_progress_on_task_change()`
|
||||||
|
- `trigger_update_project_progress`
|
||||||
|
- `update_project_progress_on_type_change()`
|
||||||
|
- `trigger_update_project_progress_type`
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Automatic progress mode calculates progress from tasks with status `done`.
|
||||||
|
|
||||||
|
## Execution
|
||||||
|
|
||||||
|
Run after `0007_add_client_portal_tables.sql`.
|
||||||
@@ -7,6 +7,11 @@ This file is the canonical order of SQL files for database setup and migration.
|
|||||||
| 0001 | `supabase/schema.sql` | `docs/database/0001-initial-schema.md` | Baseline registered |
|
| 0001 | `supabase/schema.sql` | `docs/database/0001-initial-schema.md` | Baseline registered |
|
||||||
| 0002 | `supabase/migrations/0002_add_freelancer_os_core_tables.sql` | `docs/database/0002-freelancer-os-core-tables.md` | Pending execution |
|
| 0002 | `supabase/migrations/0002_add_freelancer_os_core_tables.sql` | `docs/database/0002-freelancer-os-core-tables.md` | Pending execution |
|
||||||
| 0003 | `supabase/migrations/0003_add_project_planning_assets.sql` | `docs/database/0003-project-planning-assets.md` | Pending execution |
|
| 0003 | `supabase/migrations/0003_add_project_planning_assets.sql` | `docs/database/0003-project-planning-assets.md` | Pending execution |
|
||||||
|
| 0004 | `supabase/migrations/0004_add_business_os_tables.sql` | `docs/database/0004-business-os-tables.md` | Pending execution |
|
||||||
|
| 0005 | `supabase/migrations/0005_add_advanced_crm_tables.sql` | `docs/database/0005-advanced-crm-tables.md` | Pending execution |
|
||||||
|
| 0006 | `supabase/migrations/0006_add_pgvector_and_embeddings.sql` | `docs/database/0006-pgvector-and-embeddings.md` | Pending execution |
|
||||||
|
| 0007 | `supabase/migrations/0007_add_client_portal_tables.sql` | `docs/database/0007-client-portal-tables.md` | Pending execution |
|
||||||
|
| 0008 | `supabase/migrations/0008_add_project_progress_and_quota.sql` | `docs/database/0008-project-progress-and-quota.md` | Pending execution |
|
||||||
| 0009 | `supabase/migrations/0009_lock_registration_after_first_admin.sql` | `docs/database/0009-lock-registration-after-first-admin.md` | Pending execution |
|
| 0009 | `supabase/migrations/0009_lock_registration_after_first_admin.sql` | `docs/database/0009-lock-registration-after-first-admin.md` | Pending execution |
|
||||||
| seed-0001 | `supabase/seeds/0001_demo_freelancer_os_data.sql` | `docs/database/seed-0001-demo-freelancer-os-data.md` | Optional demo seed, pending execution |
|
| seed-0001 | `supabase/seeds/0001_demo_freelancer_os_data.sql` | `docs/database/seed-0001-demo-freelancer-os-data.md` | Optional demo seed, pending execution |
|
||||||
|
|
||||||
@@ -23,3 +28,13 @@ This file is the canonical order of SQL files for database setup and migration.
|
|||||||
Seed files are optional and should live under `supabase/seeds/`.
|
Seed files are optional and should live under `supabase/seeds/`.
|
||||||
|
|
||||||
They must also be documented and registered in this file, but they should only be run in local/demo environments unless explicitly approved.
|
They must also be documented and registered in this file, but they should only be run in local/demo environments unless explicitly approved.
|
||||||
|
|
||||||
|
## Applying The Ordered SQL
|
||||||
|
|
||||||
|
Use the migration helper from the repository root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
DATABASE_URL='postgresql://postgres:password@host:5432/postgres' bash ./scripts/apply-migrations.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The helper applies `0001` through `0009` in the order listed above. It uses local `psql` when available, otherwise it runs `psql` through Docker.
|
||||||
|
|||||||
+131
-38
@@ -1,57 +1,150 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Neta - Freelancer Operating System Installation Script
|
# Neta - Freelancer Operating System installer
|
||||||
|
|
||||||
set -e
|
set -euo pipefail
|
||||||
|
|
||||||
echo "🚀 Neta kurulumu başlıyor..."
|
REPO_URL="${NETA_REPO_URL:-https://github.com/poyrazavsever/neta.git}"
|
||||||
|
TARGET_DIR="${NETA_TARGET_DIR:-neta-os}"
|
||||||
|
|
||||||
# 1. Check for Git
|
info() {
|
||||||
if ! [ -x "$(command -v git)" ]; then
|
printf "\n%s\n" "$1"
|
||||||
echo "Hata: Git yüklü değil. Lütfen önce Git'i kurun." >&2
|
}
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "Error: $1" >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
require_command() {
|
||||||
|
command -v "$1" >/dev/null 2>&1 || fail "$1 is required."
|
||||||
|
}
|
||||||
|
|
||||||
|
compose_cmd() {
|
||||||
|
if docker compose version >/dev/null 2>&1; then
|
||||||
|
echo "docker compose"
|
||||||
|
elif command -v docker-compose >/dev/null 2>&1; then
|
||||||
|
echo "docker-compose"
|
||||||
|
else
|
||||||
|
fail "Docker Compose is required."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_required() {
|
||||||
|
local var_name="$1"
|
||||||
|
local label="$2"
|
||||||
|
local current_value="${!var_name:-}"
|
||||||
|
local value
|
||||||
|
|
||||||
|
if [ -n "$current_value" ]; then
|
||||||
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 2. Check for Docker
|
while true; do
|
||||||
if ! [ -x "$(command -v docker)" ]; then
|
read -r -p "$label: " value
|
||||||
echo "Hata: Docker yüklü değil. Lütfen önce Docker'ı kurun." >&2
|
if [ -n "$value" ]; then
|
||||||
exit 1
|
printf -v "$var_name" "%s" "$value"
|
||||||
|
export "$var_name"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo "This value is required."
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_optional() {
|
||||||
|
local var_name="$1"
|
||||||
|
local label="$2"
|
||||||
|
local default_value="$3"
|
||||||
|
local current_value="${!var_name:-}"
|
||||||
|
local value
|
||||||
|
|
||||||
|
if [ -n "$current_value" ]; then
|
||||||
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 3. Target directory
|
read -r -p "$label [$default_value]: " value
|
||||||
TARGET_DIR="neta-os"
|
printf -v "$var_name" "%s" "${value:-$default_value}"
|
||||||
|
export "$var_name"
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt_secret_required() {
|
||||||
|
local var_name="$1"
|
||||||
|
local label="$2"
|
||||||
|
local current_value="${!var_name:-}"
|
||||||
|
local value
|
||||||
|
|
||||||
|
if [ -n "$current_value" ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read -r -s -p "$label: " value
|
||||||
|
echo
|
||||||
|
if [ -n "$value" ]; then
|
||||||
|
printf -v "$var_name" "%s" "$value"
|
||||||
|
export "$var_name"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo "This value is required."
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
write_env_file() {
|
||||||
|
cat > .env <<EOF
|
||||||
|
NEXT_PUBLIC_SITE_URL=$NEXT_PUBLIC_SITE_URL
|
||||||
|
NETA_PORT=$NETA_PORT
|
||||||
|
NEXT_PUBLIC_SUPABASE_URL=$NEXT_PUBLIC_SUPABASE_URL
|
||||||
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=$NEXT_PUBLIC_SUPABASE_ANON_KEY
|
||||||
|
SUPABASE_SERVICE_ROLE_KEY=$SUPABASE_SERVICE_ROLE_KEY
|
||||||
|
EOF
|
||||||
|
chmod 600 .env || true
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
info "Neta self-host installer"
|
||||||
|
|
||||||
|
require_command git
|
||||||
|
require_command docker
|
||||||
|
docker info >/dev/null 2>&1 || fail "Docker is installed but the daemon is not reachable."
|
||||||
|
|
||||||
if [ -d "$TARGET_DIR" ]; then
|
if [ -d "$TARGET_DIR" ]; then
|
||||||
echo "Hata: '$TARGET_DIR' dizini zaten var. Lütfen farklı bir dizinde deneyin veya mevcut dizini silin." >&2
|
fail "'$TARGET_DIR' already exists. Set NETA_TARGET_DIR or remove the directory."
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 4. Clone repository
|
info "Cloning Neta into $TARGET_DIR"
|
||||||
echo "📦 GitHub'dan kodlar indiriliyor..."
|
git clone "$REPO_URL" "$TARGET_DIR"
|
||||||
git clone https://github.com/poyrazavsever/neta.git "$TARGET_DIR"
|
|
||||||
cd "$TARGET_DIR"
|
cd "$TARGET_DIR"
|
||||||
|
|
||||||
# 5. Setup environment variables
|
prompt_optional NEXT_PUBLIC_SITE_URL "Public Neta URL" "http://localhost:3000"
|
||||||
echo "⚙️ Çevresel değişkenler ayarlanıyor..."
|
prompt_optional NETA_PORT "Host port for Neta" "3000"
|
||||||
if [ -f ".env.example" ]; then
|
prompt_required NEXT_PUBLIC_SUPABASE_URL "Supabase API URL"
|
||||||
cp .env.example .env.local
|
prompt_secret_required NEXT_PUBLIC_SUPABASE_ANON_KEY "Supabase anon key"
|
||||||
|
prompt_secret_required SUPABASE_SERVICE_ROLE_KEY "Supabase service role key"
|
||||||
|
|
||||||
|
write_env_file
|
||||||
|
info "Wrote .env"
|
||||||
|
|
||||||
|
read -r -p "Apply Neta database migrations now? Requires a direct Postgres DATABASE_URL. [y/N]: " apply_migrations
|
||||||
|
if [ "$apply_migrations" = "y" ] || [ "$apply_migrations" = "Y" ]; then
|
||||||
|
prompt_secret_required DATABASE_URL "Postgres DATABASE_URL"
|
||||||
|
DATABASE_URL="$DATABASE_URL" bash ./scripts/apply-migrations.sh
|
||||||
else
|
else
|
||||||
echo "Uyarı: .env.example dosyası bulunamadı."
|
echo "Skipping migrations. Run them later with:"
|
||||||
|
echo " DATABASE_URL='postgresql://...' bash ./scripts/apply-migrations.sh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 6. Start with Docker Compose
|
local compose
|
||||||
echo "🐳 Docker container'ları inşa ediliyor ve başlatılıyor..."
|
compose="$(compose_cmd)"
|
||||||
if docker compose version > /dev/null 2>&1; then
|
|
||||||
docker compose up -d --build
|
|
||||||
elif docker-compose version > /dev/null 2>&1; then
|
|
||||||
docker-compose up -d --build
|
|
||||||
else
|
|
||||||
echo "Hata: docker-compose komutu bulunamadı." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
info "Validating Docker Compose configuration"
|
||||||
echo "✅ Kurulum tamamlandı!"
|
$compose config >/dev/null
|
||||||
echo "Neta başarıyla ayağa kaldırıldı."
|
|
||||||
echo "Tarayıcınızdan http://localhost:3000 adresine giderek Neta'yı kullanmaya başlayabilirsiniz."
|
info "Building and starting Neta"
|
||||||
echo "İlk girişte oluşturacağınız hesap, sistemin tek yöneticisi (admin) olacaktır."
|
$compose up -d --build
|
||||||
|
|
||||||
|
info "Neta is starting"
|
||||||
|
echo "Open: $NEXT_PUBLIC_SITE_URL"
|
||||||
|
echo "Create the first admin account at: $NEXT_PUBLIC_SITE_URL/register"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
|
||||||
|
if [ -z "${DATABASE_URL:-}" ]; then
|
||||||
|
echo "DATABASE_URL is required." >&2
|
||||||
|
echo "Example:" >&2
|
||||||
|
echo " DATABASE_URL='postgresql://postgres:password@host:5432/postgres' bash ./scripts/apply-migrations.sh" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SQL_FILES=(
|
||||||
|
"supabase/schema.sql"
|
||||||
|
"supabase/migrations/0002_add_freelancer_os_core_tables.sql"
|
||||||
|
"supabase/migrations/0003_add_project_planning_assets.sql"
|
||||||
|
"supabase/migrations/0004_add_business_os_tables.sql"
|
||||||
|
"supabase/migrations/0005_add_advanced_crm_tables.sql"
|
||||||
|
"supabase/migrations/0006_add_pgvector_and_embeddings.sql"
|
||||||
|
"supabase/migrations/0007_add_client_portal_tables.sql"
|
||||||
|
"supabase/migrations/0008_add_project_progress_and_quota.sql"
|
||||||
|
"supabase/migrations/0009_lock_registration_after_first_admin.sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
run_sql_file() {
|
||||||
|
local file_path="$1"
|
||||||
|
local absolute_path="$ROOT_DIR/$file_path"
|
||||||
|
|
||||||
|
if [ ! -f "$absolute_path" ]; then
|
||||||
|
echo "Missing SQL file: $file_path" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Applying $file_path"
|
||||||
|
|
||||||
|
if command -v psql >/dev/null 2>&1; then
|
||||||
|
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f "$absolute_path"
|
||||||
|
elif command -v docker >/dev/null 2>&1; then
|
||||||
|
docker run --rm -i postgres:16-alpine \
|
||||||
|
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -f - < "$absolute_path"
|
||||||
|
else
|
||||||
|
echo "Neither psql nor docker is available to run migrations." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
for sql_file in "${SQL_FILES[@]}"; do
|
||||||
|
run_sql_file "$sql_file"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "All Neta migrations were applied."
|
||||||
+18
-1
@@ -29,4 +29,21 @@ Do not overwrite already executed SQL without also creating a new ordered migrat
|
|||||||
|
|
||||||
1. `schema.sql`
|
1. `schema.sql`
|
||||||
2. `migrations/0002_add_freelancer_os_core_tables.sql`
|
2. `migrations/0002_add_freelancer_os_core_tables.sql`
|
||||||
3. Optional: `seeds/0001_demo_freelancer_os_data.sql`
|
3. `migrations/0003_add_project_planning_assets.sql`
|
||||||
|
4. `migrations/0004_add_business_os_tables.sql`
|
||||||
|
5. `migrations/0005_add_advanced_crm_tables.sql`
|
||||||
|
6. `migrations/0006_add_pgvector_and_embeddings.sql`
|
||||||
|
7. `migrations/0007_add_client_portal_tables.sql`
|
||||||
|
8. `migrations/0008_add_project_progress_and_quota.sql`
|
||||||
|
9. `migrations/0009_lock_registration_after_first_admin.sql`
|
||||||
|
10. Optional local/demo data: `seeds/0001_demo_freelancer_os_data.sql`
|
||||||
|
|
||||||
|
## Apply Migrations
|
||||||
|
|
||||||
|
From the repository root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
DATABASE_URL='postgresql://postgres:password@host:5432/postgres' bash ./scripts/apply-migrations.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The script applies all required schema files in canonical order. It requires either local `psql` or Docker. If `psql` is not installed, it runs `psql` through the `postgres:16-alpine` Docker image.
|
||||||
|
|||||||
Reference in New Issue
Block a user