Imported from masrurimz/groundup-ai-fullstack-test-mar-2026 (
AGENTS.md). Install upstream withnpx skills add masrurimz/groundup-ai-fullstack-test-mar-2026. Copyright stays with the author.
Repository Guidelines
Project Overview
GroundUp AI is a fullstack monorepo for industrial anomaly monitoring. Operators review machine anomaly alerts, inspect audio, waveforms, and spectrograms, then annotate each alert with a suspected reason, remediation action, and comment.
The codebase is contract-first: the FastAPI backend defines the OpenAPI spec, and the frontend consumes a generated TypeScript client from apps/web/src/lib/api-client/.
Start with:
README.mdfor setup and command overviewdocs/architecture.mdfor system/data-flow detailsdocs/data-pipeline.mdfor dataset and media pipeline constraintsapps/server/MIGRATION_GUIDE.mdbefore changing database schema
Architecture & Data Flow
High-level structure
apps/web/: React 19 + TanStack Start frontend, SSR, file-based routingapps/server/: FastAPI backend with async SQLAlchemy and Alembicpackages/env/: shared env schema/validation for web and serverpackages/config/: shared TS configpackages/infra/: Alchemy/Cloudflare deployment config
Main data flow
- Browser hits TanStack Start routes in
apps/web/src/routes/. - Frontend query/mutation code in
apps/web/src/lib/query/andapps/web/src/lib/api/calls the generated OpenAPI client. - FastAPI routes in
apps/server/app/api/routes/execute business logic and persist relational data with SQLAlchemy. - PostgreSQL + TimescaleDB stores alerts, lookup tables, and audit history.
- RustFS (S3-compatible) stores WAVs, waveform JSON, and spectrogram PNGs.
Important domain patterns
Alert.statusis computed, not stored; seedocs/architecture.md.- Reasons are machine-scoped; actions are global.
- Alert annotations must validate active/in-scope lookup values.
- Waveform retrieval uses a three-tier cache: in-memory -> S3 JSON -> compute from WAV.
- Dashboard analytics come from TimescaleDB continuous aggregates, not ad hoc frontend math.
Key Directories
apps/web/src/routes/: TanStack Router route files such asalerts.$alertId.tsx,settings.reasons.tsxapps/web/src/components/: UI and feature components (dashboard/,alerts/)apps/web/src/lib/api/: API adapters and view-model shapingapps/web/src/lib/query/: TanStack Query options/loaders/mutationsapps/web/src/test/: test setup, MSW utilities, render helpersapps/server/app/api/routes/: backend endpoint modulesapps/server/app/services/: backend business logic, media/storage logicapps/server/app/schemas/: request/response schemasapps/server/alembic/: migrations only source of schema evolutionapps/server/tests/unit/,apps/server/tests/integration/: backend unit/integration coveragedocs/: architecture, data pipeline, rollout notesscripts/: repo-level utilities such as environment switching and client generation
Development Commands
Run from repo root unless noted.
Core workspace commands
bun install— install JS workspace depsbun run dev— run web + server through Turbo with Infisical env injectionbun run dev:web— frontend onlybun run dev:server— backend onlybun run build— workspace buildbun run test— Turbo test across appsbun run test:web— web tests onlybun run test:server— server tests onlybun run check:types— workspace type checksbun run check:lint— workspace lint checksbun run check— Oxlint + Oxfmt autofix at root
Backend-specific
bun run db:migrate— apply Alembic migrationsbun run seed— seed base datasetbun run seed:dev— seed base dataset plus dev-only recordsuv run --directory apps/server pytest -v— backend tests directly
Frontend-specific
bun run --filter=web testorcd apps/web && bun run test— Vitest suitecd apps/web && bun run check:types— frontend TS check
Generated client
bun run generate:client— regenerate frontend API client after backend API/schema changesbun run verify:generated:client— regenerate and fail on diff
Environment switching
bun env:use dev|staging|prod— rewrites rootpackage.jsonenv:runand.infisical.jsonbun env:use— print current environment
Runtime / Tooling Preferences
- JS runtime and package manager: Bun (
packageManager: bun@1.3.9) - Python runtime: 3.13 via
uv - Monorepo orchestrator: Turbo
- Secrets: Infisical; do not introduce
.envfiles - Frontend lint/format: Oxlint + Oxfmt
- Backend lint/format: Ruff
- Backend typing:
ty - Git hooks:
lefthook - Local DB/service dependencies: Docker Compose / TimescaleDB
Assistant rules for this repo:
- Prefer root scripts over ad hoc commands.
- Preserve the Bun + UV split; frontend and shared TS live under Bun, backend under UV.
- Do not hand-edit generated client files in
apps/web/src/lib/api-client/. - Do not bypass Alembic with
create_all()-style schema changes. - Expect Infisical auth/connectivity for normal dev commands.
Code Conventions & Common Patterns
Frontend
- TanStack Start + TanStack Router file-based routes under
apps/web/src/routes/ - TanStack Query is the default server-state layer; query options live in
apps/web/src/lib/query/ - Tests use a shared QueryClient wrapper in
apps/web/src/test/test-utils.tsx - Prefer existing query-option and mutation-hook patterns over new fetch wrappers
- Coverage excludes generated files such as
src/lib/api-client/**andsrc/routeTree.gen.ts
Example query pattern:
export const alertsQueryOptions = (filters: AlertFilters) =>
queryOptions({
queryKey: ["alerts", filters],
queryFn: () => listAlertsApiV1AlertsGet({ query: filters }),
});
Backend
- FastAPI app is async; SQLAlchemy uses async sessions
- Route handlers live in
app/api/routes/, not in model modules - Request/response validation belongs in schema modules
- Tests patch storage and override DB session dependencies rather than hitting real object storage
- Migration workflow is strict: schema changes go through Alembic, then related seed/client/test updates
Cross-cutting
- Contract-first is mandatory: backend API changes must be followed by generated client updates and affected frontend/test updates
- Historical snapshot fields on alerts are intentional; do not remove them casually
- Use documented domain rules from
docs/architecture.mdrather than inferring from UI labels
Testing & QA
Frameworks
- Frontend: Vitest + Testing Library + JSDOM (
apps/web/vitest.config.ts) - Backend: Pytest + pytest-asyncio + httpx ASGI transport (
apps/server/tests/) - CI:
.github/workflows/ci.yml
Test locations and patterns
- Frontend tests sit beside features, e.g.
apps/web/src/components/alerts/status-badge.test.tsx - Backend tests are split into:
apps/server/tests/unit/apps/server/tests/integration/
- Backend integration tests rely on TimescaleDB and seeded fixtures from
apps/server/tests/conftest.py - Frontend test rendering should use
apps/web/src/test/test-utils.tsxto get a QueryClientProvider
Quality gates
CI runs in this order:
- Frontend lint (
oxlint) and TS typecheck - Backend lint (
ruff check) and typecheck (ty check) - Frontend tests
- Backend tests against TimescaleDB
Pre-commit hooks run:
bun oxlint --fixbun oxfmt --writeuv run --directory apps/server ruff format app testsuv run --directory apps/server ruff check app tests
Important Files
package.json— root scripts and workspace entry pointsturbo.json— workspace task graphREADME.md— setup, commands, architecture summarydocs/architecture.md— authoritative domain/data-flow referencedocs/data-pipeline.md— dataset, audio, cache, and seed workflowapps/server/MIGRATION_GUIDE.md— required migration workflowapps/web/vitest.config.ts— frontend test environment and coverage scopeapps/server/tests/conftest.py— backend test fixtures, DB isolation, storage mockingscripts/env-switch.ts— environment switching behaviorlefthook.yml— enforced pre-commit formatting/linting
Common Assistant Workflows
Changing backend API or schemas
- Update backend routes/schemas/models/migrations.
- Run
bun run db:migrateif needed. - Regenerate the client with
bun run generate:client. - Update frontend query/mutation consumers.
- Update or add backend and frontend tests.
Changing frontend data access
- Check
apps/web/src/lib/api/andapps/web/src/lib/query/for an existing pattern. - Reuse generated client functions instead of custom fetch code.
- Add/adjust Vitest coverage near the feature.
Changing database behavior
- Read
apps/server/MIGRATION_GUIDE.md. - Add an Alembic migration; do not rely on runtime schema creation.
- Update seeds/tests/docs if the domain model changes.
Caveats
- Normal development expects Infisical access at
https://infisical.zahid.es/api. - Dataset seeding depends on
../extracted_data/Fullstack Test/, which is outside the repo. - Local backend tests may require a running TimescaleDB instance if not using the CI service setup.
- Frontend build/dev may rely on generated local Alchemy/Cloudflare config in
.alchemy/.