Main branch Resync on w/ gitea. v0.1.6 #1
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.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from .settings import settings
|
||||
|
||||
SQLALCHEMY_DATABASE_URL = "sqlite:///./tesseract.db"
|
||||
SQLALCHEMY_DATABASE_URL = settings.database_url
|
||||
|
||||
engine = create_engine(
|
||||
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
|
||||
|
||||
@@ -6,20 +6,21 @@ import json
|
||||
|
||||
from . import models, schemas, crud
|
||||
from .database import engine, get_db
|
||||
from .settings import settings
|
||||
|
||||
# Create database tables
|
||||
models.Base.metadata.create_all(bind=engine)
|
||||
|
||||
app = FastAPI(
|
||||
title="Tesseract - Nested Todo Tree API",
|
||||
description="API for managing deeply nested todo trees",
|
||||
version="1.0.0"
|
||||
title=settings.api_title,
|
||||
description=settings.api_description,
|
||||
version=settings.api_version
|
||||
)
|
||||
|
||||
# CORS middleware for frontend
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["http://localhost:5173", "http://localhost:3000"], # Vite default port
|
||||
allow_origins=settings.cors_origins_list,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
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:
|
||||
backend:
|
||||
build:
|
||||
@@ -7,10 +5,12 @@ services:
|
||||
dockerfile: Dockerfile
|
||||
container_name: tesseract-backend
|
||||
ports:
|
||||
- "8000:8000"
|
||||
- "8002:8002"
|
||||
volumes:
|
||||
- ./backend/app:/app/app
|
||||
- tesseract-db:/app
|
||||
env_file:
|
||||
- ./backend/.env
|
||||
environment:
|
||||
- PYTHONUNBUFFERED=1
|
||||
restart: unless-stopped
|
||||
@@ -21,7 +21,9 @@ services:
|
||||
dockerfile: Dockerfile
|
||||
container_name: tesseract-frontend
|
||||
ports:
|
||||
- "3000:80"
|
||||
- "3002:80"
|
||||
env_file:
|
||||
- ./frontend/.env
|
||||
depends_on:
|
||||
- backend
|
||||
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">
|
||||
TESSERACT
|
||||
<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>
|
||||
</div>
|
||||
<SearchBar />
|
||||
|
||||
@@ -84,9 +84,10 @@ function SearchBar() {
|
||||
return
|
||||
}
|
||||
|
||||
const debounceMs = parseInt(import.meta.env.VITE_SEARCH_DEBOUNCE_MS || '300')
|
||||
const timeoutId = setTimeout(() => {
|
||||
handleSearch(query)
|
||||
}, 300)
|
||||
}, debounceMs)
|
||||
|
||||
return () => clearTimeout(timeoutId)
|
||||
}, [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 = {}) {
|
||||
const response = await fetch(`${API_BASE}${endpoint}`, {
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import { defineConfig, loadEnv } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: 5173,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:8000',
|
||||
changeOrigin: true,
|
||||
export default defineConfig(({ mode }) => {
|
||||
const env = loadEnv(mode, process.cwd(), '')
|
||||
|
||||
return {
|
||||
plugins: [react()],
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: parseInt(env.VITE_DEV_PORT || '5173'),
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: env.VITE_API_URL || 'http://localhost:8000',
|
||||
changeOrigin: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user