Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Broodly — Copilot Instructions

## About

Broodly is a field-first beekeeping decision-support app: a single Expo + React Native codebase (iOS, Android, web) backed by a Go GraphQL API on GCP.

## Tech Stack

| Layer | Technology |
|---|---|
| Mobile/Web | Expo + React Native + TypeScript |
| Design System | Gluestack UI v3 + NativeWind |
| Routing | Expo Router |
| Server State | TanStack React Query (persistent cache) |
| UI State | Zustand |
| GraphQL Client | urql or Apollo Client |
| Backend | Go 1.24 / toolchain 1.26.2 (chi + gqlgen) |
| Database | PostgreSQL 16 + pgvector |
| Auth | Firebase Authentication (Google + Apple Sign-In only) |
| AI/ML | Vertex AI (Gemini, Embedding 2.0) |
| Hosting | GCP Cloud Run |
| IaC | Terraform |
| Package Manager | pnpm (monorepo workspaces) |
| Linting | ESLint (TS/JS), golangci-lint (Go) |
| Formatting | Prettier (TS/JS/JSON/MD) |
| Testing | Jest (mobile/packages), `go test` (API) |

## Project Structure

```
broodly/
├── apps/
│ ├── mobile/ # Expo app — screens in app/, features in src/features/
│ └── api/ # Go GraphQL API — domain/, service/, repository/ under internal/
├── packages/
│ ├── ui/ # Shared Gluestack-based component library
│ ├── graphql-types/ # Generated TypeScript types (never hand-write these)
│ ├── domain-types/ # Shared constants and domain types
│ ├── config/ # Shared configuration
│ └── test-utils/ # Shared testing utilities
├── infra/terraform/ # GCP infrastructure as code
├── tests/ # Integration and e2e tests
└── docs/ # ADRs, architecture docs, runbooks
```

Key conventions:
- Shared UI components → `packages/ui/src/`, exported from `packages/ui/src/index.ts`
- Feature components → `apps/mobile/src/features/<feature>/components/`
- Screen files → `apps/mobile/app/` (Expo Router file-based routing)
- Package boundaries are hard: `packages/ui` must not import from `apps/mobile`
Comment on lines +30 to +50

## Local Dev Commands

```bash
# Install all dependencies (run from repo root)
pnpm install

# --- Mobile app (Expo) ---
pnpm --filter mobile start # Start Expo dev server
pnpm --filter mobile start -- --ios # Open on iOS simulator
pnpm --filter mobile start -- --android # Open on Android emulator
pnpm --filter mobile test # Run Jest tests (mobile)
pnpm --filter mobile lint # ESLint (mobile)
pnpm --filter mobile typecheck # TypeScript check (mobile)

# --- API server (Go) ---
cd apps/api
go run cmd/server/main.go # Start API server
go test ./... -race -coverprofile=coverage.out # Run all Go tests (matches CI)
go vet ./... # Go static analysis
golangci-lint run ./... # Lint (matches CI; install: https://golangci-lint.run/welcome/install/)

# --- Monorepo-wide (run from repo root) ---
cd ../..
pnpm test # Run all JS/TS tests across all packages

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Run workspace scripts from the repo root

When this fenced block is followed top-to-bottom, line 67 leaves the shell in apps/api, but these pnpm commands are root package scripts from /workspace/broodly/package.json; apps/api has no package manifest or JS/TS scripts. Since pnpm run runs scripts from a package manifest (https://pnpm.io/cli/run), users copying the documented flow can run the monorepo checks from the wrong directory instead of exercising the workspace; add a cd ../.. or use pnpm -C ../.. ... before this section.

Useful? React with 👍 / 👎.

pnpm lint # ESLint across all packages
pnpm typecheck # TypeScript check across all packages
pnpm format # Prettier format all files
pnpm format:check # Prettier check (CI-safe, no writes)

# --- Code generation (run from apps/api) ---
cd apps/api
go run github.com/99designs/gqlgen generate # Regenerate gqlgen resolvers

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make the gqlgen command runnable

When contributors follow this new codegen step from apps/api, this go run is resolved in the current module because it has no @version suffix (checked go help run), but apps/api/go.mod/go.sum do not require github.com/99designs/gqlgen (rg 99designs apps/api/go.mod apps/api/go.sum returns no matches). In a normal module-aware Go setup this fails with “no required module provides package” instead of regenerating resolvers, so either add a tracked tool dependency or use a versioned command such as .../gqlgen@<version>.

Useful? React with 👍 / 👎.

sqlc generate # Regenerate sqlc queries

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make the sqlc generation command runnable

This newly documented sqlc generate step is not runnable in the current API tree: apps/api/sqlc.yaml points at internal/repository/queries/ and migrations/, but I checked the tracked files under apps/api and neither input directory exists. Contributors who follow the local-dev commands will hit a sqlc input-path error instead of regenerating code, so either add the expected inputs/placeholders or mark this as a planned command until the repository contains them.

Useful? React with 👍 / 👎.

```

