Meditate is a full-stack daily spiritual reflection app.
It helps a signed-in user:
- follow a Bible plan
- read today's scripture
- select verses for reflection
- generate AI-assisted summary, prayer ideas, and action steps
- persist and reload AI output for today's meditation
- Backend: ASP.NET Core Web API, EF Core, SQL Server, JWT auth
- Frontend: React + TypeScript + Vite + Tailwind
- AI: OpenAI API (configured via environment variable or configuration)
backend/ ASP.NET Core API
frontend/ React + TypeScript client
- .NET SDK 10.x
- Node.js 20+
- SQL Server (local or container)
- Copy backend/appsettings.example.json to
backend/appsettings.Development.json. - Set a strong JWT key and local DB connection string.
- Set OpenAI key (recommended via env var):
export OPENAI_API_KEY="your_key_here"cd backend
dotnet ef database update
dotnet runAPI default URL:
http://localhost:5172
- Copy frontend/.env.example to
frontend/.env.local. - Confirm
VITE_API_BASE_URLpoints to the backend.
cd frontend
npm install
npm run devFrontend default URL:
http://localhost:5173
Backend:
cd backend
dotnet buildFrontend:
cd frontend
npm run buildNever commit:
- API keys
- JWT secrets
- production DB passwords
.envfiles with real credentialsappsettings.Development.jsonwith sensitive values
Use instead:
- environment variables
- .NET user secrets
- local-only files already ignored by Git
OpenAI resolution order in backend:
OPENAI_API_KEYenvironment variableOpenAI:ApiKeyin app configuration
Before publishing or opening a PR:
- Confirm no secrets are staged:
git status
git diff --staged-
If a secret was accidentally committed, rotate it immediately and remove it from history.
-
Ensure CI passes locally:
cd backend && dotnet build
cd ../frontend && npm run build- Keep dependencies updated and review alerts from Dependabot and GitHub Security tab.
- Authentication uses Bearer JWT tokens.
- AI generation endpoint remains:
POST /api/ai/generate-day
- Today meditation endpoint returns saved AI data:
GET /api/meditation/today
-
If you see
BadImageFormatExceptionduring active development:- stop watch processes
- run
dotnet clean && dotnet build - start backend again
-
If frontend HMR shows old parse errors after a fix:
- stop dev server
- run
npm run buildto confirm syntax - restart
npm run dev