convert pdf to md, add OVERVIEW and docs
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# effects — if you are changing X, open these
|
||||
|
||||
One job: turn "I am about to change X" into a short list of cards to read first. This file
|
||||
is an **index only**. It holds no facts — if it disagrees with a card, the card is right
|
||||
and this file is stale.
|
||||
|
||||
## Inputs
|
||||
|
||||
- Reference: `../objects/_index.md`, `../processes/CONTEXT.md`
|
||||
- Reference: `../CONTEXT.md` — read the traps before any change to money or rosters
|
||||
|
||||
## Read first, always
|
||||
|
||||
Four things are true of this codebase and wrong in most people's mental model. All four
|
||||
are in `../CONTEXT.md`:
|
||||
|
||||
1. A student's classroom has **two** rival sources of truth.
|
||||
2. Money is integer cents — except `Portfolio#cash_balance`, which returns dollars.
|
||||
3. Cash is never stored; the balance includes **pending** orders.
|
||||
4. The Alpha Vantage key is read two different ways with two different fallbacks.
|
||||
|
||||
## By what you are changing
|
||||
|
||||
| If you are changing… | Open | Then check |
|
||||
|---|---|---|
|
||||
| **anything with a balance** | [portfolio](../objects/money/portfolio.md), [portfolio-transaction](../objects/money/portfolio-transaction.md) | every `_cents` vs dollars boundary; pending-order subtraction |
|
||||
| **order placement or execution** | [order](../objects/trading/order.md), [place-and-execute-order](../processes/place-and-execute-order.md) | model validations *and* `ExecuteOrder` — they duplicate each other |
|
||||
| **the trading fee** | [portfolio-transaction](../objects/money/portfolio-transaction.md), [order](../objects/trading/order.md) | fee is per user **per sweep**, and `Portfolio` anticipates exactly one |
|
||||
| **holdings or share counts** | [portfolio-stock](../objects/trading/portfolio-stock.md), [portfolio-position](../objects/trading/portfolio-position.md) | lots are append-only; sells are negative rows |
|
||||
| **stock prices or the API** | [stock](../objects/trading/stock.md), [refresh-market-data](../processes/refresh-market-data.md) | the two key lookups; the six auto-overwritten columns |
|
||||
| **payout amounts** | [grade-entry](../objects/gradebook/grade-entry.md), [finalize-gradebook-earnings](../processes/finalize-gradebook-earnings.md) | constants are code, not config; `GRADE_OPTIONS` order is load-bearing |
|
||||
| **gradebook workflow or status** | [grade-book](../objects/gradebook/grade-book.md) | the `completed?` guard is the only double-pay protection; finalize is **admin-only** |
|
||||
| **rosters or enrollment** | [classroom-enrollment](../objects/org/classroom-enrollment.md), [classroom](../objects/org/classroom.md), [student](../objects/identity/student.md) | both roster paths, every time |
|
||||
| **the school-year skeleton** | [school-year](../objects/org/school-year.md), [quarter](../objects/org/quarter.md), [year](../objects/org/year.md) | the two auto-create cascades; the `"YYYY - YYYY"` string format |
|
||||
| **login, roles, or permissions** | [user](../objects/identity/user.md), [authenticate-authorize](../processes/authenticate-authorize.md) | username-not-email; `/admin` bypasses Pundit; `verify_authorized` is off |
|
||||
| **a scheduled job** | [processes/CONTEXT.md](../processes/CONTEXT.md), `config/recurring.yml` | jobs bypass authorization entirely |
|
||||
| **charts or history** | [portfolio-snapshot](../objects/trading/portfolio-snapshot.md), [snapshot-portfolio-worth](../processes/snapshot-portfolio-worth.md) | history is unrecoverable if a month is missed |
|
||||
| **creating students in bulk** | [import-students](../processes/import-students.md), [student](../objects/identity/student.md) | `classroom_id` drives the enrollment callback |
|
||||
| **announcements** | [announcement](../objects/announcement.md) | `body` column is dead; content is Action Text |
|
||||
|
||||
## Changes with a wider blast radius than they look
|
||||
|
||||
| Change | Why it spreads |
|
||||
|---|---|
|
||||
| `Portfolio#cash_balance` return unit | every caller converts by hand; there is no shared money type |
|
||||
| `GradeEntry::GRADE_OPTIONS` order | improvement bonuses compare array indices |
|
||||
| `users.classroom_id` | still joined by `Order.for_teacher`, `Classroom#students`, and redirects |
|
||||
| `PortfolioTransaction` enum values | integer-backed; renumbering rewrites the meaning of existing rows |
|
||||
| `Year#name` format | SQL ordering and quarter navigation both parse the string |
|
||||
| adding a `before_action` to `ApplicationController` | runs on `/admin` too — `Admin::BaseController` inherits it |
|
||||
|
||||
## Changes that are safer than they look
|
||||
|
||||
| Change | Why it is contained |
|
||||
|---|---|
|
||||
| editing a gradebook after finalize | deposits carry no link back; nothing recomputes |
|
||||
| archiving a stock | sells still work; only buying is blocked |
|
||||
| discarding a user | the ledger is untouched and still sums |
|
||||
| deleting snapshots | charts break, balances do not |
|
||||
| editing `app/controllers/schools_controller.rb` | it is a **ghost** — no route reaches it |
|
||||
|
||||
## Human check
|
||||
|
||||
After a change, re-read the **Does not hit** line of every card you opened. That line is
|
||||
the one most likely to have gone stale, and a wrong "does not hit" is more expensive than
|
||||
a missing card.
|
||||
Reference in New Issue
Block a user