|
| 1 | +# Contributing |
| 2 | + |
| 3 | +A short guide to keep changes consistent and CI green. The repo is small, so |
| 4 | +the only hard rule is the title: **green CI, clear file location, no surprise |
| 5 | +abstractions.** |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Quick start |
| 10 | + |
| 11 | +```bash |
| 12 | +make install # once: venv, npm deps, pre-commit hooks |
| 13 | +make dev # runs backend (:8001) and frontend (:3121) together |
| 14 | +make check # mirrors CI - run before pushing |
| 15 | +make pre-commit # format + check (the safe way to ship) |
| 16 | +make help # lists every target |
| 17 | +``` |
| 18 | + |
| 19 | +The `Makefile` is the source of truth for commands. If a step is missing |
| 20 | +from the Makefile, add it there before adding it to your shell history. |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## File layout |
| 25 | + |
| 26 | +### Backend (`backend/`, flat Python package) |
| 27 | + |
| 28 | +``` |
| 29 | +backend/ |
| 30 | +├── server.py FastAPI app, routes, request/response models. |
| 31 | +├── calculator.py compute_chart(): full birth-chart pipeline. |
| 32 | +├── transits.py Sign / nakshatra / retrograde event scanner. |
| 33 | +├── muhurta.py Auspicious-window finder. |
| 34 | +├── advanced_panchang.py Daily Drik Panchang (tithi, nakshatra, yoga ...). |
| 35 | +├── panchang_extras.py Layered yogas on top of advanced_panchang. |
| 36 | +├── panchang_constants.py Tables for the panchang modules. |
| 37 | +├── ayanamsa.py Ayanamsa option table + setter. |
| 38 | +├── constants.py Sign / nakshatra / tithi / vara names. |
| 39 | +├── vargas.py D1-D60 divisional chart math. |
| 40 | +├── dasha_extras.py Antardasha / Pratyantar sub-period computation. |
| 41 | +├── drishti.py Vedic aspect calculator. |
| 42 | +├── relationships.py Natural / temporal / 5-fold friendship matrices. |
| 43 | +├── jaimini.py Chara karakas + Karakamsa / Swamsa charts. |
| 44 | +├── kalsarpa.py Kalsarpa Yoga detection. |
| 45 | +├── mangal.py Mangal Dosha analysis. |
| 46 | +├── sade_sati.py Saturn-from-Moon 120-year transit table. |
| 47 | +├── gowri_panchang.py Tamil/Telugu Gowri Panchangam. |
| 48 | +├── hora.py Planetary Hora hours. |
| 49 | +├── nalla_neram.py Tamil Nalla Neram windows. |
| 50 | +├── tamil_calendar.py Tamil calendar (year, month, weekday). |
| 51 | +├── tyajyam.py Inauspicious time periods. |
| 52 | +├── pdf/ PDF report renderer (its own subpackage). |
| 53 | +├── ephe/ Swiss Ephemeris data files. NEVER move or delete. |
| 54 | +└── tests/ pytest suites + conftest. |
| 55 | +``` |
| 56 | + |
| 57 | +**Where does new backend code go?** |
| 58 | + |
| 59 | +- A new astronomical calculation (varga variant, dosha analysis): new |
| 60 | + top-level `backend/<name>.py`. Match the existing one-word naming. |
| 61 | +- A new panchang section: add to `advanced_panchang.py` if it shares the |
| 62 | + daily sunrise/sunset machinery, otherwise its own module. |
| 63 | +- A new API route: in `server.py`. Keep `server.py` thin - it should |
| 64 | + delegate calculation to a module. |
| 65 | +- Constants and lookup tables: prefer `constants.py` (chart names) or |
| 66 | + `panchang_constants.py` (panchang tables). |
| 67 | + |
| 68 | +**Style:** `make format-backend` (ruff format) handles every choice. No |
| 69 | +manual style decisions. |
| 70 | + |
| 71 | +### Frontend (`frontend/src/`, feature-folder layout) |
| 72 | + |
| 73 | +``` |
| 74 | +src/ |
| 75 | +├── App.tsx Shell: TopBar, route switcher, Footer. |
| 76 | +├── main.tsx Entry: I18nProvider + StrictMode. |
| 77 | +├── index.css Tailwind globals + token bridge. |
| 78 | +│ |
| 79 | +├── pages/ One file per top-level route. |
| 80 | +│ ├── KundaliPage.tsx |
| 81 | +│ ├── PanchangPage.tsx |
| 82 | +│ ├── MuhurtaPage.tsx |
| 83 | +│ ├── TransitsPage.tsx |
| 84 | +│ └── ... |
| 85 | +│ |
| 86 | +├── components/ UI grouped by the page that owns it. |
| 87 | +│ ├── common/ Used by 2+ pages (CitySearch, MandalaLoader). |
| 88 | +│ ├── shell/ TopBar, Footer, NotificationBanner. |
| 89 | +│ ├── ui/ Generic primitives (DatePicker, Switch). |
| 90 | +│ ├── kundali/ Kundali-page-specific (Charts, PlanetsTable). |
| 91 | +│ ├── panchang/ Panchang-page-specific (Section, TimeBand). |
| 92 | +│ └── transits/ Transit-page-specific (TransitTimeline). |
| 93 | +│ |
| 94 | +├── lib/ Pure utilities. No React, no JSX. |
| 95 | +│ ├── api.ts Typed fetch wrappers for every backend route. |
| 96 | +│ ├── format.ts Date / time / number formatters. |
| 97 | +│ ├── planets.ts Planet abbr -> colour / long-name tables. |
| 98 | +│ ├── seo.ts applySeo() for per-route title/canonical. |
| 99 | +│ └── ... |
| 100 | +│ |
| 101 | +├── i18n/ Internationalisation. |
| 102 | +│ ├── index.tsx LANGUAGES, I18nProvider, useI18n. |
| 103 | +│ ├── astro.ts Planet/sign/nakshatra translation dictionaries. |
| 104 | +│ └── locales/ UI-string dictionaries per locale. |
| 105 | +│ |
| 106 | +└── types/api.ts TypeScript shapes for backend responses. |
| 107 | +``` |
| 108 | + |
| 109 | +**Where does new frontend code go?** |
| 110 | + |
| 111 | +- New top-level route: page file in `pages/` + entry in `App.tsx` |
| 112 | + (`View` union, `VIEW_PATH`, `SEO_BY_VIEW`, `viewFromPath`) + tab in |
| 113 | + `components/shell/TopBar.tsx` + nav-label key in |
| 114 | + `i18n/locales/en.ts` (other locales fall back to English). |
| 115 | +- New component used by one page: `components/<page>/<Name>.tsx`. |
| 116 | +- New component used by two or more pages: promote to `components/common/`. |
| 117 | +- New API call: typed wrapper in `lib/api.ts` + matching type in |
| 118 | + `types/api.ts`. |
| 119 | +- New translatable string: English in `i18n/locales/en.ts` (mandatory); |
| 120 | + other locales optional - they fall back to English automatically. Astro |
| 121 | + names (planet / sign / nakshatra) go in `i18n/astro.ts` instead. |
| 122 | + |
| 123 | +**Path alias:** `@/...` resolves to `src/...`. Always use it. Never |
| 124 | +`../../components/...`. |
| 125 | + |
| 126 | +**Style:** `make format-frontend` (oxfmt) handles every choice. |
| 127 | + |
| 128 | +--- |
| 129 | + |
| 130 | +## Conventions |
| 131 | + |
| 132 | +### Naming |
| 133 | + |
| 134 | +- **Files:** snake_case for Python, kebab-case isn't used in this repo; |
| 135 | + TSX files are PascalCase for components (`TransitTimeline.tsx`) and |
| 136 | + camelCase for non-component modules (`urlState.ts`). |
| 137 | +- **Tests:** mirror the module they cover: `transits.py` -> |
| 138 | + `tests/test_transits.py`. |
| 139 | + |
| 140 | +### Imports |
| 141 | + |
| 142 | +- Backend: prefer absolute imports (`from calculator import compute_chart`). |
| 143 | + `conftest.py` puts `backend/` on `sys.path` for tests. |
| 144 | +- Frontend: always use `@/` alias. |
| 145 | + |
| 146 | +### Types |
| 147 | + |
| 148 | +- Backend uses Pydantic models in `server.py` for request bodies. |
| 149 | +- Frontend mirrors every response shape in `types/api.ts`. Run |
| 150 | + `make check-frontend` to catch shape drift. |
| 151 | + |
| 152 | +### Comments |
| 153 | + |
| 154 | +CLAUDE.md is authoritative here. Short version: |
| 155 | + |
| 156 | +- Default to no comments. Names should carry the meaning. |
| 157 | +- Add a comment only for the non-obvious **why**: a hidden constraint, a |
| 158 | + workaround for a specific bug, behaviour that would surprise a reader. |
| 159 | +- No em dashes (use `-`). UI/i18n strings stay plain ASCII in English. |
| 160 | + Hindi / Tamil / Bengali / etc. use their native script. |
| 161 | + |
| 162 | +--- |
| 163 | + |
| 164 | +## Workflow |
| 165 | + |
| 166 | +```bash |
| 167 | +git checkout -b feat/whatever |
| 168 | +# ... edit ... |
| 169 | +make pre-commit # format + verify; same gates as CI |
| 170 | +git add ... |
| 171 | +git commit -m "feat: short message" |
| 172 | +git push -u origin feat/whatever |
| 173 | +gh pr create |
| 174 | +``` |
| 175 | + |
| 176 | +The `pre-commit-config.yaml` hooks fire automatically on `git commit` once |
| 177 | +`make install-hooks` has been run. They run ruff + oxfmt + oxlint - the |
| 178 | +same tools `make check` runs in `--check` mode. |
| 179 | + |
| 180 | +### Before opening a PR |
| 181 | + |
| 182 | +1. `make pre-commit` passes (mirrors CI gates). |
| 183 | +2. `make test` passes (CI doesn't run tests today, but the suite is |
| 184 | + fast and catches a lot). |
| 185 | +3. Manual UI test if you touched anything visual. Memory note: |
| 186 | + visual changes need to be confirmed in a browser before shipping. |
| 187 | + |
| 188 | +--- |
| 189 | + |
| 190 | +## Industry-standard practices we've adopted |
| 191 | + |
| 192 | +| Practice | Where | Why | |
| 193 | +|---|---|---| |
| 194 | +| **Pre-commit hooks** | `.pre-commit-config.yaml` | Catch format issues before CI does. | |
| 195 | +| **Single dev entrypoint** | `Makefile` | New contributors run one command, not five. | |
| 196 | +| **Editor consistency** | `.editorconfig` | Same indentation/EOLs across editors. | |
| 197 | +| **Path aliases** | `@/` in `tsconfig.json`, `vite.config.ts` | Refactors stop breaking on file moves. | |
| 198 | +| **Feature folders** | `components/{kundali,panchang,...}/` | Keep the change-blast-radius small. | |
| 199 | +| **CI mirror locally** | `make check` | "Works on my machine" goes away. | |
| 200 | +| **Typed API boundary** | `types/api.ts` + Pydantic in `server.py` | Schema drift caught at build time. | |
| 201 | + |
| 202 | +--- |
| 203 | + |
| 204 | +## Known hot spots |
| 205 | + |
| 206 | +These files are large enough that a future split would help, but the |
| 207 | +mechanical risk is non-trivial. Listed so they get prioritised when |
| 208 | +touched substantially: |
| 209 | + |
| 210 | +| File | Lines | Suggested split | |
| 211 | +|---|---|---| |
| 212 | +| `frontend/src/i18n/astro.ts` | 2161 | Each locale dict (HI/TA/...) into its own file under `i18n/astro/`, keep `index.ts` for the lookup helpers. | |
| 213 | +| `backend/advanced_panchang.py` | 1255 | Group by panchang section: tithi/nak/yoga/karana detectors separated from sunrise/sunset machinery. | |
| 214 | +| `frontend/src/pages/PanchangPage.tsx` | 1161 | Extract each `<Section>` block into its own component under `components/panchang/`. | |
| 215 | + |
| 216 | +A split is only worth it if it reduces "where do I edit?" friction. Don't |
| 217 | +split for line-count alone. |
0 commit comments