Reworked variable system, no longer hardcoded
This commit is contained in:
14
backend/.env.example
Normal file
14
backend/.env.example
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Database Configuration
|
||||||
|
DATABASE_URL=sqlite:///./tesseract.db
|
||||||
|
|
||||||
|
# API Configuration
|
||||||
|
API_TITLE=Tesseract - Nested Todo Tree API
|
||||||
|
API_DESCRIPTION=API for managing deeply nested todo trees
|
||||||
|
API_VERSION=1.0.0
|
||||||
|
|
||||||
|
# CORS Configuration (comma-separated list of allowed origins)
|
||||||
|
CORS_ORIGINS=http://localhost:5173,http://localhost:3000
|
||||||
|
|
||||||
|
# Server Configuration
|
||||||
|
HOST=0.0.0.0
|
||||||
|
PORT=8000
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from .settings import settings
|
||||||
|
|
||||||
SQLALCHEMY_DATABASE_URL = "sqlite:///./tesseract.db"
|
SQLALCHEMY_DATABASE_URL = settings.database_url
|
||||||
|
|
||||||
engine = create_engine(
|
engine = create_engine(
|
||||||
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
|
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
|
||||||
|
|||||||
@@ -6,20 +6,21 @@ import json
|
|||||||
|
|
||||||
from . import models, schemas, crud
|
from . import models, schemas, crud
|
||||||
from .database import engine, get_db
|
from .database import engine, get_db
|
||||||
|
from .settings import settings
|
||||||
|
|
||||||
# Create database tables
|
# Create database tables
|
||||||
models.Base.metadata.create_all(bind=engine)
|
models.Base.metadata.create_all(bind=engine)
|
||||||
|
|
||||||
app = FastAPI(
|
app = FastAPI(
|
||||||
title="Tesseract - Nested Todo Tree API",
|
title=settings.api_title,
|
||||||
description="API for managing deeply nested todo trees",
|
description=settings.api_description,
|
||||||
version="1.0.0"
|
version=settings.api_version
|
||||||
)
|
)
|
||||||
|
|
||||||
# CORS middleware for frontend
|
# CORS middleware for frontend
|
||||||
app.add_middleware(
|
app.add_middleware(
|
||||||
CORSMiddleware,
|
CORSMiddleware,
|
||||||
allow_origins=["http://localhost:5173", "http://localhost:3000"], # Vite default port
|
allow_origins=settings.cors_origins_list,
|
||||||
allow_credentials=True,
|
allow_credentials=True,
|
||||||
allow_methods=["*"],
|
allow_methods=["*"],
|
||||||
allow_headers=["*"],
|
allow_headers=["*"],
|
||||||
|
|||||||
37
backend/app/settings.py
Normal file
37
backend/app/settings.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
|
||||||
|
class Settings(BaseSettings):
|
||||||
|
"""Application settings loaded from environment variables"""
|
||||||
|
|
||||||
|
# Database Configuration
|
||||||
|
database_url: str = "sqlite:///./tesseract.db"
|
||||||
|
|
||||||
|
# API Configuration
|
||||||
|
api_title: str = "Tesseract - Nested Todo Tree API"
|
||||||
|
api_description: str = "API for managing deeply nested todo trees"
|
||||||
|
api_version: str = "1.0.0"
|
||||||
|
|
||||||
|
# CORS Configuration
|
||||||
|
cors_origins: str = "http://localhost:5173,http://localhost:3000"
|
||||||
|
|
||||||
|
# Server Configuration
|
||||||
|
host: str = "0.0.0.0"
|
||||||
|
port: int = 8000
|
||||||
|
|
||||||
|
model_config = SettingsConfigDict(
|
||||||
|
env_file=".env",
|
||||||
|
env_file_encoding="utf-8",
|
||||||
|
case_sensitive=False,
|
||||||
|
extra="ignore"
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cors_origins_list(self) -> List[str]:
|
||||||
|
"""Parse comma-separated CORS origins into a list"""
|
||||||
|
return [origin.strip() for origin in self.cors_origins.split(",")]
|
||||||
|
|
||||||
|
|
||||||
|
# Global settings instance
|
||||||
|
settings = Settings()
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
backend:
|
backend:
|
||||||
build:
|
build:
|
||||||
@@ -7,10 +5,12 @@ services:
|
|||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: tesseract-backend
|
container_name: tesseract-backend
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- "8002:8002"
|
||||||
volumes:
|
volumes:
|
||||||
- ./backend/app:/app/app
|
- ./backend/app:/app/app
|
||||||
- tesseract-db:/app
|
- tesseract-db:/app
|
||||||
|
env_file:
|
||||||
|
- ./backend/.env
|
||||||
environment:
|
environment:
|
||||||
- PYTHONUNBUFFERED=1
|
- PYTHONUNBUFFERED=1
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -21,7 +21,9 @@ services:
|
|||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
container_name: tesseract-frontend
|
container_name: tesseract-frontend
|
||||||
ports:
|
ports:
|
||||||
- "3000:80"
|
- "3002:80"
|
||||||
|
env_file:
|
||||||
|
- ./frontend/.env
|
||||||
depends_on:
|
depends_on:
|
||||||
- backend
|
- backend
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
18
frontend/.env.example
Normal file
18
frontend/.env.example
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# API Configuration
|
||||||
|
# Base URL for API requests (relative path used in production)
|
||||||
|
VITE_API_BASE_URL=/api
|
||||||
|
|
||||||
|
# Backend API URL (used for development proxy)
|
||||||
|
VITE_API_URL=http://localhost:8000
|
||||||
|
|
||||||
|
# Development Configuration
|
||||||
|
# Port for Vite development server
|
||||||
|
VITE_DEV_PORT=5173
|
||||||
|
|
||||||
|
# Application Configuration
|
||||||
|
# Application version displayed in UI
|
||||||
|
VITE_APP_VERSION=0.1.5
|
||||||
|
|
||||||
|
# UI/UX Configuration
|
||||||
|
# Search input debounce delay in milliseconds
|
||||||
|
VITE_SEARCH_DEBOUNCE_MS=300
|
||||||
@@ -13,7 +13,7 @@ function App() {
|
|||||||
<h1 className="text-2xl font-bold text-cyber-orange">
|
<h1 className="text-2xl font-bold text-cyber-orange">
|
||||||
TESSERACT
|
TESSERACT
|
||||||
<span className="ml-3 text-sm text-gray-500">Task Decomposition Engine</span>
|
<span className="ml-3 text-sm text-gray-500">Task Decomposition Engine</span>
|
||||||
<span className="ml-2 text-xs text-gray-600">v0.1.5</span>
|
<span className="ml-2 text-xs text-gray-600">v{import.meta.env.VITE_APP_VERSION || '0.1.5'}</span>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<SearchBar />
|
<SearchBar />
|
||||||
|
|||||||
@@ -84,9 +84,10 @@ function SearchBar() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const debounceMs = parseInt(import.meta.env.VITE_SEARCH_DEBOUNCE_MS || '300')
|
||||||
const timeoutId = setTimeout(() => {
|
const timeoutId = setTimeout(() => {
|
||||||
handleSearch(query)
|
handleSearch(query)
|
||||||
}, 300)
|
}, debounceMs)
|
||||||
|
|
||||||
return () => clearTimeout(timeoutId)
|
return () => clearTimeout(timeoutId)
|
||||||
}, [query, selectedProjects])
|
}, [query, selectedProjects])
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const API_BASE = '/api';
|
const API_BASE = import.meta.env.VITE_API_BASE_URL || '/api';
|
||||||
|
|
||||||
async function fetchAPI(endpoint, options = {}) {
|
async function fetchAPI(endpoint, options = {}) {
|
||||||
const response = await fetch(`${API_BASE}${endpoint}`, {
|
const response = await fetch(`${API_BASE}${endpoint}`, {
|
||||||
|
|||||||
@@ -1,16 +1,20 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig, loadEnv } from 'vite'
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig(({ mode }) => {
|
||||||
|
const env = loadEnv(mode, process.cwd(), '')
|
||||||
|
|
||||||
|
return {
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
server: {
|
server: {
|
||||||
host: '0.0.0.0',
|
host: '0.0.0.0',
|
||||||
port: 5173,
|
port: parseInt(env.VITE_DEV_PORT || '5173'),
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://localhost:8000',
|
target: env.VITE_API_URL || 'http://localhost:8000',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user