This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Flaredown is a chronic-illness symptom tracker. It is a monorepo with three deployable apps:
backend/— Rails 7.1 API (Ruby 3.2.3), the only backend for all clients.frontend/— Ember.js 2.18 web app (the production web client at app.flaredown.com), proxies API calls to the backend.native/— Expo / React Native + TypeScript app (newer, in-progress replacement for the Ember client).
The root app/ directory is a stray remnant (single g-recaptcha.js), not a fourth app.
Everything is Dockerized; make wraps docker compose. Prefer these over running services natively.
make start/make stop— run the full dev stack (backend + workers + Ember frontend) via thedevprofile.make startNative/make stopNative— run backend + React Native (nativeprofile).make build— rebuild the backend image. Do this before running specs if backend code/deps changed.make seed— seed databases (rails app:setup).make console— Rails console.- Web app: http://localhost:4300 (Ember). Native: http://localhost:19006. Backend API: http://localhost:3000.
- All backend specs:
make specs(equivalentlyscript/backend rspec spec spec). - A single spec:
script/backend rspec spec/services/weather_retriever_spec.rb. Thescript/backendwrapper runs any command inside the backend container (docker compose --profile dev run --rm backend $@). - Add
debuggerto Ruby code to break into an interactive shell under rspec. - Frontend (Ember):
cd frontend && npm test(ember test). - Native:
cd native && npm test(jest),npm run tsc(typecheck).
- Ruby:
script/backend standardrb(StandardRB, not RuboCop). - ERB:
script/backend erb_lint --lint-all. - Native:
cd native && npm run lint(eslint + prettier),npm run lint:fixto autofix.
CI (.github/workflows/{backend,frontend,native}.yml) uses path filters — backend jobs only run when backend/** changes, etc. StandardRB, ERB lint, rspec, and frontend build are required for merge.
The backend uses both PostgreSQL and MongoDB simultaneously, split by data type:
- PostgreSQL (ActiveRecord) — relational/reference data:
User(Devise auth),Condition,Symptom,Treatment,Food,Tag,Profile,Weather, and theuser_*join tables. These models subclassActiveRecord::Baseand carry a# == Schema Informationheader. Schema lives indb/schema.rb+db/structure.sql; migrations indb/migrate/. - MongoDB (Mongoid 9) — high-volume, user-generated, schemaless data:
Checkin(the core daily symptom/treatment/tag log),Comment,Reaction,Pattern,Notification,HarveyBradshawIndex,Feedback,PromotionRate,OracleRequest. Theseinclude Mongoid::Document. Config inconfig/mongoid.yml.
The two stores are linked by an encrypted foreign key: Mongo documents store encrypted_user_id (symmetric-encryption gem, see config/symmetric-encryption.yml) rather than a plain user_id, and dereference it back to the Postgres User. When querying check-in data by user, filter on encrypted_user_id, not user_id. Checkin embeds condition/symptom/treatment sub-documents inline.
Versioned JSON API under app/controllers/api/v1/, routed via namespace :api { scope module: :v1 } in config/routes.rb. Serialization uses active_model_serializers 0.9 (app/serializers/). Auth is Devise + devise_invitable + Facebook OmniAuth; authorization is CanCanCan with a Mongoid adapter (app/models/ability.rb). Business logic lives in app/services/ (e.g. weather_retriever, pattern_creator, chart_list_service) — controllers should stay thin.
Sidekiq (config/sidekiq.yml, worker process in Procfile) backed by Redis, with jobs in app/jobs/ (check-in reminders, data exports, notification dispatch, top-posts mailers). Recurring schedules are defined in config/cronotab.rb (Crono) and rake tasks under lib/tasks/ invoked by Heroku Scheduler.
Tomorrow.io (weather, via tomorrowio_rb), Pusher (realtime), Geocoder + nearest_time_zone (location → timezone for reminders), AWS SES (inbound/bounce handling in aws_ses_controller).
Heroku, via rake tasks in the root Rakefile. Frontend and backend are separate Heroku apps deployed with git subtree split (rake production:deploy / rake staging:deploy). Commits to master auto-deploy to staging. Postgres/Redis are Heroku addons; MongoDB is hosted at mongodb.com.
- The Ember frontend requires Node >= 18 (
enginesinfrontend/package.json, enforced byengine-strict=trueinfrontend/.npmrc).frontend/.nvmrcpins the version CI builds against;nvm installorasdf installinfrontend/picks it up. The build does not work on Node 16 or older, so switch versions rather than bypassing the engine check. frontend/npm installneeds nosudo,--unsafe-permor--allow-root, as root or otherwise. If you are tempted to add one, something else is wrong.- Env files:
cp backend/env-example backend/.envandcp frontend/env-example frontend/.env. They are read independently — Rails readsbackend/.env, andfrontend/config/environment.jsloadsfrontend/.envitself (at the top of the file, deliberately: ember-cli evaluates that file before addon config hooks run, so loading.envvia an addon silently drops the values on a cold build).FACEBOOK_APP_IDis only needed for Facebook login.