feat: add Phase 1 infrastructure skeleton

Backend (FastAPI):
- docker-compose with all 4 services
- FastAPI app with health endpoints
- SQLAlchemy models for all tables
- Placeholder API endpoints for all routes
- Config and database modules
- requirements.txt with all dependencies

Frontend (React):
- package.json with React, Tailwind, React Query, React Router
- Vite config with API proxy
- Tailwind and TypeScript configs
- Basic App with routing skeleton
- Placeholder pages (Dashboard, MealDetail, Pantry)

Infrastructure:
- nginx config for reverse proxy
- Dockerfile for backend and frontend
This commit is contained in:
2026-05-04 19:29:35 -07:00
parent 0c5b0aa5ed
commit 1328ec359d
26 changed files with 761 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.database import get_db
router = APIRouter()
@router.post("/scrape")
def trigger_scrape(db: Session = Depends(get_db)):
return {"message": "Scrape trigger - not yet implemented"}
@router.get("/logs")
def get_logs(db: Session = Depends(get_db)):
return {"message": "Logs endpoint - not yet implemented"}
@router.post("/test-email")
def test_email(db: Session = Depends(get_db)):
return {"message": "Test email - not yet implemented"}
+20
View File
@@ -0,0 +1,20 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.database import get_db
router = APIRouter()
@router.get("/planned")
def get_planned_meals(db: Session = Depends(get_db)):
return {"message": "Planned meals endpoint - not yet implemented"}
@router.post("/{meal_id}/approve")
def approve_meal(meal_id: str, db: Session = Depends(get_db)):
return {"message": f"Approve meal {meal_id} - not yet implemented"}
@router.post("/{meal_id}/deny")
def deny_meal(meal_id: str, db: Session = Depends(get_db)):
return {"message": f"Deny meal {meal_id} - not yet implemented"}
+20
View File
@@ -0,0 +1,20 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.database import get_db
router = APIRouter()
@router.get("/")
def get_pantry(db: Session = Depends(get_db)):
return {"message": "Pantry endpoint - not yet implemented"}
@router.post("/")
def add_pantry_item(db: Session = Depends(get_db)):
return {"message": "Add pantry item - not yet implemented"}
@router.delete("/{item_id}")
def remove_pantry_item(item_id: str, db: Session = Depends(get_db)):
return {"message": f"Remove pantry item {item_id} - not yet implemented"}
+15
View File
@@ -0,0 +1,15 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.database import get_db
router = APIRouter()
@router.get("/")
def get_profile(db: Session = Depends(get_db)):
return {"message": "Profile endpoint - not yet implemented"}
@router.put("/")
def update_profile(db: Session = Depends(get_db)):
return {"message": "Update profile endpoint - not yet implemented"}
+20
View File
@@ -0,0 +1,20 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.database import get_db
router = APIRouter()
@router.get("/")
def get_recipes(db: Session = Depends(get_db)):
return {"message": "Recipes endpoint - not yet implemented"}
@router.get("/{recipe_id}")
def get_recipe(recipe_id: str, db: Session = Depends(get_db)):
return {"message": f"Recipe {recipe_id} - not yet implemented"}
@router.post("/")
def create_recipe(db: Session = Depends(get_db)):
return {"message": "Create recipe endpoint - not yet implemented"}
+15
View File
@@ -0,0 +1,15 @@
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.database import get_db
router = APIRouter()
@router.get("/")
def get_shopping_list(db: Session = Depends(get_db)):
return {"message": "Shopping list endpoint - not yet implemented"}
@router.get("/print")
def get_printable_shopping_list(db: Session = Depends(get_db)):
return {"message": "Printable shopping list - not yet implemented"}