## Required Environment Variables

Key variables (copy into `apps/mobile/.env` and `apps/api/.env` respectively):

| Variable | Where used | Purpose |
|---|---|---|
| `EXPO_PUBLIC_API_URL` | mobile | GraphQL API base URL |
| `FIREBASE_PROJECT_ID` | mobile + api | Firebase project for auth |
| `DATABASE_URL` | api | PostgreSQL connection string |
| `GCP_PROJECT_ID` | api | GCP project for Vertex AI and Cloud Storage |

Never commit `.env` files. Use GCP Secret Manager in deployed environments.

## Testing Framework

- **Mobile / packages:** Jest with `@testing-library/react-native`. Tests co-located as `ComponentName/ComponentName.test.tsx`. Run with `pnpm --filter mobile test`.
- **API:** `go test ./... -race -coverprofile=coverage.out` (matches CI). Integration tests require a running PostgreSQL instance (see README or ask in #dev for local DB setup steps).
- **E2E:** Maestro flows planned under `tests/e2e/` — not yet wired into CI (deferred until 3+ screens exist).
- TDD is required: write failing tests before implementation. No `.skip()`, no coverage-ignore comments.

## Repo-Specific Overrides

- Use Gluestack UI v3 compound component patterns exclusively — never build custom primitives when a Gluestack component exists.
- Never hardcode hex colors; use Gluestack design tokens (`bg-primary-500`, `text-error-600`, etc.).
- Minimum touch target is 48×48 px (gloved field use); primary inspection actions are 56×48 px.
- All server data fetching goes through TanStack Query. Mutations must invalidate relevant queries on success.
- GraphQL types come from `packages/graphql-types/` — never hand-write response types.
- The zero-tap beeyard inspection flow is the core differentiator: voice-driven, no taps required in the field.
5 changes: 0 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,3 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
.dev-lead/
.dev-lead/
.dev-lead/
.dev-lead/
.dev-lead/
.dev-lead/
3 changes: 3 additions & 0 deletions apps/api/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
DATABASE_URL=postgres://postgres:postgres@localhost:5432/broodly?sslmode=disable
FIREBASE_PROJECT_ID=your-firebase-project-id
GCP_PROJECT_ID=your-gcp-project-id
2 changes: 2 additions & 0 deletions apps/mobile/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
EXPO_PUBLIC_API_URL=http://localhost:8080/graphql
FIREBASE_PROJECT_ID=your-firebase-project-id

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Prefix the mobile Firebase env var

For mobile code that reads the Firebase project ID in the Expo JavaScript bundle, copying this example leaves the value unavailable: Expo only inlines .env variables with the EXPO_PUBLIC_ prefix into client code (see Expo environment variable docs: https://docs.expo.dev/guides/environment-variables/). Since the new instructions mark this variable as used by mobile + api, the mobile example should expose a public, non-secret name such as EXPO_PUBLIC_FIREBASE_PROJECT_ID rather than FIREBASE_PROJECT_ID.

Useful? React with 👍 / 👎.

Loading